Переглянути джерело

Merge pull request #27383 from runcom/authz-peercerts

pkg/authorization: send request's TLS peer certificates to plugins
Sebastiaan van Stijn 8 роки тому
батько
коміт
16f6b3e8a9
2 змінених файлів з 41 додано та 0 видалено
  1. 34 0
      pkg/authorization/api.go
  2. 7 0
      pkg/authorization/authz.go

+ 34 - 0
pkg/authorization/api.go

@@ -1,5 +1,11 @@
 package authorization
 
+import (
+	"crypto/x509"
+	"encoding/json"
+	"encoding/pem"
+)
+
 const (
 	// AuthZApiRequest is the url for daemon request authorization
 	AuthZApiRequest = "AuthZPlugin.AuthZReq"
@@ -11,6 +17,31 @@ const (
 	AuthZApiImplements = "authz"
 )
 
+// PeerCertificate is a wrapper around x509.Certificate which provides a sane
+// enconding/decoding to/from PEM format and JSON.
+type PeerCertificate x509.Certificate
+
+// MarshalJSON returns the JSON encoded pem bytes of a PeerCertificate.
+func (pc *PeerCertificate) MarshalJSON() ([]byte, error) {
+	b := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: pc.Raw})
+	return json.Marshal(b)
+}
+
+// UnmarshalJSON populates a new PeerCertificate struct from JSON data.
+func (pc *PeerCertificate) UnmarshalJSON(b []byte) error {
+	var buf []byte
+	if err := json.Unmarshal(b, &buf); err != nil {
+		return err
+	}
+	derBytes, _ := pem.Decode(buf)
+	c, err := x509.ParseCertificate(derBytes.Bytes)
+	if err != nil {
+		return err
+	}
+	*pc = PeerCertificate(*c)
+	return nil
+}
+
 // Request holds data required for authZ plugins
 type Request struct {
 	// User holds the user extracted by AuthN mechanism
@@ -31,6 +62,9 @@ type Request struct {
 	// RequestHeaders stores the raw request headers sent to the docker daemon
 	RequestHeaders map[string]string `json:"RequestHeaders,omitempty"`
 
+	// RequestPeerCertificates stores the request's TLS peer certificates in PEM format
+	RequestPeerCertificates []*PeerCertificate `json:"RequestPeerCertificates,omitempty"`
+
 	// ResponseStatusCode stores the status code returned from docker daemon
 	ResponseStatusCode int `json:"ResponseStatusCode,omitempty"`
 

+ 7 - 0
pkg/authorization/authz.go

@@ -78,6 +78,13 @@ func (ctx *Ctx) AuthZRequest(w http.ResponseWriter, r *http.Request) error {
 		RequestHeaders:  headers(r.Header),
 	}
 
+	if r.TLS != nil {
+		for _, c := range r.TLS.PeerCertificates {
+			pc := PeerCertificate(*c)
+			ctx.authReq.RequestPeerCertificates = append(ctx.authReq.RequestPeerCertificates, &pc)
+		}
+	}
+
 	for i, plugin := range ctx.plugins {
 		logrus.Debugf("AuthZ request using plugin %s", plugin.Name())