github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/ca/forward.go (about) 1 package ca 2 3 import ( 4 "context" 5 6 "google.golang.org/grpc/metadata" 7 "google.golang.org/grpc/peer" 8 ) 9 10 const ( 11 certForwardedKey = "forwarded_cert" 12 certCNKey = "forwarded_cert_cn" 13 certOUKey = "forwarded_cert_ou" 14 certOrgKey = "forwarded_cert_org" 15 remoteAddrKey = "remote_addr" 16 ) 17 18 // forwardedTLSInfoFromContext obtains forwarded TLS CN/OU from the grpc.MD 19 // object in ctx. 20 func forwardedTLSInfoFromContext(ctx context.Context) (remoteAddr string, cn string, org string, ous []string) { 21 md, _ := metadata.FromIncomingContext(ctx) 22 if len(md[remoteAddrKey]) != 0 { 23 remoteAddr = md[remoteAddrKey][0] 24 } 25 if len(md[certCNKey]) != 0 { 26 cn = md[certCNKey][0] 27 } 28 if len(md[certOrgKey]) != 0 { 29 org = md[certOrgKey][0] 30 } 31 ous = md[certOUKey] 32 return 33 } 34 35 func isForwardedRequest(ctx context.Context) bool { 36 md, _ := metadata.FromIncomingContext(ctx) 37 if len(md[certForwardedKey]) != 1 { 38 return false 39 } 40 return md[certForwardedKey][0] == "true" 41 } 42 43 // WithMetadataForwardTLSInfo reads certificate from context and returns context where 44 // ForwardCert is set based on original certificate. 45 func WithMetadataForwardTLSInfo(ctx context.Context) (context.Context, error) { 46 md, ok := metadata.FromIncomingContext(ctx) 47 if !ok { 48 md = metadata.MD{} 49 } 50 51 ous := []string{} 52 org := "" 53 cn := "" 54 55 certSubj, err := certSubjectFromContext(ctx) 56 if err == nil { 57 cn = certSubj.CommonName 58 ous = certSubj.OrganizationalUnit 59 if len(certSubj.Organization) > 0 { 60 org = certSubj.Organization[0] 61 } 62 } 63 64 // If there's no TLS cert, forward with blank TLS metadata. 65 // Note that the presence of this blank metadata is extremely 66 // important. Without it, it would look like manager is making 67 // the request directly. 68 md[certForwardedKey] = []string{"true"} 69 md[certCNKey] = []string{cn} 70 md[certOrgKey] = []string{org} 71 md[certOUKey] = ous 72 peer, ok := peer.FromContext(ctx) 73 if ok { 74 md[remoteAddrKey] = []string{peer.Addr.String()} 75 } 76 77 return metadata.NewOutgoingContext(ctx, md), nil 78 }