Skip to content

Commit

Permalink
Add SHA-256 support to RPC digest auth
Browse files Browse the repository at this point in the history
  • Loading branch information
rojer committed Apr 13, 2021
1 parent cdf002b commit d884ce1
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 28 deletions.
12 changes: 7 additions & 5 deletions common/mgrpc/frame/frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,13 @@ type Command struct {
}

type FrameAuth struct {
Realm string `json:"realm"`
Username string `json:"username"`
Nonce int `json:"nonce"`
CNonce int `json:"cnonce"`
Response string `json:"response"`
Realm string `json:"realm"`
Username string `json:"username"`
Nonce int `json:"nonce"`
CNonce int `json:"cnonce"`
Algorithm string `json:"algorithm,omitempty"`
Response string `json:"response"`
Opaque string `json:"opaque,omitempty"`
}

// Trace groups optional call tracing info.
Expand Down
65 changes: 42 additions & 23 deletions common/mgrpc/mgrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"crypto/md5"
"crypto/rand"
"crypto/sha256"
"crypto/tls"
"encoding/hex"
"encoding/json"
Expand Down Expand Up @@ -77,10 +78,12 @@ type req struct {
}

type authErrorMsg struct {
AuthType string `json:"auth_type"`
Nonce int `json:"nonce"`
NC int `json:"nc"`
Realm string `json:"realm"`
AuthType string `json:"auth_type"`
Nonce int `json:"nonce"`
NC int `json:"nc"`
Realm string `json:"realm"`
Algorithm string `json:"algorithm,omitempty"`
Opaque string `json:"opaque,omitempty"`
}

const tcpKeepAliveInterval = 3 * time.Minute
Expand Down Expand Up @@ -425,20 +428,25 @@ func (r *mgRPCImpl) Call(
cnonce := int(cnonceBig.Int64())

// Compute resp
resp := mkMd5Resp(
resp, err := mkDigestResp(
"dummy_method", "dummy_uri", username, authMsg.Realm, passwd,
authMsg.Nonce, authMsg.NC, cnonce, "auth",
authMsg.Algorithm, authMsg.Nonce, authMsg.NC, cnonce, "auth",
)
if err != nil {
return nil, errors.Trace(err)
}

cmdWithAuth := *cmd
cmdWithAuth.Auth = &frame.FrameAuth{
Realm: authMsg.Realm,
Nonce: authMsg.Nonce,
Username: username,
CNonce: cnonce,
Response: resp,
Realm: authMsg.Realm,
Nonce: authMsg.Nonce,
Username: username,
CNonce: cnonce,
Algorithm: authMsg.Algorithm,
Response: resp,
Opaque: authMsg.Opaque,
}
glog.V(2).Infof("resending cmd %d with auth added: %v", cmd.ID, cmdWithAuth)
glog.V(2).Infof("resending cmd %d with auth added: %+v", cmd.ID, cmdWithAuth)
return r.Call(ctx, dst, &cmdWithAuth, getCreds)

default:
Expand Down Expand Up @@ -479,18 +487,29 @@ func (r *mgRPCImpl) SetCodecOptions(opts *codec.Options) error {
return r.codec.SetOptions(opts)
}

func mkMd5Resp(method, uri, username, realm, passwd string, nonce, nc, cnonce int, qop string) string {
ha1Arr := md5.Sum([]byte(fmt.Sprintf("%s:%s:%s", username, realm, passwd)))
ha1 := hex.EncodeToString(ha1Arr[:])
func mkDigestResp(method, uri, username, realm, passwd, algorithm string, nonce, nc, cnonce int, qop string) (string, error) {

hashFunc := func(data []byte) []byte {
s := md5.Sum(data)
return s[:]
}
switch algorithm {
case "":
case "MD5":
case "SHA-256":
hashFunc = func(data []byte) []byte {
s := sha256.Sum256(data)
return s[:]
}
default:
return "", fmt.Errorf("unknown digest algorithm %q", algorithm)
}

ha1 := hex.EncodeToString(hashFunc([]byte(fmt.Sprintf("%s:%s:%s", username, realm, passwd))))

ha2Arr := md5.Sum([]byte(fmt.Sprintf("%s:%s", method, uri)))
ha2 := hex.EncodeToString(ha2Arr[:])
ha2 := hex.EncodeToString(hashFunc([]byte(fmt.Sprintf("%s:%s", method, uri))))

respArr := md5.Sum([]byte(fmt.Sprintf(
"%s:%d:%d:%d:%s:%s",
ha1, nonce, nc, cnonce, "auth", ha2,
)))
resp := hex.EncodeToString(respArr[:])
resp := hex.EncodeToString(hashFunc([]byte(fmt.Sprintf("%s:%d:%d:%d:%s:%s", ha1, nonce, nc, cnonce, qop, ha2))))

return resp
return resp, nil
}

0 comments on commit d884ce1

Please sign in to comment.