From 90e2c175430efa91369e823a6a6406b25221529f Mon Sep 17 00:00:00 2001 From: Jeremy Ellington Date: Wed, 9 Mar 2005 17:16:14 +0000 Subject: [PATCH] From Holger Liebig. Many changes, primarily to support Intel's v2 capable BMC. Also includes many general fixes. Thank you Holger. --- ipmitool/src/plugins/lanplus/lanplus.c | 60 ++++++++++++++----- ipmitool/src/plugins/lanplus/lanplus_crypt.h | 11 +++- .../src/plugins/lanplus/lanplus_crypt_impl.c | 2 +- ipmitool/src/plugins/lanplus/lanplus_dump.c | 24 ++++---- .../src/plugins/lanplus/lanplus_strings.c | 2 +- 5 files changed, 65 insertions(+), 34 deletions(-) diff --git a/ipmitool/src/plugins/lanplus/lanplus.c b/ipmitool/src/plugins/lanplus/lanplus.c index 3b281ec..c4c64f4 100644 --- a/ipmitool/src/plugins/lanplus/lanplus.c +++ b/ipmitool/src/plugins/lanplus/lanplus.c @@ -50,13 +50,16 @@ #include #include -#include +#ifdef HAVE_CONFIG_H +# include +#endif #include #include #include #include #include #include +#include #include #include @@ -303,6 +306,20 @@ static const struct valstr ipmi_channel_medium_vals[] = { { 0x00, NULL }, }; +static const struct valstr plus_payload_types_vals[] = { + { IPMI_PAYLOAD_TYPE_IPMI, "IPMI (0)" }, // IPMI Message + { IPMI_PAYLOAD_TYPE_SOL, "SOL (1)" }, // SOL (Serial over LAN) + { IPMI_PAYLOAD_TYPE_OEM, "OEM (2)" }, // OEM Explicid + + { IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST, "OpenSession Req (0x10)" }, + { IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE,"OpenSession Resp (0x11)" }, + { IPMI_PAYLOAD_TYPE_RAKP_1, "RAKP1 (0x12)" }, + { IPMI_PAYLOAD_TYPE_RAKP_2, "RAKP2 (0x13)" }, + { IPMI_PAYLOAD_TYPE_RAKP_3, "RAKP3 (0x14)" }, + { IPMI_PAYLOAD_TYPE_RAKP_4, "RAKP4 (0x15)" }, + { 0x00, NULL }, +}; + static struct ipmi_rq_entry * ipmi_req_lookup_entry(uint8_t seq, uint8_t cmd) { @@ -481,7 +498,7 @@ ipmi_handle_pong(struct ipmi_intf * intf, struct ipmi_rs * rsp) printf(" ASF Version %s\n" " RMCP Version %s\n" " RMCP Sequence %d\n" - " IANA Enterprise %d\n\n", + " IANA Enterprise %ld\n\n", (pong->sup_entities & 0x01) ? "1.0" : "unknown", (pong->rmcp.ver == 6) ? "1.0" : "unknown", pong->rmcp.seq, @@ -514,7 +531,7 @@ int ipmiv2_lan_ping(struct ipmi_intf * intf) { struct asf_hdr asf_ping = { - .iana = ASF_RMCP_IANA, + .iana = htonl(ASF_RMCP_IANA), .type = ASF_TYPE_PING, }; struct rmcp_hdr rmcp_ping = { @@ -657,9 +674,9 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf) lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header"); lprintf(LOG_DEBUG+1, "<< Authtype : %s", - val2str(rsp->session.authtype, ipmi_authtype_vals)); - lprintf(LOG_DEBUG+1, "<< Payload type : 0x%x", - rsp->session.payloadtype); + val2str(rsp->session.authtype, ipmi_authtype_session_vals)); + lprintf(LOG_DEBUG+1, "<< Payload type : %s", + val2str(rsp->session.payloadtype, plus_payload_types_vals)); lprintf(LOG_DEBUG+1, "<< Session ID : 0x%08lx", (long)rsp->session.id); lprintf(LOG_DEBUG+1, "<< Sequence : 0x%08lx", @@ -829,6 +846,9 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf) void read_open_session_response(struct ipmi_rs * rsp, int offset) { + memset(&rsp->payload.open_session_response, 0, + sizeof(rsp->payload.open_session_response)); + /* Message tag */ rsp->payload.open_session_response.message_tag = rsp->data[offset]; @@ -838,6 +858,8 @@ read_open_session_response(struct ipmi_rs * rsp, int offset) /* Maximum privilege level */ rsp->payload.open_session_response.max_priv_level = rsp->data[offset + 2]; + /*** offset + 3 is reserved ***/ + /* Remote console session ID */ memcpy(&(rsp->payload.open_session_response.console_id), rsp->data + offset + 4, @@ -847,6 +869,11 @@ read_open_session_response(struct ipmi_rs * rsp, int offset) BSWAP_32(rsp->payload.open_session_response.console_id); #endif + /* only tag, status, privlvl, and console id are returned if error */ + if (rsp->payload.open_session_response.rakp_return_code != + IPMI_RAKP_STATUS_NO_ERRORS) + return; + /* BMC session ID */ memcpy(&(rsp->payload.open_session_response.bmc_id), rsp->data + offset + 8, @@ -1450,9 +1477,8 @@ ipmi_lanplus_build_v2x_msg( ((session->v2_data.integrity_alg != IPMI_INTEGRITY_NONE)? 0x40 : 0x00); } - if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE) - { + { /* Session ID -- making it LSB */ msg[IMPI_LANPLUS_OFFSET_SESSION_ID ] = session->v2_data.bmc_id & 0xff; msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8) & 0xff; @@ -1465,7 +1491,6 @@ ipmi_lanplus_build_v2x_msg( msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff; msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff; } - /* * Payload Length is set below (we don't know how big the payload is until after @@ -1831,7 +1856,7 @@ ipmi_lanplus_build_v15_ipmi_cmd( lprintf(LOG_DEBUG+1, ">> IPMI Request Session Header"); lprintf(LOG_DEBUG+1, ">> Authtype : %s", - val2str(IPMI_SESSION_AUTHTYPE_NONE, ipmi_authtype_vals)); + val2str(IPMI_SESSION_AUTHTYPE_NONE, ipmi_authtype_session_vals)); lprintf(LOG_DEBUG+1, ">> Sequence : 0x%08lx", (long)session->out_seq); lprintf(LOG_DEBUG+1, ">> Session ID : 0x%08lx", @@ -2386,7 +2411,6 @@ ipmi_lanplus_send_ipmi_cmd( } - /* * ipmi_get_auth_capabilities_cmd * @@ -2801,12 +2825,15 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf) memcpy(session->v2_data.bmc_rand, rsp->payload.rakp2_message.bmc_rand, 16); memcpy(session->v2_data.bmc_guid, rsp->payload.rakp2_message.bmc_guid, 16); + printbuf(session->v2_data.bmc_rand, 16, "bmc_rand"); + /* * It is at this point that we have to decode the random number and determine * whether the BMC has authenticated. */ if (! lanplus_rakp2_hmac_matches(session, - rsp->payload.rakp2_message.key_exchange_auth_code)) + rsp->payload.rakp2_message.key_exchange_auth_code, + intf)) { /* Error */ lprintf(LOG_INFO, "> RAKP 2 HMAC is invalid"); @@ -2875,7 +2902,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf) v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_3; v2_payload.payload_length = 8; - v2_payload.payload.rakp_1_message.message = msg; + v2_payload.payload.rakp_3_message.message = msg; /* * If the rakp2 return code indicates and error, we don't have to @@ -2887,7 +2914,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf) { uint32_t auth_length; - if (lanplus_generate_rakp3_authcode(msg + 8, session, &auth_length)) + if (lanplus_generate_rakp3_authcode(msg + 8, session, &auth_length, intf)) { /* Error */ lprintf(LOG_INFO, "> Error generating RAKP 3 authcode"); @@ -2958,7 +2985,8 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf) { /* Validate the authcode */ if (lanplus_rakp4_hmac_matches(session, - rsp->payload.rakp4_message.integrity_check_value)) + rsp->payload.rakp4_message.integrity_check_value, + intf)) { /* Success */ session->v2_data.session_state = LANPLUS_STATE_ACTIVE; @@ -3097,6 +3125,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf) intf->opened = 1; + /* * * Make sure the BMC supports IPMI v2 / RMCP+ @@ -3136,6 +3165,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf) goto fail; } + /* * RAKP 3 */ diff --git a/ipmitool/src/plugins/lanplus/lanplus_crypt.h b/ipmitool/src/plugins/lanplus/lanplus_crypt.h index 49d3e73..8f8ff7b 100644 --- a/ipmitool/src/plugins/lanplus/lanplus_crypt.h +++ b/ipmitool/src/plugins/lanplus/lanplus_crypt.h @@ -41,15 +41,20 @@ /* * See the implementation file for documentation + * ipmi_intf can be used for oem specific implementations + * e.g. if (ipmi_oem_active(intf, "OEM_XYZ")) */ int lanplus_rakp2_hmac_matches(const struct ipmi_session * session, - const uint8_t * hmac); + const uint8_t * hmac, + struct ipmi_intf * intf); int lanplus_rakp4_hmac_matches(const struct ipmi_session * session, - const uint8_t * hmac); + const uint8_t * hmac, + struct ipmi_intf * intf); int lanplus_generate_rakp3_authcode(char * buffer, const struct ipmi_session * session, - uint32_t * auth_length); + uint32_t * auth_length, + struct ipmi_intf * intf); int lanplus_generate_sik(struct ipmi_session * session); int lanplus_generate_k1(struct ipmi_session * session); int lanplus_generate_k2(struct ipmi_session * session); diff --git a/ipmitool/src/plugins/lanplus/lanplus_crypt_impl.c b/ipmitool/src/plugins/lanplus/lanplus_crypt_impl.c index ad5df2f..cf5c02d 100644 --- a/ipmitool/src/plugins/lanplus/lanplus_crypt_impl.c +++ b/ipmitool/src/plugins/lanplus/lanplus_crypt_impl.c @@ -80,7 +80,7 @@ int lanplus_seed_prng(uint32_t bytes) int lanplus_rand(uint8_t * buffer, uint32_t num_bytes) { -#define IPMI_LANPLUS_FAKE_RAND 1 +#undef IPMI_LANPLUS_FAKE_RAND #ifdef IPMI_LANPLUS_FAKE_RAND /* diff --git a/ipmitool/src/plugins/lanplus/lanplus_dump.c b/ipmitool/src/plugins/lanplus/lanplus_dump.c index 34f7979..9a7f75a 100644 --- a/ipmitool/src/plugins/lanplus/lanplus_dump.c +++ b/ipmitool/src/plugins/lanplus/lanplus_dump.c @@ -43,7 +43,7 @@ extern const struct valstr ipmi_auth_algorithms[]; extern const struct valstr ipmi_integrity_algorithms[]; extern const struct valstr ipmi_encryption_algorithms[]; -#define DUMP_PREFIX_INCOMING "<< " +#define DUMP_PREFIX_INCOMING "<<" void lanplus_dump_open_session_response(const struct ipmi_rs * rsp) { @@ -66,6 +66,12 @@ void lanplus_dump_open_session_response(const struct ipmi_rs * rsp) printf("%s Console Session ID : 0x%08lx\n", DUMP_PREFIX_INCOMING, (long)rsp->payload.open_session_response.console_id); + + /* only tag, status, privlvl, and console id are returned if error */ + if (rsp->payload.open_session_response.rakp_return_code != + IPMI_RAKP_STATUS_NO_ERRORS) + return; + printf("%s BMC Session ID : 0x%08lx\n", DUMP_PREFIX_INCOMING, (long)rsp->payload.open_session_response.bmc_id); @@ -154,26 +160,16 @@ void lanplus_dump_rakp4_message(const struct ipmi_rs * rsp, uint8_t auth_alg) printf("%s Message tag : 0x%02x\n", DUMP_PREFIX_INCOMING, - rsp->payload.rakp2_message.message_tag); + rsp->payload.rakp4_message.message_tag); printf("%s RMCP+ status : %s\n", DUMP_PREFIX_INCOMING, - val2str(rsp->payload.rakp2_message.rakp_return_code, + val2str(rsp->payload.rakp4_message.rakp_return_code, ipmi_rakp_return_codes)); printf("%s Console Session ID : 0x%08lx\n", DUMP_PREFIX_INCOMING, - (long)rsp->payload.rakp2_message.console_id); - - printf("%s BMC random number : 0x", DUMP_PREFIX_INCOMING); - for (i = 0; i < 16; ++i) - printf("%02x", rsp->payload.rakp2_message.bmc_rand[i]); - printf("\n"); - - printf("%s BMC GUID : 0x", DUMP_PREFIX_INCOMING); - for (i = 0; i < 16; ++i) - printf("%02x", rsp->payload.rakp2_message.bmc_guid[i]); - printf("\n"); + (long)rsp->payload.rakp4_message.console_id); switch(auth_alg) { diff --git a/ipmitool/src/plugins/lanplus/lanplus_strings.c b/ipmitool/src/plugins/lanplus/lanplus_strings.c index 6c3e028..074f898 100644 --- a/ipmitool/src/plugins/lanplus/lanplus_strings.c +++ b/ipmitool/src/plugins/lanplus/lanplus_strings.c @@ -18,7 +18,7 @@ const struct valstr ipmi_rakp_return_codes[] = { { IPMI_RAKP_STATUS_INVALID_NAME_LENGTH, "invalid name length" }, { IPMI_RAKP_STATUS_UNAUTHORIZED_NAME, "unauthorized name" }, { IPMI_RAKP_STATUS_UNAUTHORIZED_GUID, "unauthorized GUID" }, - { IPMI_RAKP_STATUS_INVALID_INTEGRITY_CHECK_VALUE, "invlalid integrity check value" }, + { IPMI_RAKP_STATUS_INVALID_INTEGRITY_CHECK_VALUE, "invalid integrity check value" }, { IPMI_RAKP_STATUS_INVALID_CONFIDENTIALITY_ALGORITHM, "invalid confidentiality algorithm" }, { IPMI_RAKP_STATUS_NO_CIPHER_SUITE_MATCH, "no matching cipher suite" }, { IPMI_RAKP_STATUS_ILLEGAL_PARAMTER, "illegal parameter" },