diff --git a/.gitignore b/.gitignore index 5b8cb0a..58ca89e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,30 @@ +.deps +.libs +*.o +*.lo +*.la +*.*~ +Makefile Makefile.in aclocal.m4 autom4te.cache compile config.guess +config.h config.h.in +config.log +config.status config.sub configure depcomp install-sh ltmain.sh +libtool missing +stamp-h1 +control/ipmitool.spec +control/pkginfo +control/prototype +control/rpmmacros +src/ipmievd +src/ipmitool diff --git a/bootstrap b/bootstrap index 6347427..c38b12b 100755 --- a/bootstrap +++ b/bootstrap @@ -31,7 +31,15 @@ # EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. aclocal -libtoolize --automake --copy + +case `uname` in + Darwin*) + glibtoolize --automake --copy + ;; + *) + libtoolize --automake --copy + ;; +esac autoheader automake --foreign --add-missing --copy diff --git a/configure.ac b/configure.ac index 88232a6..ad1657d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,11 @@ dnl dnl autoconf for ipmitool dnl -AC_INIT([ipmitool], [1.8.18-csv]) +m4_define([git_suffix], m4_esyscmd_s(./csv-revision)) +AC_INIT([ipmitool], [1.8.18git_suffix]) AC_CONFIG_SRCDIR([src/ipmitool.c]) AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE +AM_INIT_AUTOMAKE([foreign]) AM_CONFIG_HEADER(config.h) AC_PREREQ(2.50) AC_SUBST(ac_configure_args) diff --git a/csv-revision b/csv-revision new file mode 100755 index 0000000..289c133 --- /dev/null +++ b/csv-revision @@ -0,0 +1,10 @@ +#!/bin/sh + +git describe --first-parent --tags 2>/dev/null | ( + IFS=- read tag rev hash + if [ $? ] && [ -n "$rev" ]; then + echo .$rev.$hash + elif [ -d .git ]; then + echo .0.gsnapshot + fi +) diff --git a/include/ipmitool/ipmi_fru.h b/include/ipmitool/ipmi_fru.h index 65696ba..d03abfc 100644 --- a/include/ipmitool/ipmi_fru.h +++ b/include/ipmitool/ipmi_fru.h @@ -614,5 +614,6 @@ typedef struct ipmi_fru_bloc { int ipmi_fru_main(struct ipmi_intf *intf, int argc, char **argv); int ipmi_fru_print(struct ipmi_intf *intf, struct sdr_record_fru_locator *fru); +char *get_fru_area_str(uint8_t *data, uint32_t *offset); #endif /* IPMI_FRU_H */ diff --git a/include/ipmitool/ipmi_picmg.h b/include/ipmitool/ipmi_picmg.h index 3d70454..0bcbd93 100644 --- a/include/ipmitool/ipmi_picmg.h +++ b/include/ipmitool/ipmi_picmg.h @@ -12,6 +12,7 @@ #define PICMG_CPCI_MAJOR_VERSION 1 #define PICMG_ATCA_MAJOR_VERSION 2 #define PICMG_AMC_MAJOR_VERSION 4 +#define PICMG_UTCA_MAJOR_VERSION 5 /* PICMG commands */ #define PICMG_GET_PICMG_PROPERTIES_CMD 0x00 diff --git a/include/ipmitool/ipmi_sel.h b/include/ipmitool/ipmi_sel.h index 1c325db..a6a2a42 100644 --- a/include/ipmitool/ipmi_sel.h +++ b/include/ipmitool/ipmi_sel.h @@ -579,8 +579,8 @@ static const struct ipmi_event_sensor_types sensor_specific_event_types[] = { { 0xF1, 0x00, 0xff, "IPMB-A disabled, IPMB-B disabled" }, { 0xF1, 0x01, 0xff, "IPMB-A enabled, IPMB-B disabled" }, { 0xF1, 0x02, 0xff, "IPMB-A disabled, IPMB-B enabled" }, - { 0xF1, 0x03, 0xff, "IPMB-A enabled, IPMP-B enabled" }, - /* PICNG Moduke Hot Swap */ + { 0xF1, 0x03, 0xff, "IPMB-A enabled, IPMB-B enabled" }, + /* PICMG Module Hot Swap */ { 0xF2, 0x00, 0xff, "Module Handle Closed" }, { 0xF2, 0x01, 0xff, "Module Handle Opened" }, { 0xF2, 0x02, 0xff, "Quiesced" }, @@ -599,7 +599,7 @@ static const struct ipmi_event_sensor_types vita_sensor_event_types[] = { { 0xF1, 0x00, 0xFF, "IPMB-A disabled, IPMB-B disabled" }, { 0xF1, 0x01, 0xFF, "IPMB-A enabled, IPMB-B disabled" }, { 0xF1, 0x02, 0xFF, "IPMB-A disabled, IPMB-B enabled" }, - { 0xF1, 0x03, 0xFF, "IPMB-A enabled, IPMP-B enabled" }, + { 0xF1, 0x03, 0xFF, "IPMB-A enabled, IPMB-B enabled" }, /* VITA FRU Temperature */ { 0xF3, 0x00, 0xff, "At or below Lower Non-critical" }, { 0xF3, 0x01, 0xff, "At or below Lower Critical" }, diff --git a/lib/ipmi_cfgp.c b/lib/ipmi_cfgp.c index b8af80d..dfc4743 100644 --- a/lib/ipmi_cfgp.c +++ b/lib/ipmi_cfgp.c @@ -30,7 +30,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include +#ifdef HAVE_MALLOC_H +# include +#else +# include +#endif #include #include diff --git a/lib/ipmi_ekanalyzer.c b/lib/ipmi_ekanalyzer.c index 7a6c63d..f6d8b90 100644 --- a/lib/ipmi_ekanalyzer.c +++ b/lib/ipmi_ekanalyzer.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -2696,12 +2697,19 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, int ret = 0; unsigned char len = 0; unsigned int size_board = 0; + int custom_fields = 0; if (input_file == NULL || board_type == NULL || board_length == NULL) { return (size_t)(-1); } file_offset = ftell(input_file); + /* + * TODO: This whole file's code is extremely dirty and wicked. + * Must eventually switch to using ipmi_fru.c code or some + * specialized FRU library. + */ + /* Board length*/ ret = fread(&len, 1, 1, input_file); if ((ret != 1) || ferror(input_file)) { @@ -2717,14 +2725,15 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, goto out; } if (strncmp(board_type, "Custom", 6 ) != 0) { - unsigned char *data; + unsigned char *data, *str; unsigned int i = 0; - data = malloc(size_board); + data = malloc(size_board + 1); /* Make room for type/length field */ if (data == NULL) { lprintf(LOG_ERR, "ipmitool: malloc failure"); return (size_t)(-1); } - ret = fread(data, size_board, 1, input_file); + data[0] = len; /* Save the type/length byte in 'data' */ + ret = fread(data + 1, size_board, 1, input_file); if ((ret != 1) || ferror(input_file)) { lprintf(LOG_ERR, "Invalid board type size!"); free(data); @@ -2733,17 +2742,11 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, } printf("%s type: 0x%02x\n", board_type, len); printf("%s: ", board_type); - for (i = 0; i < size_board; i++) { - if ((len & TYPE_CODE) == TYPE_CODE) { - printf("%c", data[i]); - } else { - /* other than language code (binary, BCD, - * ASCII 6 bit...) is not supported - */ - printf("%02x", data[i]); - } - } - printf("\n"); + i = 0; + str = (unsigned char *)get_fru_area_str(data, &i); + printf("%s\n", str); + free(str); + str = NULL; free(data); data = NULL; (*board_length) -= size_board; @@ -2756,7 +2759,12 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, /* take the rest of data in the area minus 1 byte of * checksum */ - printf("Additional Custom Mfg. length: 0x%02x\n", len); + if (custom_fields) { + printf("End of Custom Mfg. fields (0x%02x)\n", len); + } else { + printf("No Additional Custom Mfg. fields (0x%02x)\n", len); + } + padding = (*board_length) - 1; if ((padding > 0) && (!feof(input_file))) { printf("Unused space: %d (bytes)\n", padding); @@ -2770,16 +2778,18 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, printf("Checksum: 0x%02x\n", checksum); goto out; } + custom_fields++; printf("Additional Custom Mfg. length: 0x%02x\n", len); if ((size_board > 0) && (size_board < (*board_length))) { - unsigned char * additional_data = NULL; + unsigned char *additional_data, *str; unsigned int i = 0; - additional_data = malloc(size_board); + additional_data = malloc(size_board + 1); /* Make room for type/length field */ if (additional_data == NULL) { lprintf(LOG_ERR, "ipmitool: malloc failure"); return (size_t)(-1); } - ret = fread(additional_data, size_board, 1, input_file); + additional_data[0] = len; + ret = fread(additional_data + 1, size_board, 1, input_file); if ((ret != 1) || ferror(input_file)) { lprintf(LOG_ERR, "Invalid Additional Data!"); if (additional_data != NULL) { @@ -2788,18 +2798,27 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, } goto out; } - printf("Additional Custom Mfg. Data: %02x", - additional_data[0]); - for (i = 1; i < size_board; i++) { - printf("-%02x", additional_data[i]); - } - printf("\n"); + printf("Additional Custom Mfg. Data: "); + i = 0; + str = (unsigned char *)get_fru_area_str(additional_data, &i); + printf("%s\n", str); + free(str); + str = NULL; free(additional_data); additional_data = NULL; + (*board_length) -= size_board; + ret = fread(&len, 1, 1, input_file); + if ((ret != 1) || ferror(input_file)) { + lprintf(LOG_ERR, "Invalid Length!"); + goto out; + } + (*board_length)--; + size_board = (len & 0x3f); } else { - printf("No Additional Custom Mfg. %d\n", *board_length); + printf("ERROR: File has insufficient data (%d bytes) for the " + "Additional Custom Mfg. field\n", *board_length); goto out; } } diff --git a/lib/ipmi_fru.c b/lib/ipmi_fru.c index cf00eff..42c1f19 100644 --- a/lib/ipmi_fru.c +++ b/lib/ipmi_fru.c @@ -107,7 +107,7 @@ char * get_fru_area_str(uint8_t * data, uint32_t * offset) { static const char bcd_plus[] = "0123456789 -.:,_"; char * str; - int len, off, size, i, j, k, typecode; + int len, off, size, i, j, k, typecode, char_idx; union { uint32_t bits; char chars[4]; @@ -126,15 +126,15 @@ char * get_fru_area_str(uint8_t * data, uint32_t * offset) switch (typecode) { case 0: /* 00b: binary/unspecified */ - /* hex dump -> 2x length */ - size = (len*2); + case 1: /* 01b: BCD plus */ + /* hex dump or BCD -> 2x length */ + size = (len * 2); break; case 2: /* 10b: 6-bit ASCII */ /* 4 chars per group of 1-3 bytes */ - size = ((((len+2)*4)/3) & ~3); + size = (((len * 4 + 2) / 3) & ~3); break; case 3: /* 11b: 8-bit ASCII */ - case 1: /* 01b: BCD plus */ /* no length adjustment */ size = len; break; @@ -149,7 +149,7 @@ char * get_fru_area_str(uint8_t * data, uint32_t * offset) return NULL; memset(str, 0, size+1); - if (len == 0) { + if (size == 0) { str[0] = '\0'; *offset = off; return str; @@ -157,30 +157,30 @@ char * get_fru_area_str(uint8_t * data, uint32_t * offset) switch (typecode) { case 0: /* Binary */ - strncpy(str, buf2str(&data[off], len), len*2); + strncpy(str, buf2str(&data[off], len), size); break; case 1: /* BCD plus */ - for (k=0; k> ((k % 2) ? 0 : 4)) & 0x0f)]; str[k] = '\0'; break; case 2: /* 6-bit ASCII */ - for (i=j=0; i 1 ? data[off+i+1] : 0); u.chars[1] = (k > 2 ? data[off+i+2] : 0); -#define CHAR_IDX 3 + char_idx = 3; #else memcpy((void *)&u.bits, &data[off+i], k); -#define CHAR_IDX 0 + char_idx = 0; #endif for (k=0; k<4; k++) { - str[j++] = ((u.chars[CHAR_IDX] & 0x3f) + 0x20); + str[j++] = ((u.chars[char_idx] & 0x3f) + 0x20); u.bits >>= 6; } } @@ -188,8 +188,8 @@ char * get_fru_area_str(uint8_t * data, uint32_t * offset) break; case 3: - memcpy(str, &data[off], len); - str[len] = '\0'; + memcpy(str, &data[off], size); + str[size] = '\0'; break; } diff --git a/lib/ipmi_picmg.c b/lib/ipmi_picmg.c index c7d9c8e..2166cbe 100644 --- a/lib/ipmi_picmg.c +++ b/lib/ipmi_picmg.c @@ -37,11 +37,6 @@ #include #include -#define PICMG_EXTENSION_ATCA_MAJOR_VERSION 2 -#define PICMG_EXTENSION_AMC0_MAJOR_VERSION 4 -#define PICMG_EXTENSION_UTCA_MAJOR_VERSION 5 - - #define PICMG_EKEY_MODE_QUERY 0 #define PICMG_EKEY_MODE_PRINT_ALL 1 #define PICMG_EKEY_MODE_PRINT_ENABLED 2 @@ -2367,9 +2362,9 @@ picmg_discover(struct ipmi_intf *intf) { } else if (rsp->data[0] != 0) { lprintf(LOG_INFO,"Invalid Get PICMG Properties group extension %#x", rsp->data[0]); - } else if ((rsp->data[1] & 0x0F) != PICMG_EXTENSION_ATCA_MAJOR_VERSION - && (rsp->data[1] & 0x0F) != PICMG_EXTENSION_AMC0_MAJOR_VERSION - && (rsp->data[1] & 0x0F) != PICMG_EXTENSION_UTCA_MAJOR_VERSION) { + } else if ((rsp->data[1] & 0x0F) != PICMG_ATCA_MAJOR_VERSION + && (rsp->data[1] & 0x0F) != PICMG_AMC_MAJOR_VERSION + && (rsp->data[1] & 0x0F) != PICMG_UTCA_MAJOR_VERSION) { lprintf(LOG_INFO,"Unknown PICMG Extension Version %d.%d", (rsp->data[1] & 0x0F), (rsp->data[1] >> 4)); } else { diff --git a/lib/ipmi_sdr.c b/lib/ipmi_sdr.c index 2a9cbe3..167c252 100644 --- a/lib/ipmi_sdr.c +++ b/lib/ipmi_sdr.c @@ -4217,7 +4217,7 @@ ipmi_sdr_get_info(struct ipmi_intf *intf, * returns pointer to static buffer */ static char * -ipmi_sdr_timestamp(uint32_t stamp) +ipmi_sdr_timestamp(time_t stamp) { static char tbuf[40]; time_t s = (time_t) stamp; @@ -4240,7 +4240,7 @@ ipmi_sdr_timestamp(uint32_t stamp) int ipmi_sdr_print_info(struct ipmi_intf *intf) { - uint32_t timestamp; + time_t timestamp; uint16_t free_space; struct get_sdr_repository_info_rsp sdr_repository_info; @@ -4274,21 +4274,51 @@ ipmi_sdr_print_info(struct ipmi_intf *intf) break; } - timestamp = - (sdr_repository_info.most_recent_addition_timestamp[3] << 24) | - (sdr_repository_info.most_recent_addition_timestamp[2] << 16) | - (sdr_repository_info.most_recent_addition_timestamp[1] << 8) | - sdr_repository_info.most_recent_addition_timestamp[0]; - printf("Most recent Addition : %s\n", - ipmi_sdr_timestamp(timestamp)); - - timestamp = - (sdr_repository_info.most_recent_erase_timestamp[3] << 24) | - (sdr_repository_info.most_recent_erase_timestamp[2] << 16) | - (sdr_repository_info.most_recent_erase_timestamp[1] << 8) | - sdr_repository_info.most_recent_erase_timestamp[0]; - printf("Most recent Erase : %s\n", - ipmi_sdr_timestamp(timestamp)); + if(sdr_repository_info.delete_sdr_supported && sdr_repository_info.partial_add_sdr_supported) + { + timestamp = + (sdr_repository_info.most_recent_addition_timestamp[3] << 24) | + (sdr_repository_info.most_recent_addition_timestamp[2] << 16) | + (sdr_repository_info.most_recent_addition_timestamp[1] << 8) | + sdr_repository_info.most_recent_addition_timestamp[0]; + printf("Most recent Addition : %s\n", + ipmi_sdr_timestamp(timestamp)); + + timestamp = + (sdr_repository_info.most_recent_erase_timestamp[3] << 24) | + (sdr_repository_info.most_recent_erase_timestamp[2] << 16) | + (sdr_repository_info.most_recent_erase_timestamp[1] << 8) | + sdr_repository_info.most_recent_erase_timestamp[0]; + printf("Most recent Erase : %s\n", + ipmi_sdr_timestamp(timestamp)); + } + else if (sdr_repository_info.partial_add_sdr_supported) + { + timestamp = + (sdr_repository_info.most_recent_addition_timestamp[3] << 24) | + (sdr_repository_info.most_recent_addition_timestamp[2] << 16) | + (sdr_repository_info.most_recent_addition_timestamp[1] << 8) | + sdr_repository_info.most_recent_addition_timestamp[0]; + printf("Most recent Addition : %s\n", + ipmi_sdr_timestamp(timestamp)); + printf("Most recent Erase : NA\n"); + } + else if(sdr_repository_info.delete_sdr_supported) + { + printf("Most recent Addition : NA\n"); + timestamp = + (sdr_repository_info.most_recent_erase_timestamp[3] << 24) | + (sdr_repository_info.most_recent_erase_timestamp[2] << 16) | + (sdr_repository_info.most_recent_erase_timestamp[1] << 8) | + sdr_repository_info.most_recent_erase_timestamp[0]; + printf("Most recent Erase : %s\n", + ipmi_sdr_timestamp(timestamp)); + } + else + { + printf("Most recent Addition : NA\n"); + printf("Most recent Erase : NA\n"); + } printf("SDR overflow : %s\n", (sdr_repository_info.overflow_flag ? "yes" : "no")); diff --git a/src/plugins/lanplus/lanplus_crypt_impl.c b/src/plugins/lanplus/lanplus_crypt_impl.c index d5fac37..9652a5e 100644 --- a/src/plugins/lanplus/lanplus_crypt_impl.c +++ b/src/plugins/lanplus/lanplus_crypt_impl.c @@ -164,11 +164,7 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv, uint8_t * output, uint32_t * bytes_written) { - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv); - EVP_CIPHER_CTX_set_padding(&ctx, 0); - + EVP_CIPHER_CTX *ctx = NULL; *bytes_written = 0; @@ -182,6 +178,14 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv, printbuf(input, input_length, "encrypting this data"); } + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + lprintf(LOG_DEBUG, "ERROR: EVP_CIPHER_CTX_new() failed"); + return; + } + EVP_CIPHER_CTX_init(ctx); + EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv); + EVP_CIPHER_CTX_set_padding(ctx, 0); /* * The default implementation adds a whole block of padding if the input @@ -191,28 +195,28 @@ lanplus_encrypt_aes_cbc_128(const uint8_t * iv, assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0); - if(!EVP_EncryptUpdate(&ctx, output, (int *)bytes_written, input, input_length)) + if(!EVP_EncryptUpdate(ctx, output, (int *)bytes_written, input, input_length)) { /* Error */ *bytes_written = 0; - return; } else { uint32_t tmplen; - if(!EVP_EncryptFinal_ex(&ctx, output + *bytes_written, (int *)&tmplen)) + if(!EVP_EncryptFinal_ex(ctx, output + *bytes_written, (int *)&tmplen)) { + /* Error */ *bytes_written = 0; - return; /* Error */ } else { /* Success */ *bytes_written += tmplen; - EVP_CIPHER_CTX_cleanup(&ctx); } } + /* performs cleanup and free */ + EVP_CIPHER_CTX_free(ctx); } @@ -239,11 +243,7 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv, uint8_t * output, uint32_t * bytes_written) { - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX_init(&ctx); - EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv); - EVP_CIPHER_CTX_set_padding(&ctx, 0); - + EVP_CIPHER_CTX *ctx = NULL; if (verbose >= 5) { @@ -252,12 +252,20 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv, printbuf(input, input_length, "decrypting this data"); } - *bytes_written = 0; if (input_length == 0) return; + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + lprintf(LOG_DEBUG, "ERROR: EVP_CIPHER_CTX_new() failed"); + return; + } + EVP_CIPHER_CTX_init(ctx); + EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv); + EVP_CIPHER_CTX_set_padding(ctx, 0); + /* * The default implementation adds a whole block of padding if the input * data is perfectly aligned. We would like to keep that from happening. @@ -266,33 +274,33 @@ lanplus_decrypt_aes_cbc_128(const uint8_t * iv, assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0); - if (!EVP_DecryptUpdate(&ctx, output, (int *)bytes_written, input, input_length)) + if (!EVP_DecryptUpdate(ctx, output, (int *)bytes_written, input, input_length)) { /* Error */ lprintf(LOG_DEBUG, "ERROR: decrypt update failed"); *bytes_written = 0; - return; } else { uint32_t tmplen; - if (!EVP_DecryptFinal_ex(&ctx, output + *bytes_written, (int *)&tmplen)) + if (!EVP_DecryptFinal_ex(ctx, output + *bytes_written, (int *)&tmplen)) { + /* Error */ char buffer[1000]; ERR_error_string(ERR_get_error(), buffer); lprintf(LOG_DEBUG, "the ERR error %s", buffer); lprintf(LOG_DEBUG, "ERROR: decrypt final failed"); *bytes_written = 0; - return; /* Error */ } else { /* Success */ *bytes_written += tmplen; - EVP_CIPHER_CTX_cleanup(&ctx); } } + /* performs cleanup and free */ + EVP_CIPHER_CTX_free(ctx); if (verbose >= 5) {