From eb54136775f63a6a159f3c55ee4772d7aa363cc4 Mon Sep 17 00:00:00 2001 From: Zdenek Styblik Date: Wed, 11 Mar 2015 19:41:34 +0100 Subject: [PATCH] ID:319 - Interface safe re-open Currently, interface-management code in the ipmitool does not allow safe interface re-opening (i.e. closing and opening again). It is because the session is allocated in the interface setup callback while is freed in the close callback. So, normal re-opening of the interface, which can be required for example durng the HPM.1 upgrade, leads to segmentation fault. That's why in the ipmi_hpmfwupg.c instead of normal closing interface, directly access the interface data for subsequent re-opening. Commit for Dmitry Bazhenov --- include/ipmitool/ipmi_intf.h | 37 ++++--- lib/ipmi_dcmi.c | 24 ++--- lib/ipmi_hpmfwupg.c | 11 +-- lib/ipmi_main.c | 4 +- lib/ipmi_sol.c | 42 ++++---- lib/ipmi_tsol.c | 34 +++---- src/ipmievd.c | 4 +- src/ipmishell.c | 10 +- src/plugins/ipmi_intf.c | 136 +++++++++----------------- src/plugins/lan/lan.c | 139 +++++++++++++++------------ src/plugins/lanplus/lanplus.c | 120 +++++++++++------------ src/plugins/lanplus/lanplus_crypt.c | 24 ++--- src/plugins/serial/serial_basic.c | 22 ++--- src/plugins/serial/serial_terminal.c | 22 ++--- 14 files changed, 290 insertions(+), 339 deletions(-) diff --git a/include/ipmitool/ipmi_intf.h b/include/ipmitool/ipmi_intf.h index 6b6e247..efec82d 100644 --- a/include/ipmitool/ipmi_intf.h +++ b/include/ipmitool/ipmi_intf.h @@ -62,36 +62,43 @@ enum LANPLUS_SESSION_STATE { #define IPMI_SIK_BUFFER_SIZE 20 #define IPMI_KG_BUFFER_SIZE 21 /* key plus null byte */ -struct ipmi_session { - char *hostname; /* Numeric IP adress or DNS name - see RFC 1034/RFC 1035 */ +struct ipmi_session_params { + char * hostname; uint8_t username[17]; - uint8_t authcode[IPMI_AUTHCODE_BUFFER_SIZE + 1]; - uint8_t challenge[16]; - uint8_t authtype; + uint8_t authcode_set[IPMI_AUTHCODE_BUFFER_SIZE + 1]; uint8_t authtype_set; -#define IPMI_AUTHSTATUS_PER_MSG_DISABLED 0x10 -#define IPMI_AUTHSTATUS_PER_USER_DISABLED 0x08 -#define IPMI_AUTHSTATUS_NONNULL_USERS_ENABLED 0x04 -#define IPMI_AUTHSTATUS_NULL_USERS_ENABLED 0x02 -#define IPMI_AUTHSTATUS_ANONYMOUS_USERS_ENABLED 0x01 - uint8_t authstatus; - uint8_t authextra; uint8_t privlvl; uint8_t cipher_suite_id; char sol_escape_char; int password; int port; - int active; int retry; + uint32_t timeout; + uint8_t kg[IPMI_KG_BUFFER_SIZE]; /* BMC key */ + uint8_t lookupbit; +}; +#define IPMI_AUTHSTATUS_PER_MSG_DISABLED 0x10 +#define IPMI_AUTHSTATUS_PER_USER_DISABLED 0x08 +#define IPMI_AUTHSTATUS_NONNULL_USERS_ENABLED 0x04 +#define IPMI_AUTHSTATUS_NULL_USERS_ENABLED 0x02 +#define IPMI_AUTHSTATUS_ANONYMOUS_USERS_ENABLED 0x01 + +struct ipmi_session { + int active; uint32_t session_id; uint32_t in_seq; uint32_t out_seq; + + uint8_t authcode[IPMI_AUTHCODE_BUFFER_SIZE + 1]; + uint8_t challenge[16]; + uint8_t authtype; + uint8_t authstatus; + uint8_t authextra; uint32_t timeout; struct sockaddr_storage addr; socklen_t addrlen; - int ai_family; /* Protocol family for socket. */ /* * This struct holds state data specific to IPMI v2 / RMCP+ sessions @@ -107,7 +114,6 @@ struct ipmi_session { uint8_t integrity_alg; uint8_t crypt_alg; uint8_t max_priv_level; - uint8_t lookupbit; uint32_t console_id; uint32_t bmc_id; @@ -171,6 +177,7 @@ struct ipmi_intf { int vita_avail; IPMI_OEM manufacturer_id; + struct ipmi_session_params ssn_params; struct ipmi_session * session; struct ipmi_oem_handle * oem; struct ipmi_cmd * cmdlist; diff --git a/lib/ipmi_dcmi.c b/lib/ipmi_dcmi.c index b0f85cb..aeee944 100755 --- a/lib/ipmi_dcmi.c +++ b/lib/ipmi_dcmi.c @@ -750,7 +750,7 @@ ipmi_dcmi_prnt_oobDiscover(struct ipmi_intf * intf) "DCMI Discovery is available only when LANplus(IPMI v2.0) is enabled."); return (-1); # else - struct ipmi_session *s; + struct ipmi_session_params *p; if (intf->opened == 0 && intf->open != NULL) { if (intf->open(intf) < 0) @@ -759,18 +759,18 @@ ipmi_dcmi_prnt_oobDiscover(struct ipmi_intf * intf) if (intf == NULL || intf->session == NULL) return -1; - s = intf->session; + p = &intf->ssn_params; - if (s->port == 0) - s->port = IPMI_LAN_PORT; - if (s->privlvl == 0) - s->privlvl = IPMI_SESSION_PRIV_ADMIN; - if (s->timeout == 0) - s->timeout = IPMI_LAN_TIMEOUT; - if (s->retry == 0) - s->retry = IPMI_LAN_RETRY; + if (p->port == 0) + p->port = IPMI_LAN_PORT; + if (p->privlvl == 0) + p->privlvl = IPMI_SESSION_PRIV_ADMIN; + if (p->timeout == 0) + p->timeout = IPMI_LAN_TIMEOUT; + if (p->retry == 0) + p->retry = IPMI_LAN_RETRY; - if (s->hostname == NULL || strlen((const char *)s->hostname) == 0) { + if (p->hostname == NULL || strlen((const char *)p->hostname) == 0) { lprintf(LOG_ERR, "No hostname specified!"); return -1; } @@ -785,7 +785,7 @@ ipmi_dcmi_prnt_oobDiscover(struct ipmi_intf * intf) if (intf->fd < 0) { lperror(LOG_ERR, "Connect to %s failed", - s->hostname); + p->hostname); intf->close(intf); return -1; } diff --git a/lib/ipmi_hpmfwupg.c b/lib/ipmi_hpmfwupg.c index 9dfa0f3..2a4925c 100644 --- a/lib/ipmi_hpmfwupg.c +++ b/lib/ipmi_hpmfwupg.c @@ -2194,18 +2194,15 @@ HpmfwupgSendCmd(struct ipmi_intf *intf, struct ipmi_rq req, lprintf(LOG_DEBUG, "HPM: try to re-open IOL session"); { /* force session re-open */ - intf->opened = 0; - intf->session->authtype = IPMI_SESSION_AUTHTYPE_NONE; - intf->session->session_id = 0; - intf->session->in_seq = 0; - intf->session->out_seq = 0; - intf->session->active = 0; - intf->session->retry = 10; + intf->abort = 1; + intf->close(intf); + while (intf->open(intf) == HPMFWUPG_ERROR && inaccessTimeoutCounter < inaccessTimeout) { inaccessTimeoutCounter += (time(NULL) - timeoutSec1); timeoutSec1 = time(NULL); } + /* Fake timeout to retry command */ fakeRsp.ccode = 0xc3; rsp = &fakeRsp; diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c index 0f01001..a033778 100644 --- a/lib/ipmi_main.c +++ b/lib/ipmi_main.c @@ -272,9 +272,7 @@ void ipmi_catch_sigint() if (ipmi_main_intf != NULL) { printf("\nSIGN INT: Close Interface %s\n",ipmi_main_intf->desc); /* reduce retry count to a single retry */ - if (ipmi_main_intf->session) { - ipmi_main_intf->session->retry = 1; - } + ipmi_main_intf->ssn_params.retry = 1; /* close interface */ ipmi_main_intf->close(ipmi_main_intf); } diff --git a/lib/ipmi_sol.c b/lib/ipmi_sol.c index 244a27e..5415ea7 100644 --- a/lib/ipmi_sol.c +++ b/lib/ipmi_sol.c @@ -544,8 +544,8 @@ ipmi_get_sol_info( case 0x80: if( intf->session != NULL ) { lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported - defaulting to %d", - val2str(data[1], sol_parameter_vals), intf->session->port); - params->payload_port = intf->session->port; + val2str(data[1], sol_parameter_vals), intf->ssn_params.port); + params->payload_port = intf->ssn_params.port; } else { lprintf(LOG_ERR, "Info: SOL parameter '%s' not supported - can't determine which " @@ -1235,14 +1235,14 @@ printSolEscapeSequences(struct ipmi_intf * intf) %c? - this message\n\ %c%c - send the escape character by typing it twice\n\ (Note that escapes are only recognized immediately after newline.)\n", - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char); } @@ -1379,25 +1379,25 @@ processSolUserInput( switch (ch) { case '.': printf("%c. [terminated ipmitool]\n", - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char); retval = 1; break; case 'Z' - 64: printf("%c^Z [suspend ipmitool]\n", - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char); suspendSelf(1); /* Restore tty back to raw */ continue; case 'X' - 64: printf("%c^Z [suspend ipmitool]\n", - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char); suspendSelf(0); /* Don't restore to raw mode */ continue; case 'B': printf("%cB [send break]\n", - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char); sendBreak(intf); continue; @@ -1406,16 +1406,16 @@ processSolUserInput( continue; default: - if (ch != intf->session->sol_escape_char) + if (ch != intf->ssn_params.sol_escape_char) v2_payload.payload.sol_packet.data[length++] = - intf->session->sol_escape_char; + intf->ssn_params.sol_escape_char; v2_payload.payload.sol_packet.data[length++] = ch; } } else { - if (last_was_cr && (ch == intf->session->sol_escape_char)) { + if (last_was_cr && (ch == intf->ssn_params.sol_escape_char)) { escape_pending = 1; continue; } @@ -1441,7 +1441,7 @@ processSolUserInput( struct ipmi_rs * rsp = NULL; int try = 0; - while (try < intf->session->retry) { + while (try < intf->ssn_params.retry) { v2_payload.payload.sol_packet.character_count = length; @@ -1827,12 +1827,12 @@ ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval, /* NOTE: the spec does allow for SOL traffic to be sent on * a different port. we do not yet support that feature. */ - if (intf->session->sol_data.port != intf->session->port) + if (intf->session->sol_data.port != intf->ssn_params.port) { /* try byteswapping port in case BMC sent it incorrectly */ uint16_t portswap = BSWAP_16(intf->session->sol_data.port); - if (portswap == intf->session->port) { + if (portswap == intf->ssn_params.port) { intf->session->sol_data.port = portswap; } else { @@ -1842,7 +1842,7 @@ ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval, } printf("[SOL Session operational. Use %c? for help]\n", - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char); if(looptest == 1) { diff --git a/lib/ipmi_tsol.c b/lib/ipmi_tsol.c index d7460bd..70d7357 100644 --- a/lib/ipmi_tsol.c +++ b/lib/ipmi_tsol.c @@ -185,12 +185,12 @@ print_escape_seq(struct ipmi_intf *intf) " %c? - this message\n" " %c%c - send the escape character by typing it twice\n" " (Note that escapes are only recognized immediately after newline.)", - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char, - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char, + intf->ssn_params.sol_escape_char); } static int @@ -264,7 +264,7 @@ do_inbuf_actions(struct ipmi_intf *intf, char *in_buff, int len) for(i = 0; i < len ;) { if (!in_esc) { if (last_was_cr && - (in_buff[i] == intf->session->sol_escape_char)) { + (in_buff[i] == intf->ssn_params.sol_escape_char)) { in_esc = 1; memmove(in_buff, in_buff + 1, len - i - 1); len--; @@ -272,7 +272,7 @@ do_inbuf_actions(struct ipmi_intf *intf, char *in_buff, int len) } } if (in_esc) { - if (in_buff[i] == intf->session->sol_escape_char) { + if (in_buff[i] == intf->ssn_params.sol_escape_char) { in_esc = 0; i++; continue; @@ -281,23 +281,23 @@ do_inbuf_actions(struct ipmi_intf *intf, char *in_buff, int len) switch (in_buff[i]) { case '.': printf("%c. [terminated ipmitool]\n", - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char); return -1; case 'Z' - 64: printf("%c^Z [suspend ipmitool]\n", - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char); /* Restore tty back to raw */ suspend_self(1); break; case 'X' - 64: printf("%c^X [suspend ipmitool]\n", - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char); /* Don't restore to raw mode */ suspend_self(0); break; case '?': printf("%c? [ipmitool help]\n", - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char); print_escape_seq(intf); break; } @@ -425,20 +425,20 @@ ipmi_tsol_main(struct ipmi_intf *intf, int argc, char **argv) sin.sin_port = htons(port); sa_in = (struct sockaddr_in *)&intf->session->addr; - result = inet_pton(AF_INET, (const char *)intf->session->hostname, + result = inet_pton(AF_INET, (const char *)intf->ssn_params.hostname, &sa_in->sin_addr); if (result <= 0) { - struct hostent *host = gethostbyname((const char *)intf->session->hostname); + struct hostent *host = gethostbyname((const char *)intf->ssn_params.hostname); if (host == NULL ) { lprintf(LOG_ERR, "Address lookup for %s failed", - intf->session->hostname); + intf->ssn_params.hostname); return -1; } if (host->h_addrtype != AF_INET) { lprintf(LOG_ERR, "Address lookup for %s failed. Got %s, expected IPv4 address.", - intf->session->hostname, + intf->ssn_params.hostname, (host->h_addrtype == AF_INET6) ? "IPv6" : "Unknown"); return (-1); } @@ -501,7 +501,7 @@ ipmi_tsol_main(struct ipmi_intf *intf, int argc, char **argv) } printf("[SOL Session operational. Use %c? for help]\n", - intf->session->sol_escape_char); + intf->ssn_params.sol_escape_char); gettimeofday(&_start_keepalive, 0); diff --git a/src/ipmievd.c b/src/ipmievd.c index fec5493..9ba2ece 100644 --- a/src/ipmievd.c +++ b/src/ipmievd.c @@ -832,8 +832,8 @@ ipmievd_sel_main(struct ipmi_intf * intf, int argc, char ** argv) if (intf->session != NULL) { snprintf(eintf->prefix, - strlen((const char *)intf->session->hostname) + 3, - "%s: ", intf->session->hostname); + strlen((const char *)intf->ssn_params.hostname) + 3, + "%s: ", intf->ssn_params.hostname); } return ipmievd_main(eintf, argc, argv); diff --git a/src/ipmishell.c b/src/ipmishell.c index c5b6af0..6cfcbe8 100644 --- a/src/ipmishell.c +++ b/src/ipmishell.c @@ -301,7 +301,7 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv) return (-1); } printf("Set session hostname to %s\n", - intf->session->hostname); + intf->ssn_params.hostname); } else if (strncmp(argv[0], "user", 4) == 0 || strncmp(argv[0], "username", 8) == 0) { @@ -311,7 +311,7 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv) return (-1); } printf("Set session username to %s\n", - intf->session->username); + intf->ssn_params.username); } else if (strncmp(argv[0], "pass", 4) == 0 || strncmp(argv[0], "password", 8) == 0) { @@ -336,7 +336,7 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv) return (-1); } printf("Set session authtype to %s\n", - val2str(intf->session->authtype_set, + val2str(intf->ssn_params.authtype_set, ipmi_authtype_session_vals)); } else if (strncmp(argv[0], "privlvl", 7) == 0) { @@ -354,7 +354,7 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv) return (-1); } printf("Set session privilege level to %s\n", - val2str(intf->session->privlvl, + val2str(intf->ssn_params.privlvl, ipmi_privlvl_vals)); } else if (strncmp(argv[0], "port", 4) == 0) { @@ -369,7 +369,7 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv) lprintf(LOG_ERR, "Failed to set session port."); return (-1); } - printf("Set session port to %d\n", intf->session->port); + printf("Set session port to %d\n", intf->ssn_params.port); } else if (strncmp(argv[0], "localaddr", 9) == 0) { uint8_t my_addr = 0; diff --git a/src/plugins/ipmi_intf.c b/src/plugins/ipmi_intf.c index 19a0469..2207241 100644 --- a/src/plugins/ipmi_intf.c +++ b/src/plugins/ipmi_intf.c @@ -196,139 +196,106 @@ struct ipmi_intf * ipmi_intf_load(char * name) void ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname) { - if (intf->session == NULL || hostname == NULL) { + if (intf->ssn_params.hostname != NULL) { + free(intf->ssn_params.hostname); + intf->ssn_params.hostname = NULL; + } + if (hostname == NULL) { return; } - if (intf->session->hostname != NULL) { - free(intf->session->hostname); - intf->session->hostname = NULL; - } - intf->session->hostname = strdup(hostname); + intf->ssn_params.hostname = strdup(hostname); } void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username) { - if (intf->session == NULL) - return; - - memset(intf->session->username, 0, 17); + memset(intf->ssn_params.username, 0, 17); if (username == NULL) return; - memcpy(intf->session->username, username, __min(strlen(username), 16)); + memcpy(intf->ssn_params.username, username, __min(strlen(username), 16)); } void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password) { - if (intf->session == NULL) - return; - - memset(intf->session->authcode, 0, IPMI_AUTHCODE_BUFFER_SIZE); + memset(intf->ssn_params.authcode_set, 0, IPMI_AUTHCODE_BUFFER_SIZE); if (password == NULL) { - intf->session->password = 0; + intf->ssn_params.password = 0; return; } - intf->session->password = 1; - memcpy(intf->session->authcode, password, + intf->ssn_params.password = 1; + memcpy(intf->ssn_params.authcode_set, password, __min(strlen(password), IPMI_AUTHCODE_BUFFER_SIZE)); } void ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t level) { - if (intf->session == NULL) - return; - - intf->session->privlvl = level; + intf->ssn_params.privlvl = level; } void ipmi_intf_session_set_lookupbit(struct ipmi_intf * intf, uint8_t lookupbit) { - if (intf->session == NULL) - return; - - intf->session->v2_data.lookupbit = lookupbit; + intf->ssn_params.lookupbit = lookupbit; } void ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id) { - if (intf->session == NULL) - return; - - intf->session->cipher_suite_id = cipher_suite_id; + intf->ssn_params.cipher_suite_id = cipher_suite_id; } void ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char) { - if (intf->session == NULL) - return; - - intf->session->sol_escape_char = sol_escape_char; + intf->ssn_params.sol_escape_char = sol_escape_char; } void ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey) { - if (intf->session == NULL) - return; - - memset(intf->session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE); + memset(intf->ssn_params.kg, 0, IPMI_KG_BUFFER_SIZE); if (kgkey == NULL) return; - memcpy(intf->session->v2_data.kg, kgkey, + memcpy(intf->ssn_params.kg, kgkey, __min(strlen(kgkey), IPMI_KG_BUFFER_SIZE)); } void ipmi_intf_session_set_port(struct ipmi_intf * intf, int port) { - if (intf->session == NULL) - return; - - intf->session->port = port; + intf->ssn_params.port = port; } void ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype) { - if (intf->session == NULL) - return; - /* clear password field if authtype NONE specified */ if (authtype == IPMI_SESSION_AUTHTYPE_NONE) { - memset(intf->session->authcode, 0, IPMI_AUTHCODE_BUFFER_SIZE); - intf->session->password = 0; + memset(intf->ssn_params.authcode_set, 0, IPMI_AUTHCODE_BUFFER_SIZE); + intf->ssn_params.password = 0; } - intf->session->authtype_set = authtype; + intf->ssn_params.authtype_set = authtype; } void ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout) { - if (intf->session == NULL) - return; - - intf->session->timeout = timeout; + intf->ssn_params.timeout = timeout; } void ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry) { - if (intf->session == NULL) - return; - - intf->session->retry = retry; + intf->ssn_params.retry = retry; } void @@ -337,10 +304,7 @@ ipmi_intf_session_cleanup(struct ipmi_intf *intf) if (intf->session == NULL) { return; } - if (intf->session->hostname != NULL) { - free(intf->session->hostname); - intf->session->hostname = NULL; - } + free(intf->session); intf->session = NULL; } @@ -349,26 +313,27 @@ void ipmi_cleanup(struct ipmi_intf * intf) { ipmi_sdr_list_empty(intf); + ipmi_intf_session_set_hostname(intf, NULL); } #if defined(IPMI_INTF_LAN) || defined (IPMI_INTF_LANPLUS) int ipmi_intf_socket_connect(struct ipmi_intf * intf) { - struct ipmi_session *session; + struct ipmi_session_params *params; struct sockaddr_storage addr; struct addrinfo hints; struct addrinfo *rp0 = NULL, *rp; char service[NI_MAXSERV]; - if (!intf || intf->session == NULL) { + if (!intf) { return -1; } - session = intf->session; + params = &intf->ssn_params; - if (session->hostname == NULL || strlen((const char *)session->hostname) == 0) { + if (params->hostname == NULL || strlen((const char *)params->hostname) == 0) { lprintf(LOG_ERR, "No hostname specified!"); return -1; } @@ -376,7 +341,7 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf) /* open port to BMC */ memset(&addr, 0, sizeof(addr)); - sprintf(service, "%d", session->port); + sprintf(service, "%d", params->port); /* Obtain address(es) matching host/port */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ @@ -384,19 +349,18 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf) hints.ai_flags = 0; /* use AI_NUMERICSERV for no name resolution */ hints.ai_protocol = IPPROTO_UDP; /* */ - if (getaddrinfo(session->hostname, service, &hints, &rp0) != 0) { + if (getaddrinfo(params->hostname, service, &hints, &rp0) != 0) { lprintf(LOG_ERR, "Address lookup for %s failed", - session->hostname); + params->hostname); return -1; } /* getaddrinfo() returns a list of address structures. * Try each address until we successfully connect(2). * If socket(2) (or connect(2)) fails, we (close the socket - * and) try the next address. + * and) try the next address. */ - session->ai_family = AF_UNSPEC; for (rp = rp0; rp != NULL; rp = rp->ai_next) { /* We are only interested in IPv4 and IPv6 */ if ((rp->ai_family != AF_INET6) && (rp->ai_family != AF_INET)) { @@ -410,9 +374,7 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf) if (rp->ai_family == AF_INET) { if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) { - memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen); - session->addrlen = rp->ai_addrlen; - session->ai_family = rp->ai_family; + hints.ai_family = rp->ai_family; break; /* Success */ } } else if (rp->ai_family == AF_INET6) { @@ -424,14 +386,12 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf) if (addr6->sin6_scope_id != 0) { len = sizeof(struct sockaddr_in6); if (getnameinfo((struct sockaddr *)addr6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) { - lprintf(LOG_DEBUG, "Trying address: %s scope=%d", - hbuf, + lprintf(LOG_DEBUG, "Trying address: %s scope=%d", + hbuf, addr6->sin6_scope_id); } if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) { - memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen); - session->addrlen = rp->ai_addrlen; - session->ai_family = rp->ai_family; + hints.ai_family = rp->ai_family; break; /* Success */ } } else { @@ -441,7 +401,7 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf) if (getifaddrs(&ifaddrs) < 0) { lprintf(LOG_ERR, "Interface address lookup for %s failed", - session->hostname); + params->hostname); break; } @@ -462,17 +422,17 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf) } len = sizeof(struct sockaddr_in6); if ( getnameinfo((struct sockaddr *)tmp6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) { - lprintf(LOG_DEBUG, "Testing %s interface address: %s scope=%d", - ifa->ifa_name != NULL ? ifa->ifa_name : "???", - hbuf, + lprintf(LOG_DEBUG, "Testing %s interface address: %s scope=%d", + ifa->ifa_name != NULL ? ifa->ifa_name : "???", + hbuf, tmp6->sin6_scope_id); } if (tmp6->sin6_scope_id != 0) { addr6->sin6_scope_id = tmp6->sin6_scope_id; } else { - /* - * No scope information in interface address information + /* + * No scope information in interface address information * On some OS'es, getifaddrs() is returning out the 'kernel' representation * of scoped addresses which stores the scope in the 3rd and 4th * byte. See also this page: @@ -487,19 +447,17 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf) /* OK, now try to connect with the scope id from this interface address */ if (addr6->sin6_scope_id != 0) { if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) { - memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen); - session->addrlen = rp->ai_addrlen; - session->ai_family = rp->ai_family; + hints.ai_family = rp->ai_family; lprintf(LOG_DEBUG, "Successful connected on %s interface with scope id %d", ifa->ifa_name, tmp6->sin6_scope_id); break; /* Success */ } - } + } } } freeifaddrs(ifaddrs); } } - if (session->ai_family != AF_UNSPEC) { + if (hints.ai_family != AF_UNSPEC) { break; } close(intf->fd); diff --git a/src/plugins/lan/lan.c b/src/plugins/lan/lan.c index 5eda274..4fb2209 100644 --- a/src/plugins/lan/lan.c +++ b/src/plugins/lan/lan.c @@ -262,7 +262,7 @@ ipmi_lan_recv_packet(struct ipmi_intf * intf) FD_ZERO(&err_set); FD_SET(intf->fd, &err_set); - tmout.tv_sec = intf->session->timeout; + tmout.tv_sec = intf->ssn_params.timeout; tmout.tv_usec = 0; ret = select(intf->fd + 1, &read_set, NULL, &err_set, &tmout); @@ -288,7 +288,7 @@ ipmi_lan_recv_packet(struct ipmi_intf * intf) FD_ZERO(&err_set); FD_SET(intf->fd, &err_set); - tmout.tv_sec = intf->session->timeout; + tmout.tv_sec = intf->ssn_params.timeout; tmout.tv_usec = 0; ret = select(intf->fd + 1, &read_set, NULL, &err_set, &tmout); @@ -955,7 +955,7 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) break; usleep(5000); - if (++try >= intf->session->retry) { + if (++try >= intf->ssn_params.retry) { lprintf(LOG_DEBUG, " No response from remote controller"); break; } @@ -1305,7 +1305,7 @@ ipmi_lan_send_sol_payload(struct ipmi_intf * intf, } usleep(5000); - if (++try >= intf->session->retry) { + if (++try >= intf->ssn_params.retry) { lprintf(LOG_DEBUG, " No response from remote controller"); break; } @@ -1580,10 +1580,11 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf) struct ipmi_rs * rsp; struct ipmi_rq req; struct ipmi_session * s = intf->session; + struct ipmi_session_params *p = &intf->ssn_params; uint8_t msg_data[2]; msg_data[0] = IPMI_LAN_CHANNEL_E; - msg_data[1] = s->privlvl; + msg_data[1] = p->privlvl; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_APP; @@ -1634,44 +1635,44 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf) s->authstatus = rsp->data[2]; - if (s->password && - (s->authtype_set == 0 || - s->authtype_set == IPMI_SESSION_AUTHTYPE_MD5) && + if (p->password && + (p->authtype_set == 0 || + p->authtype_set == IPMI_SESSION_AUTHTYPE_MD5) && (rsp->data[1] & 1<authtype = IPMI_SESSION_AUTHTYPE_MD5; } - else if (s->password && - (s->authtype_set == 0 || - s->authtype_set == IPMI_SESSION_AUTHTYPE_MD2) && + else if (p->password && + (p->authtype_set == 0 || + p->authtype_set == IPMI_SESSION_AUTHTYPE_MD2) && (rsp->data[1] & 1<authtype = IPMI_SESSION_AUTHTYPE_MD2; } - else if (s->password && - (s->authtype_set == 0 || - s->authtype_set == IPMI_SESSION_AUTHTYPE_PASSWORD) && + else if (p->password && + (p->authtype_set == 0 || + p->authtype_set == IPMI_SESSION_AUTHTYPE_PASSWORD) && (rsp->data[1] & 1<authtype = IPMI_SESSION_AUTHTYPE_PASSWORD; } - else if (s->password && - (s->authtype_set == 0 || - s->authtype_set == IPMI_SESSION_AUTHTYPE_OEM) && + else if (p->password && + (p->authtype_set == 0 || + p->authtype_set == IPMI_SESSION_AUTHTYPE_OEM) && (rsp->data[1] & 1<authtype = IPMI_SESSION_AUTHTYPE_OEM; } - else if ((s->authtype_set == 0 || - s->authtype_set == IPMI_SESSION_AUTHTYPE_NONE) && + else if ((p->authtype_set == 0 || + p->authtype_set == IPMI_SESSION_AUTHTYPE_NONE) && (rsp->data[1] & 1<authtype = IPMI_SESSION_AUTHTYPE_NONE; } else { - if (!(rsp->data[1] & 1<authtype_set)) + if (!(rsp->data[1] & 1<authtype_set)) lprintf(LOG_ERR, "Authentication type %s not supported", - val2str(s->authtype_set, ipmi_authtype_session_vals)); + val2str(p->authtype_set, ipmi_authtype_session_vals)); else lprintf(LOG_ERR, "No supported authtypes found"); @@ -1698,7 +1699,7 @@ ipmi_get_session_challenge_cmd(struct ipmi_intf * intf) memset(msg_data, 0, 17); msg_data[0] = s->authtype; - memcpy(msg_data+1, s->username, 16); + memcpy(msg_data+1, intf->ssn_params.username, 16); memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_APP; @@ -1755,12 +1756,12 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf) req.msg.cmd = 0x3a; msg_data[0] = s->authtype; - msg_data[1] = s->privlvl; + msg_data[1] = intf->ssn_params.privlvl; /* supermicro oem authentication hack */ if (ipmi_oem_active(intf, "supermicro")) { uint8_t * special = ipmi_auth_special(s); - memcpy(s->authcode, special, 16); + memcpy(intf->session->authcode, special, 16); memset(msg_data + 2, 0, 16); lprintf(LOG_DEBUG, " OEM Auth : %s", buf2str(special, 16)); @@ -1837,8 +1838,6 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf) return -1; } - bridge_possible = 1; - lprintf(LOG_DEBUG, "\nSession Activated"); lprintf(LOG_DEBUG, " Auth Type : %s", val2str(rsp->data[0], ipmi_authtype_session_vals)); @@ -1859,7 +1858,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf) { struct ipmi_rs * rsp; struct ipmi_rq req; - uint8_t privlvl = intf->session->privlvl; + uint8_t privlvl = intf->ssn_params.privlvl; uint8_t backup_bridge_possible = bridge_possible; if (privlvl <= IPMI_SESSION_PRIV_USER) @@ -1992,23 +1991,27 @@ ipmi_lan_activate_session(struct ipmi_intf * intf) rc = ipmi_set_session_privlvl_cmd(intf); if (rc < 0) - goto fail; + goto close_fail; return 0; + close_fail: + ipmi_close_session_cmd(intf); fail: lprintf(LOG_ERR, "Error: Unable to establish LAN session"); return -1; } -static void +void ipmi_lan_close(struct ipmi_intf * intf) { - if (intf->abort == 0) + if (!intf->abort && intf->session) ipmi_close_session_cmd(intf); - if (intf->fd >= 0) + if (intf->fd >= 0) { close(intf->fd); + intf->fd = -1; + } ipmi_req_clear_entries(); ipmi_intf_session_cleanup(intf); @@ -2022,69 +2025,79 @@ ipmi_lan_open(struct ipmi_intf * intf) { int rc; struct ipmi_session *s; + struct ipmi_session_params *p; + struct sockaddr_storage addr; - if (intf == NULL || intf->session == NULL) + if (intf == NULL || intf->opened) return -1; + s = intf->session; + p = &intf->ssn_params; - if (s->port == 0) - s->port = IPMI_LAN_PORT; - if (s->privlvl == 0) - s->privlvl = IPMI_SESSION_PRIV_ADMIN; - if (s->timeout == 0) - s->timeout = IPMI_LAN_TIMEOUT; - if (s->retry == 0) - s->retry = IPMI_LAN_RETRY; + if (p->port == 0) + p->port = IPMI_LAN_PORT; + if (p->privlvl == 0) + p->privlvl = IPMI_SESSION_PRIV_ADMIN; + if (p->timeout == 0) + p->timeout = IPMI_LAN_TIMEOUT; + if (p->retry == 0) + p->retry = IPMI_LAN_RETRY; - if (s->hostname == NULL || strlen((const char *)s->hostname) == 0) { + if (p->hostname == NULL || strlen((const char *)p->hostname) == 0) { lprintf(LOG_ERR, "No hostname specified!"); return -1; } - intf->abort = 1; - - intf->session->sol_data.sequence_number = 1; - - if (ipmi_intf_socket_connect (intf) == -1) { + if (ipmi_intf_socket_connect(intf) == -1) { lprintf(LOG_ERR, "Could not open socket!"); return -1; } - if (intf->fd < 0) { - lperror(LOG_ERR, "Connect to %s failed", - s->hostname); - intf->close(intf); - return -1; + s = (struct ipmi_session *)malloc(sizeof(struct ipmi_session)); + if (!s) { + lprintf(LOG_ERR, "ipmitool: malloc failure"); + goto fail; } intf->opened = 1; + intf->abort = 1; + + intf->session = s; + + memset(s, 0, sizeof(struct ipmi_session)); + s->sol_data.sequence_number = 1; + s->timeout = p->timeout; + memcpy(&s->authcode, &p->authcode_set, sizeof(s->authcode)); + s->addrlen = sizeof(s->addr); + if (getsockname(intf->fd, &s->addr, &s->addrlen)) { + goto fail; + } /* try to open session */ rc = ipmi_lan_activate_session(intf); if (rc < 0) { - intf->close(intf); - intf->opened = 0; - return -1; + goto fail; } - intf->manufacturer_id = ipmi_get_oem(intf); - /* automatically detect interface request and response sizes */ hpm2_detect_max_payload_size(intf); + /* set manufactirer OEM id */ + intf->manufacturer_id = ipmi_get_oem(intf); + + /* now allow bridging */ + bridge_possible = 1; return intf->fd; + + fail: + lprintf(LOG_ERR, "Error: Unable to establish IPMI v1.5 / RMCP session"); + intf->close(intf); + return -1; } static int ipmi_lan_setup(struct ipmi_intf * intf) { - intf->session = malloc(sizeof(struct ipmi_session)); - if (intf->session == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - return -1; - } - memset(intf->session, 0, sizeof(struct ipmi_session)); - /* setup default LAN maximum request and response sizes */ intf->max_request_data_size = IPMI_LAN_MAX_REQUEST_SIZE; intf->max_response_data_size = IPMI_LAN_MAX_RESPONSE_SIZE; diff --git a/src/plugins/lanplus/lanplus.c b/src/plugins/lanplus/lanplus.c index 739dfd1..37fbeb5 100644 --- a/src/plugins/lanplus/lanplus.c +++ b/src/plugins/lanplus/lanplus.c @@ -2128,7 +2128,7 @@ ipmi_lanplus_send_payload( * so it will only be valid after the open completes. */ saved_timeout = session->timeout; - while (try < session->retry) { + while (try < intf->ssn_params.retry) { //ltime = time(NULL); if (xmit) { @@ -2266,16 +2266,16 @@ ipmi_lanplus_send_payload( case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST: session->v2_data.session_state = LANPLUS_STATE_OPEN_SESSION_SENT; /* not retryable for timeouts, force no retry */ - try = session->retry; + try = intf->ssn_params.retry; break; case IPMI_PAYLOAD_TYPE_RAKP_1: session->v2_data.session_state = LANPLUS_STATE_RAKP_1_SENT; /* not retryable for timeouts, force no retry */ - try = session->retry; + try = intf->ssn_params.retry; break; case IPMI_PAYLOAD_TYPE_RAKP_3: /* not retryable for timeouts, force no retry */ - try = session->retry; + try = intf->ssn_params.retry; session->v2_data.session_state = LANPLUS_STATE_RAKP_3_SENT; break; } @@ -2680,7 +2680,7 @@ ipmi_get_auth_capabilities_cmd( bridgePossible = 0; msg_data[0] = IPMI_LAN_CHANNEL_E | 0x80; // Ask for IPMI v2 data as well - msg_data[1] = intf->session->privlvl; + msg_data[1] = intf->ssn_params.privlvl; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_APP; // 0x06 @@ -2731,7 +2731,8 @@ ipmi_close_session_cmd(struct ipmi_intf * intf) uint32_t bmc_session_lsbf; uint8_t backupBridgePossible; - if (intf->session->v2_data.session_state != LANPLUS_STATE_ACTIVE) + if (intf->session == NULL + || intf->session->v2_data.session_state != LANPLUS_STATE_ACTIVE) return -1; backupBridgePossible = bridgePossible; @@ -2812,8 +2813,8 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf) memset(msg, 0, IPMI_OPEN_SESSION_REQUEST_SIZE); msg[0] = 0; /* Message tag */ - if (ipmi_oem_active(intf, "intelplus") || session->privlvl != IPMI_SESSION_PRIV_ADMIN) - msg[1] = session->privlvl; + if (ipmi_oem_active(intf, "intelplus") || intf->ssn_params.privlvl != IPMI_SESSION_PRIV_ADMIN) + msg[1] = intf->ssn_params.privlvl; else msg[1] = 0; /* Give us highest privlg level based on supported algorithms */ msg[2] = 0; /* reserved */ @@ -2827,13 +2828,13 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf) msg[7] = (session->v2_data.console_id >> 24) & 0xff; - if (lanplus_get_requested_ciphers(session->cipher_suite_id, + if (lanplus_get_requested_ciphers(intf->ssn_params.cipher_suite_id, &(session->v2_data.requested_auth_alg), &(session->v2_data.requested_integrity_alg), &(session->v2_data.requested_crypt_alg))) { lprintf(LOG_WARNING, "Unsupported cipher suite ID : %d\n", - session->cipher_suite_id); + intf->ssn_params.cipher_suite_id); free(msg); msg = NULL; return 1; @@ -3033,14 +3034,14 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf) /* * Requested maximum privilege level. */ - msg[24] = session->privlvl | session->v2_data.lookupbit; + msg[24] = intf->ssn_params.privlvl | intf->ssn_params.lookupbit; session->v2_data.requested_role = msg[24]; msg[25] = 0; /* reserved */ msg[26] = 0; /* reserved */ /* Username specification */ - msg[27] = strlen((const char *)session->username); + msg[27] = strlen((const char *)intf->ssn_params.username); if (msg[27] > IPMI_MAX_USER_NAME_LENGTH) { lprintf(LOG_ERR, "ERROR: user name too long. " @@ -3050,7 +3051,7 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf) msg = NULL; return 1; } - memcpy(msg + 28, session->username, msg[27]); + memcpy(msg + 28, intf->ssn_params.username, msg[27]); v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_1; if (ipmi_oem_active(intf, "i82571spt")) { @@ -3296,15 +3297,16 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf) void ipmi_lanplus_close(struct ipmi_intf * intf) { - if (!intf->abort) + if (!intf->abort && intf->session) ipmi_close_session_cmd(intf); - if (intf->fd >= 0) + if (intf->fd >= 0) { close(intf->fd); + intf->fd = -1; + } ipmi_req_clear_entries(); ipmi_intf_session_cleanup(intf); - intf->session = NULL; intf->opened = 0; intf->manufacturer_id = IPMI_OEM_UNKNOWN; intf = NULL; @@ -3318,7 +3320,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf) struct ipmi_rs * rsp; struct ipmi_rq req; uint8_t backupBridgePossible; - uint8_t privlvl = intf->session->privlvl; + uint8_t privlvl = intf->ssn_params.privlvl; if (privlvl <= IPMI_SESSION_PRIV_USER) return 0; /* no need to set higher */ @@ -3368,55 +3370,54 @@ ipmi_lanplus_open(struct ipmi_intf * intf) int rc; int retry; struct get_channel_auth_cap_rsp auth_cap; + struct ipmi_session_params *params; struct ipmi_session *session; - if (!intf || !intf->session) + if (!intf) return -1; - session = intf->session; - if (!session->port) - session->port = IPMI_LANPLUS_PORT; - if (!session->privlvl) - session->privlvl = IPMI_SESSION_PRIV_ADMIN; - if (!session->timeout) - session->timeout = IPMI_LAN_TIMEOUT; - if (!session->retry) - session->retry = IPMI_LAN_RETRY; + if (intf->opened) + return intf->fd; - if (session->hostname == NULL || strlen((const char *)session->hostname) == 0) { + params = &intf->ssn_params; + + if (!params->port) + params->port = IPMI_LANPLUS_PORT; + if (!params->privlvl) + params->privlvl = IPMI_SESSION_PRIV_ADMIN; + if (!params->timeout) + params->timeout = IPMI_LAN_TIMEOUT; + if (!params->retry) + params->retry = IPMI_LAN_RETRY; + + if (params->hostname == NULL || strlen((const char *)params->hostname) == 0) { lprintf(LOG_ERR, "No hostname specified!"); return -1; } - intf->abort = 1; + if (ipmi_intf_socket_connect(intf) == -1) { + lprintf(LOG_ERR, "Could not open socket!"); + goto fail; + } + session = (struct ipmi_session *)malloc(sizeof (struct ipmi_session)); + if (!session) { + lprintf(LOG_ERR, "ipmitool: malloc failure"); + goto fail; + } + + intf->session = session; /* Setup our lanplus session state */ + memset(session, 0, sizeof(struct ipmi_session)); + session->timeout = params->timeout; + memcpy(&session->authcode, ¶ms->authcode_set, sizeof(session->authcode)); session->v2_data.auth_alg = IPMI_AUTH_RAKP_NONE; session->v2_data.crypt_alg = IPMI_CRYPT_NONE; - session->v2_data.console_id = 0x00; - session->v2_data.bmc_id = 0x00; session->sol_data.sequence_number = 1; - //session->sol_data.last_received_sequence_number = 0; - //session->sol_data.last_received_byte_count = 0; - memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE); - - /* Kg is set in ipmi_intf */ - //memset(session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE); - - if (ipmi_intf_socket_connect (intf) == -1) { - lprintf(LOG_ERR, "Could not open socket!"); - return -1; - } - - if (intf->fd < 0) { - lperror(LOG_ERR, "Connect to %s failed", - session->hostname); - intf->close(intf); - return -1; - } intf->opened = 1; + intf->abort = 1; /* * @@ -3445,7 +3446,6 @@ ipmi_lanplus_open(struct ipmi_intf * intf) * Open session */ if ((rc = ipmi_lanplus_open_session(intf)) == 1) { - intf->close(intf); goto fail; } if (rc == 2) { @@ -3456,7 +3456,6 @@ ipmi_lanplus_open(struct ipmi_intf * intf) * RAKP 1 */ if ((rc = ipmi_lanplus_rakp1(intf)) == 1) { - intf->close(intf); goto fail; } if (rc == 2) { @@ -3467,7 +3466,6 @@ ipmi_lanplus_open(struct ipmi_intf * intf) * RAKP 3 */ if ((rc = ipmi_lanplus_rakp3(intf)) == 1) { - intf->close(intf); goto fail; } if (rc == 0) break; @@ -3476,24 +3474,25 @@ ipmi_lanplus_open(struct ipmi_intf * intf) lprintf(LOG_DEBUG, "IPMIv2 / RMCP+ SESSION OPENED SUCCESSFULLY\n"); + intf->abort = 0; + if (!ipmi_oem_active(intf, "i82571spt")) { rc = ipmi_set_session_privlvl_cmd(intf); if (rc < 0) { - intf->close(intf); goto fail; } } intf->manufacturer_id = ipmi_get_oem(intf); - bridgePossible = 1; /* automatically detect interface request and response sizes */ hpm2_detect_max_payload_size(intf); + bridgePossible = 1; return intf->fd; fail: lprintf(LOG_ERR, "Error: Unable to establish IPMI v2 / RMCP+ session"); - intf->opened = 0; + intf->close(intf); return -1; } @@ -3636,13 +3635,6 @@ static int ipmi_lanplus_setup(struct ipmi_intf * intf) if (lanplus_seed_prng(16)) return -1; - intf->session = malloc(sizeof(struct ipmi_session)); - if (intf->session == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - return -1; - } - memset(intf->session, 0, sizeof(struct ipmi_session)); - /* setup default LAN maximum request and response sizes */ intf->max_request_data_size = IPMI_LAN_MAX_REQUEST_SIZE; intf->max_response_data_size = IPMI_LAN_MAX_RESPONSE_SIZE; @@ -3652,7 +3644,7 @@ static int ipmi_lanplus_setup(struct ipmi_intf * intf) static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size) { - if (intf->session->cipher_suite_id == 3) { + if (intf->ssn_params.cipher_suite_id == 3) { /* * encrypted payload can only be multiple of 16 bytes */ @@ -3670,7 +3662,7 @@ static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t siz static void ipmi_lanp_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size) { - if (intf->session->cipher_suite_id == 3) { + if (intf->ssn_params.cipher_suite_id == 3) { /* * encrypted payload can only be multiple of 16 bytes */ diff --git a/src/plugins/lanplus/lanplus_crypt.c b/src/plugins/lanplus/lanplus_crypt.c index 54fd5cb..1cdd050 100644 --- a/src/plugins/lanplus/lanplus_crypt.c +++ b/src/plugins/lanplus/lanplus_crypt.c @@ -95,7 +95,7 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session, 16 + /* GUIDc */ 1 + /* ROLEm */ 1 + /* ULENGTHm */ - strlen((const char *)session->username); /* optional */ + strlen((const char *)intf->ssn_params.username); /* optional */ buffer = malloc(bufferLength); if (buffer == NULL) { @@ -163,11 +163,11 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session, } /* ULENGTHm */ - buffer[57] = strlen((const char *)session->username); + buffer[57] = strlen((const char *)intf->ssn_params.username); /* UserName [optional] */ for (i = 0; i < buffer[57]; ++i) - buffer[58 + i] = session->username[i]; + buffer[58 + i] = intf->ssn_params.username[i]; if (verbose > 2) { @@ -375,7 +375,7 @@ lanplus_generate_rakp3_authcode(uint8_t * output_buffer, 4 + /* SIDm */ 1 + /* ROLEm */ 1 + /* ULENGTHm */ - strlen((const char *)session->username); + strlen((const char *)intf->ssn_params.username); input_buffer = malloc(input_buffer_length); if (input_buffer == NULL) { @@ -406,16 +406,16 @@ lanplus_generate_rakp3_authcode(uint8_t * output_buffer, /* ROLEm */ if (ipmi_oem_active(intf, "intelplus") || ipmi_oem_active(intf, "i82571spt")) - input_buffer[20] = session->privlvl; + input_buffer[20] = intf->ssn_params.privlvl; else input_buffer[20] = session->v2_data.requested_role; /* ULENGTHm */ - input_buffer[21] = strlen((const char *)session->username); + input_buffer[21] = strlen((const char *)intf->ssn_params.username); /* USERNAME */ for (i = 0; i < input_buffer[21]; ++i) - input_buffer[22 + i] = session->username[i]; + input_buffer[22 + i] = intf->ssn_params.username[i]; if (verbose > 2) { @@ -491,7 +491,7 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf) 16 + /* Rc */ 1 + /* ROLEm */ 1 + /* ULENGTHm */ - strlen((const char *)session->username); + strlen((const char *)intf->ssn_params.username); input_buffer = malloc(input_buffer_length); if (input_buffer == NULL) { @@ -536,13 +536,13 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf) } /* ULENGTHm */ - input_buffer[33] = strlen((const char *)session->username); + input_buffer[33] = strlen((const char *)intf->ssn_params.username); /* USERNAME */ for (i = 0; i < input_buffer[33]; ++i) - input_buffer[34 + i] = session->username[i]; + input_buffer[34 + i] = intf->ssn_params.username[i]; - if (session->v2_data.kg[0]) + if (intf->ssn_params.kg[0]) { /* We will be hashing with Kg */ /* @@ -550,7 +550,7 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf) * using Kg. It specifies that Kg should not be truncated. * Kg is set in ipmi_intf. */ - input_key = session->v2_data.kg; + input_key = intf->ssn_params.kg; } else { diff --git a/src/plugins/serial/serial_basic.c b/src/plugins/serial/serial_basic.c index d81fe8e..ff8648d 100644 --- a/src/plugins/serial/serial_basic.c +++ b/src/plugins/serial/serial_basic.c @@ -184,16 +184,10 @@ static int is_system; static int serial_bm_setup(struct ipmi_intf * intf) { - intf->session = malloc(sizeof(struct ipmi_session)); - if (intf->session == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - return -1; - } - memset(intf->session, 0, sizeof(struct ipmi_session)); - /* setup default LAN maximum request and response sizes */ intf->max_request_data_size = SERIAL_BM_MAX_RQ_SIZE; intf->max_response_data_size = SERIAL_BM_MAX_RS_SIZE; + return 0; } @@ -286,10 +280,10 @@ serial_bm_open(struct ipmi_intf * intf) /* set the new options for the port with flushing */ tcsetattr(intf->fd, TCSAFLUSH, &ti); - if (intf->session->timeout == 0) - intf->session->timeout = SERIAL_BM_TIMEOUT; - if (intf->session->retry == 0) - intf->session->retry = SERIAL_BM_RETRY_COUNT; + if (intf->ssn_params.timeout == 0) + intf->ssn_params.timeout = SERIAL_BM_TIMEOUT; + if (intf->ssn_params.retry == 0) + intf->ssn_params.retry = SERIAL_BM_RETRY_COUNT; intf->opened = 1; @@ -460,7 +454,7 @@ serial_bm_wait_for_data(struct ipmi_intf * intf) pfd.events = POLLIN; pfd.revents = 0; - n = poll(&pfd, 1, intf->session->timeout*1000); + n = poll(&pfd, 1, intf->ssn_params.timeout * 1000); if (n < 0) { lperror(LOG_ERR, "Poll for serial data failed"); return -1; @@ -888,7 +882,7 @@ serial_bm_get_message(struct ipmi_intf * intf, tm = clock() - start; tm /= CLOCKS_PER_SEC; - } while (tm < intf->session->timeout); + } while (tm < intf->ssn_params.timeout); return 0; } @@ -911,7 +905,7 @@ serial_bm_send_request(struct ipmi_intf * intf, struct ipmi_rq * req) read_ctx.max_buffer_size = SERIAL_BM_MAX_BUFFER_SIZE; /* Send the message and receive the answer */ - for (retry = 0; retry < intf->session->retry; retry++) { + for (retry = 0; retry < intf->ssn_params.retry; retry++) { /* build output message */ bridging_level = serial_bm_build_msg(intf, req, msg, sizeof (msg), req_ctx, &msg_len); diff --git a/src/plugins/serial/serial_terminal.c b/src/plugins/serial/serial_terminal.c index a49738d..a187fb7 100644 --- a/src/plugins/serial/serial_terminal.c +++ b/src/plugins/serial/serial_terminal.c @@ -226,10 +226,10 @@ ipmi_serial_term_open(struct ipmi_intf * intf) /* set the new options for the port with flushing */ tcsetattr(intf->fd, TCSAFLUSH, &ti); - if (intf->session->timeout == 0) - intf->session->timeout = IPMI_SERIAL_TIMEOUT; - if (intf->session->retry == 0) - intf->session->retry = IPMI_SERIAL_RETRY; + if (intf->ssn_params.timeout == 0) + intf->ssn_params.timeout = IPMI_SERIAL_TIMEOUT; + if (intf->ssn_params.retry == 0) + intf->ssn_params.retry = IPMI_SERIAL_RETRY; intf->opened = 1; @@ -260,7 +260,7 @@ serial_wait_for_data(struct ipmi_intf * intf) pfd.events = POLLIN; pfd.revents = 0; - n = poll(&pfd, 1, intf->session->timeout*1000); + n = poll(&pfd, 1, intf->ssn_params.timeout*1000); if (n < 0) { lperror(LOG_ERR, "Poll for serial data failed"); return -1; @@ -770,7 +770,7 @@ serial_term_get_message(struct ipmi_intf * intf, tm = clock() - start; tm /= CLOCKS_PER_SEC; - } while (tm < intf->session->timeout); + } while (tm < intf->ssn_params.timeout); return 0; } @@ -788,7 +788,7 @@ ipmi_serial_term_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) } /* Send the message and receive the answer */ - for (retry = 0; retry < intf->session->retry; retry++) { + for (retry = 0; retry < intf->ssn_params.retry; retry++) { /* build output message */ bridging_level = serial_term_build_msg(intf, req, msg, sizeof (msg), req_ctx, &msg_len); @@ -883,14 +883,6 @@ ipmi_serial_term_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) static int ipmi_serial_term_setup(struct ipmi_intf * intf) { - intf->session = malloc(sizeof(struct ipmi_session)); - if (intf->session == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - return -1; - } - - memset(intf->session, 0, sizeof(struct ipmi_session)); - /* setup default LAN maximum request and response sizes */ intf->max_request_data_size = IPMI_SERIAL_MAX_RQ_SIZE; intf->max_response_data_size = IPMI_SERIAL_MAX_RS_SIZE;