bmc-toolbox/bmclib

Default IPMI Cipher

Kwongyhue opened this issue · 1 comments

Hello,
The default cipher for ipmitool is cipher suite 3. This is because conformity to the IPMI 2.0 specification requires this suite to be supported. However, it's not the strongest cipher that can be supported by the BMC (cipher suite 17).
Requesting cipher suite 17 be attempted by default and subsequently using the universally supported cipher suite 3 upon failure.

I think it should look like this?

From: Kwongyhue <kwongyhue.chow@gmail.com>
Date: Fri, 28 Apr 2023 11:04:32 -0500
Subject: [PATCH] ipmi: Set default cipher suite to 17

---
 internal/ipmi/ipmi.go | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/internal/ipmi/ipmi.go b/internal/ipmi/ipmi.go
index 0bde857..eae82ca 100644
--- a/internal/ipmi/ipmi.go
+++ b/internal/ipmi/ipmi.go
@@ -36,8 +36,11 @@ func New(username string, password string, host string) (ipmi *Ipmi, err error)
 }
 
 func (i *Ipmi) run(ctx context.Context, command []string) (output string, err error) {
-	ipmiArgs := []string{"-I", "lanplus", "-U", i.Username, "-E", "-N", "5"}
-	if strings.Contains(i.Host, ":") {
+    var out []byte
+    var ipmiCiphers = []string{"-C 17", "-C 3"}
+    ipmiArgs := []string{"-I", "lanplus", "-U", i.Username, "-E", "-N", "5"}
+    
+    if strings.Contains(i.Host, ":") {
 		host, port, err := net.SplitHostPort(i.Host)
 		if err == nil {
 			ipmiArgs = append(ipmiArgs, "-H", host, "-p", port)
@@ -46,14 +49,21 @@ func (i *Ipmi) run(ctx context.Context, command []string) (output string, err er
 		ipmiArgs = append(ipmiArgs, "-H", i.Host)
 	}
 
-	ipmiArgs = append(ipmiArgs, command...)
-	cmd := exec.CommandContext(ctx, i.ipmitool, ipmiArgs...)
-	cmd.Env = []string{fmt.Sprintf("IPMITOOL_PASSWORD=%s", i.Password)}
-	out, err := cmd.CombinedOutput()
-	if ctx.Err() == context.DeadlineExceeded {
-		return string(out), ctx.Err()
-	}
-	return string(out), errors.Wrap(err, strings.TrimSpace(string(out)))
+    for _, cipherString := range ipmiCiphers {
+        ipmiCmd := append(ipmiArgs, cipherString)
+        ipmiCmd = append(ipmiCmd, command...)
+        cmd := exec.CommandContext(ctx, i.ipmitool, ipmiCmd...)
+        cmd.Env = []string{fmt.Sprintf("IPMITOOL_PASSWORD=%s", i.Password)}
+        out, err = cmd.CombinedOutput()
+        if err == nil {
+            break
+        }
+    }
+
+    if ctx.Err() == context.DeadlineExceeded {
+        return string(out), ctx.Err()
+    }
+    return string(out), errors.Wrap(err, strings.TrimSpace(string(out)))
 }
 
 // PowerCycle reboots the machine via bmc
-- 
2.39.2 (Apple Git-143)

fixed in #324