Merge lp:~pedronis/ubuntu-push/http-ssl into lp:ubuntu-push/automatic
- http-ssl
- Merge into automatic
Proposed by
Samuele Pedroni
Status: | Merged |
---|---|
Approved by: | Samuele Pedroni |
Approved revision: | 328 |
Merged at revision: | 333 |
Proposed branch: | lp:~pedronis/ubuntu-push/http-ssl |
Merge into: | lp:ubuntu-push/automatic |
Diff against target: |
655 lines (+198/-138) 17 files modified
client/session/session_test.go (+4/-25) sampleconfigs/dev.json (+1/-1) server/acceptance/acceptance_test.go (+1/-1) server/acceptance/ssl/README (+1/-1) server/acceptance/ssl/testing.cert (+7/-7) server/acceptance/ssl/testing.key (+7/-7) server/acceptance/suites/broadcast.go (+1/-1) server/acceptance/suites/suite.go (+1/-1) server/config_test.go (+12/-11) server/dev/server.go (+2/-2) server/listener/listener.go (+4/-13) server/listener/listener_test.go (+9/-17) server/runner_devices.go (+2/-29) server/runner_http.go (+6/-1) server/runner_test.go (+45/-6) server/tlsconfig.go (+53/-0) testing/tls.go (+42/-15) |
To merge this branch: | bzr merge lp:~pedronis/ubuntu-push/http-ssl |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Guillermo Gonzalez | Approve | ||
Review via email:
|
Commit message
- let the http runner serve over tls optionally
- more realistic testing cert/key
- review how we setup tls in tests
Description of the change
- let the http runner serve over tls optionally
- more realistic testing cert/key
- review how we setup tls in tests
To post a comment you must log in.
- 327. By Samuele Pedroni
-
comment tweak
- 328. By Samuele Pedroni
-
fix, thanks verterok
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'client/session/session_test.go' |
2 | --- client/session/session_test.go 2014-08-26 16:05:28 +0000 |
3 | +++ client/session/session_test.go 2014-09-04 19:21:18 +0000 |
4 | @@ -1489,14 +1489,7 @@ |
5 | |
6 | func (cs *clientSessionSuite) TestDialBadServerName(c *C) { |
7 | // a borked server name |
8 | - cert, err := tls.X509KeyPair(helpers.TestCertPEMBlock, helpers.TestKeyPEMBlock) |
9 | - c.Assert(err, IsNil) |
10 | - tlsCfg := &tls.Config{ |
11 | - Certificates: []tls.Certificate{cert}, |
12 | - SessionTicketsDisabled: true, |
13 | - } |
14 | - |
15 | - lst, err := tls.Listen("tcp", "localhost:0", tlsCfg) |
16 | + lst, err := tls.Listen("tcp", "localhost:0", helpers.TestTLSServerConfig) |
17 | c.Assert(err, IsNil) |
18 | // advertise |
19 | ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
20 | @@ -1541,19 +1534,12 @@ |
21 | |
22 | func (cs *clientSessionSuite) TestDialWorks(c *C) { |
23 | // happy path thoughts |
24 | - cert, err := tls.X509KeyPair(helpers.TestCertPEMBlock, helpers.TestKeyPEMBlock) |
25 | - c.Assert(err, IsNil) |
26 | - tlsCfg := &tls.Config{ |
27 | - Certificates: []tls.Certificate{cert}, |
28 | - SessionTicketsDisabled: true, |
29 | - } |
30 | - |
31 | - lst, err := tls.Listen("tcp", "localhost:0", tlsCfg) |
32 | + lst, err := tls.Listen("tcp", "localhost:0", helpers.TestTLSServerConfig) |
33 | c.Assert(err, IsNil) |
34 | // advertise |
35 | ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
36 | b, err := json.Marshal(map[string]interface{}{ |
37 | - "domain": "localhost", |
38 | + "domain": "push-delivery", |
39 | "hosts": []string{"nowhere", lst.Addr().String()}, |
40 | }) |
41 | if err != nil { |
42 | @@ -1649,14 +1635,7 @@ |
43 | |
44 | func (cs *clientSessionSuite) TestDialWorksDirect(c *C) { |
45 | // happy path thoughts |
46 | - cert, err := tls.X509KeyPair(helpers.TestCertPEMBlock, helpers.TestKeyPEMBlock) |
47 | - c.Assert(err, IsNil) |
48 | - tlsCfg := &tls.Config{ |
49 | - Certificates: []tls.Certificate{cert}, |
50 | - SessionTicketsDisabled: true, |
51 | - } |
52 | - |
53 | - lst, err := tls.Listen("tcp", "localhost:0", tlsCfg) |
54 | + lst, err := tls.Listen("tcp", "localhost:0", helpers.TestTLSServerConfig) |
55 | c.Assert(err, IsNil) |
56 | sess, err := NewSession(lst.Addr().String(), dialTestConf, "wah", cs.lvls, cs.log) |
57 | c.Assert(err, IsNil) |
58 | |
59 | === modified file 'sampleconfigs/dev.json' |
60 | --- sampleconfigs/dev.json 2014-07-15 17:14:07 +0000 |
61 | +++ sampleconfigs/dev.json 2014-09-04 19:21:18 +0000 |
62 | @@ -10,5 +10,5 @@ |
63 | "http_read_timeout": "5s", |
64 | "http_write_timeout": "5s", |
65 | "max_notifications_per_app": 25, |
66 | - "delivery_domain": "localhost" |
67 | + "delivery_domain": "push-delivery" |
68 | } |
69 | |
70 | === modified file 'server/acceptance/acceptance_test.go' |
71 | --- server/acceptance/acceptance_test.go 2014-05-02 09:56:49 +0000 |
72 | +++ server/acceptance/acceptance_test.go 2014-09-04 19:21:18 +0000 |
73 | @@ -34,7 +34,7 @@ |
74 | cfg := make(map[string]interface{}) |
75 | suites.FillServerConfig(cfg, addr) |
76 | suites.FillHTTPServerConfig(cfg, httpAddr) |
77 | - cfg["delivery_domain"] = "localhost" |
78 | + cfg["delivery_domain"] = "push-delivery" |
79 | return cfg |
80 | } |
81 | |
82 | |
83 | === modified file 'server/acceptance/ssl/README' |
84 | --- server/acceptance/ssl/README 2014-02-21 16:17:28 +0000 |
85 | +++ server/acceptance/ssl/README 2014-09-04 19:21:18 +0000 |
86 | @@ -3,6 +3,6 @@ |
87 | |
88 | Generated with: |
89 | |
90 | - go run /usr/lib/go/src/pkg/crypto/tls/generate_cert.go -ca -host localhost -rsa-bits 512 -duration 87600h |
91 | + go run /usr/lib/go/src/pkg/crypto/tls/generate_cert.go -ca -host push-delivery -rsa-bits 512 -duration 87600h |
92 | |
93 | and then renamed. |
94 | |
95 | === modified file 'server/acceptance/ssl/testing.cert' |
96 | --- server/acceptance/ssl/testing.cert 2014-01-14 15:35:20 +0000 |
97 | +++ server/acceptance/ssl/testing.cert 2014-09-04 19:21:18 +0000 |
98 | @@ -1,10 +1,10 @@ |
99 | -----BEGIN CERTIFICATE----- |
100 | MIIBYzCCAQ+gAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD |
101 | -bzAeFw0xMzEyMTkyMDU1NDNaFw0yMzEyMTcyMDU1NDNaMBIxEDAOBgNVBAoTB0Fj |
102 | -bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAPw+niki17X2qALE2A2AzE1q5dvK |
103 | -9CI4OduRtT9IgbFLC6psqAT21NA+QbY17nWSSpyP65zkMkwKXrbDzstwLPkCAwEA |
104 | -AaNUMFIwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud |
105 | -EwEB/wQFMAMBAf8wGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMAsGCSqGSIb3 |
106 | -DQEBBQNBAFqiVI+Km2XPSO+pxITaPvhmuzg+XG3l1+2di3gL+HlDobocjBqRctRU |
107 | -YySO32W07acjGJmCHUKpCJuq9X8hpmk= |
108 | +bzAeFw0xNDA4MjkxMjQyMDFaFw0yNDA4MjYxMjQyMDFaMBIxEDAOBgNVBAoTB0Fj |
109 | +bWUgQ28wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA1FT6lkow0eky+Dnj2Z4nTrTF |
110 | +DgcKOt9Wr4B4gRH1bWmRqScOPxyHA5YodN7O1w8X8sdWko9puf59I1sWWr5LNwID |
111 | +AQABo1IwUDAOBgNVHQ8BAf8EBAMCAKQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYD |
112 | +VR0TAQH/BAUwAwEB/zAYBgNVHREEETAPgg1wdXNoLWRlbGl2ZXJ5MAsGCSqGSIb3 |
113 | +DQEBBQNBABtWCdMFkhIO8+oM3vugOWle9WJZ1FCRWD+cMl76mI1lhmNF4lvEZG47 |
114 | +xUjekA1+heU39WpOEzZSybrOdiEaGbI= |
115 | -----END CERTIFICATE----- |
116 | |
117 | === modified file 'server/acceptance/ssl/testing.key' |
118 | --- server/acceptance/ssl/testing.key 2014-01-14 15:35:20 +0000 |
119 | +++ server/acceptance/ssl/testing.key 2014-09-04 19:21:18 +0000 |
120 | @@ -1,9 +1,9 @@ |
121 | -----BEGIN RSA PRIVATE KEY----- |
122 | -MIIBPAIBAAJBAPw+niki17X2qALE2A2AzE1q5dvK9CI4OduRtT9IgbFLC6psqAT2 |
123 | -1NA+QbY17nWSSpyP65zkMkwKXrbDzstwLPkCAwEAAQJAKwXbIBULScP6QA6m8xam |
124 | -wgWbkvN41GVWqPafPV32kPBvKwSc+M1e+JR7g3/xPZE7TCELcfYi4yXEHZZI3Pbh |
125 | -oQIhAP/UsgJbsfH1GFv8Y8qGl5l/kmwwkwHhuKvEC87Yur9FAiEA/GlQv3ZfaXnT |
126 | -lcCFT0aL02O0RDiRYyMUG/JAZQJs6CUCIQCHO5SZYIUwxIGK5mCNxxXOAzyQSiD7 |
127 | -hqkKywf+4FvfDQIhALa0TLyqJFom0t7c4iIGAIRc8UlIYQSPiajI64+x9775AiEA |
128 | -0v4fgSK/Rq059zW1753JjuB6aR0Uh+3RqJII4dUR1Wg= |
129 | +MIIBOgIBAAJBANRU+pZKMNHpMvg549meJ060xQ4HCjrfVq+AeIER9W1pkaknDj8c |
130 | +hwOWKHTeztcPF/LHVpKPabn+fSNbFlq+SzcCAwEAAQJBAIOO+4xu/3yv/rKqO7C0 |
131 | +Oyqa+pVMa1w60R0AfqmKFQTqiTgevM77uqjpW1+t0hpK20nyj6MUIPaL+9kZgp7t |
132 | +mnECIQDqw79PXSzudf10XGy9ve5bRazINHxQYgJ7FvlTT6JhdQIhAOeJxq9zcKni |
133 | +69ueO1ualz0hn8w6uHPsG9FlZ8C+7Jh7AiAWJgebjjfZ+4nA+6NKt2uQct9dOA5u |
134 | +awC+6ij1ojK4rQIgNEqAbcWDj0qpe8sLms+aEntSjJxCZiPP0IW3XeeApZsCIDwo |
135 | +x+YyxXQWJlf9L5TNYPRo+KFEdk3Cew0lv6QNs+xe |
136 | -----END RSA PRIVATE KEY----- |
137 | |
138 | === modified file 'server/acceptance/suites/broadcast.go' |
139 | --- server/acceptance/suites/broadcast.go 2014-08-15 09:33:48 +0000 |
140 | +++ server/acceptance/suites/broadcast.go 2014-09-04 19:21:18 +0000 |
141 | @@ -261,7 +261,7 @@ |
142 | host, err := gh.Get() |
143 | c.Assert(err, IsNil) |
144 | expected := &gethosts.Host{ |
145 | - Domain: "localhost", |
146 | + Domain: "push-delivery", |
147 | Hosts: []string{s.ServerAddr}, |
148 | } |
149 | c.Check(host, DeepEquals, expected) |
150 | |
151 | === modified file 'server/acceptance/suites/suite.go' |
152 | --- server/acceptance/suites/suite.go 2014-08-27 21:19:51 +0000 |
153 | +++ server/acceptance/suites/suite.go 2014-09-04 19:21:18 +0000 |
154 | @@ -111,7 +111,7 @@ |
155 | } |
156 | |
157 | func testClientSession(addr string, deviceId, model, imageChannel string, reportPings bool) *acceptance.ClientSession { |
158 | - tlsConfig, err := kit.MakeTLSConfig("", false, helpers.SourceRelative("../ssl/testing.cert"), "") |
159 | + tlsConfig, err := kit.MakeTLSConfig("push-delivery", false, helpers.SourceRelative("../ssl/testing.cert"), "") |
160 | if err != nil { |
161 | panic(fmt.Sprintf("could not read ssl/testing.cert: %v", err)) |
162 | } |
163 | |
164 | === modified file 'server/config_test.go' |
165 | --- server/config_test.go 2014-02-10 23:19:08 +0000 |
166 | +++ server/config_test.go 2014-09-04 19:21:18 +0000 |
167 | @@ -26,6 +26,7 @@ |
168 | . "launchpad.net/gocheck" |
169 | |
170 | "launchpad.net/ubuntu-push/config" |
171 | + helpers "launchpad.net/ubuntu-push/testing" |
172 | ) |
173 | |
174 | type configSuite struct{} |
175 | @@ -52,22 +53,22 @@ |
176 | c.Check(cfg.Addr(), Equals, "127.0.0.1:9999") |
177 | } |
178 | |
179 | -func (s *configSuite) TestDevicesParsedConfigLoadFinish(c *C) { |
180 | +func (s *configSuite) TestTLSParsedConfigLoadPEMs(c *C) { |
181 | tmpDir := c.MkDir() |
182 | - cfg := &DevicesParsedConfig{ |
183 | + cfg := &TLSParsedConfig{ |
184 | ParsedKeyPEMFile: "key.key", |
185 | ParsedCertPEMFile: "cert.cert", |
186 | } |
187 | - err := cfg.FinishLoad(tmpDir) |
188 | + err := cfg.LoadPEMs(tmpDir) |
189 | c.Check(err, ErrorMatches, "reading key_pem_file:.*no such file.*") |
190 | - err = ioutil.WriteFile(filepath.Join(tmpDir, "key.key"), []byte("KeY"), os.ModePerm) |
191 | + err = ioutil.WriteFile(filepath.Join(tmpDir, "key.key"), helpers.TestKeyPEMBlock, os.ModePerm) |
192 | c.Assert(err, IsNil) |
193 | - err = cfg.FinishLoad(tmpDir) |
194 | + err = cfg.LoadPEMs(tmpDir) |
195 | c.Check(err, ErrorMatches, "reading cert_pem_file:.*no such file.*") |
196 | - err = ioutil.WriteFile(filepath.Join(tmpDir, "cert.cert"), []byte("CeRt"), os.ModePerm) |
197 | - c.Assert(err, IsNil) |
198 | - err = cfg.FinishLoad(tmpDir) |
199 | - c.Assert(err, IsNil) |
200 | - c.Check(string(cfg.KeyPEMBlock()), Equals, "KeY") |
201 | - c.Check(string(cfg.CertPEMBlock()), Equals, "CeRt") |
202 | + err = ioutil.WriteFile(filepath.Join(tmpDir, "cert.cert"), helpers.TestCertPEMBlock, os.ModePerm) |
203 | + c.Assert(err, IsNil) |
204 | + err = cfg.LoadPEMs(tmpDir) |
205 | + c.Assert(err, IsNil) |
206 | + tlsCfg := cfg.TLSServerConfig() |
207 | + c.Check(tlsCfg.Certificates, HasLen, 1) |
208 | } |
209 | |
210 | === modified file 'server/dev/server.go' |
211 | --- server/dev/server.go 2014-07-08 15:08:52 +0000 |
212 | +++ server/dev/server.go 2014-09-04 19:21:18 +0000 |
213 | @@ -64,7 +64,7 @@ |
214 | if err != nil { |
215 | server.BootLogFatalf("reading config: %v", err) |
216 | } |
217 | - err = cfg.DevicesParsedConfig.FinishLoad(filepath.Dir(cfgFpaths[len(cfgFpaths)-1])) |
218 | + err = cfg.DevicesParsedConfig.LoadPEMs(filepath.Dir(cfgFpaths[len(cfgFpaths)-1])) |
219 | if err != nil { |
220 | server.BootLogFatalf("reading config: %v", err) |
221 | } |
222 | @@ -95,7 +95,7 @@ |
223 | }) |
224 | }) |
225 | handler := api.PanicTo500Handler(mux, logger) |
226 | - go server.HTTPServeRunner(nil, handler, &cfg.HTTPServeParsedConfig)() |
227 | + go server.HTTPServeRunner(nil, handler, &cfg.HTTPServeParsedConfig, nil)() |
228 | // listen for device connections |
229 | server.DevicesRunner(lst, func(conn net.Conn) error { |
230 | track := session.NewTracker(logger) |
231 | |
232 | === modified file 'server/listener/listener.go' |
233 | --- server/listener/listener.go 2014-03-06 19:21:44 +0000 |
234 | +++ server/listener/listener.go 2014-09-04 19:21:18 +0000 |
235 | @@ -30,10 +30,8 @@ |
236 | type DeviceListenerConfig interface { |
237 | // Addr to listen on. |
238 | Addr() string |
239 | - // TLS key |
240 | - KeyPEMBlock() []byte |
241 | - // TLS cert |
242 | - CertPEMBlock() []byte |
243 | + // TLS config |
244 | + TLSServerConfig() *tls.Config |
245 | } |
246 | |
247 | // DeviceListener listens and setup sessions from device connections. |
248 | @@ -52,15 +50,8 @@ |
249 | return nil, err |
250 | } |
251 | } |
252 | - cert, err := tls.X509KeyPair(cfg.CertPEMBlock(), cfg.KeyPEMBlock()) |
253 | - if err != nil { |
254 | - return nil, err |
255 | - } |
256 | - tlsCfg := &tls.Config{ |
257 | - Certificates: []tls.Certificate{cert}, |
258 | - SessionTicketsDisabled: true, |
259 | - } |
260 | - return &DeviceListener{tls.NewListener(lst, tlsCfg)}, err |
261 | + tlsCfg := cfg.TLSServerConfig() |
262 | + return &DeviceListener{tls.NewListener(lst, tlsCfg)}, nil |
263 | } |
264 | |
265 | // handleTemporary checks and handles if the error is just a temporary network |
266 | |
267 | === modified file 'server/listener/listener_test.go' |
268 | --- server/listener/listener_test.go 2014-08-04 14:47:00 +0000 |
269 | +++ server/listener/listener_test.go 2014-09-04 19:21:18 +0000 |
270 | @@ -18,7 +18,6 @@ |
271 | |
272 | import ( |
273 | "crypto/tls" |
274 | - "crypto/x509" |
275 | "net" |
276 | "os/exec" |
277 | "regexp" |
278 | @@ -68,12 +67,8 @@ |
279 | return cfg.addr |
280 | } |
281 | |
282 | -func (cfg *testDevListenerCfg) KeyPEMBlock() []byte { |
283 | - return helpers.TestKeyPEMBlock |
284 | -} |
285 | - |
286 | -func (cfg *testDevListenerCfg) CertPEMBlock() []byte { |
287 | - return helpers.TestCertPEMBlock |
288 | +func (cfg *testDevListenerCfg) TLSServerConfig() *tls.Config { |
289 | + return helpers.TestTLSServerConfig |
290 | } |
291 | |
292 | func (s *listenerSuite) TestDeviceListen(c *C) { |
293 | @@ -130,11 +125,8 @@ |
294 | return err |
295 | } |
296 | |
297 | -func testTlsDial(c *C, addr string) (net.Conn, error) { |
298 | - cp := x509.NewCertPool() |
299 | - ok := cp.AppendCertsFromPEM((&testDevListenerCfg{}).CertPEMBlock()) |
300 | - c.Assert(ok, Equals, true) |
301 | - return tls.Dial("tcp", addr, &tls.Config{RootCAs: cp}) |
302 | +func testTlsDial(addr string) (net.Conn, error) { |
303 | + return tls.Dial("tcp", addr, helpers.TestTLSClientConfig) |
304 | } |
305 | |
306 | func testWriteByte(c *C, conn net.Conn, toWrite uint32) { |
307 | @@ -159,11 +151,11 @@ |
308 | errCh <- lst.AcceptLoop(testSession, s.testlog) |
309 | }() |
310 | listenerAddr := lst.Addr().String() |
311 | - conn1, err := testTlsDial(c, listenerAddr) |
312 | + conn1, err := testTlsDial(listenerAddr) |
313 | c.Assert(err, IsNil) |
314 | defer conn1.Close() |
315 | testWriteByte(c, conn1, '1') |
316 | - conn2, err := testTlsDial(c, listenerAddr) |
317 | + conn2, err := testTlsDial(listenerAddr) |
318 | c.Assert(err, IsNil) |
319 | defer conn2.Close() |
320 | testWriteByte(c, conn2, '2') |
321 | @@ -203,7 +195,7 @@ |
322 | res, err := cmd.Output() |
323 | c.Assert(err, IsNil) |
324 | c.Assert(string(res), Matches, "(?s).*timed out.*") |
325 | - conn2, err := testTlsDial(c, listenerAddr) |
326 | + conn2, err := testTlsDial(listenerAddr) |
327 | c.Assert(err, IsNil) |
328 | defer conn2.Close() |
329 | testWriteByte(c, conn2, '2') |
330 | @@ -225,7 +217,7 @@ |
331 | }, s.testlog) |
332 | }() |
333 | listenerAddr := lst.Addr().String() |
334 | - _, err = testTlsDial(c, listenerAddr) |
335 | + _, err = testTlsDial(listenerAddr) |
336 | c.Assert(err, Not(IsNil)) |
337 | lst.Close() |
338 | c.Check(<-errCh, ErrorMatches, ".*use of closed.*") |
339 | @@ -244,7 +236,7 @@ |
340 | }() |
341 | listenerAddr := lst.Addr().String() |
342 | c.Check(listenerAddr, Equals, foreignLst.Addr().String()) |
343 | - conn1, err := testTlsDial(c, listenerAddr) |
344 | + conn1, err := testTlsDial(listenerAddr) |
345 | c.Assert(err, IsNil) |
346 | defer conn1.Close() |
347 | testWriteByte(c, conn1, '1') |
348 | |
349 | === modified file 'server/runner_devices.go' |
350 | --- server/runner_devices.go 2014-03-12 12:34:18 +0000 |
351 | +++ server/runner_devices.go 2014-09-04 19:21:18 +0000 |
352 | @@ -17,7 +17,6 @@ |
353 | package server |
354 | |
355 | import ( |
356 | - "fmt" |
357 | "net" |
358 | "syscall" |
359 | "time" |
360 | @@ -36,26 +35,8 @@ |
361 | ParsedSessionQueueSize config.ConfigQueueSize `json:"session_queue_size"` |
362 | ParsedBrokerQueueSize config.ConfigQueueSize `json:"broker_queue_size"` |
363 | // device listener configuration |
364 | - ParsedAddr config.ConfigHostPort `json:"addr"` |
365 | - ParsedKeyPEMFile string `json:"key_pem_file"` |
366 | - ParsedCertPEMFile string `json:"cert_pem_file"` |
367 | - // private post-processed config |
368 | - certPEMBlock []byte |
369 | - keyPEMBlock []byte |
370 | -} |
371 | - |
372 | -func (cfg *DevicesParsedConfig) FinishLoad(baseDir string) error { |
373 | - keyPEMBlock, err := config.LoadFile(cfg.ParsedKeyPEMFile, baseDir) |
374 | - if err != nil { |
375 | - return fmt.Errorf("reading key_pem_file: %v", err) |
376 | - } |
377 | - certPEMBlock, err := config.LoadFile(cfg.ParsedCertPEMFile, baseDir) |
378 | - if err != nil { |
379 | - return fmt.Errorf("reading cert_pem_file: %v", err) |
380 | - } |
381 | - cfg.keyPEMBlock = keyPEMBlock |
382 | - cfg.certPEMBlock = certPEMBlock |
383 | - return nil |
384 | + ParsedAddr config.ConfigHostPort `json:"addr"` |
385 | + TLSParsedConfig |
386 | } |
387 | |
388 | func (cfg *DevicesParsedConfig) PingInterval() time.Duration { |
389 | @@ -78,14 +59,6 @@ |
390 | return cfg.ParsedAddr.HostPort() |
391 | } |
392 | |
393 | -func (cfg *DevicesParsedConfig) KeyPEMBlock() []byte { |
394 | - return cfg.keyPEMBlock |
395 | -} |
396 | - |
397 | -func (cfg *DevicesParsedConfig) CertPEMBlock() []byte { |
398 | - return cfg.certPEMBlock |
399 | -} |
400 | - |
401 | // DevicesRunner returns a function to accept device connections. |
402 | // If adoptLst is not nil it will be used as the underlying listener, instead |
403 | // of creating one, wrapped in a TLS layer. |
404 | |
405 | === modified file 'server/runner_http.go' |
406 | --- server/runner_http.go 2014-03-25 19:02:18 +0000 |
407 | +++ server/runner_http.go 2014-09-04 19:21:18 +0000 |
408 | @@ -17,6 +17,7 @@ |
409 | package server |
410 | |
411 | import ( |
412 | + "crypto/tls" |
413 | "net" |
414 | "net/http" |
415 | |
416 | @@ -32,7 +33,8 @@ |
417 | |
418 | // HTTPServeRunner returns a function to serve HTTP requests. |
419 | // If httpLst is not nil it will be used as the underlying listener. |
420 | -func HTTPServeRunner(httpLst net.Listener, h http.Handler, parsedCfg *HTTPServeParsedConfig) func() { |
421 | +// If tlsCfg is not nit server over TLS with the config. |
422 | +func HTTPServeRunner(httpLst net.Listener, h http.Handler, parsedCfg *HTTPServeParsedConfig, tlsCfg *tls.Config) func() { |
423 | if httpLst == nil { |
424 | var err error |
425 | httpLst, err = net.Listen("tcp", parsedCfg.ParsedHTTPAddr.HostPort()) |
426 | @@ -46,6 +48,9 @@ |
427 | ReadTimeout: parsedCfg.ParsedHTTPReadTimeout.TimeDuration(), |
428 | WriteTimeout: parsedCfg.ParsedHTTPWriteTimeout.TimeDuration(), |
429 | } |
430 | + if tlsCfg != nil { |
431 | + httpLst = tls.NewListener(httpLst, tlsCfg) |
432 | + } |
433 | return func() { |
434 | err := srv.Serve(httpLst) |
435 | if err != nil { |
436 | |
437 | === modified file 'server/runner_test.go' |
438 | --- server/runner_test.go 2014-03-25 19:02:18 +0000 |
439 | +++ server/runner_test.go 2014-09-04 19:21:18 +0000 |
440 | @@ -17,6 +17,7 @@ |
441 | package server |
442 | |
443 | import ( |
444 | + "crypto/tls" |
445 | "fmt" |
446 | "io/ioutil" |
447 | "net" |
448 | @@ -68,7 +69,7 @@ |
449 | func (s *runnerSuite) TestHTTPServeRunner(c *C) { |
450 | errCh := make(chan interface{}, 1) |
451 | h := http.HandlerFunc(testHandle) |
452 | - runner := HTTPServeRunner(nil, h, &testHTTPServeParsedConfig) |
453 | + runner := HTTPServeRunner(nil, h, &testHTTPServeParsedConfig, nil) |
454 | c.Assert(s.lst, Not(IsNil)) |
455 | defer s.lst.Close() |
456 | c.Check(s.kind, Equals, "http") |
457 | @@ -89,16 +90,25 @@ |
458 | c.Check(<-errCh, Matches, "accepting http connections:.*closed.*") |
459 | } |
460 | |
461 | +func cert() tls.Certificate { |
462 | + cert, err := tls.X509KeyPair(helpers.TestCertPEMBlock, helpers.TestKeyPEMBlock) |
463 | + if err != nil { |
464 | + panic(err) |
465 | + } |
466 | + return cert |
467 | +} |
468 | + |
469 | var testDevicesParsedConfig = DevicesParsedConfig{ |
470 | ParsedPingInterval: config.ConfigTimeDuration{60 * time.Second}, |
471 | ParsedExchangeTimeout: config.ConfigTimeDuration{10 * time.Second}, |
472 | ParsedBrokerQueueSize: config.ConfigQueueSize(1000), |
473 | ParsedSessionQueueSize: config.ConfigQueueSize(10), |
474 | ParsedAddr: "127.0.0.1:0", |
475 | - ParsedKeyPEMFile: "", |
476 | - ParsedCertPEMFile: "", |
477 | - keyPEMBlock: helpers.TestKeyPEMBlock, |
478 | - certPEMBlock: helpers.TestCertPEMBlock, |
479 | + TLSParsedConfig: TLSParsedConfig{ |
480 | + ParsedKeyPEMFile: "", |
481 | + ParsedCertPEMFile: "", |
482 | + cert: cert(), |
483 | + }, |
484 | } |
485 | |
486 | func (s *runnerSuite) TestDevicesRunner(c *C) { |
487 | @@ -135,7 +145,36 @@ |
488 | lst0, err := net.Listen("tcp", "127.0.0.1:0") |
489 | c.Assert(err, IsNil) |
490 | defer lst0.Close() |
491 | - HTTPServeRunner(lst0, nil, &testHTTPServeParsedConfig) |
492 | + HTTPServeRunner(lst0, nil, &testHTTPServeParsedConfig, nil) |
493 | c.Assert(s.lst, Equals, lst0) |
494 | c.Check(s.kind, Equals, "http") |
495 | } |
496 | + |
497 | +func (s *runnerSuite) TestHTTPServeRunnerTLS(c *C) { |
498 | + errCh := make(chan interface{}, 1) |
499 | + h := http.HandlerFunc(testHandle) |
500 | + runner := HTTPServeRunner(nil, h, &testHTTPServeParsedConfig, helpers.TestTLSServerConfig) |
501 | + c.Assert(s.lst, Not(IsNil)) |
502 | + defer s.lst.Close() |
503 | + c.Check(s.kind, Equals, "http") |
504 | + go func() { |
505 | + defer func() { |
506 | + errCh <- recover() |
507 | + }() |
508 | + runner() |
509 | + }() |
510 | + cli := http.Client{ |
511 | + Transport: &http.Transport{ |
512 | + TLSClientConfig: helpers.TestTLSClientConfig, |
513 | + }, |
514 | + } |
515 | + resp, err := cli.Get(fmt.Sprintf("https://%s/", s.lst.Addr())) |
516 | + c.Assert(err, IsNil) |
517 | + defer resp.Body.Close() |
518 | + c.Assert(resp.StatusCode, Equals, 200) |
519 | + body, err := ioutil.ReadAll(resp.Body) |
520 | + c.Assert(err, IsNil) |
521 | + c.Check(string(body), Equals, "yay!\n") |
522 | + s.lst.Close() |
523 | + c.Check(<-errCh, Matches, "accepting http connections:.*closed.*") |
524 | +} |
525 | |
526 | === added file 'server/tlsconfig.go' |
527 | --- server/tlsconfig.go 1970-01-01 00:00:00 +0000 |
528 | +++ server/tlsconfig.go 2014-09-04 19:21:18 +0000 |
529 | @@ -0,0 +1,53 @@ |
530 | +/* |
531 | + Copyright 2013-2014 Canonical Ltd. |
532 | + |
533 | + This program is free software: you can redistribute it and/or modify it |
534 | + under the terms of the GNU General Public License version 3, as published |
535 | + by the Free Software Foundation. |
536 | + |
537 | + This program is distributed in the hope that it will be useful, but |
538 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
539 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
540 | + PURPOSE. See the GNU General Public License for more details. |
541 | + |
542 | + You should have received a copy of the GNU General Public License along |
543 | + with this program. If not, see <http://www.gnu.org/licenses/>. |
544 | +*/ |
545 | + |
546 | +package server |
547 | + |
548 | +import ( |
549 | + "crypto/tls" |
550 | + "fmt" |
551 | + |
552 | + "launchpad.net/ubuntu-push/config" |
553 | +) |
554 | + |
555 | +// A TLSParsedConfig holds and can be used to parse a tls server config. |
556 | +type TLSParsedConfig struct { |
557 | + ParsedKeyPEMFile string `json:"key_pem_file"` |
558 | + ParsedCertPEMFile string `json:"cert_pem_file"` |
559 | + // private post-processed config |
560 | + cert tls.Certificate |
561 | +} |
562 | + |
563 | +func (cfg *TLSParsedConfig) LoadPEMs(baseDir string) error { |
564 | + keyPEMBlock, err := config.LoadFile(cfg.ParsedKeyPEMFile, baseDir) |
565 | + if err != nil { |
566 | + return fmt.Errorf("reading key_pem_file: %v", err) |
567 | + } |
568 | + certPEMBlock, err := config.LoadFile(cfg.ParsedCertPEMFile, baseDir) |
569 | + if err != nil { |
570 | + return fmt.Errorf("reading cert_pem_file: %v", err) |
571 | + } |
572 | + cfg.cert, err = tls.X509KeyPair(certPEMBlock, keyPEMBlock) |
573 | + return err |
574 | +} |
575 | + |
576 | +func (cfg *TLSParsedConfig) TLSServerConfig() *tls.Config { |
577 | + tlsCfg := &tls.Config{ |
578 | + Certificates: []tls.Certificate{cfg.cert}, |
579 | + SessionTicketsDisabled: true, |
580 | + } |
581 | + return tlsCfg |
582 | +} |
583 | |
584 | === modified file 'testing/tls.go' |
585 | --- testing/tls.go 2014-01-21 21:36:07 +0000 |
586 | +++ testing/tls.go 2014-09-04 19:21:18 +0000 |
587 | @@ -16,26 +16,53 @@ |
588 | |
589 | package testing |
590 | |
591 | -// key&cert generated with go run /usr/lib/go/src/pkg/crypto/tls/generate_cert.go -ca -host localhost -rsa-bits 512 -duration 87600h |
592 | +import ( |
593 | + "crypto/tls" |
594 | + "crypto/x509" |
595 | +) |
596 | + |
597 | +// key&cert generated with go run /usr/lib/go/src/pkg/crypto/tls/generate_cert.go -ca -host push-delivery -rsa-bits 512 -duration 87600h |
598 | var ( |
599 | TestKeyPEMBlock = []byte(`-----BEGIN RSA PRIVATE KEY----- |
600 | -MIIBPAIBAAJBAPw+niki17X2qALE2A2AzE1q5dvK9CI4OduRtT9IgbFLC6psqAT2 |
601 | -1NA+QbY17nWSSpyP65zkMkwKXrbDzstwLPkCAwEAAQJAKwXbIBULScP6QA6m8xam |
602 | -wgWbkvN41GVWqPafPV32kPBvKwSc+M1e+JR7g3/xPZE7TCELcfYi4yXEHZZI3Pbh |
603 | -oQIhAP/UsgJbsfH1GFv8Y8qGl5l/kmwwkwHhuKvEC87Yur9FAiEA/GlQv3ZfaXnT |
604 | -lcCFT0aL02O0RDiRYyMUG/JAZQJs6CUCIQCHO5SZYIUwxIGK5mCNxxXOAzyQSiD7 |
605 | -hqkKywf+4FvfDQIhALa0TLyqJFom0t7c4iIGAIRc8UlIYQSPiajI64+x9775AiEA |
606 | -0v4fgSK/Rq059zW1753JjuB6aR0Uh+3RqJII4dUR1Wg= |
607 | +MIIBOgIBAAJBANRU+pZKMNHpMvg549meJ060xQ4HCjrfVq+AeIER9W1pkaknDj8c |
608 | +hwOWKHTeztcPF/LHVpKPabn+fSNbFlq+SzcCAwEAAQJBAIOO+4xu/3yv/rKqO7C0 |
609 | +Oyqa+pVMa1w60R0AfqmKFQTqiTgevM77uqjpW1+t0hpK20nyj6MUIPaL+9kZgp7t |
610 | +mnECIQDqw79PXSzudf10XGy9ve5bRazINHxQYgJ7FvlTT6JhdQIhAOeJxq9zcKni |
611 | +69ueO1ualz0hn8w6uHPsG9FlZ8C+7Jh7AiAWJgebjjfZ+4nA+6NKt2uQct9dOA5u |
612 | +awC+6ij1ojK4rQIgNEqAbcWDj0qpe8sLms+aEntSjJxCZiPP0IW3XeeApZsCIDwo |
613 | +x+YyxXQWJlf9L5TNYPRo+KFEdk3Cew0lv6QNs+xe |
614 | -----END RSA PRIVATE KEY-----`) |
615 | |
616 | TestCertPEMBlock = []byte(`-----BEGIN CERTIFICATE----- |
617 | MIIBYzCCAQ+gAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD |
618 | -bzAeFw0xMzEyMTkyMDU1NDNaFw0yMzEyMTcyMDU1NDNaMBIxEDAOBgNVBAoTB0Fj |
619 | -bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAPw+niki17X2qALE2A2AzE1q5dvK |
620 | -9CI4OduRtT9IgbFLC6psqAT21NA+QbY17nWSSpyP65zkMkwKXrbDzstwLPkCAwEA |
621 | -AaNUMFIwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud |
622 | -EwEB/wQFMAMBAf8wGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMAsGCSqGSIb3 |
623 | -DQEBBQNBAFqiVI+Km2XPSO+pxITaPvhmuzg+XG3l1+2di3gL+HlDobocjBqRctRU |
624 | -YySO32W07acjGJmCHUKpCJuq9X8hpmk= |
625 | +bzAeFw0xNDA4MjkxMjQyMDFaFw0yNDA4MjYxMjQyMDFaMBIxEDAOBgNVBAoTB0Fj |
626 | +bWUgQ28wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA1FT6lkow0eky+Dnj2Z4nTrTF |
627 | +DgcKOt9Wr4B4gRH1bWmRqScOPxyHA5YodN7O1w8X8sdWko9puf59I1sWWr5LNwID |
628 | +AQABo1IwUDAOBgNVHQ8BAf8EBAMCAKQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYD |
629 | +VR0TAQH/BAUwAwEB/zAYBgNVHREEETAPgg1wdXNoLWRlbGl2ZXJ5MAsGCSqGSIb3 |
630 | +DQEBBQNBABtWCdMFkhIO8+oM3vugOWle9WJZ1FCRWD+cMl76mI1lhmNF4lvEZG47 |
631 | +xUjekA1+heU39WpOEzZSybrOdiEaGbI= |
632 | -----END CERTIFICATE-----`) |
633 | ) |
634 | + |
635 | +// test tls server & client config |
636 | +var TestTLSServerConfig, TestTLSClientConfig *tls.Config |
637 | + |
638 | +func init() { |
639 | + cert, err := tls.X509KeyPair(TestCertPEMBlock, TestKeyPEMBlock) |
640 | + if err != nil { |
641 | + panic(err) |
642 | + } |
643 | + TestTLSServerConfig = &tls.Config{ |
644 | + Certificates: []tls.Certificate{cert}, |
645 | + } |
646 | + cp := x509.NewCertPool() |
647 | + ok := cp.AppendCertsFromPEM(TestCertPEMBlock) |
648 | + if !ok { |
649 | + panic("failed to parse test cert") |
650 | + } |
651 | + TestTLSClientConfig = &tls.Config{ |
652 | + RootCAs: cp, |
653 | + ServerName: "push-delivery", |
654 | + } |
655 | +} |
looks good.