1919import sys
2020import unittest
2121
22+ sys .path [0 :0 ] = ["" ]
23+
2224try :
2325 from ssl import CertificateError
2426except ImportError :
2527 # Backport.
2628 from pymongo .ssl_match_hostname import CertificateError
2729
28- sys .path [0 :0 ] = ["" ]
29-
3030from urllib import quote_plus
3131
3232from nose .plugins .skip import SkipTest
3333
3434from pymongo import MongoClient , MongoReplicaSetClient
35- from pymongo .common import HAS_SSL
35+ from pymongo .common import HAS_SSL , validate_cert_reqs
3636from pymongo .errors import (ConfigurationError ,
3737 ConnectionFailure ,
3838 OperationFailure )
5252
5353# To fully test this start a mongod instance (built with SSL support) like so:
5454# mongod --dbpath /path/to/data/directory --sslOnNormalPorts \
55- # --sslPEMKeyFile /path/to/mongo/jstests/libs /server.pem \
56- # --sslCAFile /path/to/mongo/jstests/libs /ca.pem \
57- # --sslCRLFile /path/to/mongo/jstests/libs /crl.pem \
55+ # --sslPEMKeyFile /path/to/pymongo/test/certificates /server.pem \
56+ # --sslCAFile /path/to/pymongo/test/certificates /ca.pem \
57+ # --sslCRLFile /path/to/pymongo/test/certificates /crl.pem \
5858# --sslWeakCertificateValidation
5959# Also, make sure you have 'server' as an alias for localhost in /etc/hosts
6060#
@@ -85,17 +85,19 @@ def is_server_resolvable():
8585 MongoClient (host , port , connectTimeoutMS = 100 , ssl = True )
8686 SIMPLE_SSL = True
8787 except ConnectionFailure :
88- # Is MongoDB configured with server.pem, ca.pem, and crl.pem from
89- # mongodb jstests/lib?
90- try :
91- MongoClient (host , port , connectTimeoutMS = 100 , ssl = True ,
92- ssl_certfile = CLIENT_PEM )
93- CERT_SSL = True
94- except ConnectionFailure :
95- pass
88+ pass
89+
90+ # Is MongoDB configured with server.pem, ca.pem, and crl.pem from
91+ # mongodb jstests/lib?
92+ try :
93+ MongoClient (host , port , connectTimeoutMS = 100 , ssl = True ,
94+ ssl_certfile = CLIENT_PEM )
95+ CERT_SSL = True
96+ except ConnectionFailure :
97+ pass
9698
97- if CERT_SSL :
98- SERVER_IS_RESOLVABLE = is_server_resolvable ()
99+ if CERT_SSL :
100+ SERVER_IS_RESOLVABLE = is_server_resolvable ()
99101
100102
101103class TestClientSSL (unittest .TestCase ):
@@ -123,7 +125,6 @@ def test_no_ssl_module(self):
123125 ssl_certfile = CLIENT_PEM )
124126
125127 def test_config_ssl (self ):
126- """Tests various ssl configurations"""
127128 self .assertRaises (ConfigurationError , MongoClient , ssl = 'foo' )
128129 self .assertRaises (ConfigurationError ,
129130 MongoClient ,
@@ -199,6 +200,39 @@ def test_config_ssl(self):
199200 ssl_keyfile = CLIENT_PEM ,
200201 ssl_certfile = CLIENT_PEM )
201202
203+ self .assertRaises (
204+ ConfigurationError , validate_cert_reqs , 'ssl_cert_reqs' , 3 )
205+ self .assertRaises (
206+ ConfigurationError , validate_cert_reqs , 'ssl_cert_reqs' , - 1 )
207+ self .assertRaises (
208+ ConfigurationError , validate_cert_reqs , 'ssl_cert_reqs' , 'foo' )
209+ self .assertEqual (
210+ validate_cert_reqs ('ssl_cert_reqs' , None ), None )
211+ self .assertEqual (
212+ validate_cert_reqs ('ssl_cert_reqs' , ssl .CERT_NONE ),
213+ ssl .CERT_NONE )
214+ self .assertEqual (
215+ validate_cert_reqs ('ssl_cert_reqs' , ssl .CERT_OPTIONAL ),
216+ ssl .CERT_OPTIONAL )
217+ self .assertEqual (
218+ validate_cert_reqs ('ssl_cert_reqs' , ssl .CERT_REQUIRED ),
219+ ssl .CERT_REQUIRED )
220+ self .assertEqual (
221+ validate_cert_reqs ('ssl_cert_reqs' , 0 ), ssl .CERT_NONE )
222+ self .assertEqual (
223+ validate_cert_reqs ('ssl_cert_reqs' , 1 ), ssl .CERT_OPTIONAL )
224+ self .assertEqual (
225+ validate_cert_reqs ('ssl_cert_reqs' , 2 ), ssl .CERT_REQUIRED )
226+ self .assertEqual (
227+ validate_cert_reqs ('ssl_cert_reqs' , 'CERT_NONE' ),
228+ ssl .CERT_NONE )
229+ self .assertEqual (
230+ validate_cert_reqs ('ssl_cert_reqs' , 'CERT_OPTIONAL' ),
231+ ssl .CERT_OPTIONAL )
232+ self .assertEqual (
233+ validate_cert_reqs ('ssl_cert_reqs' , 'CERT_REQUIRED' ),
234+ ssl .CERT_REQUIRED )
235+
202236
203237class TestSSL (unittest .TestCase ):
204238
@@ -234,9 +268,9 @@ def test_cert_ssl(self):
234268 # Expects the server to be running with the server.pem, ca.pem
235269 # and crl.pem provided in mongodb and the server tests eg:
236270 #
237- # --sslPEMKeyFile=jstests/libs /server.pem
238- # --sslCAFile=jstests/libs /ca.pem
239- # --sslCRLFile=jstests/libs /crl.pem
271+ # --sslPEMKeyFile=/path/to/pymongo/test/certificates /server.pem
272+ # --sslCAFile=/path/to/pymongo/test/certificates /ca.pem
273+ # --sslCRLFile=/path/to/pymongo/test/certificates /crl.pem
240274 #
241275 # Also requires an /etc/hosts entry where "server" is resolvable
242276 if not CERT_SSL :
@@ -260,9 +294,9 @@ def test_cert_ssl_implicitly_set(self):
260294 # Expects the server to be running with the server.pem, ca.pem
261295 # and crl.pem provided in mongodb and the server tests eg:
262296 #
263- # --sslPEMKeyFile=jstests/libs /server.pem
264- # --sslCAFile=jstests/libs /ca.pem
265- # --sslCRLFile=jstests/libs /crl.pem
297+ # --sslPEMKeyFile=/path/to/pymongo/test/certificates /server.pem
298+ # --sslCAFile=/path/to/pymongo/test/certificates /ca.pem
299+ # --sslCRLFile=/path/to/pymongo/test/certificates /crl.pem
266300 #
267301 # Also requires an /etc/hosts entry where "server" is resolvable
268302 if not CERT_SSL :
@@ -286,9 +320,9 @@ def test_cert_ssl_validation(self):
286320 # Expects the server to be running with the server.pem, ca.pem
287321 # and crl.pem provided in mongodb and the server tests eg:
288322 #
289- # --sslPEMKeyFile=jstests/libs /server.pem
290- # --sslCAFile=jstests/libs /ca.pem
291- # --sslCRLFile=jstests/libs /crl.pem
323+ # --sslPEMKeyFile=/path/to/pymongo/test/certificates /server.pem
324+ # --sslCAFile=/path/to/pymongo/test/certificates /ca.pem
325+ # --sslCRLFile=/path/to/pymongo/test/certificates /crl.pem
292326 #
293327 # Also requires an /etc/hosts entry where "server" is resolvable
294328 if not CERT_SSL :
@@ -323,13 +357,39 @@ def test_cert_ssl_validation(self):
323357 self .assertTrue (db .test .find_one ()['ssl' ])
324358 client .drop_database ('pymongo_ssl_test' )
325359
360+ def test_cert_ssl_uri_support (self ):
361+ # Expects the server to be running with the server.pem, ca.pem
362+ # and crl.pem provided in mongodb and the server tests eg:
363+ #
364+ # --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
365+ # --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
366+ # --sslCRLFile=/path/to/pymongo/test/certificates/crl.pem
367+ #
368+ # Also requires an /etc/hosts entry where "server" is resolvable
369+ if not CERT_SSL :
370+ raise SkipTest ("No mongod available over SSL with certs" )
371+
372+ if not SERVER_IS_RESOLVABLE :
373+ raise SkipTest ("No hosts entry for 'server'. Cannot validate "
374+ "hostname in the certificate" )
375+
376+ uri_fmt = ("mongodb://server/?ssl=true&ssl_certfile=%s&ssl_cert_reqs"
377+ "=%s&ssl_ca_certs=%s" )
378+ client = MongoClient (uri_fmt % (CLIENT_PEM , 'CERT_REQUIRED' , CA_PEM ))
379+
380+ db = client .pymongo_ssl_test
381+ db .test .drop ()
382+ db .test .insert ({'ssl' : True })
383+ self .assertTrue (db .test .find_one ()['ssl' ])
384+ client .drop_database ('pymongo_ssl_test' )
385+
326386 def test_cert_ssl_validation_optional (self ):
327387 # Expects the server to be running with the server.pem, ca.pem
328388 # and crl.pem provided in mongodb and the server tests eg:
329389 #
330- # --sslPEMKeyFile=jstests/libs /server.pem
331- # --sslCAFile=jstests/libs /ca.pem
332- # --sslCRLFile=jstests/libs /crl.pem
390+ # --sslPEMKeyFile=/path/to/pymongo/test/certificates /server.pem
391+ # --sslCAFile=/path/to/pymongo/test/certificates /ca.pem
392+ # --sslCRLFile=/path/to/pymongo/test/certificates /crl.pem
333393 #
334394 # Also requires an /etc/hosts entry where "server" is resolvable
335395 if not CERT_SSL :
@@ -369,9 +429,9 @@ def test_cert_ssl_validation_hostname_fail(self):
369429 # Expects the server to be running with the server.pem, ca.pem
370430 # and crl.pem provided in mongodb and the server tests eg:
371431 #
372- # --sslPEMKeyFile=jstests/libs /server.pem
373- # --sslCAFile=jstests/libs /ca.pem
374- # --sslCRLFile=jstests/libs /crl.pem
432+ # --sslPEMKeyFile=/path/to/pymongo/test/certificates /server.pem
433+ # --sslCAFile=/path/to/pymongo/test/certificates /ca.pem
434+ # --sslCRLFile=/path/to/pymongo/test/certificates /crl.pem
375435 if not CERT_SSL :
376436 raise SkipTest ("No mongod available over SSL with certs" )
377437
@@ -406,9 +466,9 @@ def test_mongodb_x509_auth(self):
406466 # and crl.pem provided in mongodb and the server tests as well as
407467 # --auth
408468 #
409- # --sslPEMKeyFile=jstests/libs /server.pem
410- # --sslCAFile=jstests/libs /ca.pem
411- # --sslCRLFile=jstests/libs /crl.pem
469+ # --sslPEMKeyFile=/path/to/pymongo/test/certificates /server.pem
470+ # --sslCAFile=/path/to/pymongo/test/certificates /ca.pem
471+ # --sslCRLFile=/path/to/pymongo/test/certificates /crl.pem
412472 # --auth
413473 if not CERT_SSL :
414474 raise SkipTest ("No mongod available over SSL with certs" )
0 commit comments