@@ -32,6 +32,8 @@ type ClientConfig struct {
32
32
ServerFingerprint string `toml:"server-fingerprint" comment:"Configure manager certificate pinning\n Put here the manager's certificate fingerprint"`
33
33
Unsafe bool `toml:"unsafe" comment:"Allow unsafe HTTPS connection"`
34
34
MaxUploadSize int64 `toml:"max-upload-size" comment:"Maximum allowed upload size"`
35
+
36
+ localAddr string
35
37
}
36
38
37
39
// ManagerIP returns the IP address of the manager if any, returns nil otherwise
@@ -47,40 +49,70 @@ func (cc *ClientConfig) ManagerIP() net.IP {
47
49
return nil
48
50
}
49
51
52
+ func (cc * ClientConfig ) DialContext (ctx context.Context , network , addr string ) (con net.Conn , err error ) {
53
+ log .Infof ("Dial" )
54
+ dialer := net.Dialer {
55
+ Timeout : 30 * time .Second ,
56
+ KeepAlive : 30 * time .Second ,
57
+ DualStack : true ,
58
+ }
59
+ con , err = dialer .DialContext (ctx , network , addr )
60
+
61
+ if err == nil && con != nil {
62
+ if addr , ok := con .LocalAddr ().(* net.TCPAddr ); ok {
63
+ cc .localAddr = addr .IP .String ()
64
+ }
65
+ }
66
+
67
+ return
68
+ }
69
+
70
+ func (cc * ClientConfig ) DialTLSContext (ctx context.Context , network , addr string ) (net.Conn , error ) {
71
+
72
+ log .Infof ("Dial TLS" )
73
+ c , err := tls .Dial (network , addr , & tls.Config {InsecureSkipVerify : cc .Unsafe })
74
+
75
+ if err != nil {
76
+ return c , err
77
+ }
78
+
79
+ if c != nil {
80
+ if addr , ok := c .LocalAddr ().(* net.TCPAddr ); ok {
81
+ cc .localAddr = addr .IP .String ()
82
+ }
83
+ }
84
+
85
+ if cc .ServerFingerprint == "" {
86
+ return c , err
87
+ }
88
+
89
+ connstate := c .ConnectionState ()
90
+ for _ , peercert := range connstate .PeerCertificates {
91
+ der , err := x509 .MarshalPKIXPublicKey (peercert .PublicKey )
92
+ hash := data .Sha256 (der )
93
+ if err != nil {
94
+ return c , err
95
+ }
96
+
97
+ if hash == cc .ServerFingerprint {
98
+ return c , err
99
+ }
100
+ }
101
+ return c , fmt .Errorf ("server fingerprint not verified" )
102
+ }
103
+
50
104
// Transport creates an approriate HTTP transport from a configuration
51
105
// Cert pinning inspired by: https://medium.com/@zmanian/server-public-key-pinning-in-go-7a57bbe39438
52
106
func (cc * ClientConfig ) Transport () http.RoundTripper {
53
107
return & http.Transport {
54
108
Proxy : nil ,
55
- DialContext : (& net.Dialer {
109
+ /* DialContext: (&net.Dialer{
56
110
Timeout: 30 * time.Second,
57
111
KeepAlive: 30 * time.Second,
58
112
DualStack: true,
59
- }).DialContext ,
60
- DialTLSContext : func (ctx context.Context , network , addr string ) (net.Conn , error ) {
61
- c , err := tls .Dial (network , addr , & tls.Config {InsecureSkipVerify : cc .Unsafe })
62
-
63
- if err != nil {
64
- return c , err
65
- }
66
-
67
- if cc .ServerFingerprint == "" {
68
- return c , err
69
- }
70
- connstate := c .ConnectionState ()
71
- for _ , peercert := range connstate .PeerCertificates {
72
- der , err := x509 .MarshalPKIXPublicKey (peercert .PublicKey )
73
- hash := data .Sha256 (der )
74
- if err != nil {
75
- return c , err
76
- }
77
-
78
- if hash == cc .ServerFingerprint {
79
- return c , err
80
- }
81
- }
82
- return c , fmt .Errorf ("server fingerprint not verified" )
83
- },
113
+ }).DialContext,*/
114
+ DialContext : cc .DialContext ,
115
+ DialTLSContext : cc .DialTLSContext ,
84
116
MaxIdleConns : 100 ,
85
117
IdleConnTimeout : 90 * time .Second ,
86
118
TLSHandshakeTimeout : 10 * time .Second ,
@@ -90,7 +122,7 @@ func (cc *ClientConfig) Transport() http.RoundTripper {
90
122
91
123
// ManagerClient structure definition
92
124
type ManagerClient struct {
93
- config ClientConfig
125
+ config * ClientConfig
94
126
ManagerIP net.IP
95
127
96
128
HTTPClient http.Client
@@ -124,7 +156,7 @@ func NewManagerClient(c *ClientConfig) (*ManagerClient, error) {
124
156
125
157
mc := & ManagerClient {
126
158
HTTPClient : http.Client {Transport : tpt },
127
- config : * c ,
159
+ config : c ,
128
160
ManagerIP : c .ManagerIP (),
129
161
}
130
162
@@ -158,6 +190,8 @@ func (m *ManagerClient) Prepare(method, url string, body io.Reader) (*http.Reque
158
190
if err == nil {
159
191
r .Header .Add ("User-Agent" , UserAgent )
160
192
r .Header .Add ("Hostname" , Hostname )
193
+ // the address used by the client to connect to the manager
194
+ r .Header .Add ("IP" , m .config .localAddr )
161
195
r .Header .Add ("UUID" , m .config .UUID )
162
196
r .Header .Add ("Api-Key" , m .config .Key )
163
197
}
0 commit comments