Index: bmc-config/src/bmc-lan-conf-security-keys-section.c =================================================================== RCS file: /sources/freeipmi/freeipmi/bmc-config/src/bmc-lan-conf-security-keys-section.c,v retrieving revision 1.19 diff -u -5 -r1.19 bmc-lan-conf-security-keys-section.c --- bmc-config/src/bmc-lan-conf-security-keys-section.c 31 Jan 2007 06:32:05 -0000 1.19 +++ bmc-config/src/bmc-lan-conf-security-keys-section.c 3 May 2007 17:34:50 -0000 @@ -3,10 +3,11 @@ #include "bmc-config-api.h" #include "bmc-diff.h" #include "bmc-map.h" #include "bmc-sections.h" #include "bmc-validate.h" +#include "ipmi-common.h" static bmc_err_t k_r_checkout (bmc_config_state_data_t *state_data, const struct section *sect, struct keyvalue *kv) @@ -87,27 +88,33 @@ static bmc_err_t k_g_checkout (bmc_config_state_data_t *state_data, const struct section *sect, struct keyvalue *kv) { - uint8_t k_g[IPMI_MAX_K_G_LENGTH + 1]; + uint8_t k_g[IPMI_MAX_K_G_LENGTH]; bmc_err_t ret; - memset (k_g, 0, IPMI_MAX_K_G_LENGTH + 1); + memset (k_g, 0, IPMI_MAX_K_G_LENGTH); if ((ret = get_k_g (state_data, k_g, IPMI_MAX_K_G_LENGTH)) != BMC_ERR_SUCCESS) return ret; if (kv->value) free (kv->value); - k_g[IPMI_MAX_K_G_LENGTH] = '\0'; - if (!(kv->value = strdup ((char *)k_g))) + if (!(kv->value = (char *)malloc(IPMI_MAX_K_G_LENGTH*2+3))) { - perror("strdup"); + perror("malloc"); + return BMC_ERR_FATAL_ERROR; + } + + if (!format_kg(kv->value, IPMI_MAX_K_G_LENGTH*2+3, (unsigned char *)k_g)) + { + free (kv->value); + kv->value = NULL; return BMC_ERR_FATAL_ERROR; } return BMC_ERR_SUCCESS; } @@ -115,36 +122,51 @@ static bmc_err_t k_g_commit (bmc_config_state_data_t *state_data, const struct section *sect, const struct keyvalue *kv) { - return set_k_g (state_data, - (uint8_t *)kv->value, - kv->value ? strlen (kv->value): 0); + uint8_t k_g[IPMI_MAX_K_G_LENGTH]; + + memset (k_g, 0, IPMI_MAX_K_G_LENGTH); + + if (parse_kg(k_g, IPMI_MAX_K_G_LENGTH, kv->value) < 0) + return BMC_ERR_FATAL_ERROR; + + return set_k_g (state_data, k_g, IPMI_MAX_K_G_LENGTH); } static bmc_diff_t k_g_diff (bmc_config_state_data_t *state_data, const struct section *sect, const struct keyvalue *kv) { - uint8_t k_g[IPMI_MAX_K_G_LENGTH + 1]; + uint8_t k_g[IPMI_MAX_K_G_LENGTH]; + uint8_t kv_k_g[IPMI_MAX_K_G_LENGTH]; + char k_g_str[IPMI_MAX_K_G_LENGTH*2+3]; bmc_err_t ret; - memset (k_g, 0, IPMI_MAX_K_G_LENGTH + 1); + memset (k_g, 0, IPMI_MAX_K_G_LENGTH); if ((ret = get_k_g (state_data, k_g, IPMI_MAX_K_G_LENGTH)) != BMC_ERR_SUCCESS) return ret; - if (strcmp (kv->value ? kv->value : "", (char *)k_g)) + if (!format_kg(k_g_str, IPMI_MAX_K_G_LENGTH*2+3, k_g)) + return BMC_ERR_FATAL_ERROR; + + if (parse_kg(kv_k_g, IPMI_MAX_K_G_LENGTH, kv->value) < 0) + return BMC_ERR_FATAL_ERROR; + + /* a printable k_g key can have two representations, so compare the + binary keys */ + if (memcmp (kv_k_g, k_g, IPMI_MAX_K_G_LENGTH)) { ret = BMC_DIFF_DIFFERENT; report_diff (sect->section_name, kv->key, kv->value, - (char *)k_g); + k_g_str); } else ret = BMC_DIFF_SAME; return ret; @@ -153,13 +175,15 @@ static bmc_validate_t k_g_validate (bmc_config_state_data_t *state_data, const struct section *sect, const char *value) { - if (strlen (value) <= IPMI_MAX_K_G_LENGTH) - return BMC_VALIDATE_VALID_VALUE; - return BMC_VALIDATE_INVALID_VALUE; + uint8_t k_g[IPMI_MAX_K_G_LENGTH]; + + if (parse_kg(k_g, IPMI_MAX_K_G_LENGTH, value) < 0) + return BMC_VALIDATE_INVALID_VALUE; + return BMC_VALIDATE_VALID_VALUE; } struct section * bmc_lan_conf_security_keys_section_get (bmc_config_state_data_t *state_data) { @@ -180,11 +204,11 @@ goto cleanup; if (bmc_section_add_keyvalue (state_data, lan_conf_security_keys_section, "K_G", - "Give string or blank to clear. Max 20 chars", + "Give string or blank to clear. Max 20 bytes, prefix with 0x to enter hex", 0, k_g_checkout, k_g_commit, k_g_diff, k_g_validate) < 0) Index: bmc-config/src/bmc-serial-conf-section.c =================================================================== RCS file: /sources/freeipmi/freeipmi/bmc-config/src/bmc-serial-conf-section.c,v retrieving revision 1.20 diff -u -5 -r1.20 bmc-serial-conf-section.c --- bmc-config/src/bmc-serial-conf-section.c 31 Jan 2007 06:32:05 -0000 1.20 +++ bmc-config/src/bmc-serial-conf-section.c 3 May 2007 17:34:50 -0000 @@ -359,11 +359,11 @@ return ret; if (kv->value) free (kv->value); - if (!(kv->value = connect_mode_string (value))) + if (!(kv->value = strdup(connect_mode_string (value)))) { perror("strdup"); return BMC_ERR_FATAL_ERROR; } Index: common/src/ipmi-common.c =================================================================== RCS file: /sources/freeipmi/freeipmi/common/src/ipmi-common.c,v retrieving revision 1.15 diff -u -5 -r1.15 ipmi-common.c --- common/src/ipmi-common.c 28 Apr 2007 00:28:17 -0000 1.15 +++ common/src/ipmi-common.c 3 May 2007 17:34:50 -0000 @@ -136,11 +136,11 @@ } /* a k_g key is interpreted as ascii text unless it is prefixed with "0x", in which case is it interpreted as hexadecimal */ int -parse_kg(unsigned char *outbuf, int outsz, char *instr) +parse_kg(unsigned char *outbuf, int outsz, const char *instr) { char *p, *q; int i, j; char buf[3] = {0, 0, 0}; @@ -178,11 +178,11 @@ return 1; } char * -format_kg(char *outstr, int outsz, unsigned char *k_g) +format_kg(char *outstr, int outsz, const unsigned char *k_g) { int i; int printable = 1; int foundnull = 0; char *p; Index: common/src/ipmi-common.h =================================================================== RCS file: /sources/freeipmi/freeipmi/common/src/ipmi-common.h,v retrieving revision 1.11 diff -u -5 -r1.11 ipmi-common.h --- common/src/ipmi-common.h 28 Apr 2007 00:28:17 -0000 1.11 +++ common/src/ipmi-common.h 3 May 2007 17:34:50 -0000 @@ -71,11 +71,11 @@ /* From David Wheeler's Secure Programming Guide */ void *guaranteed_memset(void *s, int c, size_t n); /* Turn an input string into a 20-byte binary k_g key */ -int parse_kg(unsigned char *outbuf, int outsz, char *instr); +int parse_kg(unsigned char *outbuf, int outsz, const char *instr); /* Turn a 20-byte binary k_g key into an output string */ -char *format_kg(char *outstr, int outsz, unsigned char *k_g); +char *format_kg(char *outstr, int outsz, const unsigned char *k_g); #endif Index: ipmiconsole/ipmiconsole.8.in =================================================================== RCS file: /sources/freeipmi/freeipmi/ipmiconsole/ipmiconsole.8.in,v retrieving revision 1.13 diff -u -5 -r1.13 ipmiconsole.8.in --- ipmiconsole/ipmiconsole.8.in 29 Apr 2007 16:54:10 -0000 1.13 +++ ipmiconsole/ipmiconsole.8.in 3 May 2007 17:34:51 -0000 @@ -67,15 +67,15 @@ Prompt for password to avoid possibility of listing it in process lists. .TP .I "-k, --k-g str" Specify the K_g BMC key to use for authentication. If not specified, a -NULL key is assumed. +NULL key is assumed. The key may be entered in hex by prefixing with '0x'. .TP .I "-K, --k-g-prompt" Prompt for K_g to avoid possibility of listing it in process -lists. +lists. The key may be entered in hex by prefixing with '0x'. .TP .I "-l, --privilege str" Specify the privilege type to use. The currently available privilege types are "user", "operator", and "admin". If not specified, a privilege of "admin" is assumed. The privilege must be atleast the Index: ipmiconsole/ipmiconsole.conf.5.in =================================================================== RCS file: /sources/freeipmi/freeipmi/ipmiconsole/ipmiconsole.conf.5.in,v retrieving revision 1.4 diff -u -5 -r1.4 ipmiconsole.conf.5.in --- ipmiconsole/ipmiconsole.conf.5.in 9 Mar 2007 02:44:46 -0000 1.4 +++ ipmiconsole/ipmiconsole.conf.5.in 3 May 2007 17:34:51 -0000 @@ -70,11 +70,11 @@ .TP .I password str Specify the default password to use. .TP .I k_g str -Specify the BMC key (K_g) to use. +Specify the BMC key (K_g) to use. Prefix with '0x' to enter the key in hex. .TP .I privilege str Specify the default privilege type to use. .B Ipmiconsole currently supports the following privilege types: "user", "operator", Index: ipmiconsole/src/ipmiconsole/Makefile.am =================================================================== RCS file: /sources/freeipmi/freeipmi/ipmiconsole/src/ipmiconsole/Makefile.am,v retrieving revision 1.3 diff -u -5 -r1.3 Makefile.am --- ipmiconsole/src/ipmiconsole/Makefile.am 16 Feb 2007 18:00:01 -0000 1.3 +++ ipmiconsole/src/ipmiconsole/Makefile.am 3 May 2007 17:34:51 -0000 @@ -17,14 +17,18 @@ ipmiconsole_CPPFLAGS = -I$(srcdir)/../libipmiconsole \ -I$(srcdir)/../../../common/src ipmiconsole_LDADD = ../../../common/src/libllnlcommon.la \ + ../../../common/src/libipmicommon.la \ ../libipmiconsole/libipmiconsole.la ../../../common/src/libllnlcommon.la: force-dependency-check $(MAKE) -C $(dir $@) $(notdir $@) +../../../common/src/libipmicommon.la: force-dependency-check + $(MAKE) -C $(dir $@) $(notdir $@) + ../libipmiconsole/libipmiconsole.la: force-dependency-check $(MAKE) -C $(dir $@) $(notdir $@) force-dependency-check: Index: ipmiconsole/src/ipmiconsole/ipmiconsole.c =================================================================== RCS file: /sources/freeipmi/freeipmi/ipmiconsole/src/ipmiconsole/ipmiconsole.c,v retrieving revision 1.11 diff -u -5 -r1.11 ipmiconsole.c --- ipmiconsole/src/ipmiconsole/ipmiconsole.c 31 Mar 2007 04:03:06 -0000 1.11 +++ ipmiconsole/src/ipmiconsole/ipmiconsole.c 3 May 2007 17:34:51 -0000 @@ -322,11 +322,11 @@ exit(1); } ipmi_config.username = strlen(conf->username) ? conf->username : NULL; ipmi_config.password = strlen(conf->password) ? conf->password : NULL; - ipmi_config.k_g = strlen(conf->k_g) ? conf->k_g : NULL; + ipmi_config.k_g = conf->k_g_configured ? conf->k_g : NULL; ipmi_config.privilege_level = conf->privilege; ipmi_config.cipher_suite_id = conf->cipher_suite_id; protocol_config.session_timeout_len = -1; protocol_config.retransmission_timeout_len = -1; Index: ipmiconsole/src/ipmiconsole/ipmiconsole_config.c =================================================================== RCS file: /sources/freeipmi/freeipmi/ipmiconsole/src/ipmiconsole/ipmiconsole_config.c,v retrieving revision 1.10 diff -u -5 -r1.10 ipmiconsole_config.c --- ipmiconsole/src/ipmiconsole/ipmiconsole_config.c 26 Apr 2007 03:23:59 -0000 1.10 +++ ipmiconsole/src/ipmiconsole/ipmiconsole_config.c 3 May 2007 17:34:51 -0000 @@ -46,10 +46,11 @@ #include "ipmiconsole_config.h" #include "conffile.h" #include "error.h" #include "secure.h" +#include "ipmi-common.h" extern struct ipmiconsole_config *conf; static void _config_default(void) @@ -66,10 +67,13 @@ #endif /* NDEBUG */ conf->config_file = IPMICONSOLE_CONFIG_FILE_DEFAULT; conf->privilege = -1; conf->cipher_suite_id = -1; + + memset(conf->k_g, '\0', IPMI_MAX_K_G_LENGTH); + conf->k_g_configured = 0; } static void _usage(void) { @@ -113,10 +117,11 @@ char options[100]; char *pw; char *kg; char *ptr; int c; + int rv; #if HAVE_GETOPT_LONG struct option long_options[] = { {"help", 0, NULL, 'H'}, @@ -208,28 +213,32 @@ err_exit("password too long"); strcpy(conf->password, pw); conf->password_set_on_cmdline++; break; case 'k': /* --k-g */ - if (strlen(optarg) > IPMI_MAX_K_G_LENGTH) - err_exit("Command Line Error: K_g too long"); - strcpy(conf->k_g, optarg); - conf->k_g_set_on_cmdline++; + if ((rv = parse_kg(conf->k_g, IPMI_MAX_K_G_LENGTH, optarg)) < 0) + err_exit("Command Line Error: Invalid K_g"); + if (rv > 0) + { + conf->k_g_configured++; + conf->k_g_set_on_cmdline++; + } if (optarg) { int n; n = strlen(optarg); secure_memset(optarg, '\0', n); } break; case 'K': /* --k-g-prompt */ - if (!(kg = getpass("K_g: "))) - err_exit("getpass: %s", strerror(errno)); - if (strlen(kg) > IPMI_MAX_K_G_LENGTH) - err_exit("K_g too long"); - strcpy(conf->k_g, kg); - conf->k_g_set_on_cmdline++; + if ((rv = parse_kg(conf->k_g, IPMI_MAX_K_G_LENGTH, kg)) < 0) + err_exit("K_g invalid"); + if (rv > 0) + { + conf->k_g_configured++; + conf->k_g_set_on_cmdline++; + } break; case 'l': /* --privilege */ if (!strcasecmp(optarg, "user")) conf->privilege = IPMICONSOLE_PRIVILEGE_USER; else if (!strcasecmp(optarg, "operator")) @@ -363,17 +372,20 @@ void *option_ptr, int option_data, void *app_ptr, int app_data) { + int rv; + if (conf->k_g_set_on_cmdline) return 0; - if (strlen(data->string) > IPMI_MAX_K_G_LENGTH) - err_exit("Config File Error: K_g too long"); + if ((rv = parse_kg(conf->k_g, IPMI_MAX_K_G_LENGTH, data->string)) < 0) + err_exit("Config File Error: K_g invalid"); + if (rv > 0) + conf->k_g_configured = 1; - strcpy(conf->k_g, data->string); return 0; } static int _cb_privilege(conffile_t cf, Index: ipmiconsole/src/ipmiconsole/ipmiconsole_config.h =================================================================== RCS file: /sources/freeipmi/freeipmi/ipmiconsole/src/ipmiconsole/ipmiconsole_config.h,v retrieving revision 1.6 diff -u -5 -r1.6 ipmiconsole_config.h --- ipmiconsole/src/ipmiconsole/ipmiconsole_config.h 26 Apr 2007 03:23:59 -0000 1.6 +++ ipmiconsole/src/ipmiconsole/ipmiconsole_config.h 3 May 2007 17:34:51 -0000 @@ -51,11 +51,11 @@ char *config_file; char hostname[MAXHOSTNAMELEN+1]; char username[IPMI_MAX_USER_NAME_LENGTH+1]; char password[IPMI_2_0_MAX_PASSWORD_LENGTH+1]; - char k_g[IPMI_MAX_K_G_LENGTH+1]; + char k_g[IPMI_MAX_K_G_LENGTH]; int privilege; int cipher_suite_id; int dont_steal; int deactivate; int lock_memory; @@ -64,10 +64,11 @@ int hostname_set_on_cmdline; int username_set_on_cmdline; int password_set_on_cmdline; int k_g_set_on_cmdline; + int k_g_configured; int privilege_set_on_cmdline; int cipher_suite_id_set_on_cmdline; int dont_steal_set_on_cmdline; int deactivate_set_on_cmdline; int lock_memory_set_on_cmdline; Index: ipmiconsole/src/libipmiconsole/ipmiconsole.c =================================================================== RCS file: /sources/freeipmi/freeipmi/ipmiconsole/src/libipmiconsole/ipmiconsole.c,v retrieving revision 1.7 diff -u -5 -r1.7 ipmiconsole.c --- ipmiconsole/src/libipmiconsole/ipmiconsole.c 31 Mar 2007 04:03:06 -0000 1.7 +++ ipmiconsole/src/libipmiconsole/ipmiconsole.c 3 May 2007 17:34:51 -0000 @@ -393,11 +393,10 @@ || (hostname && strlen(hostname) > MAXHOSTNAMELEN) || !ipmi_config || !protocol_config || (ipmi_config->username && strlen(ipmi_config->username) > IPMI_MAX_USER_NAME_LENGTH) || (ipmi_config->password && strlen(ipmi_config->password) > IPMI_2_0_MAX_PASSWORD_LENGTH) - || (ipmi_config->k_g && strlen(ipmi_config->k_g) > IPMI_MAX_K_G_LENGTH) || (ipmi_config->privilege_level >= 0 && (ipmi_config->privilege_level != IPMICONSOLE_PRIVILEGE_USER && ipmi_config->privilege_level != IPMICONSOLE_PRIVILEGE_OPERATOR && ipmi_config->privilege_level != IPMICONSOLE_PRIVILEGE_ADMIN)) || (ipmi_config->cipher_suite_id >= IPMI_CIPHER_SUITE_ID_MIN @@ -439,12 +438,16 @@ strcpy((char *)c->username, ipmi_config->username); if (ipmi_config->password) strcpy((char *)c->password, ipmi_config->password); - if (ipmi_config->k_g) - strcpy((char *)c->k_g, ipmi_config->k_g); + /* k_g is a fixed-length binary chunk that may contain nulls */ + if (ipmi_config->k_g) + { + memcpy(c->k_g, ipmi_config->k_g, IPMI_MAX_K_G_LENGTH); + c->k_g_configured = 1; + } if (ipmi_config->privilege_level >= 0) { if (ipmi_config->privilege_level == IPMICONSOLE_PRIVILEGE_USER) c->privilege_level = IPMI_PRIVILEGE_LEVEL_USER; Index: ipmiconsole/src/libipmiconsole/ipmiconsole.h =================================================================== RCS file: /sources/freeipmi/freeipmi/ipmiconsole/src/libipmiconsole/ipmiconsole.h,v retrieving revision 1.8 diff -u -5 -r1.8 ipmiconsole.h --- ipmiconsole/src/libipmiconsole/ipmiconsole.h 31 Mar 2007 04:03:06 -0000 1.8 +++ ipmiconsole/src/libipmiconsole/ipmiconsole.h 3 May 2007 17:34:51 -0000 @@ -163,11 +163,11 @@ * 20 bytes. * * k_g * * BMC Key for 2-key authentication. Pass NULL ptr to use password - * as BMC key. Maximum length of 20 bytes. + * as BMC key. Length of 20 bytes. * * privilege_level * * privilege level to authenticate with. * Index: ipmiconsole/src/libipmiconsole/ipmiconsole_defs.h =================================================================== RCS file: /sources/freeipmi/freeipmi/ipmiconsole/src/libipmiconsole/ipmiconsole_defs.h,v retrieving revision 1.7 diff -u -5 -r1.7 ipmiconsole_defs.h --- ipmiconsole/src/libipmiconsole/ipmiconsole_defs.h 28 Apr 2007 00:32:58 -0000 1.7 +++ ipmiconsole/src/libipmiconsole/ipmiconsole_defs.h 3 May 2007 17:34:51 -0000 @@ -366,11 +366,12 @@ /* Configuration Parameters */ char hostname[MAXHOSTNAMELEN+1]; uint8_t username[IPMI_MAX_USER_NAME_LENGTH+1]; uint8_t password[IPMI_2_0_MAX_PASSWORD_LENGTH+1]; - uint8_t k_g[IPMI_MAX_K_G_LENGTH+1]; + uint8_t k_g[IPMI_MAX_K_G_LENGTH]; + uint8_t k_g_configured; uint8_t privilege_level; uint8_t cipher_suite_id; unsigned int session_timeout_len; unsigned int retransmission_timeout_len; Index: ipmiconsole/src/libipmiconsole/ipmiconsole_processing.c =================================================================== RCS file: /sources/freeipmi/freeipmi/ipmiconsole/src/libipmiconsole/ipmiconsole_processing.c,v retrieving revision 1.8 diff -u -5 -r1.8 ipmiconsole_processing.c --- ipmiconsole/src/libipmiconsole/ipmiconsole_processing.c 31 Mar 2007 04:03:06 -0000 1.8 +++ ipmiconsole/src/libipmiconsole/ipmiconsole_processing.c 3 May 2007 17:34:51 -0000 @@ -1762,12 +1762,12 @@ { c->errnum = IPMICONSOLE_ERR_USERNAME_INVALID; return -1; } - if ((!strlen((char *)c->k_g) && authentication_status_k_g) - || (strlen((char *)c->k_g) && !authentication_status_k_g)) + if ((!c->k_g_configured && authentication_status_k_g) + || (c->k_g_configured && !authentication_status_k_g)) { c->errnum = IPMICONSOLE_ERR_K_G_INVALID; return -1; } @@ -1841,11 +1841,11 @@ if (c->workaround_flags & IPMICONSOLE_WORKAROUND_INTEL_2_0 && s->authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5 && password_len > IPMI_1_5_MAX_PASSWORD_LENGTH) password_len = IPMI_1_5_MAX_PASSWORD_LENGTH; - if (strlen((char *)c->k_g)) + if (c->k_g_configured) k_g = (uint8_t *)c->k_g; else k_g = NULL; if ((managed_system_random_number_len = Fiid_obj_get_data(c, @@ -1866,11 +1866,11 @@ s->integrity_algorithm, s->confidentiality_algorithm, password, password_len, k_g, - (k_g) ? strlen((char *)k_g) : 0, + (k_g) ? IPMI_MAX_K_G_LENGTH : 0, s->remote_console_random_number, IPMI_REMOTE_CONSOLE_RANDOM_NUMBER_LENGTH, managed_system_random_number, IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH, s->name_only_lookup,