handshake failure(2-way ssl support for oci pull)

pull/10807/head^2
suryatech27-cloud 4 years ago
parent 8ab18f7567
commit e813d1397f

@ -19,7 +19,11 @@ package tlsutil
import ( import (
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"fmt"
"io/ioutil"
"os" "os"
"path/filepath"
"runtime"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -56,3 +60,89 @@ func ClientConfig(opts Options) (cfg *tls.Config, err error) {
cfg = &tls.Config{InsecureSkipVerify: opts.InsecureSkipVerify, Certificates: []tls.Certificate{*cert}, RootCAs: pool} cfg = &tls.Config{InsecureSkipVerify: opts.InsecureSkipVerify, Certificates: []tls.Certificate{*cert}, RootCAs: pool}
return cfg, nil return cfg, nil
} }
func ReadCertFromSecDir(cfgFileBaseName string, host string) (opts Options, err error) {
if runtime.GOOS == "windows" || runtime.GOOS == "unix" {
fmt.Printf("%v OS not supported for this oci pull. Contact your administrator for more information !!!", runtime.GOOS)
} else {
var clientCertDir = "/etc/docker/certs.d/"
/* var fileName = helmpath.ConfigPath(cfgFileBaseName)
data, err := ioutil.ReadFile(fileName)
if err != nil {
fmt.Printf("Config file not exist %v\n", err)
}
var configDataMap map[string]map[string]interface{}
err = json.Unmarshal(data, &configDataMap)
if err != nil {
fmt.Printf("Please do login before initiating the pull : %v", err)
}
keys := reflect.ValueOf(configDataMap["auths"]).MapKeys()
strkeys := make([]string, len(keys))
for i := 0; i < len(keys); i++ {
strkeys[i] = keys[i].String()
}
//fmt.Print(strings.Join(strkeys, ","))
strkey := strings.Join(strkeys, "") */
clientCertDir = clientCertDir + host
if _, err := os.Stat(clientCertDir); err != nil {
if os.IsNotExist(err) {
os.MkdirAll(clientCertDir, os.ModePerm)
return opts, errors.Wrapf(err, "Client Certificate Directory Not Exist !! \n %v Directory created.", clientCertDir)
}
} else {
if files, err := ioutil.ReadDir(clientCertDir); err == nil {
for _, file := range files {
if filepath.Ext(file.Name()) == ".crt" {
opts.CaCertFile = clientCertDir + "/" + file.Name()
//fmt.Printf("cafile: %v\n", opts.CaCertFile)
} else if filepath.Ext(file.Name()) == ".pem" {
opts.CertFile = clientCertDir + "/" + file.Name()
//fmt.Printf("certFile: %v\n", opts.CertFile)
} else if filepath.Ext(file.Name()) == ".key" {
opts.KeyFile = clientCertDir + "/" + file.Name()
//fmt.Printf("keyFile: %v\n", opts.KeyFile)
}
}
} else {
fmt.Printf(" Certificate not found in current directory - %v\n ", err)
os.Exit(1)
}
if opts.CaCertFile == "" && opts.CertFile == "" && opts.KeyFile == "" {
fmt.Printf("Error Certificate (cacerts.crt,client.pem,client.key) required : Client authentication failed due to certificate not present in cert directory !! \n")
os.Exit(1)
}
if opts.CaCertFile == "" && opts.CertFile == "" {
fmt.Printf("Error Certificate Required : Root-CA and client certificate (cacerts.crt,client.pem) not found.\n")
os.Exit(1)
}
if opts.CaCertFile == "" && opts.KeyFile == "" {
fmt.Printf("Error Certificate Required : Root-CA and and client keyfie (cacerts.crt,client.key) not found.\n")
os.Exit(1)
}
if opts.CertFile == "" && opts.KeyFile == "" {
fmt.Printf("Error Certificate Required : Client certificate and client keyfile (client.pem,client.key) not found.\n")
os.Exit(1)
}
if opts.CaCertFile == "" {
fmt.Printf("Error Certificate Required : Client Root-CA (cacerts.crt) not found.\n")
os.Exit(1)
} else if opts.CertFile == "" {
fmt.Printf("Error Certificate Required : Client certificate(client.pem) not found.\n")
os.Exit(1)
} else if opts.KeyFile == "" {
fmt.Printf("Error Certificate Required : Client keyfile (client.key) not found.\n")
os.Exit(1)
}
}
}
return opts, nil
}

@ -125,7 +125,23 @@ func (p *Pull) Run(chartRef string) (string, error) {
saved, v, err := c.DownloadTo(chartRef, p.Version, dest) saved, v, err := c.DownloadTo(chartRef, p.Version, dest)
if err != nil { if err != nil {
return out.String(), err registryClient, err := registry.NewCrosClient(chartRef,
registry.ClientOptDebug(p.Settings.Debug),
registry.ClientOptCredentialsFile(p.Settings.RegistryConfig),
registry.ClientOptWriter(&out),
)
if err != nil {
return out.String(), err
}
c.Options = append(c.Options,
getter.WithRegistryClient(registryClient),
getter.WithTagName(p.Version))
saved, v, err = c.DownloadTo(chartRef, p.Version, dest)
if err != nil {
return out.String(), err
}
} }
if p.Verify { if p.Verify {

@ -22,9 +22,11 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net"
"net/http" "net/http"
"sort" "sort"
"strings" "strings"
"time"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes"
@ -38,6 +40,8 @@ import (
registryremote "oras.land/oras-go/pkg/registry/remote" registryremote "oras.land/oras-go/pkg/registry/remote"
registryauth "oras.land/oras-go/pkg/registry/remote/auth" registryauth "oras.land/oras-go/pkg/registry/remote/auth"
"helm.sh/helm/v3/internal/tlsutil"
"helm.sh/helm/v3/internal/urlutil"
"helm.sh/helm/v3/internal/version" "helm.sh/helm/v3/internal/version"
"helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/helmpath" "helm.sh/helm/v3/pkg/helmpath"
@ -131,6 +135,94 @@ func NewClient(options ...ClientOption) (*Client, error) {
return client, nil return client, nil
} }
func NewCrosClient(chartref string, options ...ClientOption) (*Client, error) {
client := &Client{
out: ioutil.Discard,
}
for _, option := range options {
option(client)
}
if client.credentialsFile == "" {
client.credentialsFile = helmpath.ConfigPath(CredentialsFileBasename)
}
if client.authorizer == nil {
authClient, err := dockerauth.NewClientWithDockerFallback(client.credentialsFile)
if err != nil {
return nil, err
}
client.authorizer = authClient
}
if client.resolver == nil {
host, err := urlutil.ExtractHostname(chartref)
if err != nil {
}
clientOpts, err := tlsutil.ReadCertFromSecDir(CredentialsFileBasename, host)
if err != nil {
return client, errors.Wrapf(err, "Client certificate/directory Not Exist !!")
}
cfgtls, err := tlsutil.ClientConfig(clientOpts)
if err != nil {
fmt.Printf("error :%v\n", err)
}
var rt http.RoundTripper = &http.Transport{
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 30 * time.Second,
TLSClientConfig: cfgtls,
ResponseHeaderTimeout: time.Duration(3 * time.Second),
DisableKeepAlives: true,
}
crosclient := http.Client{Transport: rt, Timeout: 30 * time.Second}
headers := http.Header{}
headers.Set("User-Agent", version.GetUserAgent())
opts := []auth.ResolverOption{auth.WithResolverHeaders(headers), auth.WithResolverClient(&crosclient)}
resolver, err := client.authorizer.ResolverWithOpts(opts...)
if err != nil {
return nil, err
}
client.resolver = resolver
}
if client.registryAuthorizer == nil {
client.registryAuthorizer = &registryauth.Client{
Header: http.Header{
"User-Agent": {version.GetUserAgent()},
},
Cache: registryauth.DefaultCache,
Credential: func(ctx context.Context, reg string) (registryauth.Credential, error) {
dockerClient, ok := client.authorizer.(*dockerauth.Client)
if !ok {
return registryauth.EmptyCredential, errors.New("unable to obtain docker client")
}
username, password, err := dockerClient.Credential(reg)
if err != nil {
return registryauth.EmptyCredential, errors.New("unable to retrieve credentials")
}
// A blank returned username and password value is a bearer token
if username == "" && password != "" {
return registryauth.Credential{
RefreshToken: password,
}, nil
}
return registryauth.Credential{
Username: username,
Password: password,
}, nil
},
}
}
return client, nil
}
// ClientOptDebug returns a function that sets the debug setting on client options set // ClientOptDebug returns a function that sets the debug setting on client options set
func ClientOptDebug(debug bool) ClientOption { func ClientOptDebug(debug bool) ClientOption {
return func(client *Client) { return func(client *Client) {

Loading…
Cancel
Save