From ecc1fb3c6bb40a5bdd99db478cd1b6295fc0d741 Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Thu, 9 Nov 2023 07:20:12 +0100 Subject: [PATCH] supermicro: support SMC BMCs that don't implement CSRF tokens Older X11 BMC firmwares don't include CSRF tokens in requests to the BMC API. --- providers/supermicro/floppy.go | 13 +++++++++---- providers/supermicro/supermicro.go | 15 ++++++++------- providers/supermicro/supermicro_test.go | 5 +++++ providers/supermicro/x11_firmware_bios.go | 13 +++++++++---- providers/supermicro/x11_firmware_bmc.go | 13 +++++++++---- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/providers/supermicro/floppy.go b/providers/supermicro/floppy.go index a1967fdf..3c652890 100644 --- a/providers/supermicro/floppy.go +++ b/providers/supermicro/floppy.go @@ -50,18 +50,23 @@ func (c *Client) MountFloppyImage(ctx context.Context, image io.Reader) error { var payloadBuffer bytes.Buffer - formParts := []struct { + type form struct { name string data io.Reader - }{ + } + + formParts := []form{ { name: "img_file", data: image, }, - { + } + + if c.serviceClient.csrfToken != "" { + formParts = append(formParts, form{ name: "csrf-token", data: bytes.NewBufferString(c.serviceClient.csrfToken), - }, + }) } payloadWriter := multipart.NewWriter(&payloadBuffer) diff --git a/providers/supermicro/supermicro.go b/providers/supermicro/supermicro.go index 1ec2b367..bb0e4818 100644 --- a/providers/supermicro/supermicro.go +++ b/providers/supermicro/supermicro.go @@ -45,6 +45,7 @@ var ( providers.FeatureFirmwareUpload, providers.FeatureFirmwareInstallUploaded, providers.FeatureFirmwareTaskStatus, + providers.FeatureFirmwareInstallSteps, } ) @@ -168,12 +169,12 @@ func (c *Client) Open(ctx context.Context) (err error) { return errors.Wrap(bmclibErrs.ErrLoginFailed, strconv.Itoa(status)) } - token := parseToken(contentsTopMenu) - if token == "" { - return errors.Wrap(bmclibErrs.ErrLoginFailed, "could not parse CSRF-TOKEN from page") - } - - c.serviceClient.setCsrfToken(token) + // Note: older firmware version on the X11s don't use a CSRF token + // so here theres no explicit requirement for it to be found. + // + // X11DPH-T 01.71.11 10/25/2019 + csrfToken := parseToken(contentsTopMenu) + c.serviceClient.setCsrfToken(csrfToken) c.bmc, err = c.bmcQueryor(ctx) if err != nil { @@ -246,7 +247,7 @@ func parseToken(body []byte) string { return "" } - re, err := regexp.Compile(`"CSRF_TOKEN", "(?P.*)"`) + re, err := regexp.Compile(fmt.Sprintf(`"%s", "(?P.*)"`, key)) if err != nil { return "" } diff --git a/providers/supermicro/supermicro_test.go b/providers/supermicro/supermicro_test.go index 2317a88a..ca0313c8 100644 --- a/providers/supermicro/supermicro_test.go +++ b/providers/supermicro/supermicro_test.go @@ -50,6 +50,11 @@ func TestParseToken(t *testing.T) { []byte(``), "RYjdEjWIhU+PCRFMBP2ZRPPePcQ4n3dM3s+rCgTnBBU", }, + { + "token with key type 5 found", + []byte(``), + "RYjdEjWIhU+PCRFMBP2ZRPPePcQ4n3dM3s+rCgTnBBU", + }, } for _, tc := range testcases { diff --git a/providers/supermicro/x11_firmware_bios.go b/providers/supermicro/x11_firmware_bios.go index e6085af4..255d43ee 100644 --- a/providers/supermicro/x11_firmware_bios.go +++ b/providers/supermicro/x11_firmware_bios.go @@ -195,18 +195,23 @@ func (c *x11) uploadBIOSFirmware(ctx context.Context, fwReader io.Reader) error var payloadBuffer bytes.Buffer var err error - formParts := []struct { + type form struct { name string data io.Reader - }{ + } + + formParts := []form{ { name: "bios_rom", data: fwReader, }, - { + } + + if c.csrfToken != "" { + formParts = append(formParts, form{ name: "csrf-token", data: bytes.NewBufferString(c.csrfToken), - }, + }) } payloadWriter := multipart.NewWriter(&payloadBuffer) diff --git a/providers/supermicro/x11_firmware_bmc.go b/providers/supermicro/x11_firmware_bmc.go index 6dfbd2b4..39ec304a 100644 --- a/providers/supermicro/x11_firmware_bmc.go +++ b/providers/supermicro/x11_firmware_bmc.go @@ -106,18 +106,23 @@ func (c *x11) uploadBMCFirmware(ctx context.Context, fwReader io.Reader) error { var payloadBuffer bytes.Buffer var err error - formParts := []struct { + type form struct { name string data io.Reader - }{ + } + + formParts := []form{ { name: "fw_image", data: fwReader, }, - { + } + + if c.csrfToken != "" { + formParts = append(formParts, form{ name: "csrf-token", data: bytes.NewBufferString(c.csrfToken), - }, + }) } payloadWriter := multipart.NewWriter(&payloadBuffer)