ipmitool: fixed IANA PEN registry, added multiple patches

This commit is contained in:
Tim Biermann 2024-02-23 21:26:27 +01:00
parent 3dabc9eea9
commit 13cbb94dfa
Signed by: tb
GPG Key ID: 42F8B4E30B673606
11 changed files with 622 additions and 8 deletions

View File

@ -12,4 +12,4 @@ drwxr-xr-x root/root usr/share/man/man1/
drwxr-xr-x root/root usr/share/man/man8/
-rw-r--r-- root/root usr/share/man/man8/ipmievd.8.gz
drwxr-xr-x root/root usr/share/misc/
-rw-r--r-- root/root usr/share/misc/enterprise-numbers
-rwxr-xr-x root/root usr/share/misc/enterprise-numbers

View File

@ -0,0 +1,16 @@
diff --git a/lib/ipmi_sdr.c b/lib/ipmi_sdr.c
index fa7b082..9bc5ac2 100644
--- a/lib/ipmi_sdr.c
+++ b/lib/ipmi_sdr.c
@@ -572,6 +572,8 @@ ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf, uint8_t sensor,
uint32_t save_addr;
uint32_t save_channel;
+ if (target == (uint8_t) 0xb1)
+ return ipmi_sdr_get_sensor_reading(intf, sensor);
if ( BRIDGE_TO_SENSOR(intf, target, channel) ) {
lprintf(LOG_DEBUG,
"Bridge to Sensor "
--
2.1.0

View File

@ -0,0 +1,12 @@
diff --color -Nur ipmitool-IPMITOOL_1_8_19.orig/include/ipmitool/ipmi_sdr.h ipmitool-IPMITOOL_1_8_19/include/ipmitool/ipmi_sdr.h
--- ipmitool-IPMITOOL_1_8_19.orig/include/ipmitool/ipmi_sdr.h 2022-09-01 11:42:31.000000000 -0700
+++ ipmitool-IPMITOOL_1_8_19/include/ipmitool/ipmi_sdr.h 2022-12-20 14:12:47.675994549 -0800
@@ -799,7 +799,7 @@
#define SENSOR_TYPE_MAX 0x2C
struct sensor_reading {
- char s_id[17]; /* name of the sensor */
+ char s_id[33]; /* name of the sensor */
struct sdr_record_full_sensor *full;
struct sdr_record_compact_sensor *compact;
uint8_t s_reading_valid; /* read value valididity */

View File

@ -0,0 +1,41 @@
diff -urNp old/doc/ipmitool.1.in new/doc/ipmitool.1.in
--- old/doc/ipmitool.1.in 2017-10-03 16:10:50.446539988 +0200
+++ new/doc/ipmitool.1.in 2017-10-03 16:16:37.039673239 +0200
@@ -3170,13 +3170,14 @@ SOL configuration data for the currently
Enable, disable or show status of SOL payload for the user on the specified channel.
.TP
-\fIset\fP <\fBparameter\fR> <\fBvalue\fR> [<\fBchannel\fR>]
+\fIset\fP <\fBparameter\fR> <\fBvalue\fR> [<\fBchannel\fR>] [\fBnoguard\fR]
.br
Configure parameters for Serial Over Lan. If no channel is given,
it will display SOL configuration data for the currently used
channel. Configuration parameter updates are automatically guarded
-with the updates to the set\-in\-progress parameter.
+with the updates to the set\-in\-progress parameter, unless \fInoguard\fR
+parameter is present.
.RS
.TP
Valid parameters and values are:
diff -urNp old/lib/ipmi_sol.c new/lib/ipmi_sol.c
--- old/lib/ipmi_sol.c 2017-10-03 16:10:50.447539996 +0200
+++ new/lib/ipmi_sol.c 2017-10-03 16:18:37.079006949 +0200
@@ -1875,7 +1875,7 @@ static void
print_sol_usage(void)
{
lprintf(LOG_NOTICE, "SOL Commands: info [<channel number>]");
- lprintf(LOG_NOTICE, " set <parameter> <value> [channel]");
+ lprintf(LOG_NOTICE, " set <parameter> <value> [channel] [noguard]");
lprintf(LOG_NOTICE, " payload <enable|disable|status> [channel] [userid]");
lprintf(LOG_NOTICE, " activate [<usesolkeepalive|nokeepalive>] [instance=<number>]");
lprintf(LOG_NOTICE, " deactivate [instance=<number>]");
@@ -1890,6 +1890,8 @@ print_sol_usage(void)
static void
print_sol_set_usage(void)
{
+ lprintf(LOG_NOTICE, "\nSOL set usage: \n");
+ lprintf(LOG_NOTICE, " sol set <parameter> <value> [channel] [noguard]\n");
lprintf(LOG_NOTICE, "\nSOL set parameters and values: \n");
lprintf(LOG_NOTICE, " set-in-progress set-complete | "
"set-in-progress | commit-write");

View File

@ -0,0 +1,39 @@
From 9d72def87ecc384d0a46525c766e755068fefe54 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=A1clav=20Dole=C5=BEal?= <vdolezal@redhat.com>
Date: Thu, 28 May 2020 13:32:31 +0200
Subject: [PATCH] lanplus: don't retry pre-session Get cipher suites
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some BMCs are ignoring it, causing needless delay.
Signed-off-by: Václav Doležal <vdolezal@redhat.com>
---
src/plugins/lanplus/lanplus.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/plugins/lanplus/lanplus.c b/src/plugins/lanplus/lanplus.c
index 3087348..c442c0e 100644
--- a/src/plugins/lanplus/lanplus.c
+++ b/src/plugins/lanplus/lanplus.c
@@ -3386,9 +3386,13 @@
};
const size_t nr_preferred = ARRAY_SIZE(cipher_order_preferred);
size_t ipref, i;
+ int rc;
+ int retry_old = intf->ssn_params.retry;
- if (ipmi_get_channel_cipher_suites(intf, "ipmi", IPMI_LAN_CHANNEL_E,
- suites, &nr_suites) < 0)
+ ipmi_intf_session_set_retry(intf, 1);
+ rc = ipmi_get_channel_cipher_suites(intf, "ipmi", IPMI_LAN_CHANNEL_E, suites, &nr_suites);
+ ipmi_intf_session_set_retry(intf, retry_old);
+ if (rc < 0)
{
/* default legacy behavior - fall back to cipher suite 3 */
return IPMI_LANPLUS_CIPHER_SUITE_3;
--
2.25.4

View File

@ -0,0 +1,22 @@
Description: fix buffer overflow
based on 101_fix_buf_overflow from Leo Iannacone <l3on@ubuntu.com>
Author: Jörg Frings-Fürst <debian@jff-webhosting.net>
Bug: TSOL buffer overflow
Bug-ubuntu: https://bugs.launchpad.net/ubuntu/+source/ipmitool/+bug/633054
Forwarded: https://sourceforge.net/p/ipmitool/patches/100/
Last-Update: 2014-12-01
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
Index: trunk/lib/ipmi_tsol.c
===================================================================
--- trunk.orig/lib/ipmi_tsol.c
+++ trunk/lib/ipmi_tsol.c
@@ -374,7 +374,7 @@ ipmi_tsol_main(struct ipmi_intf *intf, i
char *recvip = NULL;
char in_buff[IPMI_BUF_SIZE];
char out_buff[IPMI_BUF_SIZE * 8];
- char buff[IPMI_BUF_SIZE + 4];
+ char buff[IPMI_BUF_SIZE * 8 + 4];
int fd_socket, result, i;
size_t out_buff_fill, in_buff_fill;
int ip1, ip2, ip3, ip4;

View File

@ -0,0 +1,35 @@
Description: Fix soensor reading
Author: mareedu srinivasa rao
Origin: upstream, https://sourceforge.net/p/ipmitool/bugs/490/
Bug: https://sourceforge.net/p/ipmitool/bugs/490/
Bug-debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=983082
Forwarded: not-needed
Last-Update: 2022-10-29
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
Index: trunk/lib/ipmi_sdr.c
===================================================================
--- trunk.orig/lib/ipmi_sdr.c
+++ trunk/lib/ipmi_sdr.c
@@ -1799,7 +1799,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_int
sr->s_a_units);
} else /* Discrete */
snprintf(sval, sizeof(sval),
- "0x%02x", sr->s_reading);
+ "0x%02x", sr->s_data2);
}
else if (sr->s_scanning_disabled)
snprintf(sval, sizeof (sval), sr->full ? "disabled" : "Not Readable");
Index: trunk/lib/ipmi_sensor.c
===================================================================
--- trunk.orig/lib/ipmi_sensor.c
+++ trunk/lib/ipmi_sensor.c
@@ -201,7 +201,7 @@ ipmi_sensor_print_fc_discrete(struct ipm
sr->s_a_str, sr->s_a_units, "ok");
} else {
printf("| 0x%-8x | %-10s | 0x%02x%02x",
- sr->s_reading, "discrete",
+ sr->s_data2, "discrete",
sr->s_data2, sr->s_data3);
}
} else {

109
ipmitool/382.patch Normal file
View File

@ -0,0 +1,109 @@
From d43600b721f435144d416bfd34d489046cf30e99 Mon Sep 17 00:00:00 2001
From: Vincent Fazio <vfazio@gmail.com>
Date: Sat, 7 Jan 2023 21:02:48 -0600
Subject: [PATCH] Do not require the IANA PEN registry file
Previously, ipmitool would fail to run if the local copy of the IANA PEN
registry could not be parsed.
When the registry is not available the manufacturer will be "Unknown" but
ipmitool will otherwise function so should not be considered fatal.
Also, fix an issue with improperly handling the `oem_info_list_load`
return value. Previously, in `ipmi_oem_info_init`, if `oem_info_list_load`
returned a negative value due to the registry file not existing, an
improper count would cause `oem_info_init_from_list` to aallocate a list
that didn't encompass the full header/tail list.
IANA PEN registry open failed: No such file or directory
Allocating 3 entries
[ 1] 16777214 | A Debug Assisting Company, Ltd.
[ 0] 1048575 | Unspecified
Now, use a signed int and ensure a valid count of loaded OEMs is used.
Signed-off-by: Vincent Fazio <vfazio@gmail.com>
---
include/ipmitool/ipmi_strings.h | 2 +-
lib/ipmi_main.c | 5 +----
lib/ipmi_strings.c | 19 +++++--------------
3 files changed, 7 insertions(+), 19 deletions(-)
diff --git a/include/ipmitool/ipmi_strings.h b/include/ipmitool/ipmi_strings.h
index 17c37c62..d60179c3 100644
--- a/include/ipmitool/ipmi_strings.h
+++ b/include/ipmitool/ipmi_strings.h
@@ -55,7 +55,7 @@ extern const struct valstr ipmi_integrity_algorithms[];
extern const struct valstr ipmi_encryption_algorithms[];
extern const struct valstr ipmi_user_enable_status_vals[];
extern const struct valstr *ipmi_oem_info;
-int ipmi_oem_info_init();
+void ipmi_oem_info_init();
void ipmi_oem_info_free();
extern const struct valstr picmg_frucontrol_vals[];
diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c
index a673a302..510bc2de 100644
--- a/lib/ipmi_main.c
+++ b/lib/ipmi_main.c
@@ -853,10 +853,7 @@ ipmi_main(int argc, char ** argv,
}
/* load the IANA PEN registry */
- if (ipmi_oem_info_init()) {
- lprintf(LOG_ERR, "Failed to initialize the OEM info dictionary");
- goto out_free;
- }
+ ipmi_oem_info_init();
/* run OEM setup if found */
if (oemtype &&
diff --git a/lib/ipmi_strings.c b/lib/ipmi_strings.c
index 26b359f0..c8fc2d02 100644
--- a/lib/ipmi_strings.c
+++ b/lib/ipmi_strings.c
@@ -1719,39 +1719,30 @@ oem_info_init_from_list(oem_valstr_list_t *oemlist, size_t count)
return rc;
}
-int ipmi_oem_info_init()
+void ipmi_oem_info_init()
{
oem_valstr_list_t terminator = { { -1, NULL}, NULL }; /* Terminator */
oem_valstr_list_t *oemlist = &terminator;
bool free_strings = true;
- size_t count;
- int rc = -4;
+ int count;
lprintf(LOG_INFO, "Loading IANA PEN Registry...");
if (ipmi_oem_info) {
lprintf(LOG_INFO, "IANA PEN Registry is already loaded");
- rc = 0;
goto out;
}
- if (!(count = oem_info_list_load(&oemlist))) {
- /*
- * We can't identify OEMs without a loaded registry.
- * Set the pointer to dummy and return.
- */
- ipmi_oem_info = ipmi_oem_info_dummy;
- goto out;
+ if ((count = oem_info_list_load(&oemlist)) < 1) {
+ lprintf(LOG_WARN, "Failed to load entries from IANA PEN Registry");
+ count = 0;
}
/* In the array was allocated, don't free the strings at cleanup */
free_strings = !oem_info_init_from_list(oemlist, count);
- rc = IPMI_CC_OK;
-
out:
oem_info_list_free(&oemlist, free_strings);
- return rc;
}
void ipmi_oem_info_free()

View File

@ -5,19 +5,51 @@
name=ipmitool
version=1.8.19
release=1
source=(https://github.com/ipmitool/ipmitool/archive/IPMITOOL_${version//./_}.tar.gz)
renames=($name-$version.tar.gz)
release=2
source=(https://github.com/ipmitool/ipmitool/archive/IPMITOOL_${version//./_}/$name-$version.tar.gz
ipmitool-1.8.19-set-kg-key.patch
0004-slowswid.patch
0005-sensor-id-length.patch
0007-check-input.patch
0014-lanplus-cipher-retry.patch
0100-fix_buf_overflow.patch
0105-sensor_reading.patch
be11d948f89b10be094e28d8a0a5e8fb532c7b60.patch
https://crux.nu/files/distfiles/enterprise-numbers-20240223.txt.gz
382.patch)
build() {
gzip -d enterprise-numbers-20240223.txt.gz
cd ipmitool-IPMITOOL_${version//./_}
./bootstrap
IANADIR=/usr/share/misc ./configure --prefix=/usr \
--datarootdir=/usr/share
patch -Np1 -i $SRC/382.patch
patch -Np1 -i $SRC/be11d948f89b10be094e28d8a0a5e8fb532c7b60.patch
# https://src.fedoraproject.org/rpms/ipmitool/blob/rawhide/f/ipmitool.spec#_20
patch -Np1 -i $SRC/ipmitool-1.8.19-set-kg-key.patch
patch -Np1 -i $SRC/0004-slowswid.patch
patch -Np1 -i $SRC/0005-sensor-id-length.patch
patch -Np1 -i $SRC/0007-check-input.patch
patch -Np1 -i $SRC/0014-lanplus-cipher-retry.patch
patch -Np1 -i $SRC/0100-fix_buf_overflow.patch
patch -Np1 -i $SRC/0105-sensor_reading.patch
make
aclocal
libtoolize --automake --copy
autoheader
automake --foreign --add-missing --copy
aclocal
autoconf
automake --foreign
./configure --prefix=/usr \
--datarootdir=/usr/share \
--enable-file-security \
--enable-registry-download=no \
--disable-dependency-tracking
make -j ${JOBS:-1}
make DESTDIR=$PKG install
install -Dm755 $SRC/enterprise-numbers-20240223.txt $PKG/usr/share/misc/enterprise-numbers
rm -rf $PKG/usr/share/doc
}

View File

@ -0,0 +1,69 @@
From be11d948f89b10be094e28d8a0a5e8fb532c7b60 Mon Sep 17 00:00:00 2001
From: Vincent Fazio <vfazio@gmail.com>
Date: Wed, 11 Jan 2023 22:55:51 -0600
Subject: [PATCH] configure.ac: allow disabling registry downloads
Some environments require reproducible builds. Since the IANA PEN
registry is constantly updating and there is no snapshot available,
installing ipmitool via `make install` is not reproducible.
Provide a configure mechanism to disable the registry download/install..
---
configure.ac | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/configure.ac b/configure.ac
index 4ee1be82..1dd27428 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,8 +18,6 @@ AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_CHECK_PROG([RPMBUILD], [rpmbuild], [rpmbuild], [rpm])
AC_CHECK_PROG([SED], [sed], [sed])
-AC_CHECK_PROG([WGET], [wget], [wget])
-AC_CHECK_PROG([CURL], [curl], [curl])
AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h string.h sys/ioctl.h sys/stat.h unistd.h paths.h])
@@ -56,21 +54,33 @@ if test "x$exec_prefix" = "xNONE"; then
exec_prefix="$prefix"
fi
-if test "x$WGET" = "x"; then
- if test "x$CURL" = "x"; then
+dnl allow enabling/disabling the fetching of the IANA PEN registry
+AC_ARG_ENABLE([registry-download],
+ [AC_HELP_STRING([--enable-registry-download],
+ [download/install the IANA PEN registry [default=yes]])],
+ [xenable_registry_download=$enableval],
+ [xenable_registry_download=yes])
+
+AM_CONDITIONAL([DOWNLOAD], [false])
+
+if test "x$xenable_registry_download" = "xyes"; then
+ AC_CHECK_PROG([WGET], [wget], [wget])
+ AC_CHECK_PROG([CURL], [curl], [curl])
+
+ if test "x$WGET" = "x" && test "x$CURL" = "x"; then
AC_MSG_WARN([** Neither wget nor curl could be found.])
AC_MSG_WARN([** IANA PEN database will not be installed by `make install` !])
else
- DOWNLOAD="$CURL --location --progress-bar"
AM_CONDITIONAL([DOWNLOAD], [true])
+ if test "x$WGET" != "x"; then
+ DOWNLOAD="$WGET -c -nd -O -"
+ else
+ DOWNLOAD="$CURL --location --progress-bar"
+ fi
fi
-else
- DOWNLOAD="$WGET -c -nd -O -"
- AM_CONDITIONAL([DOWNLOAD], [true])
fi
-AC_MSG_WARN([** Download is:])
-AC_MSG_WARN($DOWNLOAD)
+AC_MSG_WARN([** Download is: $DOWNLOAD])
AC_SUBST(DOWNLOAD, $DOWNLOAD)
dnl

View File

@ -0,0 +1,239 @@
diff --color -Nur ipmitool-IPMITOOL_1_8_19.orig/doc/ipmitool.1.in ipmitool-IPMITOOL_1_8_19/doc/ipmitool.1.in
--- ipmitool-IPMITOOL_1_8_19.orig/doc/ipmitool.1.in 2023-01-02 11:41:51.179962218 -0800
+++ ipmitool-IPMITOOL_1_8_19/doc/ipmitool.1.in 2023-01-02 11:43:56.396850762 -0800
@@ -384,6 +384,20 @@
Displays the list of cipher suites supported for the given
application (ipmi or sol) on the given channel.
+.TP
+\fIsetkg\fP <\fIhex\fP|\fIplain\fP> <\fBkey\fP> [<\fBchannel\fR>]
+.br
+
+Sets K_g key to given value. Use \fIplain\fP to specify \fBkey\fR as simple ASCII string.
+Use \fIhex\fP to specify \fBkey\fR as sequence of hexadecimal codes of ASCII charactes.
+I.e. following two examples are equivalent:
+
+.RS
+ipmitool channel setkg plain PASSWORD
+
+ipmitool channel setkg hex 50415353574F5244
+.RE
+
.RE
.RE
.TP
diff --color -Nur ipmitool-IPMITOOL_1_8_19.orig/include/ipmitool/helper.h ipmitool-IPMITOOL_1_8_19/include/ipmitool/helper.h
--- ipmitool-IPMITOOL_1_8_19.orig/include/ipmitool/helper.h 2022-09-01 11:42:31.000000000 -0700
+++ ipmitool-IPMITOOL_1_8_19/include/ipmitool/helper.h 2023-01-02 11:44:40.775811260 -0800
@@ -67,6 +67,8 @@
# define IPMI_UID_MAX 63
#endif
+#define IPMI_KG_BUFFER_SIZE 21 /* key plus null byte */
+
struct ipmi_intf;
struct valstr {
diff --color -Nur ipmitool-IPMITOOL_1_8_19.orig/include/ipmitool/ipmi_channel.h ipmitool-IPMITOOL_1_8_19/include/ipmitool/ipmi_channel.h
--- ipmitool-IPMITOOL_1_8_19.orig/include/ipmitool/ipmi_channel.h 2022-09-01 11:42:31.000000000 -0700
+++ ipmitool-IPMITOOL_1_8_19/include/ipmitool/ipmi_channel.h 2023-01-02 11:46:39.321705721 -0800
@@ -49,6 +49,10 @@
#define IPMI_GET_USER_NAME 0x46
#define IPMI_SET_USER_PASSWORD 0x47
#define IPMI_GET_CHANNEL_CIPHER_SUITES 0x54
+#define IPMI_SET_CHANNEL_SECURITY_KEYS 0x56
+
+#define IPMI_KG_KEY_ID 1
+#define IPMI_SET_CHANNEL_SECURITY_KEYS_OP_SET 1
/* These are for channel_info_t.session_support */
#define IPMI_CHANNEL_SESSION_LESS 0x00
@@ -208,6 +212,39 @@
struct channel_access_t channel_access,
uint8_t access_option,
uint8_t privilege_option);
+struct set_channel_security_keys_req {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved1 :4;
+ uint8_t channel :4;
+
+ uint8_t __reserved2 :6;
+ uint8_t operation :2;
+
+ uint8_t key_id;
+ unsigned char key_value[IPMI_KG_BUFFER_SIZE-1]; /* we don't want space for '\0' at the end */
+#else
+ uint8_t channel :4;
+ uint8_t __reserved1 :4;
+
+ uint8_t operation :2;
+ uint8_t __reserved2 :6;
+
+ uint8_t key_id;
+ unsigned char key_value[IPMI_KG_BUFFER_SIZE-1]; /* we don't want space for '\0' at the end */
+#endif
+} __attribute__ ((packed));
+
+struct set_channel_security_keys_rsp {
+#if WORDS_BIGENDIAN
+ uint8_t __reserved1 :6;
+ uint8_t lock_status :2;
+ unsigned char key_value; /* just the first character, use &key_value to explore the rest */
+#else
+ uint8_t lock_status :2;
+ uint8_t __reserved1 :6;
+ unsigned char key_value; /* just the first character, use &key_value to explore the rest */
+#endif
+} __attribute__ ((packed));
uint8_t ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel);
void ipmi_current_channel_info(struct ipmi_intf *intf,
diff --color -Nur ipmitool-IPMITOOL_1_8_19.orig/include/ipmitool/ipmi_intf.h ipmitool-IPMITOOL_1_8_19/include/ipmitool/ipmi_intf.h
--- ipmitool-IPMITOOL_1_8_19.orig/include/ipmitool/ipmi_intf.h 2022-09-01 11:42:31.000000000 -0700
+++ ipmitool-IPMITOOL_1_8_19/include/ipmitool/ipmi_intf.h 2023-01-02 11:47:15.995673068 -0800
@@ -59,7 +59,6 @@
#define IPMI_AUTHCODE_BUFFER_SIZE 20
#define IPMI_SIK_BUFFER_SIZE IPMI_MAX_MD_SIZE
-#define IPMI_KG_BUFFER_SIZE 21 /* key plus null byte */
enum cipher_suite_ids {
IPMI_LANPLUS_CIPHER_SUITE_0 = 0,
diff --color -Nur ipmitool-IPMITOOL_1_8_19.orig/lib/ipmi_channel.c ipmitool-IPMITOOL_1_8_19/lib/ipmi_channel.c
--- ipmitool-IPMITOOL_1_8_19.orig/lib/ipmi_channel.c 2022-09-01 11:42:31.000000000 -0700
+++ ipmitool-IPMITOOL_1_8_19/lib/ipmi_channel.c 2023-01-02 11:51:08.420466223 -0800
@@ -901,6 +901,92 @@
return 0;
}
+int
+ipmi_set_channel_security_keys (struct ipmi_intf *intf, uint8_t channel, const char *method, const char *key)
+{
+ uint8_t kgkey[IPMI_KG_BUFFER_SIZE];
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct set_channel_security_keys_req req_data;
+ int rc = -1;
+
+ /* convert provided key to array of bytes */
+ if (strcmp(method, "hex") == 0) {
+ if (strlen(key) > (IPMI_KG_BUFFER_SIZE-1)*2) {
+ lprintf(LOG_ERR, "Provided key is too long, max. length is %d bytes", (IPMI_KG_BUFFER_SIZE-1));
+ printf_channel_usage();
+ return -1;
+ }
+
+ rc = ipmi_parse_hex(key, kgkey, sizeof(kgkey)-1);
+ if (rc == -1) {
+ lprintf(LOG_ERR, "Number of Kg key characters is not even");
+ return rc;
+ } else if (rc == -3) {
+ lprintf(LOG_ERR, "Kg key is not hexadecimal number");
+ return rc;
+ } else if (rc > (IPMI_KG_BUFFER_SIZE-1)) {
+ lprintf(LOG_ERR, "Kg key is too long");
+ return rc;
+ }
+
+ } else if (strcmp(method, "plain") == 0) {
+ if (strlen(key) > IPMI_KG_BUFFER_SIZE-1) {
+ lprintf(LOG_ERR, "Provided key is too long, max. length is %d bytes", (IPMI_KG_BUFFER_SIZE -1));
+ printf_channel_usage();
+ return rc;
+ }
+
+ strncpy(kgkey, key, IPMI_KG_BUFFER_SIZE-1);
+ } else {
+ printf_channel_usage();
+ return rc;
+ }
+
+ /* assemble and send request to set kg key */
+ memset(&req_data, 0, sizeof(req_data));
+ req_data.channel = channel;
+ req_data.operation = IPMI_SET_CHANNEL_SECURITY_KEYS_OP_SET;
+ req_data.key_id = IPMI_KG_KEY_ID;
+ memcpy(req_data.key_value, kgkey, IPMI_KG_BUFFER_SIZE-1);
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_APP;
+ req.msg.cmd = IPMI_SET_CHANNEL_SECURITY_KEYS;
+ req.msg.data = (uint8_t*) &req_data;
+ req.msg.data_len = sizeof(req_data);
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Set Channel Security Keys command failed");
+ return rc;
+ }
+ if (rsp->ccode > 0) {
+ const char *error = NULL;
+ switch (rsp->ccode) {
+ case 0x80:
+ error = "Key is locked";
+ break;
+ case 0x81:
+ error = "Insufficient key bytes";
+ break;
+ case 0x82:
+ error = "Too many key bytes";
+ break;
+ case 0x83:
+ error = "Key value does not meet criteria for K_g key";
+ break;
+ default:
+ error = val2str(rsp->ccode, completion_code_vals);
+ }
+ lprintf(LOG_ERR, "Error setting security key: %X (%s)", rsp->ccode, error);
+ return rc;
+ }
+
+ lprintf(LOG_NOTICE, "Set Channel Security Keys command succeeded");
+ return 0;
+}
+
int
ipmi_channel_main(struct ipmi_intf *intf, int argc, char **argv)
{
@@ -970,6 +1056,19 @@
retval = ipmi_print_channel_cipher_suites(intf,
argv[1], /* ipmi | sol */
channel);
+ } else if (strncmp(argv[0], "setkg", 5) == 0) {
+ if (argc < 3 || argc > 4)
+ printf_channel_usage();
+ else {
+ uint8_t ch = 0xe;
+ char *method = argv[1];
+ char *key = argv[2];
+ if (argc == 4) {
+ ch = (uint8_t)strtol(argv[3], NULL, 0);
+ }
+
+ retval = ipmi_set_channel_security_keys(intf, ch, method, key);
+ }
} else {
lprintf(LOG_ERR, "Invalid CHANNEL command: %s\n", argv[0]);
printf_channel_usage();
@@ -996,6 +1095,10 @@
lprintf(LOG_NOTICE,
"");
lprintf(LOG_NOTICE,
+" setkg hex|plain <key> [channel]");
+ lprintf(LOG_NOTICE,
+"");
+ lprintf(LOG_NOTICE,
"Possible privilege levels are:");
lprintf(LOG_NOTICE,
" 1 Callback level");
diff --color -Nur ipmitool-IPMITOOL_1_8_19.orig/src/plugins/ipmi_intf.c ipmitool-IPMITOOL_1_8_19/src/plugins/ipmi_intf.c
--- ipmitool-IPMITOOL_1_8_19.orig/src/plugins/ipmi_intf.c 2022-09-01 11:42:31.000000000 -0700
+++ ipmitool-IPMITOOL_1_8_19/src/plugins/ipmi_intf.c 2023-01-02 11:51:45.295433433 -0800
@@ -52,6 +52,7 @@
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_sdr.h>
#include <ipmitool/log.h>
+#include <ipmitool/helper.h>
#define IPMI_DEFAULT_PAYLOAD_SIZE 25