Merge lp:~brian.curtin/ubuntu-sso-client/local-certs into lp:ubuntu-sso-client

Proposed by Brian Curtin
Status: Merged
Approved by: dobey
Approved revision: 1036
Merged at revision: 1031
Proposed branch: lp:~brian.curtin/ubuntu-sso-client/local-certs
Merge into: lp:ubuntu-sso-client
Diff against target: 339 lines (+193/-10)
8 files modified
data/UbuntuOne-Go_Daddy_CA.pem (+29/-0)
data/UbuntuOne-Go_Daddy_Class_2_CA.pem (+25/-0)
data/UbuntuOne-ValiCert_Class_2_VA.pem (+18/-0)
setup.py (+11/-10)
ubuntu_sso/utils/__init__.py (+25/-0)
ubuntu_sso/utils/tests/test_common.py (+44/-0)
ubuntu_sso/utils/webclient/qtnetwork.py (+24/-0)
ubuntu_sso/utils/webclient/tests/test_qtnetwork.py (+17/-0)
To merge this branch: bzr merge lp:~brian.curtin/ubuntu-sso-client/local-certs
Reviewer Review Type Date Requested Status
Mike McCracken (community) Approve
dobey (community) Approve
Review via email: mp+132715@code.launchpad.net

Commit message

- Set SSL configuration with bundled certificates for all WebClient requests

Description of the change

Explicitly use the certificates we bundle with installations, fixing a longstanding problem on some Windows systems where the required certificates are not typically available.

Note: as this branch is going to be applied manually to a stable branch, it includes get_cert_location (from storage-protocol). This should be factored out to a more commonly usable location moving forward.

To post a comment you must log in.
Revision history for this message
dobey (dobey) wrote :

So, I am uncertain about this branch implementation. This effectively introduces a dependency on ubuntuone-storage-protocol in ubuntu-sso-client, only for a few .crt files. We should probably move those files (probably to ubuntuone-client-data or similar), to keep the dependencies sane, and from getting circular. I especially don't like duplicating the code that's in there.

I'd also like to confirm whether this will break ubuntu-sso-client on Linux, when the storage protocol packages aren't installed, as other applications may/do use ubuntu-sso-client for authentication.

Shipping this as a stop-gap patch on Windows to deal with the existing problem is fine by me, but I'm not sure this should land in trunk (or any stable branches) as-is.

review: Needs Information
Revision history for this message
Brian Curtin (brian.curtin) wrote :

1. I'm fine with moving the files to ubuntuone-client-data. If that's acceptable, I'll go ahead and do it.
2. I don't like duplicating the code either, but I've had my "release Windows ASAP" hat on. Given the dependency situation that we want to step around, where can I feasibly put get_cert_location? dirspec, devtools?
3. As for breakage on Linux without storage-protocol or those specific certs - it shouldn't affect it. If nothing turns up when we go to look for our specific certs, they just won't be configured. test_setup_no_certs checks this by faking out the search for "UbuntuOne*.crt" with an empty list and ensures that WebClient can still start up.
4. Perhaps I've been focused too much on the stop-gap approach, but I'm all for doing this properly the first time. I don't really like this MP as-is, but could use this type of response to get it into shape.

Revision history for this message
dobey (dobey) wrote :

On Fri, 2012-11-02 at 19:49 +0000, Brian Curtin wrote:
> 1. I'm fine with moving the files to ubuntuone-client-data. If that's
> acceptable, I'll go ahead and do it.

There are some packaging concerns here, so needs a bit of coordination
to do. And given 2.) below, I need to think about this a little bit
more, I suppose.

> 2. I don't like duplicating the code either, but I've had my "release
> Windows ASAP" hat on. Given the dependency situation that we want to
> step around, where can I feasibly put get_cert_location? dirspec,
> devtools?

The API call and the cert files should be in the same project I think,
but this does also mean we need to think a bit more about where to put
those files and API exactly.

> 3. As for breakage on Linux without storage-protocol or those specific
> certs - it shouldn't affect it. If nothing turns up when we go to look
> for our specific certs, they just won't be configured.
> test_setup_no_certs checks this by faking out the search for
> "UbuntuOne*.crt" with an empty list and ensures that WebClient can
> still start up.

Great.

> 4. Perhaps I've been focused too much on the stop-gap approach, but
> I'm all for doing this properly the first time. I don't really like
> this MP as-is, but could use this type of response to get it into
> shape.

It will require a bit more thought and work, so I think for now, the
best solution for getting a new Windows release out, is to use this
(though I would change the duplicated code to just import the call from
ubuntuone.storageprotocol.context to reduce the size of the patch, and
any potential for issues due to the code duplication.

Revision history for this message
dobey (dobey) wrote :

As we discussed on IRC yesterday, we should build a windows release from stable-4-0 with the current patch as-is, to get a working release built and released. Once that's done, this branch should be updated to pull in the .crt files and install them into the ubuntu-sso-client data directory, and pull in the get_certificates() method and related tests, tweaked to look for the certs in the new location. Once in, and packaged up in our nightlies, we can update ubuntuone-storage-protocol (which I've already added to the bug as being affected), to use the API/certs from SSO, and remove them from storage-protocol.

review: Needs Fixing
1012. By dobey

Bump version number for trunk.

1013. By dobey

Ignore some new pep8 errors, and update code to fix others.

1014. By Mike McCracken

- Add util func returning translation function for platform/pyversion/frozen status. (LP: #1074116)

1015. By Alejandro J. Cura

- Use a standard LC_CTYPE locale when the LANG is turkish. (LP: #997326).

1016. By Alejandro J. Cura

Clean up timers that are sometimes slowing down all tests that follow.

1017. By dobey

Fail the defer with an exception class like it's supposed to.

1018. By dobey

Fix a dependency on a re-export of a module in twisted.

1019. By dobey

Skip proxy tests failing due to ncsa_auth crashing.

1020. By Barry Warsaw

Switch from python-oauth to python-oauthlib for using OAuth.

1021. By Barry Warsaw

Remove some unnecessary test code that still depended on python-oauth.

1022. By dobey

Pass the timestamp argument to oauthlib as a str to workaround a problem.

1023. By dobey

Don't pass in the query parameters to oauthlib twice.

1024. By dobey

Add the version to constants.py as well.
Replace PROJECT_NAME as well to have a single location for it.
Generate the constants.py as a usable module from within tests.
Replace the prefix in constants.py only in the installed copy, and not local.
Use the correct variable for replacing the "prefix" in constants.py.
Update author information in setup().

1025. By Diego Sarmentero

Update to use Ubuntu One branding and URLs.

1026. By dobey

Unify usage of login and u1 host into environment variables, for testing.

1027. By dobey

Only replace root in the install_data string when root is set.

1028. By dobey

Handle the API changing in 0.3.8 by avoiding passing in params for GET/HEAD.

1029. By Leo Arias

Changed the environment variables for sso auth and uone from hosts to urls.

1030. By Leo Arias

Fix typo on the ubuntuone environment variable.

1031. By Brian Curtin

Merge trunk

1032. By Brian Curtin

Add pem files to data"

1033. By Brian Curtin

Add get_cert_dir (was get_cert_location in storageprotocol)

1034. By Brian Curtin

Rework setup

Revision history for this message
dobey (dobey) wrote :

There are some tests in ubuntuone-storage-protocol's test_context.py which should be copied over in this branch, to test the get_cert_dir method added here. The SSLCertLocationTestCase in its entirety, updated to use the new method. Also, is there a good reason to rename the method to get_cert_dir here? Keeping the name as _location would be fine.

review: Needs Fixing
1035. By Brian Curtin

Add tests from storageprotocol's implementation of get_cert_{location|dir}

Revision history for this message
Brian Curtin (brian.curtin) wrote :

Copied the tests over and they pass. Already explained the name change on IRC, but it was done to match the other get_* functions in the utils module.

1036. By Brian Curtin

Remove commented lines from test

Revision history for this message
dobey (dobey) :
review: Approve
Revision history for this message
Mike McCracken (mikemc) wrote :

Looks fine to me, and tests do pass on osx.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'data/UbuntuOne-Go_Daddy_CA.pem'
2--- data/UbuntuOne-Go_Daddy_CA.pem 1970-01-01 00:00:00 +0000
3+++ data/UbuntuOne-Go_Daddy_CA.pem 2013-05-22 20:16:26 +0000
4@@ -0,0 +1,29 @@
5+-----BEGIN CERTIFICATE-----
6+MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
7+ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
8+RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
9+MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
10+QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
11+b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
12+b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
13+YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
14+AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
15+KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
16+VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
17+SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
18+cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
19+6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
20+MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
21+kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
22+BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
23+BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
24+c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
25+AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
26+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
27+OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
28+A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
29+0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
30+RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
31+qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
32+U+4=
33+-----END CERTIFICATE-----
34
35=== added file 'data/UbuntuOne-Go_Daddy_Class_2_CA.pem'
36--- data/UbuntuOne-Go_Daddy_Class_2_CA.pem 1970-01-01 00:00:00 +0000
37+++ data/UbuntuOne-Go_Daddy_Class_2_CA.pem 2013-05-22 20:16:26 +0000
38@@ -0,0 +1,25 @@
39+-----BEGIN CERTIFICATE-----
40+MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJV
41+UzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQL
42+EyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X
43+DTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMx
44+ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMo
45+R28gRGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAw
46+DQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d
47+/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9
48+S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32qRe3H3I2
49+TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVl
50+OARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFA
51+pMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44
52+dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLEsNKR1EwRcbNh
53+yz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2oatTj
54+oWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdy
55+b3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
56+YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
57+BQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYX
58+MP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
59+I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheab
60+IZ0KbIIOqPjCDPoQHmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzr
61+Tia2cyvk0/ZM/iZx4mERdEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBD
62+pqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/bvZ8=
63+-----END CERTIFICATE-----
64
65=== added file 'data/UbuntuOne-ValiCert_Class_2_VA.pem'
66--- data/UbuntuOne-ValiCert_Class_2_VA.pem 1970-01-01 00:00:00 +0000
67+++ data/UbuntuOne-ValiCert_Class_2_VA.pem 2013-05-22 20:16:26 +0000
68@@ -0,0 +1,18 @@
69+-----BEGIN CERTIFICATE-----
70+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
71+IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
72+BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
73+aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
74+9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
75+NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
76+azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
77+YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
78+Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
79+cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
80+dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
81+WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
82+v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
83+UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
84+IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
85+W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
86+-----END CERTIFICATE-----
87
88=== modified file 'setup.py'
89--- setup.py 2013-04-03 18:50:39 +0000
90+++ setup.py 2013-05-22 20:16:26 +0000
91@@ -47,6 +47,8 @@
92
93 from distutils import log
94
95+from ubuntu_sso.utils import get_cert_dir
96+
97 PROJECT_NAME = 'ubuntu-sso-client'
98 VERSION = '4.3'
99
100@@ -285,14 +287,17 @@
101 cmdclass['build_i18n'] = dummy_build_i18n
102
103
104-def setup_windows():
105- """Provide the required info to setup the project on windows."""
106+data_files = [(get_cert_dir(),
107+ ['data/UbuntuOne-Go_Daddy_CA.pem',
108+ 'data/UbuntuOne-ValiCert_Class_2_VA.pem',
109+ 'data/UbuntuOne-Go_Daddy_Class_2_CA.pem'])]
110+
111+if sys.platform == 'win32':
112 set_py2exe_paths()
113- _data_files = []
114 # for PyQt, see http://www.py2exe.org/index.cgi/Py2exeAndPyQt
115 _includes = ['sip', 'email', 'ubuntu_sso.qt.gui',
116 'ubuntu_sso.qt.controllers', 'PyQt4.QtNetwork', 'PIL']
117- _extra = {
118+ extra = {
119 'options': {
120 'py2exe': {
121 'bundle_files': 1,
122@@ -306,15 +311,11 @@
123 'console': sso_executables,
124 'zipfile': None,
125 }
126- return _data_files, _extra
127-
128-if sys.platform == 'win32':
129- data_files, extra = setup_windows()
130 else:
131- data_files = [
132+ data_files.extend([
133 ('lib/ubuntu-sso-client', sso_executables),
134 ('share/dbus-1/services', ['data/com.ubuntu.sso.service']),
135- ]
136+ ])
137 extra = {}
138
139 DistUtilsExtra.auto.setup(
140
141=== modified file 'ubuntu_sso/utils/__init__.py'
142--- ubuntu_sso/utils/__init__.py 2012-10-23 14:17:58 +0000
143+++ ubuntu_sso/utils/__init__.py 2013-05-22 20:16:26 +0000
144@@ -33,6 +33,7 @@
145 import os
146 import sys
147
148+from dirspec.basedir import load_config_paths
149 from dirspec.utils import get_program_path
150
151 from twisted.internet import defer
152@@ -141,6 +142,30 @@
153 return cmd_args
154
155
156+def get_cert_dir():
157+ """Return directory containing certificate files."""
158+
159+ if getattr(sys, "frozen", None) is not None:
160+ if sys.platform == "win32":
161+ ssl_cert_location = list(load_config_paths(
162+ "ubuntuone"))[1]
163+ elif sys.platform == "darwin":
164+ main_app_dir = "".join(__file__.partition(".app")[:-1])
165+ main_app_resources_dir = os.path.join(main_app_dir,
166+ "Contents",
167+ "Resources")
168+ ssl_cert_location = main_app_resources_dir
169+ elif any(plat in sys.platform for plat in ("win32", "darwin")):
170+ pkg_dir = os.path.dirname(__file__)
171+ src_tree_path = os.path.dirname(os.path.dirname(pkg_dir))
172+ ssl_cert_location = os.path.join(src_tree_path,
173+ "data")
174+ else:
175+ ssl_cert_location = '/etc/ssl/certs'
176+
177+ return ssl_cert_location
178+
179+
180 @defer.inlineCallbacks
181 def ping_url(url, email, credentials):
182 """Ping the 'url' with the 'email' attached to it.
183
184=== modified file 'ubuntu_sso/utils/tests/test_common.py'
185--- ubuntu_sso/utils/tests/test_common.py 2013-02-11 21:52:34 +0000
186+++ ubuntu_sso/utils/tests/test_common.py 2013-05-22 20:16:26 +0000
187@@ -32,6 +32,7 @@
188
189 import logging
190 import sys
191+import os
192
193 from twisted.internet import defer
194 from twisted.web import resource
195@@ -167,6 +168,49 @@
196 self.assertEqual(expected, result)
197
198
199+class GetCertDirTestCase(TestCase):
200+ """Test determining the cert location."""
201+
202+ @defer.inlineCallbacks
203+ def setUp(self):
204+ yield super(GetCertDirTestCase, self).setUp()
205+
206+ def test_win(self):
207+ """Test geting a path when Common AppData is defined."""
208+ self.patch(utils, "__file__",
209+ os.path.join("path", "to", "ubuntu_sso",
210+ "utils", "__init__.py"))
211+ self.patch(sys, "platform", "win32")
212+ path = utils.get_cert_dir()
213+ self.assertEqual(path, os.path.join("path", "to", "data"))
214+
215+ def test_darwin_frozen(self):
216+ """Test that we get a path with .app in it on frozen darwin."""
217+ self.patch(sys, "platform", "darwin")
218+ sys.frozen = "macosx-app"
219+ self.addCleanup(delattr, sys, "frozen")
220+ self.patch(utils, "__file__",
221+ os.path.join("path", "to", "Main.app", "ignore"))
222+ path = utils.get_cert_dir()
223+ self.assertEqual(path, os.path.join("path", "to", "Main.app",
224+ "Contents", "Resources"))
225+
226+ def test_darwin_unfrozen(self):
227+ """Test that we get a source-relative path on unfrozen darwin."""
228+ self.patch(sys, "platform", "darwin")
229+ self.patch(utils, "__file__",
230+ os.path.join("path", "to", "ubuntuone",
231+ "utils", "__init__.py"))
232+ path = utils.get_cert_dir()
233+ self.assertEqual(path, os.path.join("path", "to", "data"))
234+
235+ def test_linux(self):
236+ """Test that linux gets the right path."""
237+ self.patch(sys, "platform", "linux2")
238+ path = utils.get_cert_dir()
239+ self.assertEqual(path, "/etc/ssl/certs")
240+
241+
242 class RootResource(resource.Resource):
243 """A root resource that logs the number of calls."""
244
245
246=== modified file 'ubuntu_sso/utils/webclient/qtnetwork.py'
247--- ubuntu_sso/utils/webclient/qtnetwork.py 2013-03-28 21:50:02 +0000
248+++ ubuntu_sso/utils/webclient/qtnetwork.py 2013-05-22 20:16:26 +0000
249@@ -30,6 +30,8 @@
250
251 from __future__ import unicode_literals
252
253+import glob
254+import os
255 import sys
256 from io import StringIO
257
258@@ -47,10 +49,12 @@
259 QNetworkReply,
260 QNetworkRequest,
261 QSslCertificate,
262+ QSslConfiguration,
263 )
264 from twisted.internet import defer
265
266 from ubuntu_sso.logger import setup_logging
267+from ubuntu_sso.utils import get_cert_dir
268 from ubuntu_sso.utils.webclient.common import (
269 BaseWebClient,
270 HeaderDict,
271@@ -102,6 +106,25 @@
272 self.proxy_retry = False
273 self.setup_proxy()
274
275+ # Apply our local certificates as the SSL configuration to be used
276+ # for all QNetworkRequest calls.
277+ self.ssl_config = QSslConfiguration.defaultConfiguration()
278+ ca_certs = self.ssl_config.caCertificates()
279+ try:
280+ for path in glob.glob(os.path.join(get_cert_dir(),
281+ "UbuntuOne*.pem")):
282+ with open(path) as f:
283+ cert = QSslCertificate(f.read())
284+ if cert.isValid():
285+ ca_certs.append(cert)
286+ else:
287+ logger.error("invalid certificate: {}".format(path))
288+ except (IndexError, IOError) as err:
289+ raise WebClientError(
290+ "Unable to configure SSL certificates: {}".format(err))
291+
292+ self.ssl_config.setCaCertificates(ca_certs)
293+
294 def _set_proxy(self, proxy):
295 """Set the proxy to be used."""
296 QNetworkProxy.setApplicationProxy(proxy)
297@@ -157,6 +180,7 @@
298 """Return a deferred that will be fired with a Response object."""
299 uri = self.iri_to_uri(iri)
300 request = QNetworkRequest(QUrl(uri))
301+ request.setSslConfiguration(self.ssl_config)
302 headers = yield self.build_request_headers(uri, method, extra_headers,
303 oauth_credentials)
304
305
306=== modified file 'ubuntu_sso/utils/webclient/tests/test_qtnetwork.py'
307--- ubuntu_sso/utils/webclient/tests/test_qtnetwork.py 2012-12-14 22:06:47 +0000
308+++ ubuntu_sso/utils/webclient/tests/test_qtnetwork.py 2013-05-22 20:16:26 +0000
309@@ -47,6 +47,8 @@
310 self.settings = dict(https=dict(username='user', password='pasword'))
311 self.patch(qtnetwork.gsettings, 'get_proxy_settings',
312 lambda: self.settings)
313+ self.patch(qtnetwork, "get_cert_dir", lambda: "")
314+ self.patch(qtnetwork.glob, "glob", lambda dir: [])
315
316 self.proxy = None
317
318@@ -69,6 +71,21 @@
319 def _clean_webclient_instance(self):
320 """Set the webclient not to have a proxy."""
321 qtnetwork.WebClient.proxy_instance = None
322+
323+ def test_setup_no_certs(self):
324+ # Ensure WebClient can start even if it finds no certs.
325+ # It may or may not end up working depending on the certs actually
326+ # being in the system, but not having them locally shouldn't prevent
327+ # startup.
328+ qtnetwork.WebClient()
329+
330+ def test_setup_unreadable_cert(self):
331+ # If for some reason a cert of our own is found but can't be read,
332+ # make sure we raise WebClientError.
333+ # glob only returns paths that actually exist, but we fake this by
334+ # passing something that can't be opened.
335+ self.patch(qtnetwork.glob, "glob", lambda dir: ["asdfasdfasdf"])
336+ self.assertRaises(qtnetwork.WebClientError, qtnetwork.WebClient)
337
338
339 class SetupLinuxProxyTestCase(SetupProxyTestCase):

Subscribers

People subscribed via source and target branches