From 00a85eb8f301515d16ed68a22cb754c505fc34f7 Mon Sep 17 00:00:00 2001 From: CentOS Buildsys Date: Mar 05 2014 09:55:25 +0000 Subject: import ipmitool-1.8.13-7.el7.src.rpm --- diff --git a/SOURCES/ipmitool-1.8.13-bmc-snmp.patch b/SOURCES/ipmitool-1.8.13-bmc-snmp.patch new file mode 100644 index 0000000..1fa1b71 --- /dev/null +++ b/SOURCES/ipmitool-1.8.13-bmc-snmp.patch @@ -0,0 +1,359 @@ +From f48ce96e7fd0d2fe198845f0e2bd76f95d221fb3 Mon Sep 17 00:00:00 2001 +From: Charles Rose +Date: Thu, 12 Dec 2013 16:10:11 -0500 +Subject: [PATCH] Incorporate upstream comments to #289, add whitespace, other + cleanup + +--- + contrib/bmc-snmp-proxy | 130 +++++++++++++++++++++++++++++-------------------- + 1 file changed, 76 insertions(+), 54 deletions(-) + +diff --git a/contrib/bmc-snmp-proxy b/contrib/bmc-snmp-proxy +index 1704ef3..98479b9 100644 +--- a/contrib/bmc-snmp-proxy ++++ b/contrib/bmc-snmp-proxy +@@ -3,7 +3,7 @@ + # + # bmc-snmp-proxy: Set SNMP proxy to BMC (Baseboard Management Controller) + # +-# version: 0.6 ++# version: 0.62 + # + # Authors: Charles Rose + # Jordan Hargrave +@@ -20,9 +20,9 @@ + SYSCONF_DIR="/etc/sysconfig" + CONFIG="${SYSCONF_DIR}/bmc-snmp-proxy" + +-SNMPD_LOCAL_CONF_DIR="/etc/snmp/bmc" +-SNMPD_LOCAL_CONF="${SNMPD_LOCAL_CONF_DIR}/snmpd.local.conf" +-TRAPD_LOCAL_CONF="${SNMPD_LOCAL_CONF_DIR}/snmptrapd.local.conf" ++SNMPD_BMC_CONF_DIR="/etc/snmp/bmc" ++SNMPD_BMC_CONF="${SNMPD_BMC_CONF_DIR}/snmpd.local.conf" ++TRAPD_BMC_CONF="${SNMPD_BMC_CONF_DIR}/snmptrapd.local.conf" + + TRAPD_CONF="/etc/snmp/snmptrapd.conf" + +@@ -57,14 +57,16 @@ bmc_info_exists() + else + RETVAL=2 + fi ++ + return $RETVAL + } + + check_snmp() + { +- if [ ! -d /etc/snmp ] && [ ! -x /usr/sbin/snmpd ]; then ++ if [ ! -d /etc/snmp ] || [ ! -x /usr/sbin/snmpd ]; then + RETVAL=12 + fi ++ + return $RETVAL + } + +@@ -77,11 +79,12 @@ write_snmp_conf() + printf "###############################################\n" + printf "# Automatically created by %s #\n" "${SCRIPT_NAME}" + printf "###############################################\n" +- printf "view bmcview included %s 80\n" "${BMC_OID}" +- printf "com2sec -Cn bmc_ctx bmc_sec default bmc_cmty\n" +- printf "group bmc_grp v1 bmc_sec\n" +- printf "access bmc_grp bmc_ctx any noauth exact bmcview none none\n" +- printf "proxy -Cn bmc_ctx -v 1 %s\n" "${PROXY_TOKEN}" ++ printf "#view bmcview included %s 80\n" "${BMC_OID}" ++ printf "#com2sec -Cn bmc_ctx bmc_sec default bmc_cmty\n" ++ printf "#group bmc_grp v1 bmc_sec\n" ++ printf "#access bmc_grp bmc_ctx any noauth exact bmcview none none\n" ++ printf "#proxy -Cn bmc_ctx -v 1 %s\n" "${PROXY_TOKEN}" ++ printf "proxy -v 1 %s\n" "${PROXY_TOKEN}" + printf "###############################################\n" + } + +@@ -92,6 +95,7 @@ valid_ip() + + printf -- "%s" "${1}"| grep -Eq \ + "^${octet}\\.${octet}\\.${octet}\\.${octet}$" ++ + return $? + } + +@@ -112,37 +116,38 @@ set_snmp_proxy() + if check_vars; then + PROXY_TOKEN="-c ${BMC_COMMUNITY} ${BMC_IPv4} ${BMC_OID}" + +- if [ ! -d ${SNMPD_LOCAL_CONF_DIR} ] && \ +- mkdir ${SNMPD_LOCAL_CONF_DIR}; then +- write_snmp_conf > ${SNMPD_LOCAL_CONF} +- [ $? -ne 0 ] && RETVAL=4 ++ if [ -d ${SNMPD_BMC_CONF_DIR} ]; then ++ write_snmp_conf > ${SNMPD_BMC_CONF} || RETVAL=4 + fi + else + RETVAL=3 + fi + } + +- + set_snmpd_conf_path() + { +- for SYSCONF in ${SYSCONF_DIR}/snmp*d; ++ if [ ! -d ${SNMPD_BMC_CONF_DIR} ]; then ++ mkdir ${SNMPD_BMC_CONF_DIR} || RETVAL=7 ++ fi ++ ++ # We need SNMPCONFPATH set for both snmpd and snmptrapd ++ for sysconf in ${SYSCONF_DIR}/snmp*d; + do +- if grep -q "${SNMPD_LOCAL_CONF_DIR}" "${SYSCONF}" > \ +- /dev/null 2>&1; then +- continue +- else +- printf "SNMPCONFPATH=%s\n" "${SNMPD_LOCAL_CONF_DIR}" \ +- >> ${SYSCONF} || RETVAL=7 ++ if ! grep -q "^SNMPCONFPATH.*${SNMPD_BMC_CONF_DIR}" \ ++ "${sysconf}" > /dev/null 2>&1; then ++ printf "SNMPCONFPATH=/etc/snmp:%s\n" \ ++ "${SNMPD_BMC_CONF_DIR}" >> ${sysconf} || \ ++ RETVAL=7 + fi + done ++ + return $RETVAL + } + + disable_snmp_proxy() + { +- if [ -f ${SNMPD_LOCAL_CONF} ]; then +- rm -f ${SNMPD_LOCAL_CONF} +- [ $? -ne 0 ] && RETVAL=5 ++ if [ -f ${SNMPD_BMC_CONF} ]; then ++ rm -f ${SNMPD_BMC_CONF} || RETVAL=5 + fi + } + ############################################################################# +@@ -152,6 +157,7 @@ disable_snmp_proxy() + pick_alert_dest() + { + test_ip="$1" ++ # We have 4 IPv4 and 4 IPv6 alert dest. We will set IPv4 for now. + for ALERT_DEST in `seq 1 4` + do + temp_ip=$(${IPMITOOL} lan alert print ${CHANNEL} ${ALERT_DEST}\ +@@ -165,12 +171,12 @@ pick_alert_dest() + set_alert_dest_ip() + { + ${IPMITOOL} lan alert set ${CHANNEL} ${ALERT_DEST} ipaddr ${1} \ +- retry 4 type pet >/dev/null 2>&1 +- [ $? -ne 0 ] && RETVAL=8 ++ retry 4 type pet >/dev/null 2>&1 || RETVAL=8 + } + +-bmc_alert_dest() ++config_bmc_alert_dest() + { ++ # call with enable|disable + # Pick the first active LAN channel + for CHANNEL in `seq 1 14` + do +@@ -180,12 +186,12 @@ bmc_alert_dest() + + # If TRAPD_IP is already set as an alert dest, + if pick_alert_dest "${TRAPD_IP}"; then +- # reset: reset it if we are called with reset +- [ "${1}" = "reset" ] && \ ++ # disable: reset it if we are called with disable ++ [ "${1}" = "disable" ] && \ + set_alert_dest_ip "0.0.0.0" + # else, find the next free alert dest, + elif pick_alert_dest "0.0.0.0"; then +- [ "${1}" = "reset" ] && \ ++ [ "${1}" = "disable" ] && \ + return $RETVAL + # set: the TRAPD_IP + set_alert_dest_ip "${TRAPD_IP}" +@@ -193,42 +199,54 @@ bmc_alert_dest() + # No free alert destinations + RETVAL=9 + fi ++ + return $RETVAL + } + +-set_ipmi_alert() ++set_ipmi_pef() + { +- ${IPMITOOL} lan set ${CHANNEL} alert "${1}" >/dev/null 2>&1 +- [ $? -ne 0 ] && RETVAL=10 ++ # Needs ipmitool-1.8.13 + patches ++ ${IPMITOOL} pef setpolicy ${ALERT_DEST} "${1}" >/dev/null 2>&1 || \ ++ RETVAL=10 + } + + get_host_ip() + { +- # Get host's IP that the BMC can reach. ++ # Get host's IP that the BMC can reach. This is at best a hack. + IFACE=$(/usr/sbin/ip -o -f inet address |awk '!/: lo/ {print $2}') ++ + for dev in ${IFACE} + do +- ping -c 1 -I ${dev} ${BMC_IPv4} > /dev/null 2>&1 ++ temp_ping=$(ping -c 1 -I ${dev} ${BMC_IPv4}) ++ [ $? -ne 0 ] && continue ++ ++ printf -- "%s" "$temp_ping"| awk 'NR==1{print $5}' && break + done + } + + config_bmc_alert() + { ++ # Do two things ++ # Set/Reset TRAP IP in BMC ++ # Enable/Disable PEF alerting in BMC for TRAP ++ + # Get Host's IP that the BMC can send traps to + TRAPD_IP=$(get_host_ip) + + # Set Host's IP as the alert destination in the BMC +- valid_ip ${TRAPD_IP} && bmc_alert_dest "${ACTION}" ++ valid_ip ${TRAPD_IP} && config_bmc_alert_dest "${ACTION}" ++ ++ # Enable/Disable alerting on the LAN channel ++ [ $RETVAL -eq 0 ] && set_ipmi_pef "${ACTION}" + +- # Enable alerting on the LAN channel +- [ $RETVAL -eq 0 ] && set_ipmi_alert "${ACTION}" ++ return $RETVAL + } + + write_trapd_conf() + { + printf "###############################################\n" + printf "# Automatically created by %s #\n" "${SCRIPT_NAME}" +- printf "forward %s %s\n" "${BMC_OID}*" "${FORWARD_HOST}" ++ printf "forward default %s\n" "${FORWARD_HOST}" + printf "###############################################\n" + } + +@@ -236,10 +254,9 @@ config_trapd() + { + # Proceed only if snmptrapd is available on the system + if [ -f ${TRAPD_CONF} ]; then +- write_trapd_conf > ${TRAPD_LOCAL_CONF} +- [ $? -ne 0 ] && RETVAL=11 ++ write_trapd_conf > ${TRAPD_BMC_CONF} || RETVAL=11 + else +- return 1 ++ RETVAL=11 + fi + } + +@@ -249,6 +266,7 @@ trap_sink_exists() + # multiple + FORWARD_HOST=$(awk '/^trap.*sink/{print $2}; /^informsink/{print $2}' \ + /etc/snmp/snmpd*conf | head -1) ++ + if [ -z "${FORWARD_HOST}" ]; then + # there is no trapsink setup. + return 1 +@@ -261,19 +279,20 @@ trap_sink_exists() + trap_forward() + { + NO_TRAP=0 +- ACTION=${1} # set or reset ++ ACTION=${1} # enable or disable + +- if [ "${ACTION}" = "set" ]; then ++ if [ "${ACTION}" = "enable" ]; then + # Get trapd config, + if trap_sink_exists; then +- config_trapd && config_bmc_alert ++ config_bmc_alert && config_trapd + else + # exit silently if there is no sink + NO_TRAP=1 + fi + else +- if [ -f ${TRAPD_LOCAL_CONF} ]; then +- rm -f ${TRAPD_LOCAL_CONF} >/dev/null 2>&1 ++ if [ -f ${TRAPD_BMC_CONF} ]; then ++ rm -f ${TRAPD_BMC_CONF} >/dev/null 2>&1 ++ config_bmc_alert + else + NO_TRAP=1 + fi +@@ -288,7 +307,6 @@ service_reload() + service $1 reload + [ $? -ne 0 ] && RETVAL=6 + fi +- return + } + + ############################################################################# +@@ -296,11 +314,12 @@ start() + { + if bmc_info_exists && check_snmp; then + touch ${LOCKFILE} ++ + set_snmpd_conf_path && set_snmp_proxy + [ $RETVAL -eq 0 ] && service_reload snmpd + + if [ "${TRAP_FORWARD}" = "yes" ]; then +- trap_forward "set" ++ trap_forward "enable" + [ $RETVAL -eq 0 ] && [ $NO_TRAP -eq 0 ] && \ + service_reload snmptrapd + fi +@@ -316,10 +335,11 @@ stop() + [ $RETVAL -eq 0 ] && service_reload snmpd + + if [ "${TRAP_FORWARD}" = "yes" ]; then +- trap_forward "reset" ++ trap_forward "disable" + [ $RETVAL -eq 0 ] && [ $NO_TRAP -eq 0 ] && \ + service_reload snmptrapd + fi ++ + rm -f ${LOCKFILE} + fi + } +@@ -329,12 +349,13 @@ status() + { + eval_gettext "${SCRIPT_NAME}: snmp proxy to BMC is " + # Checking for lockfile is better. +- #if grep -q "^proxy" "${SNMPD_LOCAL_CONF}" > /dev/null 2>&1 ; then ++ #if grep -q "^proxy" "${SNMPD_BMC_CONF}" > /dev/null 2>&1 ; then + if [ -f ${LOCKFILE} ]; then + eval_gettext "set" + else + eval_gettext "not set" + fi ++ + echo + RETVAL=0 + } +@@ -360,10 +381,10 @@ case "$RETVAL" in + 0|1) ;; + 2) eval_gettext "${SCRIPT_NAME}: failed to read ${BMC_INFO} " 1>&2 ;; + 3) eval_gettext "${SCRIPT_NAME}: failed to get proxy config." 1>&2 ;; +- 4) eval_gettext "${SCRIPT_NAME}: failed to set ${SNMPD_LOCAL_CONF}." 1>&2 ;; ++ 4) eval_gettext "${SCRIPT_NAME}: failed to set ${SNMPD_BMC_CONF}." 1>&2 ;; + 5) eval_gettext "${SCRIPT_NAME}: failed to disable snmp proxy." 1>&2 ;; + 6) eval_gettext "${SCRIPT_NAME}: failed to reload snmpd." 1>&2 ;; +- 7) eval_gettext "${SCRIPT_NAME}: failed to update ${SYSCONF}." 1>&2 ;; ++ 7) eval_gettext "${SCRIPT_NAME}: failed to set snmpd config." 1>&2 ;; + 8) eval_gettext "${SCRIPT_NAME}: failed to set IPMI alert dest." 1>&2 ;; + 9) eval_gettext "${SCRIPT_NAME}: no free IPMI alert dest." 1>&2 ;; + 10) eval_gettext "${SCRIPT_NAME}: failed to set IPMI PEF." 1>&2 ;; +@@ -375,6 +396,7 @@ esac + if [ ${RETVAL} -gt 1 ]; then + eval_gettext " Return code: ${RETVAL}"; echo + fi ++ + exit ${RETVAL} + ############################################################################# + # end of file +-- +1.8.3.1 + diff --git a/SOURCES/ipmitool-1.8.13-set-kg-key1.patch b/SOURCES/ipmitool-1.8.13-set-kg-key1.patch new file mode 100644 index 0000000..4dd005c --- /dev/null +++ b/SOURCES/ipmitool-1.8.13-set-kg-key1.patch @@ -0,0 +1,433 @@ +diff -up ./doc/ipmitool.1.kg1 ./doc/ipmitool.1 +--- ./doc/ipmitool.1.kg1 2014-03-05 09:04:19.334742088 +0100 ++++ ./doc/ipmitool.1 2014-03-05 09:02:53.011524309 +0100 +@@ -371,6 +371,20 @@ Configure user access information on the + + Displays the list of cipher suites supported for the given + application (ipmi or sol) on the given channel. ++.TP ++\fIsetkg\fP <\fIhex\fP|\fIplain\fP> <\fBkey\fP> [<\fBchannel\fR>] ++.br ++ ++Sets K_g key to given value. Use \fIplain\fP to specify \fBkey\fR as simple ASCII string. ++Use \fIhex\fP to specify \fBkey\fR as sequence of hexadecimal codes of ASCII charactes. ++I.e. following two examples are equivalent: ++ ++.RS ++ipmitool channel setkg plain PASSWORD ++ ++ipmitool channel setkg hex 50415353574F5244 ++.RE ++ + .RE + .RE + .TP +diff -up ./include/ipmitool/helper.h.kg1 ./include/ipmitool/helper.h +--- ./include/ipmitool/helper.h.kg1 2014-03-05 09:42:21.546499783 +0100 ++++ ./include/ipmitool/helper.h 2014-03-05 09:43:28.095667676 +0100 +@@ -58,6 +58,8 @@ + # define IPMI_UID_MAX 63 + #endif + ++#define IPMI_KG_BUFFER_SIZE 21 /* key plus null byte */ ++ + struct ipmi_intf; + + struct valstr { +@@ -100,6 +102,8 @@ uint8_t ipmi_csum(uint8_t * d, int s); + FILE * ipmi_open_file(const char * file, int rw); + void ipmi_start_daemon(struct ipmi_intf *intf); + ++unsigned char *ipmi_parse_hex(const char *str); ++ + #define ipmi_open_file_read(file) ipmi_open_file(file, 0) + #define ipmi_open_file_write(file) ipmi_open_file(file, 1) + +diff -up ./include/ipmitool/ipmi_channel.h.kg1 ./include/ipmitool/ipmi_channel.h +--- ./include/ipmitool/ipmi_channel.h.kg1 2014-03-05 09:04:41.707798532 +0100 ++++ ./include/ipmitool/ipmi_channel.h 2014-03-05 09:10:00.770603481 +0100 +@@ -48,7 +48,10 @@ + #define IPMI_GET_USER_NAME 0x46 + #define IPMI_SET_USER_PASSWORD 0x47 + #define IPMI_GET_CHANNEL_CIPHER_SUITES 0x54 ++#define IPMI_SET_CHANNEL_SECURITY_KEYS 0x56 + ++#define IPMI_KG_KEY_ID 1 ++#define IPMI_SET_CHANNEL_SECURITY_KEYS_OP_SET 1 + + /* + * The Get Authentication Capabilities response structure +@@ -246,6 +249,48 @@ struct set_user_access_data { + #endif + } ATTRIBUTE_PACKING; + #ifdef HAVE_PRAGMA_PACK ++#pragma pack(0) ++#endif ++ ++#ifdef HAVE_PRAGMA_PACK ++#pragma pack(1) ++#endif ++struct set_channel_security_keys_req { ++#if WORDS_BIGENDIAN ++ uint8_t __reserved1 :4; ++ uint8_t channel :4; ++ uint8_t __reserved2 :6; ++ uint8_t operation :2; ++ uint8_t key_id; ++ unsigned char key_value[IPMI_KG_BUFFER_SIZE-1]; /* we don't want space for '\0' at the end */ ++#else ++ uint8_t channel :4; ++ uint8_t __reserved1 :4; ++ uint8_t operation :2; ++ uint8_t __reserved2 :6; ++ uint8_t key_id; ++ unsigned char key_value[IPMI_KG_BUFFER_SIZE-1]; /* we don't want space for '\0' at the end */ ++#endif ++} ATTRIBUTE_PACKING; ++#ifdef HAVE_PRAGMA_PACK ++#pragma pack(0) ++#endif ++ ++#ifdef HAVE_PRAGMA_PACK ++#pragma pack(1) ++#endif ++struct set_channel_security_keys_rsp { ++#if WORDS_BIGENDIAN ++ uint8_t __reserved1 :6; ++ uint8_t lock_status :2; ++ unsigned char key_value; /* just the first character, use &key_value to explore the rest */ ++#else ++ uint8_t lock_status :2; ++ uint8_t __reserved1 :6; ++ unsigned char key_value; /* just the first character, use &key_value to explore the rest */ ++#endif ++} ATTRIBUTE_PACKING; ++#ifdef HAVE_PRAGMA_PACK + #pragma pack(0) + #endif + +diff -up ./include/ipmitool/ipmi_intf.h.kg1 ./include/ipmitool/ipmi_intf.h +--- ./include/ipmitool/ipmi_intf.h.kg1 2014-03-05 09:10:45.363715984 +0100 ++++ ./include/ipmitool/ipmi_intf.h 2014-03-05 09:11:27.483822244 +0100 +@@ -60,7 +60,7 @@ enum LANPLUS_SESSION_STATE { + + #define IPMI_AUTHCODE_BUFFER_SIZE 20 + #define IPMI_SIK_BUFFER_SIZE 20 +-#define IPMI_KG_BUFFER_SIZE 21 /* key plus null byte */ ++/* XXX: remove or modify # d e fine IPMI_KG_BUFFER_SIZE 21 /* key plus null byte */ + + struct ipmi_session { + uint8_t hostname[64]; +diff -up ./lib/helper.c.kg1 ./lib/helper.c +--- ./lib/helper.c.kg1 2014-03-05 09:11:41.417857400 +0100 ++++ ./lib/helper.c 2014-03-05 09:15:11.318386949 +0100 +@@ -667,6 +667,68 @@ ipmi_start_daemon(struct ipmi_intf *intf + dup(0); + } + ++/* ipmi_parse_hex - convert hexadecimal numbers to ascii string ++ * Input string must be composed of two-characer hexadecimal numbers. ++ * There is no separator between the numbers. Each number results in one character ++ * of the converted string. ++ * ++ * Example: ipmi_parse_hex("50415353574F5244") returns 'PASSWORD' ++ * ++ * @param str: input string. It must contain only even number of '0'-'9','a'-'f' and 'A-F' characters. ++ * @returns converted ascii string ++ * @returns NULL on error ++ */ ++unsigned char * ++ipmi_parse_hex(const char *str) ++{ ++ const char * p; ++ unsigned char * out, *q; ++ unsigned char b = 0; ++ int shift = 4; ++ ++ if (strlen(str) == 0) ++ return NULL; ++ ++ if (strlen(str) % 2 != 0) { ++ lprintf(LOG_ERR, "Number of hex_kg characters is not even"); ++ return NULL; ++ } ++ ++ if (strlen(str) > (IPMI_KG_BUFFER_SIZE-1)*2) { ++ lprintf(LOG_ERR, "Kg key is too long"); ++ return NULL; ++ } ++ ++ out = calloc(IPMI_KG_BUFFER_SIZE, sizeof(unsigned char)); ++ if (out == NULL) { ++ lprintf(LOG_ERR, "malloc failure"); ++ return NULL; ++ } ++ ++ for (p = str, q = out; *p; p++) { ++ if (!isxdigit(*p)) { ++ lprintf(LOG_ERR, "Kg_hex is not hexadecimal number"); ++ free(out); ++ return NULL; ++ } ++ ++ if (*p < 'A') /* it must be 0-9 */ ++ b = *p - '0'; ++ else /* it's A-F or a-f */ ++ b = (*p | 0x20) - 'a' + 10; /* convert to lowercase and to 10-15 */ ++ ++ *q = *q + b << shift; ++ if (shift) ++ shift = 0; ++ else { ++ shift = 4; ++ q++; ++ } ++ } ++ ++ return out; ++} ++ + /* is_fru_id - wrapper for str-2-int FRU ID conversion. Message is printed + * on error. + * FRU ID range: <0..255> +diff -up ./lib/ipmi_channel.c.kg1 ./lib/ipmi_channel.c +--- ./lib/ipmi_channel.c.kg1 2014-03-05 09:15:28.655430688 +0100 ++++ ./lib/ipmi_channel.c 2014-03-05 09:37:19.367737427 +0100 +@@ -786,6 +786,90 @@ ipmi_current_channel_medium(struct ipmi_ + return ipmi_get_channel_medium(intf, 0xE); + } + ++int ++ipmi_set_channel_security_keys (struct ipmi_intf *intf, uint8_t channel, ++ const char *method, const char *key) ++{ ++ unsigned char* decoded_key = NULL; ++ struct ipmi_rs *rsp; ++ struct ipmi_rq req; ++ struct set_channel_security_keys_req req_data; ++ ++ /* convert provided key to array of bytes */ ++ if (strcmp(method, "hex") == 0) { ++ if (strlen(key) > (IPMI_KG_BUFFER_SIZE-1)*2) { ++ lprintf(LOG_ERR, "Provided key is too long, max. length is 20 bytes"); ++ printf_channel_usage(); ++ return -1; ++ } ++ decoded_key = ipmi_parse_hex(key); ++ if (decoded_key == NULL) { ++ /* something went bad, ipmi_parse_hex already reported the error */ ++ return -1; ++ } ++ } else if (strcmp(method, "plain") == 0) { ++ if (strlen(key) > IPMI_KG_BUFFER_SIZE-1) { ++ lprintf(LOG_ERR, "Provided key is too long, max. length is 20 bytes"); ++ printf_channel_usage(); ++ return -1; ++ } ++ ++ decoded_key = calloc(IPMI_KG_BUFFER_SIZE, sizeof(unsigned char)); ++ if (decoded_key == NULL) { ++ lprintf(LOG_ERR, "Cannot allocate memory"); ++ return -1; ++ } ++ strncpy(decoded_key, key, IPMI_KG_BUFFER_SIZE-1); ++ } else { ++ printf_channel_usage(); ++ return -1; ++ } ++ ++ /* assemble and send request to set kg key */ ++ memset(&req_data, 0, sizeof(req_data)); ++ req_data.channel = channel; ++ req_data.operation = IPMI_SET_CHANNEL_SECURITY_KEYS_OP_SET; ++ req_data.key_id = IPMI_KG_KEY_ID; ++ memcpy(req_data.key_value, decoded_key, IPMI_KG_BUFFER_SIZE-1); ++ free(decoded_key); ++ ++ memset(&req, 0, sizeof(req)); ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.cmd = IPMI_SET_CHANNEL_SECURITY_KEYS; ++ req.msg.data = (uint8_t*) &req_data; ++ req.msg.data_len = sizeof(req_data); ++ ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ lprintf(LOG_ERR, "Set Channel Security Keys command failed"); ++ return -1; ++ } ++ if (rsp->ccode > 0) { ++ const char *error = NULL; ++ switch (rsp->ccode) { ++ case 0x80: ++ error = "Key is locked"; ++ break; ++ case 0x81: ++ error = "Insufficient key bytes"; ++ break; ++ case 0x82: ++ error = "Too many key bytes"; ++ break; ++ case 0x83: ++ error = "Key value does not meet criteria for K_g key"; ++ break; ++ default: ++ error = val2str(rsp->ccode, completion_code_vals); ++ } ++ lprintf(LOG_ERR, "Error setting security key: %X (%s)", rsp->ccode, error); ++ return -1; ++ } ++ ++ lprintf(LOG_NOTICE, "Set Channel Security Keys command succeeded"); ++ return 0; ++} ++ + void + printf_channel_usage() + { +@@ -795,6 +879,7 @@ printf_channel_usage() + " [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); + lprintf(LOG_NOTICE, " info [channel number]"); + lprintf(LOG_NOTICE, " getciphers [channel]\n"); ++ lprintf(LOG_NOTICE, " setkg hex|plain [channel]\n"); + lprintf(LOG_NOTICE, "Possible privilege levels are:"); + lprintf(LOG_NOTICE, " 1 Callback level"); + lprintf(LOG_NOTICE, " 2 User level"); +@@ -892,6 +977,21 @@ ipmi_channel_main(struct ipmi_intf * int + ch); + } + } ++ else if (strcmp(argv[0], "setkg") == 0) ++ { ++ if (argc < 3 || argc > 4) ++ printf_channel_usage(); ++ else { ++ uint8_t ch = 0xe; ++ char *method = argv[1]; ++ char *key = argv[2]; ++ if (argc == 4) { ++ ch = (uint8_t)strtol(argv[3], NULL, 0); ++ } ++ ++ retval = ipmi_set_channel_security_keys(intf, ch, method, key); ++ } ++ } + else + { + printf("Invalid CHANNEL command: %s\n", argv[0]); +diff -up ./lib/ipmi_main.c.kg1 ./lib/ipmi_main.c +--- ./lib/ipmi_main.c.kg1 2014-03-05 09:50:30.905734365 +0100 ++++ ./lib/ipmi_main.c 2014-03-05 10:47:04.857296819 +0100 +@@ -275,69 +275,6 @@ void ipmi_catch_sigint() + exit(-1); + } + +-/* ipmi_parse_hex - convert hexadecimal numbers to ascii string +- * Input string must be composed of two-characer hexadecimal numbers. +- * There is no separator between the numbers. Each number results in one character +- * of the converted string. +- * +- * Example: ipmi_parse_hex("50415353574F5244") returns 'PASSWORD' +- * +- * @param str: input string. It must contain only even number of '0'-'9','a'-'f' and 'A-F' characters. +- * @returns converted ascii string +- * @returns NULL on error +- */ +-static unsigned char * +-ipmi_parse_hex(const char *str) +-{ +- const char * p; +- unsigned char * out, *q; +- unsigned char b = 0; +- int shift = 4; +- +- if (strlen(str) == 0) +- return NULL; +- +- if (strlen(str) % 2 != 0) { +- lprintf(LOG_ERR, "Number of hex_kg characters is not even"); +- return NULL; +- } +- +- if (strlen(str) > (IPMI_KG_BUFFER_SIZE-1)*2) { +- lprintf(LOG_ERR, "Kg key is too long"); +- return NULL; +- } +- +- out = calloc(IPMI_KG_BUFFER_SIZE, sizeof(unsigned char)); +- if (out == NULL) { +- lprintf(LOG_ERR, "malloc failure"); +- return NULL; +- } +- +- for (p = str, q = out; *p; p++) { +- if (!isxdigit(*p)) { +- lprintf(LOG_ERR, "Kg_hex is not hexadecimal number"); +- free(out); +- out = NULL; +- return NULL; +- } +- +- if (*p < 'A') /* it must be 0-9 */ +- b = *p - '0'; +- else /* it's A-F or a-f */ +- b = (*p | 0x20) - 'a' + 10; /* convert to lowercase and to 10-15 */ +- +- *q = *q + b << shift; +- if (shift) +- shift = 0; +- else { +- shift = 4; +- q++; +- } +- } +- +- return out; +-} +- + /* ipmi_parse_options - helper function to handle parsing command line options + * + * @argc: count of options +@@ -521,11 +458,12 @@ ipmi_main(int argc, char ** argv, + free(kgkey); + kgkey = NULL; + } +- kgkey = strdup(optarg); ++ kgkey = calloc(IPMI_KG_BUFFER_SIZE, 1); + if (kgkey == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } ++ strncpy(kgkey, optarg, IPMI_KG_BUFFER_SIZE); + break; + case 'K': + if ((tmp_env = getenv("IPMI_KGKEY"))) { +@@ -533,11 +471,12 @@ ipmi_main(int argc, char ** argv, + free(kgkey); + kgkey = NULL; + } +- kgkey = strdup(tmp_env); ++ kgkey = calloc(IPMI_KG_BUFFER_SIZE, 1); + if (kgkey == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } ++ strncpy(kgkey, tmp_env, IPMI_KG_BUFFER_SIZE); + } else { + lprintf(LOG_WARN, "Unable to read kgkey from environment"); + } +@@ -564,11 +503,14 @@ ipmi_main(int argc, char ** argv, + kgkey = NULL; + } + kgkey = strdup(tmp_pass); +- tmp_pass = NULL; ++ kgkey = calloc(IPMI_KG_BUFFER_SIZE, 1); + if (kgkey == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); ++ tmp_pass = NULL; + goto out_free; + } ++ strncpy(kgkey, tmp_pass, IPMI_KG_BUFFER_SIZE); ++ tmp_pass = NULL; + } + break; + case 'U': diff --git a/SPECS/ipmitool.spec b/SPECS/ipmitool.spec index 866022a..8481065 100644 --- a/SPECS/ipmitool.spec +++ b/SPECS/ipmitool.spec @@ -1,7 +1,7 @@ Name: ipmitool Summary: Utility for IPMI control Version: 1.8.13 -Release: 3%{?dist} +Release: 7%{?dist} License: BSD Group: System Environment/Base URL: http://ipmitool.sourceforge.net/ @@ -36,6 +36,12 @@ Patch4: cxoem-jb-cx6.patch #Patch6: ipmitool-1.8.12-fipsman.patch # pending https://sourceforge.net/p/ipmitool/bugs/280/ Patch7: ipmitool-1.8.13-dualbridgedoc.patch +# pending http://sourceforge.net/p/ipmitool/bugs/289/ +Patch8: ipmitool-1.8.13-bmc-snmp.patch +# todo +Patch9: ipmitool-1.8.13-set-kg-key1.patch +# todo +#Patch10: ipmitool-1.8.11-set-kg-key2.patch %description This package contains a utility for interfacing with devices that support @@ -91,6 +97,9 @@ for the host OS to use. #patch5 -p0 -b .fips #patch6 -p0 -b .fipsman %patch7 -p1 -b .dualbridgedoc +%patch8 -p1 -b .bmcsnmp +%patch9 -p1 -b .kg1 +#% p atch10 -p1 -b .kegkey2 for f in AUTHORS ChangeLog; do iconv -f iso-8859-1 -t utf8 < ${f} > ${f}.utf8 @@ -182,6 +191,18 @@ install -Dm 755 contrib/bmc-snmp-proxy %{buildroot}%{_libexecdir}/bmc-sn %{_libexecdir}/bmc-snmp-proxy %changelog +* Wed Mar 05 2014 Ales Ledvinka - 1.8.13-7 +- Allow setting channel Kg key. + +* Fri Jan 24 2014 Daniel Mach - 1.8.13-6 +- Mass rebuild 2014-01-24 + +* Mon Jan 20 2014 Ales Ledvinka 1.8.13-5 +- bmc-snmp-proxy upstream bugfixes. + +* Fri Dec 27 2013 Daniel Mach - 1.8.13-4 +- Mass rebuild 2013-12-27 + * Tue Nov 5 2013 Ales Ledvinka 1.8.13-3 - Cleanup of dual bridge option.