Merge lp:~pedronis/ubuntu-push/http-ssl into lp:ubuntu-push

Proposed by Samuele Pedroni
Status: Superseded
Proposed branch: lp:~pedronis/ubuntu-push/http-ssl
Merge into: lp:ubuntu-push
Diff against target: 864 lines (+252/-206)
20 files modified
client/session/session_test.go (+4/-25)
debian/ubuntu-push-client.conf (+4/-0)
docs/highlevel.txt (+25/-34)
docs/lowlevel.txt (+25/-34)
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
Reviewer Review Type Date Requested Status
Ubuntu Push Hackers Pending
Review via email: mp+233402@code.launchpad.net

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.
lp:~pedronis/ubuntu-push/http-ssl updated
327. By Samuele Pedroni

comment tweak

328. By Samuele Pedroni

fix, thanks verterok

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'client/session/session_test.go'
--- client/session/session_test.go 2014-08-26 16:05:28 +0000
+++ client/session/session_test.go 2014-09-04 17:51:30 +0000
@@ -1489,14 +1489,7 @@
14891489
1490func (cs *clientSessionSuite) TestDialBadServerName(c *C) {1490func (cs *clientSessionSuite) TestDialBadServerName(c *C) {
1491 // a borked server name1491 // a borked server name
1492 cert, err := tls.X509KeyPair(helpers.TestCertPEMBlock, helpers.TestKeyPEMBlock)1492 lst, err := tls.Listen("tcp", "localhost:0", helpers.TestTLSServerConfig)
1493 c.Assert(err, IsNil)
1494 tlsCfg := &tls.Config{
1495 Certificates: []tls.Certificate{cert},
1496 SessionTicketsDisabled: true,
1497 }
1498
1499 lst, err := tls.Listen("tcp", "localhost:0", tlsCfg)
1500 c.Assert(err, IsNil)1493 c.Assert(err, IsNil)
1501 // advertise1494 // advertise
1502 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {1495 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -1541,19 +1534,12 @@
15411534
1542func (cs *clientSessionSuite) TestDialWorks(c *C) {1535func (cs *clientSessionSuite) TestDialWorks(c *C) {
1543 // happy path thoughts1536 // happy path thoughts
1544 cert, err := tls.X509KeyPair(helpers.TestCertPEMBlock, helpers.TestKeyPEMBlock)1537 lst, err := tls.Listen("tcp", "localhost:0", helpers.TestTLSServerConfig)
1545 c.Assert(err, IsNil)
1546 tlsCfg := &tls.Config{
1547 Certificates: []tls.Certificate{cert},
1548 SessionTicketsDisabled: true,
1549 }
1550
1551 lst, err := tls.Listen("tcp", "localhost:0", tlsCfg)
1552 c.Assert(err, IsNil)1538 c.Assert(err, IsNil)
1553 // advertise1539 // advertise
1554 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {1540 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1555 b, err := json.Marshal(map[string]interface{}{1541 b, err := json.Marshal(map[string]interface{}{
1556 "domain": "localhost",1542 "domain": "push-delivery",
1557 "hosts": []string{"nowhere", lst.Addr().String()},1543 "hosts": []string{"nowhere", lst.Addr().String()},
1558 })1544 })
1559 if err != nil {1545 if err != nil {
@@ -1649,14 +1635,7 @@
16491635
1650func (cs *clientSessionSuite) TestDialWorksDirect(c *C) {1636func (cs *clientSessionSuite) TestDialWorksDirect(c *C) {
1651 // happy path thoughts1637 // happy path thoughts
1652 cert, err := tls.X509KeyPair(helpers.TestCertPEMBlock, helpers.TestKeyPEMBlock)1638 lst, err := tls.Listen("tcp", "localhost:0", helpers.TestTLSServerConfig)
1653 c.Assert(err, IsNil)
1654 tlsCfg := &tls.Config{
1655 Certificates: []tls.Certificate{cert},
1656 SessionTicketsDisabled: true,
1657 }
1658
1659 lst, err := tls.Listen("tcp", "localhost:0", tlsCfg)
1660 c.Assert(err, IsNil)1639 c.Assert(err, IsNil)
1661 sess, err := NewSession(lst.Addr().String(), dialTestConf, "wah", cs.lvls, cs.log)1640 sess, err := NewSession(lst.Addr().String(), dialTestConf, "wah", cs.lvls, cs.log)
1662 c.Assert(err, IsNil)1641 c.Assert(err, IsNil)
16631642
=== modified file 'debian/ubuntu-push-client.conf'
--- debian/ubuntu-push-client.conf 2014-08-06 14:08:29 +0000
+++ debian/ubuntu-push-client.conf 2014-09-04 17:51:30 +0000
@@ -3,6 +3,10 @@
3start on started unity83start on started unity8
4stop on stopping unity84stop on stopping unity8
55
6# set the media role for sounds to notifications' role
7env PULSE_PROP="media.role=alert"
8export PULSE_PROP
9
6exec /usr/lib/ubuntu-push-client/ubuntu-push-client10exec /usr/lib/ubuntu-push-client/ubuntu-push-client
7respawn11respawn
812
913
=== modified file 'docs/highlevel.txt'
--- docs/highlevel.txt 2014-08-08 09:09:39 +0000
+++ docs/highlevel.txt 2014-09-04 17:51:30 +0000
@@ -3,6 +3,8 @@
33
4:Version: 0.50+4:Version: 0.50+
55
6.. contents::
7
6Introduction8Introduction
7------------9------------
810
@@ -111,8 +113,8 @@
111Persistent Notification Management113Persistent Notification Management
112~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~114~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
113115
114Some notifications are persistent, meaning they don't disappear automatically. For those notifications, there is an API that116Some notifications are persistent, meaning that, after they are presented, they don't disappear automatically.
115allows the app to manage them without having to know the underlying details of the platform.117This API allows the app to manage that type of notifications.
116118
117On each notification there's an optional ``tag`` field, used for this purpose.119On each notification there's an optional ``tag`` field, used for this purpose.
118120
@@ -192,6 +194,8 @@
192194
193Helpers output has two parts, the postal message (in the "message" key) and a notification to be presented to the user (in the "notification" key).195Helpers output has two parts, the postal message (in the "message" key) and a notification to be presented to the user (in the "notification" key).
194196
197.. note:: This format **will** change with future versions of the SDK and it **may** be incompatible.
198
195Here's a simple example::199Here's a simple example::
196200
197 {201 {
@@ -281,37 +285,27 @@
281The Ubuntu Push server is located at https://push.ubuntu.com and has a single endpoint: ``/notify``.285The Ubuntu Push server is located at https://push.ubuntu.com and has a single endpoint: ``/notify``.
282To notify a user, your application has to do a POST with ``Content-type: application/json``.286To notify a user, your application has to do a POST with ``Content-type: application/json``.
283287
288.. note:: The contents of the data field are arbitrary. They should be enough for your helper to build
289 a notification using it, and decide whether it should be displayed or not. Keep in mind
290 that this will be processed by more than one version of the helper, because the user may be using
291 an older version of your app.
292
284Here is an example of the POST body using all the fields::293Here is an example of the POST body using all the fields::
285294
286 {295 {
287 "appid": "com.ubuntu.music_music",296 "appid": "com.ubuntu.music_music",
288 "expire_on": "2014-10-08T14:48:00.000Z",297 "expire_on": "2014-10-08T14:48:00.000Z",
289 "token": "LeA4tRQG9hhEkuhngdouoA==",298 "token": "LeA4tRQG9hhEkuhngdouoA==",
290 "clear_pending": true,299 "clear_pending": true,
291 "replace_tag": "tagname",300 "replace_tag": "tagname",
292 "data": {301 "data": {
293 "message": "foobar",302 "id": 43578,
294 "notification": {303 "timestamp": 1409583746,
295 "card": {304 "serial": 1254,
296 "summary": "yes",305 "sender": "Joe",
297 "body": "hello",306 "snippet": "Hi there!"
298 "popup": true,307 }
299 "persist": true,308 }
300 "timestamp": 1407160197
301 }
302 "sound": "buzz.mp3",
303 "tag": "foo",
304 "vibrate": {
305 "pattern": [200, 100],
306 "repeat": 2
307 }
308 "emblem-counter": {
309 "count": 12,
310 "visible": true
311 }
312 }
313 }
314 }
315309
316310
317:appid: ID of the application that will receive the notification, as described in the client side documentation.311:appid: ID of the application that will receive the notification, as described in the client side documentation.
@@ -320,6 +314,3 @@
320:clear_pending: Discards all previous pending notifications. Usually in response to getting a "too-many-pending" error.314:clear_pending: Discards all previous pending notifications. Usually in response to getting a "too-many-pending" error.
321:replace_tag: If there's a pending notification with the same tag, delete it before queuing this new one.315:replace_tag: If there's a pending notification with the same tag, delete it before queuing this new one.
322:data: A JSON object.316:data: A JSON object.
323
324In this example, data is `what a helper would output <#helper-output-format>`__ but that's not necessarily the case.
325The content of the data field will be passed to the helper application which **has** to produce output in that format.
326317
=== modified file 'docs/lowlevel.txt'
--- docs/lowlevel.txt 2014-08-08 09:09:39 +0000
+++ docs/lowlevel.txt 2014-09-04 17:51:30 +0000
@@ -3,6 +3,8 @@
33
4:Version: 0.50+4:Version: 0.50+
55
6.. contents::
7
6Introduction8Introduction
7------------9------------
810
@@ -202,8 +204,8 @@
202Persistent Notification Management204Persistent Notification Management
203~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~205~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204206
205Some notifications are persistent, meaning they don't disappear automatically. For those notifications, there is an API that207Some notifications are persistent, meaning that, after they are presented, they don't disappear automatically.
206allows the app to manage them without having to know the underlying details of the platform.208This API allows the app to manage that type of notifications.
207209
208On each notification there's an optional ``tag`` field, used for this purpose.210On each notification there's an optional ``tag`` field, used for this purpose.
209211
@@ -286,6 +288,8 @@
286288
287Helpers output has two parts, the postal message (in the "message" key) and a notification to be presented to the user (in the "notification" key).289Helpers output has two parts, the postal message (in the "message" key) and a notification to be presented to the user (in the "notification" key).
288290
291.. note:: This format **will** change with future versions of the SDK and it **may** be incompatible.
292
289Here's a simple example::293Here's a simple example::
290294
291 {295 {
@@ -375,37 +379,27 @@
375The Ubuntu Push server is located at https://push.ubuntu.com and has a single endpoint: ``/notify``.379The Ubuntu Push server is located at https://push.ubuntu.com and has a single endpoint: ``/notify``.
376To notify a user, your application has to do a POST with ``Content-type: application/json``.380To notify a user, your application has to do a POST with ``Content-type: application/json``.
377381
382.. note:: The contents of the data field are arbitrary. They should be enough for your helper to build
383 a notification using it, and decide whether it should be displayed or not. Keep in mind
384 that this will be processed by more than one version of the helper, because the user may be using
385 an older version of your app.
386
378Here is an example of the POST body using all the fields::387Here is an example of the POST body using all the fields::
379388
380 {389 {
381 "appid": "com.ubuntu.music_music",390 "appid": "com.ubuntu.music_music",
382 "expire_on": "2014-10-08T14:48:00.000Z",391 "expire_on": "2014-10-08T14:48:00.000Z",
383 "token": "LeA4tRQG9hhEkuhngdouoA==",392 "token": "LeA4tRQG9hhEkuhngdouoA==",
384 "clear_pending": true,393 "clear_pending": true,
385 "replace_tag": "tagname",394 "replace_tag": "tagname",
386 "data": {395 "data": {
387 "message": "foobar",396 "id": 43578,
388 "notification": {397 "timestamp": 1409583746,
389 "card": {398 "serial": 1254,
390 "summary": "yes",399 "sender": "Joe",
391 "body": "hello",400 "snippet": "Hi there!"
392 "popup": true,401 }
393 "persist": true,402 }
394 "timestamp": 1407160197
395 }
396 "sound": "buzz.mp3",
397 "tag": "foo",
398 "vibrate": {
399 "pattern": [200, 100],
400 "repeat": 2
401 }
402 "emblem-counter": {
403 "count": 12,
404 "visible": true
405 }
406 }
407 }
408 }
409403
410404
411:appid: ID of the application that will receive the notification, as described in the client side documentation.405:appid: ID of the application that will receive the notification, as described in the client side documentation.
@@ -414,6 +408,3 @@
414:clear_pending: Discards all previous pending notifications. Usually in response to getting a "too-many-pending" error.408:clear_pending: Discards all previous pending notifications. Usually in response to getting a "too-many-pending" error.
415:replace_tag: If there's a pending notification with the same tag, delete it before queuing this new one.409:replace_tag: If there's a pending notification with the same tag, delete it before queuing this new one.
416:data: A JSON object.410:data: A JSON object.
417
418In this example, data is `what a helper would output <#helper-output-format>`__ but that's not necessarily the case.
419The content of the data field will be passed to the helper application which **has** to produce output in that format.
420411
=== modified file 'sampleconfigs/dev.json'
--- sampleconfigs/dev.json 2014-07-15 17:14:07 +0000
+++ sampleconfigs/dev.json 2014-09-04 17:51:30 +0000
@@ -10,5 +10,5 @@
10 "http_read_timeout": "5s",10 "http_read_timeout": "5s",
11 "http_write_timeout": "5s",11 "http_write_timeout": "5s",
12 "max_notifications_per_app": 25,12 "max_notifications_per_app": 25,
13 "delivery_domain": "localhost"13 "delivery_domain": "pus-delivery"
14}14}
1515
=== modified file 'server/acceptance/acceptance_test.go'
--- server/acceptance/acceptance_test.go 2014-05-02 09:56:49 +0000
+++ server/acceptance/acceptance_test.go 2014-09-04 17:51:30 +0000
@@ -34,7 +34,7 @@
34 cfg := make(map[string]interface{})34 cfg := make(map[string]interface{})
35 suites.FillServerConfig(cfg, addr)35 suites.FillServerConfig(cfg, addr)
36 suites.FillHTTPServerConfig(cfg, httpAddr)36 suites.FillHTTPServerConfig(cfg, httpAddr)
37 cfg["delivery_domain"] = "localhost"37 cfg["delivery_domain"] = "push-delivery"
38 return cfg38 return cfg
39}39}
4040
4141
=== modified file 'server/acceptance/ssl/README'
--- server/acceptance/ssl/README 2014-02-21 16:17:28 +0000
+++ server/acceptance/ssl/README 2014-09-04 17:51:30 +0000
@@ -3,6 +3,6 @@
33
4Generated with:4Generated with:
55
6 go run /usr/lib/go/src/pkg/crypto/tls/generate_cert.go -ca -host localhost -rsa-bits 512 -duration 87600h6 go run /usr/lib/go/src/pkg/crypto/tls/generate_cert.go -ca -host push-delivery -rsa-bits 512 -duration 87600h
77
8and then renamed.8and then renamed.
99
=== modified file 'server/acceptance/ssl/testing.cert'
--- server/acceptance/ssl/testing.cert 2014-01-14 15:35:20 +0000
+++ server/acceptance/ssl/testing.cert 2014-09-04 17:51:30 +0000
@@ -1,10 +1,10 @@
1-----BEGIN CERTIFICATE-----1-----BEGIN CERTIFICATE-----
2MIIBYzCCAQ+gAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD2MIIBYzCCAQ+gAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
3bzAeFw0xMzEyMTkyMDU1NDNaFw0yMzEyMTcyMDU1NDNaMBIxEDAOBgNVBAoTB0Fj3bzAeFw0xNDA4MjkxMjQyMDFaFw0yNDA4MjYxMjQyMDFaMBIxEDAOBgNVBAoTB0Fj
4bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAPw+niki17X2qALE2A2AzE1q5dvK4bWUgQ28wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA1FT6lkow0eky+Dnj2Z4nTrTF
59CI4OduRtT9IgbFLC6psqAT21NA+QbY17nWSSpyP65zkMkwKXrbDzstwLPkCAwEA5DgcKOt9Wr4B4gRH1bWmRqScOPxyHA5YodN7O1w8X8sdWko9puf59I1sWWr5LNwID
6AaNUMFIwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud6AQABo1IwUDAOBgNVHQ8BAf8EBAMCAKQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYD
7EwEB/wQFMAMBAf8wGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMAsGCSqGSIb37VR0TAQH/BAUwAwEB/zAYBgNVHREEETAPgg1wdXNoLWRlbGl2ZXJ5MAsGCSqGSIb3
8DQEBBQNBAFqiVI+Km2XPSO+pxITaPvhmuzg+XG3l1+2di3gL+HlDobocjBqRctRU8DQEBBQNBABtWCdMFkhIO8+oM3vugOWle9WJZ1FCRWD+cMl76mI1lhmNF4lvEZG47
9YySO32W07acjGJmCHUKpCJuq9X8hpmk=9xUjekA1+heU39WpOEzZSybrOdiEaGbI=
10-----END CERTIFICATE-----10-----END CERTIFICATE-----
1111
=== modified file 'server/acceptance/ssl/testing.key'
--- server/acceptance/ssl/testing.key 2014-01-14 15:35:20 +0000
+++ server/acceptance/ssl/testing.key 2014-09-04 17:51:30 +0000
@@ -1,9 +1,9 @@
1-----BEGIN RSA PRIVATE KEY-----1-----BEGIN RSA PRIVATE KEY-----
2MIIBPAIBAAJBAPw+niki17X2qALE2A2AzE1q5dvK9CI4OduRtT9IgbFLC6psqAT22MIIBOgIBAAJBANRU+pZKMNHpMvg549meJ060xQ4HCjrfVq+AeIER9W1pkaknDj8c
31NA+QbY17nWSSpyP65zkMkwKXrbDzstwLPkCAwEAAQJAKwXbIBULScP6QA6m8xam3hwOWKHTeztcPF/LHVpKPabn+fSNbFlq+SzcCAwEAAQJBAIOO+4xu/3yv/rKqO7C0
4wgWbkvN41GVWqPafPV32kPBvKwSc+M1e+JR7g3/xPZE7TCELcfYi4yXEHZZI3Pbh4Oyqa+pVMa1w60R0AfqmKFQTqiTgevM77uqjpW1+t0hpK20nyj6MUIPaL+9kZgp7t
5oQIhAP/UsgJbsfH1GFv8Y8qGl5l/kmwwkwHhuKvEC87Yur9FAiEA/GlQv3ZfaXnT5mnECIQDqw79PXSzudf10XGy9ve5bRazINHxQYgJ7FvlTT6JhdQIhAOeJxq9zcKni
6lcCFT0aL02O0RDiRYyMUG/JAZQJs6CUCIQCHO5SZYIUwxIGK5mCNxxXOAzyQSiD7669ueO1ualz0hn8w6uHPsG9FlZ8C+7Jh7AiAWJgebjjfZ+4nA+6NKt2uQct9dOA5u
7hqkKywf+4FvfDQIhALa0TLyqJFom0t7c4iIGAIRc8UlIYQSPiajI64+x9775AiEA7awC+6ij1ojK4rQIgNEqAbcWDj0qpe8sLms+aEntSjJxCZiPP0IW3XeeApZsCIDwo
80v4fgSK/Rq059zW1753JjuB6aR0Uh+3RqJII4dUR1Wg=8x+YyxXQWJlf9L5TNYPRo+KFEdk3Cew0lv6QNs+xe
9-----END RSA PRIVATE KEY-----9-----END RSA PRIVATE KEY-----
1010
=== modified file 'server/acceptance/suites/broadcast.go'
--- server/acceptance/suites/broadcast.go 2014-08-15 09:33:48 +0000
+++ server/acceptance/suites/broadcast.go 2014-09-04 17:51:30 +0000
@@ -261,7 +261,7 @@
261 host, err := gh.Get()261 host, err := gh.Get()
262 c.Assert(err, IsNil)262 c.Assert(err, IsNil)
263 expected := &gethosts.Host{263 expected := &gethosts.Host{
264 Domain: "localhost",264 Domain: "push-delivery",
265 Hosts: []string{s.ServerAddr},265 Hosts: []string{s.ServerAddr},
266 }266 }
267 c.Check(host, DeepEquals, expected)267 c.Check(host, DeepEquals, expected)
268268
=== modified file 'server/acceptance/suites/suite.go'
--- server/acceptance/suites/suite.go 2014-08-27 21:19:51 +0000
+++ server/acceptance/suites/suite.go 2014-09-04 17:51:30 +0000
@@ -111,7 +111,7 @@
111}111}
112112
113func testClientSession(addr string, deviceId, model, imageChannel string, reportPings bool) *acceptance.ClientSession {113func testClientSession(addr string, deviceId, model, imageChannel string, reportPings bool) *acceptance.ClientSession {
114 tlsConfig, err := kit.MakeTLSConfig("", false, helpers.SourceRelative("../ssl/testing.cert"), "")114 tlsConfig, err := kit.MakeTLSConfig("push-delivery", false, helpers.SourceRelative("../ssl/testing.cert"), "")
115 if err != nil {115 if err != nil {
116 panic(fmt.Sprintf("could not read ssl/testing.cert: %v", err))116 panic(fmt.Sprintf("could not read ssl/testing.cert: %v", err))
117 }117 }
118118
=== modified file 'server/config_test.go'
--- server/config_test.go 2014-02-10 23:19:08 +0000
+++ server/config_test.go 2014-09-04 17:51:30 +0000
@@ -26,6 +26,7 @@
26 . "launchpad.net/gocheck"26 . "launchpad.net/gocheck"
2727
28 "launchpad.net/ubuntu-push/config"28 "launchpad.net/ubuntu-push/config"
29 helpers "launchpad.net/ubuntu-push/testing"
29)30)
3031
31type configSuite struct{}32type configSuite struct{}
@@ -52,22 +53,22 @@
52 c.Check(cfg.Addr(), Equals, "127.0.0.1:9999")53 c.Check(cfg.Addr(), Equals, "127.0.0.1:9999")
53}54}
5455
55func (s *configSuite) TestDevicesParsedConfigLoadFinish(c *C) {56func (s *configSuite) TestTLSParsedConfigLoadPEMs(c *C) {
56 tmpDir := c.MkDir()57 tmpDir := c.MkDir()
57 cfg := &DevicesParsedConfig{58 cfg := &TLSParsedConfig{
58 ParsedKeyPEMFile: "key.key",59 ParsedKeyPEMFile: "key.key",
59 ParsedCertPEMFile: "cert.cert",60 ParsedCertPEMFile: "cert.cert",
60 }61 }
61 err := cfg.FinishLoad(tmpDir)62 err := cfg.LoadPEMs(tmpDir)
62 c.Check(err, ErrorMatches, "reading key_pem_file:.*no such file.*")63 c.Check(err, ErrorMatches, "reading key_pem_file:.*no such file.*")
63 err = ioutil.WriteFile(filepath.Join(tmpDir, "key.key"), []byte("KeY"), os.ModePerm)64 err = ioutil.WriteFile(filepath.Join(tmpDir, "key.key"), helpers.TestKeyPEMBlock, os.ModePerm)
64 c.Assert(err, IsNil)65 c.Assert(err, IsNil)
65 err = cfg.FinishLoad(tmpDir)66 err = cfg.LoadPEMs(tmpDir)
66 c.Check(err, ErrorMatches, "reading cert_pem_file:.*no such file.*")67 c.Check(err, ErrorMatches, "reading cert_pem_file:.*no such file.*")
67 err = ioutil.WriteFile(filepath.Join(tmpDir, "cert.cert"), []byte("CeRt"), os.ModePerm)68 err = ioutil.WriteFile(filepath.Join(tmpDir, "cert.cert"), helpers.TestCertPEMBlock, os.ModePerm)
68 c.Assert(err, IsNil)69 c.Assert(err, IsNil)
69 err = cfg.FinishLoad(tmpDir)70 err = cfg.LoadPEMs(tmpDir)
70 c.Assert(err, IsNil)71 c.Assert(err, IsNil)
71 c.Check(string(cfg.KeyPEMBlock()), Equals, "KeY")72 tlsCfg := cfg.TLSServerConfig()
72 c.Check(string(cfg.CertPEMBlock()), Equals, "CeRt")73 c.Check(tlsCfg.Certificates, HasLen, 1)
73}74}
7475
=== modified file 'server/dev/server.go'
--- server/dev/server.go 2014-07-08 15:08:52 +0000
+++ server/dev/server.go 2014-09-04 17:51:30 +0000
@@ -64,7 +64,7 @@
64 if err != nil {64 if err != nil {
65 server.BootLogFatalf("reading config: %v", err)65 server.BootLogFatalf("reading config: %v", err)
66 }66 }
67 err = cfg.DevicesParsedConfig.FinishLoad(filepath.Dir(cfgFpaths[len(cfgFpaths)-1]))67 err = cfg.DevicesParsedConfig.LoadPEMs(filepath.Dir(cfgFpaths[len(cfgFpaths)-1]))
68 if err != nil {68 if err != nil {
69 server.BootLogFatalf("reading config: %v", err)69 server.BootLogFatalf("reading config: %v", err)
70 }70 }
@@ -95,7 +95,7 @@
95 })95 })
96 })96 })
97 handler := api.PanicTo500Handler(mux, logger)97 handler := api.PanicTo500Handler(mux, logger)
98 go server.HTTPServeRunner(nil, handler, &cfg.HTTPServeParsedConfig)()98 go server.HTTPServeRunner(nil, handler, &cfg.HTTPServeParsedConfig, nil)()
99 // listen for device connections99 // listen for device connections
100 server.DevicesRunner(lst, func(conn net.Conn) error {100 server.DevicesRunner(lst, func(conn net.Conn) error {
101 track := session.NewTracker(logger)101 track := session.NewTracker(logger)
102102
=== modified file 'server/listener/listener.go'
--- server/listener/listener.go 2014-03-06 19:21:44 +0000
+++ server/listener/listener.go 2014-09-04 17:51:30 +0000
@@ -30,10 +30,8 @@
30type DeviceListenerConfig interface {30type DeviceListenerConfig interface {
31 // Addr to listen on.31 // Addr to listen on.
32 Addr() string32 Addr() string
33 // TLS key33 // TLS config
34 KeyPEMBlock() []byte34 TLSServerConfig() *tls.Config
35 // TLS cert
36 CertPEMBlock() []byte
37}35}
3836
39// DeviceListener listens and setup sessions from device connections.37// DeviceListener listens and setup sessions from device connections.
@@ -52,15 +50,8 @@
52 return nil, err50 return nil, err
53 }51 }
54 }52 }
55 cert, err := tls.X509KeyPair(cfg.CertPEMBlock(), cfg.KeyPEMBlock())53 tlsCfg := cfg.TLSServerConfig()
56 if err != nil {54 return &DeviceListener{tls.NewListener(lst, tlsCfg)}, nil
57 return nil, err
58 }
59 tlsCfg := &tls.Config{
60 Certificates: []tls.Certificate{cert},
61 SessionTicketsDisabled: true,
62 }
63 return &DeviceListener{tls.NewListener(lst, tlsCfg)}, err
64}55}
6556
66// handleTemporary checks and handles if the error is just a temporary network57// handleTemporary checks and handles if the error is just a temporary network
6758
=== modified file 'server/listener/listener_test.go'
--- server/listener/listener_test.go 2014-08-04 14:47:00 +0000
+++ server/listener/listener_test.go 2014-09-04 17:51:30 +0000
@@ -18,7 +18,6 @@
1818
19import (19import (
20 "crypto/tls"20 "crypto/tls"
21 "crypto/x509"
22 "net"21 "net"
23 "os/exec"22 "os/exec"
24 "regexp"23 "regexp"
@@ -68,12 +67,8 @@
68 return cfg.addr67 return cfg.addr
69}68}
7069
71func (cfg *testDevListenerCfg) KeyPEMBlock() []byte {70func (cfg *testDevListenerCfg) TLSServerConfig() *tls.Config {
72 return helpers.TestKeyPEMBlock71 return helpers.TestTLSServerConfig
73}
74
75func (cfg *testDevListenerCfg) CertPEMBlock() []byte {
76 return helpers.TestCertPEMBlock
77}72}
7873
79func (s *listenerSuite) TestDeviceListen(c *C) {74func (s *listenerSuite) TestDeviceListen(c *C) {
@@ -130,11 +125,8 @@
130 return err125 return err
131}126}
132127
133func testTlsDial(c *C, addr string) (net.Conn, error) {128func testTlsDial(addr string) (net.Conn, error) {
134 cp := x509.NewCertPool()129 return tls.Dial("tcp", addr, helpers.TestTLSClientConfig)
135 ok := cp.AppendCertsFromPEM((&testDevListenerCfg{}).CertPEMBlock())
136 c.Assert(ok, Equals, true)
137 return tls.Dial("tcp", addr, &tls.Config{RootCAs: cp})
138}130}
139131
140func testWriteByte(c *C, conn net.Conn, toWrite uint32) {132func testWriteByte(c *C, conn net.Conn, toWrite uint32) {
@@ -159,11 +151,11 @@
159 errCh <- lst.AcceptLoop(testSession, s.testlog)151 errCh <- lst.AcceptLoop(testSession, s.testlog)
160 }()152 }()
161 listenerAddr := lst.Addr().String()153 listenerAddr := lst.Addr().String()
162 conn1, err := testTlsDial(c, listenerAddr)154 conn1, err := testTlsDial(listenerAddr)
163 c.Assert(err, IsNil)155 c.Assert(err, IsNil)
164 defer conn1.Close()156 defer conn1.Close()
165 testWriteByte(c, conn1, '1')157 testWriteByte(c, conn1, '1')
166 conn2, err := testTlsDial(c, listenerAddr)158 conn2, err := testTlsDial(listenerAddr)
167 c.Assert(err, IsNil)159 c.Assert(err, IsNil)
168 defer conn2.Close()160 defer conn2.Close()
169 testWriteByte(c, conn2, '2')161 testWriteByte(c, conn2, '2')
@@ -203,7 +195,7 @@
203 res, err := cmd.Output()195 res, err := cmd.Output()
204 c.Assert(err, IsNil)196 c.Assert(err, IsNil)
205 c.Assert(string(res), Matches, "(?s).*timed out.*")197 c.Assert(string(res), Matches, "(?s).*timed out.*")
206 conn2, err := testTlsDial(c, listenerAddr)198 conn2, err := testTlsDial(listenerAddr)
207 c.Assert(err, IsNil)199 c.Assert(err, IsNil)
208 defer conn2.Close()200 defer conn2.Close()
209 testWriteByte(c, conn2, '2')201 testWriteByte(c, conn2, '2')
@@ -225,7 +217,7 @@
225 }, s.testlog)217 }, s.testlog)
226 }()218 }()
227 listenerAddr := lst.Addr().String()219 listenerAddr := lst.Addr().String()
228 _, err = testTlsDial(c, listenerAddr)220 _, err = testTlsDial(listenerAddr)
229 c.Assert(err, Not(IsNil))221 c.Assert(err, Not(IsNil))
230 lst.Close()222 lst.Close()
231 c.Check(<-errCh, ErrorMatches, ".*use of closed.*")223 c.Check(<-errCh, ErrorMatches, ".*use of closed.*")
@@ -244,7 +236,7 @@
244 }()236 }()
245 listenerAddr := lst.Addr().String()237 listenerAddr := lst.Addr().String()
246 c.Check(listenerAddr, Equals, foreignLst.Addr().String())238 c.Check(listenerAddr, Equals, foreignLst.Addr().String())
247 conn1, err := testTlsDial(c, listenerAddr)239 conn1, err := testTlsDial(listenerAddr)
248 c.Assert(err, IsNil)240 c.Assert(err, IsNil)
249 defer conn1.Close()241 defer conn1.Close()
250 testWriteByte(c, conn1, '1')242 testWriteByte(c, conn1, '1')
251243
=== modified file 'server/runner_devices.go'
--- server/runner_devices.go 2014-03-12 12:34:18 +0000
+++ server/runner_devices.go 2014-09-04 17:51:30 +0000
@@ -17,7 +17,6 @@
17package server17package server
1818
19import (19import (
20 "fmt"
21 "net"20 "net"
22 "syscall"21 "syscall"
23 "time"22 "time"
@@ -36,26 +35,8 @@
36 ParsedSessionQueueSize config.ConfigQueueSize `json:"session_queue_size"`35 ParsedSessionQueueSize config.ConfigQueueSize `json:"session_queue_size"`
37 ParsedBrokerQueueSize config.ConfigQueueSize `json:"broker_queue_size"`36 ParsedBrokerQueueSize config.ConfigQueueSize `json:"broker_queue_size"`
38 // device listener configuration37 // device listener configuration
39 ParsedAddr config.ConfigHostPort `json:"addr"`38 ParsedAddr config.ConfigHostPort `json:"addr"`
40 ParsedKeyPEMFile string `json:"key_pem_file"`39 TLSParsedConfig
41 ParsedCertPEMFile string `json:"cert_pem_file"`
42 // private post-processed config
43 certPEMBlock []byte
44 keyPEMBlock []byte
45}
46
47func (cfg *DevicesParsedConfig) FinishLoad(baseDir string) error {
48 keyPEMBlock, err := config.LoadFile(cfg.ParsedKeyPEMFile, baseDir)
49 if err != nil {
50 return fmt.Errorf("reading key_pem_file: %v", err)
51 }
52 certPEMBlock, err := config.LoadFile(cfg.ParsedCertPEMFile, baseDir)
53 if err != nil {
54 return fmt.Errorf("reading cert_pem_file: %v", err)
55 }
56 cfg.keyPEMBlock = keyPEMBlock
57 cfg.certPEMBlock = certPEMBlock
58 return nil
59}40}
6041
61func (cfg *DevicesParsedConfig) PingInterval() time.Duration {42func (cfg *DevicesParsedConfig) PingInterval() time.Duration {
@@ -78,14 +59,6 @@
78 return cfg.ParsedAddr.HostPort()59 return cfg.ParsedAddr.HostPort()
79}60}
8061
81func (cfg *DevicesParsedConfig) KeyPEMBlock() []byte {
82 return cfg.keyPEMBlock
83}
84
85func (cfg *DevicesParsedConfig) CertPEMBlock() []byte {
86 return cfg.certPEMBlock
87}
88
89// DevicesRunner returns a function to accept device connections.62// DevicesRunner returns a function to accept device connections.
90// If adoptLst is not nil it will be used as the underlying listener, instead63// If adoptLst is not nil it will be used as the underlying listener, instead
91// of creating one, wrapped in a TLS layer.64// of creating one, wrapped in a TLS layer.
9265
=== modified file 'server/runner_http.go'
--- server/runner_http.go 2014-03-25 19:02:18 +0000
+++ server/runner_http.go 2014-09-04 17:51:30 +0000
@@ -17,6 +17,7 @@
17package server17package server
1818
19import (19import (
20 "crypto/tls"
20 "net"21 "net"
21 "net/http"22 "net/http"
2223
@@ -32,7 +33,8 @@
3233
33// HTTPServeRunner returns a function to serve HTTP requests.34// HTTPServeRunner returns a function to serve HTTP requests.
34// If httpLst is not nil it will be used as the underlying listener.35// If httpLst is not nil it will be used as the underlying listener.
35func HTTPServeRunner(httpLst net.Listener, h http.Handler, parsedCfg *HTTPServeParsedConfig) func() {36// If tlsCfg is not nit server over TLS with the config.
37func HTTPServeRunner(httpLst net.Listener, h http.Handler, parsedCfg *HTTPServeParsedConfig, tlsCfg *tls.Config) func() {
36 if httpLst == nil {38 if httpLst == nil {
37 var err error39 var err error
38 httpLst, err = net.Listen("tcp", parsedCfg.ParsedHTTPAddr.HostPort())40 httpLst, err = net.Listen("tcp", parsedCfg.ParsedHTTPAddr.HostPort())
@@ -46,6 +48,9 @@
46 ReadTimeout: parsedCfg.ParsedHTTPReadTimeout.TimeDuration(),48 ReadTimeout: parsedCfg.ParsedHTTPReadTimeout.TimeDuration(),
47 WriteTimeout: parsedCfg.ParsedHTTPWriteTimeout.TimeDuration(),49 WriteTimeout: parsedCfg.ParsedHTTPWriteTimeout.TimeDuration(),
48 }50 }
51 if tlsCfg != nil {
52 httpLst = tls.NewListener(httpLst, tlsCfg)
53 }
49 return func() {54 return func() {
50 err := srv.Serve(httpLst)55 err := srv.Serve(httpLst)
51 if err != nil {56 if err != nil {
5257
=== modified file 'server/runner_test.go'
--- server/runner_test.go 2014-03-25 19:02:18 +0000
+++ server/runner_test.go 2014-09-04 17:51:30 +0000
@@ -17,6 +17,7 @@
17package server17package server
1818
19import (19import (
20 "crypto/tls"
20 "fmt"21 "fmt"
21 "io/ioutil"22 "io/ioutil"
22 "net"23 "net"
@@ -68,7 +69,7 @@
68func (s *runnerSuite) TestHTTPServeRunner(c *C) {69func (s *runnerSuite) TestHTTPServeRunner(c *C) {
69 errCh := make(chan interface{}, 1)70 errCh := make(chan interface{}, 1)
70 h := http.HandlerFunc(testHandle)71 h := http.HandlerFunc(testHandle)
71 runner := HTTPServeRunner(nil, h, &testHTTPServeParsedConfig)72 runner := HTTPServeRunner(nil, h, &testHTTPServeParsedConfig, nil)
72 c.Assert(s.lst, Not(IsNil))73 c.Assert(s.lst, Not(IsNil))
73 defer s.lst.Close()74 defer s.lst.Close()
74 c.Check(s.kind, Equals, "http")75 c.Check(s.kind, Equals, "http")
@@ -89,16 +90,25 @@
89 c.Check(<-errCh, Matches, "accepting http connections:.*closed.*")90 c.Check(<-errCh, Matches, "accepting http connections:.*closed.*")
90}91}
9192
93func cert() tls.Certificate {
94 cert, err := tls.X509KeyPair(helpers.TestCertPEMBlock, helpers.TestKeyPEMBlock)
95 if err != nil {
96 panic(err)
97 }
98 return cert
99}
100
92var testDevicesParsedConfig = DevicesParsedConfig{101var testDevicesParsedConfig = DevicesParsedConfig{
93 ParsedPingInterval: config.ConfigTimeDuration{60 * time.Second},102 ParsedPingInterval: config.ConfigTimeDuration{60 * time.Second},
94 ParsedExchangeTimeout: config.ConfigTimeDuration{10 * time.Second},103 ParsedExchangeTimeout: config.ConfigTimeDuration{10 * time.Second},
95 ParsedBrokerQueueSize: config.ConfigQueueSize(1000),104 ParsedBrokerQueueSize: config.ConfigQueueSize(1000),
96 ParsedSessionQueueSize: config.ConfigQueueSize(10),105 ParsedSessionQueueSize: config.ConfigQueueSize(10),
97 ParsedAddr: "127.0.0.1:0",106 ParsedAddr: "127.0.0.1:0",
98 ParsedKeyPEMFile: "",107 TLSParsedConfig: TLSParsedConfig{
99 ParsedCertPEMFile: "",108 ParsedKeyPEMFile: "",
100 keyPEMBlock: helpers.TestKeyPEMBlock,109 ParsedCertPEMFile: "",
101 certPEMBlock: helpers.TestCertPEMBlock,110 cert: cert(),
111 },
102}112}
103113
104func (s *runnerSuite) TestDevicesRunner(c *C) {114func (s *runnerSuite) TestDevicesRunner(c *C) {
@@ -135,7 +145,36 @@
135 lst0, err := net.Listen("tcp", "127.0.0.1:0")145 lst0, err := net.Listen("tcp", "127.0.0.1:0")
136 c.Assert(err, IsNil)146 c.Assert(err, IsNil)
137 defer lst0.Close()147 defer lst0.Close()
138 HTTPServeRunner(lst0, nil, &testHTTPServeParsedConfig)148 HTTPServeRunner(lst0, nil, &testHTTPServeParsedConfig, nil)
139 c.Assert(s.lst, Equals, lst0)149 c.Assert(s.lst, Equals, lst0)
140 c.Check(s.kind, Equals, "http")150 c.Check(s.kind, Equals, "http")
141}151}
152
153func (s *runnerSuite) TestHTTPServeRunnerTLS(c *C) {
154 errCh := make(chan interface{}, 1)
155 h := http.HandlerFunc(testHandle)
156 runner := HTTPServeRunner(nil, h, &testHTTPServeParsedConfig, helpers.TestTLSServerConfig)
157 c.Assert(s.lst, Not(IsNil))
158 defer s.lst.Close()
159 c.Check(s.kind, Equals, "http")
160 go func() {
161 defer func() {
162 errCh <- recover()
163 }()
164 runner()
165 }()
166 cli := http.Client{
167 Transport: &http.Transport{
168 TLSClientConfig: helpers.TestTLSClientConfig,
169 },
170 }
171 resp, err := cli.Get(fmt.Sprintf("https://%s/", s.lst.Addr()))
172 c.Assert(err, IsNil)
173 defer resp.Body.Close()
174 c.Assert(resp.StatusCode, Equals, 200)
175 body, err := ioutil.ReadAll(resp.Body)
176 c.Assert(err, IsNil)
177 c.Check(string(body), Equals, "yay!\n")
178 s.lst.Close()
179 c.Check(<-errCh, Matches, "accepting http connections:.*closed.*")
180}
142181
=== added file 'server/tlsconfig.go'
--- server/tlsconfig.go 1970-01-01 00:00:00 +0000
+++ server/tlsconfig.go 2014-09-04 17:51:30 +0000
@@ -0,0 +1,53 @@
1/*
2 Copyright 2013-2014 Canonical Ltd.
3
4 This program is free software: you can redistribute it and/or modify it
5 under the terms of the GNU General Public License version 3, as published
6 by the Free Software Foundation.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranties of
10 MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 PURPOSE. See the GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along
14 with this program. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17package server
18
19import (
20 "crypto/tls"
21 "fmt"
22
23 "launchpad.net/ubuntu-push/config"
24)
25
26// A TLSParsedConfig holds and can be used to parse a tls server config.
27type TLSParsedConfig struct {
28 ParsedKeyPEMFile string `json:"key_pem_file"`
29 ParsedCertPEMFile string `json:"cert_pem_file"`
30 // private post-processed config
31 cert tls.Certificate
32}
33
34func (cfg *TLSParsedConfig) LoadPEMs(baseDir string) error {
35 keyPEMBlock, err := config.LoadFile(cfg.ParsedKeyPEMFile, baseDir)
36 if err != nil {
37 return fmt.Errorf("reading key_pem_file: %v", err)
38 }
39 certPEMBlock, err := config.LoadFile(cfg.ParsedCertPEMFile, baseDir)
40 if err != nil {
41 return fmt.Errorf("reading cert_pem_file: %v", err)
42 }
43 cfg.cert, err = tls.X509KeyPair(certPEMBlock, keyPEMBlock)
44 return err
45}
46
47func (cfg *TLSParsedConfig) TLSServerConfig() *tls.Config {
48 tlsCfg := &tls.Config{
49 Certificates: []tls.Certificate{cfg.cert},
50 SessionTicketsDisabled: true,
51 }
52 return tlsCfg
53}
054
=== modified file 'testing/tls.go'
--- testing/tls.go 2014-01-21 21:36:07 +0000
+++ testing/tls.go 2014-09-04 17:51:30 +0000
@@ -16,26 +16,53 @@
1616
17package testing17package testing
1818
19// key&cert generated with go run /usr/lib/go/src/pkg/crypto/tls/generate_cert.go -ca -host localhost -rsa-bits 512 -duration 87600h19import (
20 "crypto/tls"
21 "crypto/x509"
22)
23
24// 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
20var (25var (
21 TestKeyPEMBlock = []byte(`-----BEGIN RSA PRIVATE KEY-----26 TestKeyPEMBlock = []byte(`-----BEGIN RSA PRIVATE KEY-----
22MIIBPAIBAAJBAPw+niki17X2qALE2A2AzE1q5dvK9CI4OduRtT9IgbFLC6psqAT227MIIBOgIBAAJBANRU+pZKMNHpMvg549meJ060xQ4HCjrfVq+AeIER9W1pkaknDj8c
231NA+QbY17nWSSpyP65zkMkwKXrbDzstwLPkCAwEAAQJAKwXbIBULScP6QA6m8xam28hwOWKHTeztcPF/LHVpKPabn+fSNbFlq+SzcCAwEAAQJBAIOO+4xu/3yv/rKqO7C0
24wgWbkvN41GVWqPafPV32kPBvKwSc+M1e+JR7g3/xPZE7TCELcfYi4yXEHZZI3Pbh29Oyqa+pVMa1w60R0AfqmKFQTqiTgevM77uqjpW1+t0hpK20nyj6MUIPaL+9kZgp7t
25oQIhAP/UsgJbsfH1GFv8Y8qGl5l/kmwwkwHhuKvEC87Yur9FAiEA/GlQv3ZfaXnT30mnECIQDqw79PXSzudf10XGy9ve5bRazINHxQYgJ7FvlTT6JhdQIhAOeJxq9zcKni
26lcCFT0aL02O0RDiRYyMUG/JAZQJs6CUCIQCHO5SZYIUwxIGK5mCNxxXOAzyQSiD73169ueO1ualz0hn8w6uHPsG9FlZ8C+7Jh7AiAWJgebjjfZ+4nA+6NKt2uQct9dOA5u
27hqkKywf+4FvfDQIhALa0TLyqJFom0t7c4iIGAIRc8UlIYQSPiajI64+x9775AiEA32awC+6ij1ojK4rQIgNEqAbcWDj0qpe8sLms+aEntSjJxCZiPP0IW3XeeApZsCIDwo
280v4fgSK/Rq059zW1753JjuB6aR0Uh+3RqJII4dUR1Wg=33x+YyxXQWJlf9L5TNYPRo+KFEdk3Cew0lv6QNs+xe
29-----END RSA PRIVATE KEY-----`)34-----END RSA PRIVATE KEY-----`)
3035
31 TestCertPEMBlock = []byte(`-----BEGIN CERTIFICATE-----36 TestCertPEMBlock = []byte(`-----BEGIN CERTIFICATE-----
32MIIBYzCCAQ+gAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD37MIIBYzCCAQ+gAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
33bzAeFw0xMzEyMTkyMDU1NDNaFw0yMzEyMTcyMDU1NDNaMBIxEDAOBgNVBAoTB0Fj38bzAeFw0xNDA4MjkxMjQyMDFaFw0yNDA4MjYxMjQyMDFaMBIxEDAOBgNVBAoTB0Fj
34bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAPw+niki17X2qALE2A2AzE1q5dvK39bWUgQ28wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA1FT6lkow0eky+Dnj2Z4nTrTF
359CI4OduRtT9IgbFLC6psqAT21NA+QbY17nWSSpyP65zkMkwKXrbDzstwLPkCAwEA40DgcKOt9Wr4B4gRH1bWmRqScOPxyHA5YodN7O1w8X8sdWko9puf59I1sWWr5LNwID
36AaNUMFIwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud41AQABo1IwUDAOBgNVHQ8BAf8EBAMCAKQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYD
37EwEB/wQFMAMBAf8wGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMAsGCSqGSIb342VR0TAQH/BAUwAwEB/zAYBgNVHREEETAPgg1wdXNoLWRlbGl2ZXJ5MAsGCSqGSIb3
38DQEBBQNBAFqiVI+Km2XPSO+pxITaPvhmuzg+XG3l1+2di3gL+HlDobocjBqRctRU43DQEBBQNBABtWCdMFkhIO8+oM3vugOWle9WJZ1FCRWD+cMl76mI1lhmNF4lvEZG47
39YySO32W07acjGJmCHUKpCJuq9X8hpmk=44xUjekA1+heU39WpOEzZSybrOdiEaGbI=
40-----END CERTIFICATE-----`)45-----END CERTIFICATE-----`)
41)46)
47
48// test tls server config
49var TestTLSServerConfig, TestTLSClientConfig *tls.Config
50
51func init() {
52 cert, err := tls.X509KeyPair(TestCertPEMBlock, TestKeyPEMBlock)
53 if err != nil {
54 panic(err)
55 }
56 TestTLSServerConfig = &tls.Config{
57 Certificates: []tls.Certificate{cert},
58 }
59 cp := x509.NewCertPool()
60 ok := cp.AppendCertsFromPEM(TestCertPEMBlock)
61 if !ok {
62 panic("failed to parse test cert")
63 }
64 TestTLSClientConfig = &tls.Config{
65 RootCAs: cp,
66 ServerName: "push-delivery",
67 }
68}

Subscribers

People subscribed via source and target branches