nd002test/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cacerts/handler.go

69 lines
1.9 KiB
Go

package cacerts
import (
"crypto/hmac"
"crypto/sha256"
"crypto/sha512"
"encoding/base64"
"net/http"
"strings"
apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3"
v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3"
"github.com/rancher/rancher/pkg/settings"
"github.com/rancher/rancher/pkg/tls"
)
var (
tokenHash = "tokenByHash"
)
func Handler(clusterRegistrationToken v3.ClusterRegistrationTokenCache) http.HandlerFunc {
clusterRegistrationToken.AddIndexer(tokenHash, func(obj *apimgmtv3.ClusterRegistrationToken) ([]string, error) {
if obj.Status.Token == "" {
return nil, nil
}
hash := sha256.Sum256([]byte(obj.Status.Token))
return []string{base64.StdEncoding.EncodeToString(hash[:])}, nil
})
return func(rw http.ResponseWriter, req *http.Request) {
handler(clusterRegistrationToken, rw, req)
}
}
func handler(clusterRegistrationToken v3.ClusterRegistrationTokenCache, rw http.ResponseWriter, req *http.Request) {
ca := settings.CACerts.Get()
if v, ok := req.Context().Value(tls.InternalAPI).(bool); ok && v {
ca = settings.InternalCACerts.Get()
}
rw.Header().Set("Content-Type", "text/plain")
var bytes []byte
if strings.TrimSpace(ca) != "" {
if !strings.HasSuffix(ca, "\n") {
ca += "\n"
}
bytes = []byte(ca)
}
nonce := req.Header.Get("X-Cattle-Nonce")
authorization := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
if authorization != "" && nonce != "" {
crt, err := clusterRegistrationToken.GetByIndex(tokenHash, authorization)
if err == nil && len(crt) >= 0 {
digest := hmac.New(sha512.New, []byte(crt[0].Status.Token))
digest.Write([]byte(nonce))
digest.Write([]byte{0})
digest.Write(bytes)
digest.Write([]byte{0})
hash := digest.Sum(nil)
rw.Header().Set("X-Cattle-Hash", base64.StdEncoding.EncodeToString(hash))
}
}
if len(bytes) > 0 {
_, _ = rw.Write([]byte(ca))
}
}