podman

Форк
0
115 строк · 2.9 Кб
1
// Copyright 2014 go-dockerclient authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
//
5
// The content is borrowed from Docker's own source code to provide a simple
6
// tls based dialer
7

8
package docker
9

10
import (
11
	"crypto/tls"
12
	"errors"
13
	"net"
14
	"strings"
15
	"time"
16
)
17

18
type tlsClientCon struct {
19
	*tls.Conn
20
	rawConn net.Conn
21
}
22

23
func (c *tlsClientCon) CloseWrite() error {
24
	// Go standard tls.Conn doesn't provide the CloseWrite() method so we do it
25
	// on its underlying connection.
26
	if cwc, ok := c.rawConn.(interface {
27
		CloseWrite() error
28
	}); ok {
29
		return cwc.CloseWrite()
30
	}
31
	return nil
32
}
33

34
func tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Config) (net.Conn, error) {
35
	// We want the Timeout and Deadline values from dialer to cover the
36
	// whole process: TCP connection and TLS handshake. This means that we
37
	// also need to start our own timers now.
38
	timeout := dialer.Timeout
39

40
	if !dialer.Deadline.IsZero() {
41
		deadlineTimeout := time.Until(dialer.Deadline)
42
		if timeout == 0 || deadlineTimeout < timeout {
43
			timeout = deadlineTimeout
44
		}
45
	}
46

47
	var errChannel chan error
48

49
	if timeout != 0 {
50
		errChannel = make(chan error, 2)
51
		time.AfterFunc(timeout, func() {
52
			errChannel <- errors.New("")
53
		})
54
	}
55

56
	rawConn, err := dialer.Dial(network, addr)
57
	if err != nil {
58
		return nil, err
59
	}
60

61
	colonPos := strings.LastIndex(addr, ":")
62
	if colonPos == -1 {
63
		colonPos = len(addr)
64
	}
65
	hostname := addr[:colonPos]
66

67
	// If no ServerName is set, infer the ServerName
68
	// from the hostname we're connecting to.
69
	if config.ServerName == "" {
70
		// Make a copy to avoid polluting argument or default.
71
		config = copyTLSConfig(config)
72
		config.ServerName = hostname
73
	}
74

75
	conn := tls.Client(rawConn, config)
76

77
	if timeout == 0 {
78
		err = conn.Handshake()
79
	} else {
80
		go func() {
81
			errChannel <- conn.Handshake()
82
		}()
83

84
		err = <-errChannel
85
	}
86

87
	if err != nil {
88
		rawConn.Close()
89
		return nil, err
90
	}
91

92
	// This is Docker difference with standard's crypto/tls package: returned a
93
	// wrapper which holds both the TLS and raw connections.
94
	return &tlsClientCon{conn, rawConn}, nil
95
}
96

97
// this exists to silent an error message in go vet
98
func copyTLSConfig(cfg *tls.Config) *tls.Config {
99
	return &tls.Config{
100
		Certificates:           cfg.Certificates,
101
		CipherSuites:           cfg.CipherSuites,
102
		ClientAuth:             cfg.ClientAuth,
103
		ClientCAs:              cfg.ClientCAs,
104
		ClientSessionCache:     cfg.ClientSessionCache,
105
		CurvePreferences:       cfg.CurvePreferences,
106
		InsecureSkipVerify:     cfg.InsecureSkipVerify,
107
		MaxVersion:             cfg.MaxVersion,
108
		MinVersion:             cfg.MinVersion,
109
		NextProtos:             cfg.NextProtos,
110
		Rand:                   cfg.Rand,
111
		RootCAs:                cfg.RootCAs,
112
		ServerName:             cfg.ServerName,
113
		SessionTicketsDisabled: cfg.SessionTicketsDisabled,
114
	}
115
}
116

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.