n3dr icon indicating copy to clipboard operation
n3dr copied to clipboard

n3dr repositoryV2 fails to download artifacts from Nexus 3 with self-signed certificate though --insecureSkipVerify given

Open FFock opened this issue 2 years ago • 3 comments

Although the --insecureSkipVerify option is given and the ca.crt file contains the CA of the self-signed certificate, the API calls to Nexus 3 using the http.DefaultTransport are working, the ArtifactV2 download is not working with throwing the following error:

x509: certificate signed by unknown authority

goroutine 51 [running]:
github.com/030/n3dr/internal/app/n3dr/artifactsv2.(*Nexus3).downloadIfChecksumMismatchLocalFile.func1(0xc000742480)
        /go/n3dr/internal/app/n3dr/artifactsv2/download.go:148 +0x3e5
created by github.com/030/n3dr/internal/app/n3dr/artifactsv2.(*Nexus3).downloadIfChecksumMismatchLocalFile
        /go/n3dr/internal/app/n3dr/artifactsv2/download.go:126 +0x2b8

It seems that the download.go file needs to be fixed as follows:

func (n *Nexus3) download(checksum, downloadedFileChecksum string, asset *models.AssetXO) error {
	if checksum != downloadedFileChecksum {
		log.WithFields(log.Fields{
			"actual":   downloadedFileChecksum,
			"url":      asset.DownloadURL,
			"expected": checksum,
			"insecureSkipVerify": insecureSkipVerify,
		}).Debug("download artifact as checksum deviates")

		req, err := http.NewRequest("GET", asset.DownloadURL, nil)
		if err != nil {
			return err
		}
		req.SetBasicAuth(n.User, n.Pass)

		retryClient := retryablehttp.NewClient()
		retryClient.Logger = nil
		retryClient.RetryMax = 10
		if insecureSkipVerify {
		    tr := &http.Transport{
		        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
                    }
		    retryClient.HTTPClient.Transport = tr
		}
		standardClient := retryClient.StandardClient()
...

But I have no idea if that is sufficient and how to get the bool "insecureSkipVerify" from the main.go into this download.go.

Any ideas?

FFock avatar Nov 09 '22 17:11 FFock

@FFock The insecureSkipVerify resides in the main package https://github.com/030/n3dr/blob/main/cmd/n3dr/root.go#L214 and can be passed by adding it to the struct https://github.com/030/n3dr/blob/main/cmd/n3dr/repositoriesV2.go#L51

If you add a insecureSkipVerify key to the struct https://github.com/030/n3dr/blob/main/internal/app/n3dr/connection/connection.go#L10, it should be possible to add it in the repositoriesV2.go file and to pass it to the download part.

Could you create a PR?

030 avatar Nov 14 '22 13:11 030

I tried to fix it with the code below (managed to get the global variable DisableTlsCertificateVerification correctly set and derived from the insecureSkipVerify in main. So that is working, but the download does not work at all. There is no error message, but the download does not work either. I will not be able to work on this issue for some weeks. So I have to stop here for now but maybe this snippet helps a little bit to sort out where the root cause is.

func (n *Nexus3) download(checksum, downloadedFileChecksum string, asset *models.AssetXO) error {
	if checksum != downloadedFileChecksum {
		log.WithFields(log.Fields{
			"actual":   downloadedFileChecksum,
			"url":      asset.DownloadURL,
			"expected": checksum,
			"disableTlsCertificateVerification": DisableTlsCertificateVerification,
		}).Debug("download artifact as checksum deviates")

		req, err := http.NewRequest("GET", asset.DownloadURL, nil)
		if err != nil {
			return err
		}
		req.SetBasicAuth(n.User, n.Pass)

		retryClient := retryablehttp.NewClient()
		retryClient.Logger = nil
		retryClient.RetryMax = 10
		if DisableTlsCertificateVerification {
		    tr := &http.Transport{
                        Proxy: http.ProxyFromEnvironment,
                        DialContext: (&net.Dialer{
                                Timeout:   30 * time.Second,
                                KeepAlive: 30 * time.Second,
                                DualStack: true,
                        }).DialContext,
                        MaxIdleConns:          100,
                        IdleConnTimeout:       90 * time.Second,
                        TLSHandshakeTimeout:   10 * time.Second,
                        ExpectContinueTimeout: 1 * time.Second,
                        ForceAttemptHTTP2:     true,
                        MaxIdleConnsPerHost:   runtime.GOMAXPROCS(0) + 1,
                        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		    }
		retryClient.HTTPClient.Transport = tr
		}
		standardClient := retryClient.StandardClient()

		dir := filepath.Dir(asset.Path)
		if err := os.MkdirAll(filepath.Join(n.DownloadDirName, asset.Repository, dir), chmodDir); err != nil {
			return err
		}

		dst, err := os.Create(filepath.Join(n.DownloadDirName, asset.Repository, asset.Path))
		if err != nil {
			return err
		}
		defer func() {
			if err := dst.Close(); err != nil {
				panic(err)
			}
		}()
		resp, err := standardClient.Do(req)
		if err != nil {
			return err
		}
		defer func() {
			if err := resp.Body.Close(); err != nil {
				panic(err)
			}
		}()

		if resp.StatusCode != http.StatusOK {
			err := fmt.Errorf("bad status: %s", resp.Status)
			return err
		}
		_, err = io.Copy(dst, resp.Body)
		if err != nil {
			return err
		}
		if err := dst.Sync(); err != nil {
			return err
		}

		artifacts.PrintType(asset.Format)
	}
	return nil
}

FFock avatar Nov 23 '22 08:11 FFock

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jan 16 '23 04:01 stale[bot]