- 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
This commit is contained in:
Duncan Laurie 2004-08-27 19:11:43 +00:00
parent cbc8cbdff4
commit 72417c67db
6 changed files with 103 additions and 66 deletions

View File

@ -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"

View File

@ -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 */

View File

@ -65,9 +65,13 @@
# include <config.h>
#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;

View File

@ -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;
}

View File

@ -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

View File

@ -53,14 +53,15 @@
#include <ipmitool/bswap.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
#if HAVE_CONFIG_H
# include <config.h>
#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<<IPMI_SESSION_AUTHTYPE_MD5) {
(!s->authtype_set ||
s->authtype_set == IPMI_SESSION_AUTHTYPE_MD5) &&
(rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD5))
{
s->authtype = IPMI_SESSION_AUTHTYPE_MD5;
}
else if (s->password &&
rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD) {
(!s->authtype_set ||
s->authtype_set == IPMI_SESSION_AUTHTYPE_MD2) &&
(rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD2))
{
s->authtype = IPMI_SESSION_AUTHTYPE_MD2;
}
else if (s->password &&
(!s->authtype_set ||
s->authtype_set == IPMI_SESSION_AUTHTYPE_PASSWORD) &&
(rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD))
{
s->authtype = IPMI_SESSION_AUTHTYPE_PASSWORD;
}
else if (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_NONE) {
else if ((!s->authtype_set ||
s->authtype_set == IPMI_SESSION_AUTHTYPE_NONE) &&
(rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_NONE))
{
s->authtype = IPMI_SESSION_AUTHTYPE_NONE;
}
else {
printf("No supported authtypes found!\n");
if (!(rsp->data[1] & 1<<s->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;
}