github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/daemon/containerd/resolver.go (about) 1 package containerd 2 3 import ( 4 "context" 5 "crypto/tls" 6 "errors" 7 "net/http" 8 9 cerrdefs "github.com/containerd/containerd/errdefs" 10 "github.com/containerd/containerd/remotes" 11 "github.com/containerd/containerd/remotes/docker" 12 "github.com/containerd/containerd/version" 13 "github.com/containerd/log" 14 registrytypes "github.com/Prakhar-Agarwal-byte/moby/api/types/registry" 15 "github.com/Prakhar-Agarwal-byte/moby/dockerversion" 16 "github.com/Prakhar-Agarwal-byte/moby/pkg/useragent" 17 "github.com/Prakhar-Agarwal-byte/moby/registry" 18 ) 19 20 func (i *ImageService) newResolverFromAuthConfig(ctx context.Context, authConfig *registrytypes.AuthConfig) (remotes.Resolver, docker.StatusTracker) { 21 tracker := docker.NewInMemoryTracker() 22 23 hosts := hostsWrapper(i.registryHosts, authConfig, i.registryService) 24 headers := http.Header{} 25 headers.Set("User-Agent", dockerversion.DockerUserAgent(ctx, useragent.VersionInfo{Name: "containerd-client", Version: version.Version}, useragent.VersionInfo{Name: "storage-driver", Version: i.snapshotter})) 26 27 return docker.NewResolver(docker.ResolverOptions{ 28 Hosts: hosts, 29 Tracker: tracker, 30 Headers: headers, 31 }), tracker 32 } 33 34 func hostsWrapper(hostsFn docker.RegistryHosts, optAuthConfig *registrytypes.AuthConfig, regService RegistryConfigProvider) docker.RegistryHosts { 35 var authorizer docker.Authorizer 36 if optAuthConfig != nil { 37 authorizer = authorizerFromAuthConfig(*optAuthConfig) 38 } 39 40 return func(n string) ([]docker.RegistryHost, error) { 41 hosts, err := hostsFn(n) 42 if err != nil { 43 return nil, err 44 } 45 46 for i := range hosts { 47 if hosts[i].Authorizer == nil { 48 hosts[i].Authorizer = authorizer 49 isInsecure := regService.IsInsecureRegistry(hosts[i].Host) 50 if hosts[i].Client.Transport != nil && isInsecure { 51 hosts[i].Client.Transport = httpFallback{super: hosts[i].Client.Transport} 52 } 53 } 54 } 55 return hosts, nil 56 } 57 } 58 59 func authorizerFromAuthConfig(authConfig registrytypes.AuthConfig) docker.Authorizer { 60 cfgHost := registry.ConvertToHostname(authConfig.ServerAddress) 61 if cfgHost == "" || cfgHost == registry.IndexHostname { 62 cfgHost = registry.DefaultRegistryHost 63 } 64 65 if authConfig.RegistryToken != "" { 66 return &bearerAuthorizer{ 67 host: cfgHost, 68 bearer: authConfig.RegistryToken, 69 } 70 } 71 72 return docker.NewDockerAuthorizer(docker.WithAuthCreds(func(host string) (string, string, error) { 73 if cfgHost != host { 74 log.G(context.TODO()).WithFields(log.Fields{ 75 "host": host, 76 "cfgHost": cfgHost, 77 }).Warn("Host doesn't match") 78 return "", "", nil 79 } 80 if authConfig.IdentityToken != "" { 81 return "", authConfig.IdentityToken, nil 82 } 83 return authConfig.Username, authConfig.Password, nil 84 })) 85 } 86 87 type bearerAuthorizer struct { 88 host string 89 bearer string 90 } 91 92 func (a *bearerAuthorizer) Authorize(ctx context.Context, req *http.Request) error { 93 if req.Host != a.host { 94 log.G(ctx).WithFields(log.Fields{ 95 "host": req.Host, 96 "cfgHost": a.host, 97 }).Warn("Host doesn't match for bearer token") 98 return nil 99 } 100 101 req.Header.Set("Authorization", "Bearer "+a.bearer) 102 103 return nil 104 } 105 106 func (a *bearerAuthorizer) AddResponses(context.Context, []*http.Response) error { 107 // Return not implemented to prevent retry of the request when bearer did not succeed 108 return cerrdefs.ErrNotImplemented 109 } 110 111 type httpFallback struct { 112 super http.RoundTripper 113 } 114 115 func (f httpFallback) RoundTrip(r *http.Request) (*http.Response, error) { 116 resp, err := f.super.RoundTrip(r) 117 var tlsErr tls.RecordHeaderError 118 if errors.As(err, &tlsErr) && string(tlsErr.RecordHeader[:]) == "HTTP/" { 119 // server gave HTTP response to HTTPS client 120 plainHttpUrl := *r.URL 121 plainHttpUrl.Scheme = "http" 122 123 plainHttpRequest := *r 124 plainHttpRequest.URL = &plainHttpUrl 125 126 return http.DefaultTransport.RoundTrip(&plainHttpRequest) 127 } 128 129 return resp, err 130 }