From 72417c67db19f4f27e94b6d9dd3cf044a85e6263 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Fri, 27 Aug 2004 19:11:43 +0000 Subject: [PATCH] - support for using OpenIPMI MD5 and MD2 implementations if found, otherwise fall back to internal version - add "-A authtype" parameter for forcing a certain authtype level --- ipmitool/configure.in | 32 ++++++--- ipmitool/include/ipmitool/ipmi_intf.h | 2 + ipmitool/src/ipmitool.c | 29 ++++++-- ipmitool/src/plugins/ipmi_intf.c | 6 ++ ipmitool/src/plugins/lan/Makefile.am | 2 +- ipmitool/src/plugins/lan/lan.c | 98 +++++++++++++-------------- 6 files changed, 103 insertions(+), 66 deletions(-) diff --git a/ipmitool/configure.in b/ipmitool/configure.in index c2c3ff3..d437472 100644 --- a/ipmitool/configure.in +++ b/ipmitool/configure.in @@ -3,7 +3,7 @@ dnl autoconf for ipmitool dnl AC_INIT([src/ipmitool.c]) AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE([ipmitool], [1.6.0pre2]) +AM_INIT_AUTOMAKE([ipmitool], [1.6.0pre3]) AM_CONFIG_HEADER(config.h) AC_CONFIG_SRCDIR([src/ipmitool.c]) AC_PREREQ(2.50) @@ -50,6 +50,7 @@ if test "x$exec_prefix" = "xNONE"; then exec_prefix="$prefix" fi +dnl set some things so we build with GNU tools on Solaris case "$host_os" in solaris*) MAKE=gmake @@ -64,23 +65,34 @@ AC_SUBST(OS, $host_os) AC_SUBST(PSTAMP, $host) AC_SUBST(BASEDIR, $prefix) +dnl check for OpenSSL functionality +AC_CHECK_LIB([crypto], [EVP_aes_128_cbc], + [have_crypto=yes; LIBS="$LIBS -lcrypto"], + [have_crypto=no], [-lcrypto]) + +AC_CHECK_LIB([crypto], [MD5_Init], + [LIBS="$LIBS -lcrypto" + AC_DEFINE(HAVE_CRYPTO_MD5, [1], [Define to 1 if libcrypto supports MD5.])], + [], [-lcrypto]) + +AC_CHECK_LIB([crypto], [MD2_Init], + [LIBS="$LIBS -lcrypto" + AC_DEFINE(HAVE_CRYPTO_MD2, [1], [Define to 1 if libcrypto supports MD2.])], + [], [-lcrypto]) + dnl enable IPMIv1.5 LAN interface AC_ARG_ENABLE([intf-lan], [AC_HELP_STRING([--enable-intf-lan], [enable IPMIv1.5 LAN interface [default=yes]])], [], [enable_intf_lan=yes]) if test "x$enable_intf_lan" = "xyes"; then - AC_DEFINE(IPMI_INTF_LAN, [1], [Enable LAN interface]) + AC_DEFINE(IPMI_INTF_LAN, [1], [Define to 1 to enable LAN IPMIv1.5 interface.]) AC_SUBST(INTF_LAN, [lan]) AC_SUBST(INTF_LAN_LIB, [libintf_lan.la]) IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB lan/libintf_lan.la" fi dnl enable IPMIv2.0 RMCP+ LAN interface -AC_CHECK_LIB([crypto], [EVP_aes_128_cbc], - [have_crypto=yes; LIBS="$LIBS -lcrypto"], - [have_crypto=no], - [-lcrypto]) AC_ARG_ENABLE([intf-lanplus], [AC_HELP_STRING([--enable-intf-lanplus], [enable IPMIv2.0 RMCP+ LAN interface [default=auto]])], @@ -90,7 +102,7 @@ AC_ARG_ENABLE([intf-lanplus], fi], [enable_intf_lanplus=$have_crypto]) if test "x$enable_intf_lanplus" = "xyes"; then - AC_DEFINE(IPMI_INTF_LANPLUS, [1], [Enable LAN+ interface]) + AC_DEFINE(IPMI_INTF_LANPLUS, [1], [Define to 1 to enable LAN+ IPMIv2 interface.]) AC_SUBST(INTF_LANPLUS, [lanplus]) AC_SUBST(INTF_LANPLUS_LIB, [libintf_lanplus.la]) IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB lanplus/libintf_lanplus.la" @@ -124,7 +136,7 @@ AC_ARG_ENABLE([intf-open], [enable Linux OpenIPMI interface [default=yes]])], [], [enable_intf_open=yes]) if test "x$enable_intf_open" = "xyes"; then - AC_DEFINE(IPMI_INTF_OPEN, [1], [Enable Linux OpenIPMI interface]) + AC_DEFINE(IPMI_INTF_OPEN, [1], [Define to 1 to enable Linux OpenIPMI interface.]) AC_SUBST(INTF_OPEN, [open]) AC_SUBST(INTF_OPEN_LIB, [libintf_open.la]) IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB open/libintf_open.la" @@ -136,7 +148,7 @@ AC_ARG_ENABLE([intf-imb], [enable Intel IMB driver interface [default=yes]])], [], [enable_intf_imb=yes]) if test "x$enable_intf_imb" = "xyes"; then - AC_DEFINE(IPMI_INTF_IMB, [1], [Enable IMB interface]) + AC_DEFINE(IPMI_INTF_IMB, [1], [Define to 1 to enable Intel IMB interface.]) AC_SUBST(INTF_IMB, [imb]) AC_SUBST(INTF_IMB_LIB, [libintf_imb.la]) IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB imb/libintf_imb.la" @@ -153,7 +165,7 @@ AC_ARG_ENABLE([intf-lipmi], fi], [enable_intf_lipmi=$have_lipmi]) if test "x$enable_intf_lipmi" = "xyes"; then - AC_DEFINE(IPMI_INTF_LIPMI, [1], [Enable Solaris LIPMI interface]) + AC_DEFINE(IPMI_INTF_LIPMI, [1], [Define to 1 to enable Solaris LIPMI interface.]) AC_SUBST(INTF_LIPMI, [lipmi]) AC_SUBST(INTF_LIPMI_LIB, [libintf_lipmi.la]) IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB lipmi/libintf_lipmi.la" diff --git a/ipmitool/include/ipmitool/ipmi_intf.h b/ipmitool/include/ipmitool/ipmi_intf.h index 2601894..ecad034 100644 --- a/ipmitool/include/ipmitool/ipmi_intf.h +++ b/ipmitool/include/ipmitool/ipmi_intf.h @@ -71,6 +71,7 @@ struct ipmi_session { unsigned char authcode[IPMI_AUTHCODE_BUFFER_SIZE]; unsigned char challenge[16]; unsigned char authtype; + unsigned char authtype_set; unsigned char privlvl; int password; int port; @@ -165,5 +166,6 @@ void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username); void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password); void ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, unsigned char privlvl); void ipmi_intf_session_set_port(struct ipmi_intf * intf, int port); +void ipmi_intf_session_set_authtype(struct ipmi_intf * intf, unsigned char authtype); #endif /* IPMI_INTF_H */ diff --git a/ipmitool/src/ipmitool.c b/ipmitool/src/ipmitool.c index 1711952..f507bb7 100644 --- a/ipmitool/src/ipmitool.c +++ b/ipmitool/src/ipmitool.c @@ -65,9 +65,13 @@ # include #endif +#define IPMITOOL_OPTIONS "I:hVvcgEaH:P:f:U:p:L:A:t:m:" + int csv_output = 0; int verbose = 0; +extern const struct valstr ipmi_authtype_session_vals[]; + void usage(void) { printf("ipmitool version %s\n", VERSION); @@ -82,6 +86,7 @@ void usage(void) printf(" -H hostname Remote host name for LAN interface\n"); printf(" -p port Remote RMCP port [default=623]\n"); printf(" -L level Remote session privilege level [default=USER]\n"); + printf(" -A authtype Force use of authentication type NONE, PASSWORD, MD2 or MD5\n"); printf(" -U username Remote session username\n"); printf(" -P password Remote session password\n"); printf(" -f file Read remote session password from file\n"); @@ -218,11 +223,22 @@ int main(int argc, char ** argv) { int (*submain)(struct ipmi_intf *, int, char **); struct ipmi_intf * intf = NULL; - char * tmp, * hostname = NULL, * username = NULL, * password = NULL, * intfname = NULL; - int port = 0, argflag, i, intfarg = 0, rc = 0, thump = 0; - unsigned char privlvl = 0, target_addr = 0, my_addr = 0; + unsigned char privlvl = 0; + unsigned char target_addr = 0; + unsigned char my_addr = 0; + unsigned char authtype = 0; + char * tmp = NULL; + char * hostname = NULL; + char * username = NULL; + char * password = NULL; + char * intfname = NULL; + int port = 0; + int argflag, i; + int intfarg = 0; + int rc = 0; + int thump = 0; - while ((argflag = getopt(argc, (char **)argv, "I:hVvcgEaH:P:f:U:p:L:t:m:")) != -1) + while ((argflag = getopt(argc, (char **)argv, IPMITOOL_OPTIONS)) != -1) { switch (argflag) { case 'I': @@ -299,6 +315,9 @@ int main(int argc, char ** argv) if (!privlvl) printf("Invalid privilege level %s!\n", optarg); break; + case 'A': + authtype = (int)str2val(optarg, ipmi_authtype_session_vals); + break; case 'p': port = atoi(optarg); break; @@ -341,6 +360,8 @@ int main(int argc, char ** argv) ipmi_intf_session_set_port(intf, port); if (privlvl) ipmi_intf_session_set_privlvl(intf, privlvl); + if (authtype) + ipmi_intf_session_set_authtype(intf, authtype); intf->thump = thump; intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR; diff --git a/ipmitool/src/plugins/ipmi_intf.c b/ipmitool/src/plugins/ipmi_intf.c index e43fc49..60183fb 100644 --- a/ipmitool/src/plugins/ipmi_intf.c +++ b/ipmitool/src/plugins/ipmi_intf.c @@ -162,3 +162,9 @@ void ipmi_intf_session_set_port(struct ipmi_intf * intf, int port) if (intf && intf->session) intf->session->port = port; } + +void ipmi_intf_session_set_authtype(struct ipmi_intf * intf, unsigned char authtype) +{ + if (intf && intf->session) + intf->session->authtype_set = authtype; +} diff --git a/ipmitool/src/plugins/lan/Makefile.am b/ipmitool/src/plugins/lan/Makefile.am index bb4ab54..601d6ec 100644 --- a/ipmitool/src/plugins/lan/Makefile.am +++ b/ipmitool/src/plugins/lan/Makefile.am @@ -39,5 +39,5 @@ INCLUDES = -I$(top_srcdir)/include EXTRA_LTLIBRARIES = libintf_lan.la noinst_LTLIBRARIES = @INTF_LAN_LIB@ libintf_lan_la_LIBADD = $(top_builddir)/lib/libipmitool.la -libintf_lan_la_SOURCES = lan.c lan.h asf.h rmcp.h md5.c md5.h +libintf_lan_la_SOURCES = lan.c lan.h asf.h rmcp.h auth.c auth.h md5.c md5.h diff --git a/ipmitool/src/plugins/lan/lan.c b/ipmitool/src/plugins/lan/lan.c index b62a694..1b1f002 100644 --- a/ipmitool/src/plugins/lan/lan.c +++ b/ipmitool/src/plugins/lan/lan.c @@ -53,14 +53,15 @@ #include #include #include + #if HAVE_CONFIG_H # include #endif #include "lan.h" -#include "md5.h" #include "rmcp.h" #include "asf.h" +#include "auth.h" extern const struct valstr ipmi_privlvl_vals[]; extern const struct valstr ipmi_authtype_vals[]; @@ -415,52 +416,18 @@ ipmi_lan_ping(struct ipmi_intf * intf) */ static void ipmi_lan_thump_first(struct ipmi_intf * intf) { + /* is this random data? */ unsigned char data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x20, 0x18, 0xc8, 0xc2, 0x01, 0x01, 0x3c }; ipmi_lan_send_packet(intf, data, 16); } + static void ipmi_lan_thump(struct ipmi_intf * intf) { unsigned char data[10] = "thump"; ipmi_lan_send_packet(intf, data, 10); } -/* - * multi-session authcode generation for md5 - * H(password + session_id + msg + session_seq + password) - */ -static unsigned char * -ipmi_auth_md5(struct ipmi_session * s, unsigned char * data, int data_len) -{ - md5_state_t state; - static md5_byte_t digest[16]; - uint32_t temp; - - memset(digest, 0, 16); - memset(&state, 0, sizeof(md5_state_t)); - - md5_init(&state); - - md5_append(&state, (const md5_byte_t *)s->authcode, 16); - md5_append(&state, (const md5_byte_t *)&s->session_id, 4); - md5_append(&state, (const md5_byte_t *)data, data_len); - -#if WORDS_BIGENDIAN - temp = BSWAP_32(s->in_seq); -#else - temp = s->in_seq; -#endif - md5_append(&state, (const md5_byte_t *)&temp, 4); - md5_append(&state, (const md5_byte_t *)s->authcode, 16); - - md5_finish(&state, digest); - - if (verbose > 3) - printf(" MD5 AuthCode : %s\n", buf2str(digest, 16)); - return digest; -} - - static struct ipmi_rs * ipmi_lan_poll_recv(struct ipmi_intf * intf) { @@ -475,13 +442,15 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf) /* parse response headers */ memcpy(&rmcp_rsp, rsp->data, 4); - if (rmcp_rsp.class == RMCP_CLASS_ASF) { - /* might be ping response packet */ + switch (rmcp_rsp.class) { + case RMCP_CLASS_ASF: + /* ping response packet */ rv = ipmi_handle_pong(intf, rsp); return (rv <= 0) ? NULL : rsp; - } - - if (rmcp_rsp.class != RMCP_CLASS_IPMI) { + case RMCP_CLASS_IPMI: + /* handled by rest of function */ + break; + default: if (verbose > 1) printf("Invalid RMCP class: %x\n", rmcp_rsp.class); rsp = ipmi_lan_recv_packet(intf); @@ -599,7 +568,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) .class = RMCP_CLASS_IPMI, .seq = 0xff, }; - unsigned char * msg; + unsigned char * msg, * temp; int cs, cs2, mp, tmp; int ap = 0; int len = 0; @@ -708,10 +677,17 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) msg[len++] = ipmi_csum(msg+cs2, tmp); } - if (s->active && - s->authtype == IPMI_SESSION_AUTHTYPE_MD5) { - unsigned char * d = ipmi_auth_md5(intf->session, msg+mp, msg[mp-1]); - memcpy(msg+ap, d, 16); + if (s->active) { + switch (s->authtype) { + case IPMI_SESSION_AUTHTYPE_MD5: + temp = ipmi_auth_md5(intf->session, msg+mp, msg[mp-1]); + memcpy(msg+ap, temp, 16); + break; + case IPMI_SESSION_AUTHTYPE_MD2: + temp = ipmi_auth_md2(intf->session, msg+mp, msg[mp-1]); + memcpy(msg+ap, temp, 16); + break; + } } if (s->in_seq) { @@ -941,18 +917,38 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf) } if (s->password && - rsp->data[1] & 1<authtype_set || + s->authtype_set == IPMI_SESSION_AUTHTYPE_MD5) && + (rsp->data[1] & 1<authtype = IPMI_SESSION_AUTHTYPE_MD5; } else if (s->password && - rsp->data[1] & 1<authtype_set || + s->authtype_set == IPMI_SESSION_AUTHTYPE_MD2) && + (rsp->data[1] & 1<authtype = IPMI_SESSION_AUTHTYPE_MD2; + } + else if (s->password && + (!s->authtype_set || + s->authtype_set == IPMI_SESSION_AUTHTYPE_PASSWORD) && + (rsp->data[1] & 1<authtype = IPMI_SESSION_AUTHTYPE_PASSWORD; } - else if (rsp->data[1] & 1<authtype_set || + s->authtype_set == IPMI_SESSION_AUTHTYPE_NONE) && + (rsp->data[1] & 1<authtype = IPMI_SESSION_AUTHTYPE_NONE; } else { - printf("No supported authtypes found!\n"); + if (!(rsp->data[1] & 1<authtype_set)) + printf("Authentication type %s not supported!\n", + val2str(s->authtype_set, ipmi_authtype_session_vals)); + else + printf("No supported authtypes found!\n"); return -1; }