1 /*
2  * Copyright (C) 2003-2015 FreeIPMI Core Team
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 
19 #if HAVE_CONFIG_H
20 #include "config.h"
21 #endif /* HAVE_CONFIG_H */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #if STDC_HEADERS
26 #include <string.h>
27 #include <ctype.h>
28 #endif /* STDC_HEADERS */
29 #if HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif /* HAVE_UNISTD_H */
32 #include <errno.h>
33 #include <assert.h>
34 
35 #include <freeipmi/freeipmi.h>
36 
37 #include "freeipmi-portability.h"
38 #include "parse-common.h"
39 
40 #define WORKAROUND_FLAG_BUFLEN 1024
41 
42 int
parse_inband_driver_type(const char * str)43 parse_inband_driver_type (const char *str)
44 {
45   assert (str);
46 
47   if (strcasecmp (str, IPMI_PARSE_DEVICE_KCS_STR) == 0)
48     return (IPMI_DEVICE_KCS);
49   else if (strcasecmp (str, IPMI_PARSE_DEVICE_SSIF_STR) == 0)
50     return (IPMI_DEVICE_SSIF);
51   /* support "open" for those that might be used to
52    * ipmitool.
53    */
54   else if (strcasecmp (str, IPMI_PARSE_DEVICE_OPENIPMI_STR) == 0
55            || strcasecmp (str, IPMI_PARSE_DEVICE_OPENIPMI_STR2) == 0)
56     return (IPMI_DEVICE_OPENIPMI);
57   /* support "bmc" for those that might be used to
58    * ipmitool.
59    */
60   else if (strcasecmp (str, IPMI_PARSE_DEVICE_SUNBMC_STR) == 0
61            || strcasecmp (str, IPMI_PARSE_DEVICE_SUNBMC_STR2) == 0)
62     return (IPMI_DEVICE_SUNBMC);
63   else if (strcasecmp (str, IPMI_PARSE_DEVICE_INTELDCMI_STR) == 0)
64     return (IPMI_DEVICE_INTELDCMI);
65 
66   return (-1);
67 }
68 
69 int
parse_outofband_driver_type(const char * str)70 parse_outofband_driver_type (const char *str)
71 {
72   assert (str);
73 
74   if (strcasecmp (str, IPMI_PARSE_DEVICE_LAN_STR) == 0)
75     return (IPMI_DEVICE_LAN);
76   /* support "lanplus" for those that might be used to ipmitool.
77    * support typo variants to ease.
78    */
79   else if (strcasecmp (str, IPMI_PARSE_DEVICE_LAN_2_0_STR) == 0
80            || strcasecmp (str, IPMI_PARSE_DEVICE_LAN_2_0_STR2) == 0
81            || strcasecmp (str, IPMI_PARSE_DEVICE_LAN_2_0_STR3) == 0
82            || strcasecmp (str, IPMI_PARSE_DEVICE_LAN_2_0_STR4) == 0
83            || strcasecmp (str, IPMI_PARSE_DEVICE_LAN_2_0_STR5) == 0)
84     return (IPMI_DEVICE_LAN_2_0);
85 
86   return (-1);
87 }
88 
89 int
parse_driver_type(const char * str)90 parse_driver_type (const char *str)
91 {
92   int ret;
93 
94   assert (str);
95 
96   if ((ret = parse_inband_driver_type (str)) < 0)
97     ret = parse_outofband_driver_type (str);
98 
99   return (ret);
100 }
101 
102 int
parse_authentication_type(const char * str)103 parse_authentication_type (const char *str)
104 {
105   assert (str);
106 
107   if (strcasecmp (str, IPMI_PARSE_AUTHENTICATION_TYPE_NONE_STR) == 0)
108     return (IPMI_AUTHENTICATION_TYPE_NONE);
109   /* keep "plain" for backwards compatability */
110   else if (strcasecmp (str, IPMI_PARSE_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY_STR) == 0
111            || strcasecmp (str, IPMI_PARSE_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY_STR2) == 0)
112     return (IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY);
113   else if (strcasecmp (str, IPMI_PARSE_AUTHENTICATION_TYPE_MD2_STR) == 0)
114     return (IPMI_AUTHENTICATION_TYPE_MD2);
115   else if (strcasecmp (str, IPMI_PARSE_AUTHENTICATION_TYPE_MD5_STR) == 0)
116     return (IPMI_AUTHENTICATION_TYPE_MD5);
117 
118   return (-1);
119 }
120 
121 int
parse_privilege_level(const char * str)122 parse_privilege_level (const char *str)
123 {
124   assert (str);
125 
126   if (strcasecmp (str, IPMI_PARSE_PRIVILEGE_LEVEL_USER_STR) == 0)
127     return (IPMI_PRIVILEGE_LEVEL_USER);
128   else if (strcasecmp (str, IPMI_PARSE_PRIVILEGE_LEVEL_OPERATOR_STR) == 0)
129     return (IPMI_PRIVILEGE_LEVEL_OPERATOR);
130   else if (strcasecmp (str, IPMI_PARSE_PRIVILEGE_LEVEL_ADMIN_STR) == 0
131            || strcasecmp (str, IPMI_PARSE_PRIVILEGE_LEVEL_ADMIN_STR2) == 0)
132     return (IPMI_PRIVILEGE_LEVEL_ADMIN);
133 
134   return (-1);
135 }
136 
137 static int
_parse_workaround_flags(const char * str,unsigned int * workaround_flags_outofband,unsigned int * workaround_flags_outofband_2_0,unsigned int * workaround_flags_inband,unsigned int * workaround_flags_sdr,unsigned int * section_specific_workaround_flags,int command_line_flag)138 _parse_workaround_flags (const char *str,
139                          unsigned int *workaround_flags_outofband,
140                          unsigned int *workaround_flags_outofband_2_0,
141                          unsigned int *workaround_flags_inband,
142                          unsigned int *workaround_flags_sdr,
143                          unsigned int *section_specific_workaround_flags,
144                          int command_line_flag)
145 {
146   char buf[WORKAROUND_FLAG_BUFLEN+1];
147   char *tok;
148 
149   assert (str);
150 
151   memset (buf, '\0', WORKAROUND_FLAG_BUFLEN+1);
152   strncpy (buf, str, WORKAROUND_FLAG_BUFLEN);
153 
154   if (workaround_flags_outofband)
155     (*workaround_flags_outofband) = 0;
156   if (workaround_flags_outofband_2_0)
157     (*workaround_flags_outofband_2_0) = 0;
158   if (workaround_flags_inband)
159     (*workaround_flags_inband) = 0;
160   if (workaround_flags_sdr)
161     (*workaround_flags_sdr) = 0;
162   if (section_specific_workaround_flags)
163     (*section_specific_workaround_flags) = 0;
164 
165   tok = strtok (buf, ",");
166   while (tok)
167     {
168       if (command_line_flag
169           && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_NONE_STR))
170         {
171           if (workaround_flags_outofband)
172             (*workaround_flags_outofband) = 0;
173           if (workaround_flags_outofband_2_0)
174             (*workaround_flags_outofband_2_0) = 0;
175           if (workaround_flags_inband)
176             (*workaround_flags_inband) = 0;
177           if (workaround_flags_sdr)
178             (*workaround_flags_sdr) = 0;
179           if (section_specific_workaround_flags)
180             (*section_specific_workaround_flags) = 0;
181           break;
182         }
183 
184       /* special case, may apply to outofband and outofband_2_0 */
185       if (!strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_AUTHENTICATION_CAPABILITIES_STR))
186         {
187           if (workaround_flags_outofband)
188             (*workaround_flags_outofband) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_AUTHENTICATION_CAPABILITIES;
189           if (workaround_flags_outofband_2_0)
190             (*workaround_flags_outofband_2_0) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_AUTHENTICATION_CAPABILITIES;
191         }
192       /* special case, may apply to outofband and outofband_2_0 */
193       else if (!strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_CHECKSUM_CHECK_STR))
194         {
195           if (workaround_flags_outofband)
196             (*workaround_flags_outofband) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_CHECKSUM_CHECK;
197           if (workaround_flags_outofband_2_0)
198             (*workaround_flags_outofband_2_0) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NO_CHECKSUM_CHECK;
199         }
200       else if (workaround_flags_outofband
201                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_ACCEPT_SESSION_ID_ZERO_STR))
202         (*workaround_flags_outofband) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_ACCEPT_SESSION_ID_ZERO;
203       else if (workaround_flags_outofband
204                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_FORCE_PERMSG_AUTHENTICATION_STR))
205         (*workaround_flags_outofband) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_FORCE_PERMSG_AUTHENTICATION;
206       else if (workaround_flags_outofband
207                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_CHECK_UNEXPECTED_AUTHCODE_STR))
208         (*workaround_flags_outofband) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_CHECK_UNEXPECTED_AUTHCODE;
209       else if (workaround_flags_outofband
210                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_BIG_ENDIAN_SEQUENCE_NUMBER_STR))
211         (*workaround_flags_outofband) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_BIG_ENDIAN_SEQUENCE_NUMBER;
212       else if (workaround_flags_outofband
213                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_AUTH_CODE_CHECK_STR))
214         (*workaround_flags_outofband) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_AUTH_CODE_CHECK;
215 #if 0
216       /* handled above w/ special case */
217       else if (workaround_flags_outofband_2_0
218                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_AUTHENTICATION_CAPABILITIES_STR))
219         (*workaround_flags_outofband_2_0) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_AUTHENTICATION_CAPABILITIES;
220 #endif
221       else if (workaround_flags_outofband_2_0
222                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION_STR))
223         (*workaround_flags_outofband_2_0) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION;
224       else if (workaround_flags_outofband_2_0
225                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUPERMICRO_2_0_SESSION_STR))
226         (*workaround_flags_outofband_2_0) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUPERMICRO_2_0_SESSION;
227       else if (workaround_flags_outofband_2_0
228                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUN_2_0_SESSION_STR))
229         (*workaround_flags_outofband_2_0) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUN_2_0_SESSION;
230       else if (workaround_flags_outofband_2_0
231                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE_STR))
232         (*workaround_flags_outofband_2_0) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE;
233       else if (workaround_flags_outofband_2_0
234                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NON_EMPTY_INTEGRITY_CHECK_VALUE_STR))
235         (*workaround_flags_outofband_2_0) |= IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NON_EMPTY_INTEGRITY_CHECK_VALUE;
236       else if (workaround_flags_inband
237                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_INBAND_ASSUME_IO_BASE_ADDRESS_STR))
238         (*workaround_flags_inband) |= IPMI_PARSE_WORKAROUND_FLAGS_INBAND_ASSUME_IO_BASE_ADDRESS;
239       else if (workaround_flags_inband
240                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_INBAND_SPIN_POLL_STR))
241         (*workaround_flags_inband) |= IPMI_PARSE_WORKAROUND_FLAGS_INBAND_SPIN_POLL;
242       else if (workaround_flags_sdr
243                && !strcasecmp (tok, IPMI_PARSE_WORKAROUND_FLAGS_SDR_ASSUME_MAX_SDR_RECORD_COUNT_STR))
244         (*workaround_flags_sdr) |= IPMI_PARSE_WORKAROUND_FLAGS_SDR_ASSUME_MAX_SDR_RECORD_COUNT;
245       else if (section_specific_workaround_flags
246                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_SOL_PAYLOAD_SIZE_STR))
247         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_SOL_PAYLOAD_SIZE;
248       else if (section_specific_workaround_flags
249                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_SOL_PORT_STR))
250         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_SOL_PORT;
251       else if (section_specific_workaround_flags
252                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SKIP_SOL_ACTIVATION_STATUS_STR))
253         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SKIP_SOL_ACTIVATION_STATUS;
254       else if (section_specific_workaround_flags
255                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SKIP_CHANNEL_PAYLOAD_SUPPORT_STR))
256         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SKIP_CHANNEL_PAYLOAD_SUPPORT;
257       else if (section_specific_workaround_flags
258                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SERIAL_ALERTS_DEFERRED_STR))
259         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SERIAL_ALERTS_DEFERRED;
260       else if (section_specific_workaround_flags
261                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_INCREMENT_SOL_PACKET_SEQUENCE_STR))
262         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_INCREMENT_SOL_PACKET_SEQUENCE;
263       else if (section_specific_workaround_flags
264                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SKIP_CHECKS_STR))
265         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SKIP_CHECKS;
266       else if (section_specific_workaround_flags
267                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_ASSUME_SYSTEM_EVENT_STR))
268         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_ASSUME_SYSTEM_EVENT;
269       else if (section_specific_workaround_flags
270                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_DISCRETE_READING_STR))
271         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_DISCRETE_READING;
272       else if (section_specific_workaround_flags
273                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_SCANNING_DISABLED_STR))
274         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_SCANNING_DISABLED;
275       else if (section_specific_workaround_flags
276                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_ASSUME_BMC_OWNER_STR))
277         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_ASSUME_BMC_OWNER;
278       else if (section_specific_workaround_flags
279                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_AUTH_CODE_STR))
280         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_AUTH_CODE;
281       else if (section_specific_workaround_flags
282                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SLOW_COMMIT_STR))
283         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SLOW_COMMIT;
284       else if (section_specific_workaround_flags
285                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_VERY_SLOW_COMMIT_STR))
286         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_VERY_SLOW_COMMIT;
287       else if (section_specific_workaround_flags
288                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SOL_CHANNEL_ASSUME_LAN_CHANNEL_STR))
289         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_SOL_CHANNEL_ASSUME_LAN_CHANNEL;
290       else if (section_specific_workaround_flags
291                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_STATE_FLAG_STR))
292         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_STATE_FLAG;
293       else if (section_specific_workaround_flags
294                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_MALFORMED_ACK_STR))
295         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_MALFORMED_ACK;
296       else if (section_specific_workaround_flags
297                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_GUID_FORMAT_STR))
298         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_GUID_FORMAT;
299       else if (section_specific_workaround_flags
300                && !strcasecmp (tok, IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING_STR))
301         (*section_specific_workaround_flags) |= IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING;
302       else
303         return (-1);
304       tok = strtok (NULL, ",");
305     }
306 
307   return (0);
308 }
309 
310 int
parse_workaround_flags(const char * str,unsigned int * workaround_flags_outofband,unsigned int * workaround_flags_outofband_2_0,unsigned int * workaround_flags_inband,unsigned int * workaround_flags_sdr,unsigned int * section_specific_workaround_flags)311 parse_workaround_flags (const char *str,
312                         unsigned int *workaround_flags_outofband,
313                         unsigned int *workaround_flags_outofband_2_0,
314                         unsigned int *workaround_flags_inband,
315                         unsigned int *workaround_flags_sdr,
316                         unsigned int *section_specific_workaround_flags)
317 {
318   return (_parse_workaround_flags (str,
319                                    workaround_flags_outofband,
320                                    workaround_flags_outofband_2_0,
321                                    workaround_flags_inband,
322                                    workaround_flags_sdr,
323                                    section_specific_workaround_flags,
324                                    0));
325 }
326 
327 int
parse_workaround_flags_tool(const char * str,unsigned int * workaround_flags_outofband,unsigned int * workaround_flags_outofband_2_0,unsigned int * workaround_flags_inband,unsigned int * workaround_flags_sdr,unsigned int * section_specific_workaround_flags)328 parse_workaround_flags_tool (const char *str,
329                              unsigned int *workaround_flags_outofband,
330                              unsigned int *workaround_flags_outofband_2_0,
331                              unsigned int *workaround_flags_inband,
332                              unsigned int *workaround_flags_sdr,
333                              unsigned int *section_specific_workaround_flags)
334 {
335   return (_parse_workaround_flags (str,
336                                    workaround_flags_outofband,
337                                    workaround_flags_outofband_2_0,
338                                    workaround_flags_inband,
339                                    workaround_flags_sdr,
340                                    section_specific_workaround_flags,
341                                    1));
342 }
343 
344 /* a k_g key is interpreted as ascii text unless it is prefixed with
345    "0x", in which case is it interpreted as hexadecimal */
346 int
parse_kg(void * out,unsigned int outlen,const char * in)347 parse_kg (void *out, unsigned int outlen, const char *in)
348 {
349   char *p, *q;
350   unsigned int i, j;
351   char buf[3] = { 0, 0, 0};
352   int rv = 0;
353 
354   assert (out);
355   assert (in);
356   assert (outlen >= IPMI_MAX_K_G_LENGTH);
357 
358   if (!strlen (in))
359     return (0);
360 
361   if (!strncasecmp (in, "0x", 2))
362     {
363       if (strlen (in) > IPMI_MAX_K_G_LENGTH*2+2)
364         return (-1);
365       p = (char *)in + 2;
366       /* wipe buffer, '\0', possibly ok */
367       memset (out, '\0', IPMI_MAX_K_G_LENGTH);
368       for (i = j = 0; i < strlen (p); i+=2, j++)
369         {
370           if (!isxdigit (p[i])
371               || (p[i+1] && !isxdigit (p[i+1])))
372             return (-1);
373           buf[0] = p[i];
374           if (p[i+1])
375             buf[1] = p[i+1];
376           else
377             buf[1] = 0;
378           buf[2] = '\0';
379           errno = 0;
380           (((uint8_t *)out)[j]) = (uint8_t)strtoul (buf, &q, 16);
381           if (errno
382               || ((p[i+1] && (q != buf + 2))
383                   || (!p[i+1] && (q != buf + 1))))
384             return (-1);
385           rv++;
386         }
387     }
388   else
389     {
390       if (strlen (in) > IPMI_MAX_K_G_LENGTH)
391         return (-1);
392       /* wipe buffer, '\0', possibly ok */
393       memset (out, '\0', IPMI_MAX_K_G_LENGTH);
394       memcpy (out, in, strlen (in));
395       rv = strlen (in);
396     }
397 
398   return (rv);
399 }
400 
401 void
parse_get_freeipmi_outofband_flags(unsigned int parse_workaround_flags_outofband,unsigned int * freeipmi_workaround_flags_outofband)402 parse_get_freeipmi_outofband_flags (unsigned int parse_workaround_flags_outofband,
403                                     unsigned int *freeipmi_workaround_flags_outofband)
404 {
405   assert (freeipmi_workaround_flags_outofband);
406 
407   (*freeipmi_workaround_flags_outofband) = 0;
408 
409   if (parse_workaround_flags_outofband & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_AUTHENTICATION_CAPABILITIES)
410     (*freeipmi_workaround_flags_outofband) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_AUTHENTICATION_CAPABILITIES;
411   if (parse_workaround_flags_outofband & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_ACCEPT_SESSION_ID_ZERO)
412     (*freeipmi_workaround_flags_outofband) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_ACCEPT_SESSION_ID_ZERO;
413   if (parse_workaround_flags_outofband & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_FORCE_PERMSG_AUTHENTICATION)
414     (*freeipmi_workaround_flags_outofband) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_FORCE_PERMSG_AUTHENTICATION;
415   if (parse_workaround_flags_outofband & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_CHECK_UNEXPECTED_AUTHCODE)
416     (*freeipmi_workaround_flags_outofband) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_CHECK_UNEXPECTED_AUTHCODE;
417   if (parse_workaround_flags_outofband & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_BIG_ENDIAN_SEQUENCE_NUMBER)
418     (*freeipmi_workaround_flags_outofband) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_BIG_ENDIAN_SEQUENCE_NUMBER;
419   if (parse_workaround_flags_outofband & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_AUTH_CODE_CHECK)
420     (*freeipmi_workaround_flags_outofband) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_NO_AUTH_CODE_CHECK;
421   if (parse_workaround_flags_outofband & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_CHECKSUM_CHECK)
422     (*freeipmi_workaround_flags_outofband) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_NO_CHECKSUM_CHECK;
423 }
424 
425 void
parse_get_freeipmi_outofband_2_0_flags(unsigned int parse_workaround_flags_outofband_2_0,unsigned int * freeipmi_workaround_flags_outofband_2_0)426 parse_get_freeipmi_outofband_2_0_flags (unsigned int parse_workaround_flags_outofband_2_0,
427                                         unsigned int *freeipmi_workaround_flags_outofband_2_0)
428 {
429   assert (freeipmi_workaround_flags_outofband_2_0);
430 
431   (*freeipmi_workaround_flags_outofband_2_0) = 0;
432 
433   if (parse_workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_AUTHENTICATION_CAPABILITIES)
434     (*freeipmi_workaround_flags_outofband_2_0) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_AUTHENTICATION_CAPABILITIES;
435   if (parse_workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION)
436     (*freeipmi_workaround_flags_outofband_2_0) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION;
437   if (parse_workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUPERMICRO_2_0_SESSION)
438     (*freeipmi_workaround_flags_outofband_2_0) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUPERMICRO_2_0_SESSION;
439   if (parse_workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUN_2_0_SESSION)
440     (*freeipmi_workaround_flags_outofband_2_0) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUN_2_0_SESSION;
441   if (parse_workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE)
442     (*freeipmi_workaround_flags_outofband_2_0) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE;
443   if (parse_workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NON_EMPTY_INTEGRITY_CHECK_VALUE)
444     (*freeipmi_workaround_flags_outofband_2_0) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_NON_EMPTY_INTEGRITY_CHECK_VALUE;
445   if (parse_workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NO_CHECKSUM_CHECK)
446     (*freeipmi_workaround_flags_outofband_2_0) |= IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_NO_CHECKSUM_CHECK;
447 }
448 
449 void
parse_get_freeipmi_inband_flags(unsigned int parse_workaround_flags_inband,unsigned int * freeipmi_workaround_flags_inband)450 parse_get_freeipmi_inband_flags (unsigned int parse_workaround_flags_inband,
451                                  unsigned int *freeipmi_workaround_flags_inband)
452 {
453   assert (freeipmi_workaround_flags_inband);
454 
455   (*freeipmi_workaround_flags_inband) = 0;
456 
457   if (parse_workaround_flags_inband & IPMI_PARSE_WORKAROUND_FLAGS_INBAND_ASSUME_IO_BASE_ADDRESS)
458     (*freeipmi_workaround_flags_inband) |= IPMI_WORKAROUND_FLAGS_INBAND_ASSUME_IO_BASE_ADDRESS;
459 
460   if (parse_workaround_flags_inband & IPMI_PARSE_WORKAROUND_FLAGS_INBAND_SPIN_POLL)
461     (*freeipmi_workaround_flags_inband) |= IPMI_WORKAROUND_FLAGS_INBAND_SPIN_POLL;
462 }
463