mongo 2.11.3 → 2.11.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,27 +3,18 @@ require 'spec_helper'
3
3
  # this test performs direct network connections without retries.
4
4
  # In case of intermittent network issues, retry the entire failing test.
5
5
  describe Mongo::Socket::SSL, retry: 3 do
6
+ clean_slate_for_all
6
7
  require_tls
7
8
 
8
- let(:address) do
9
- default_address.tap do
10
- ClientRegistry.instance.close_all_clients
11
- end
12
- end
13
-
14
- let!(:resolver) do
15
- address.send(:create_resolver, {})
16
- end
17
-
18
- let(:socket_timeout) do
19
- 1
20
- end
9
+ let(:host_name) { 'localhost' }
21
10
 
22
11
  let(:socket) do
23
- resolver.socket(socket_timeout, options)
12
+ described_class.new('127.0.0.1', default_address.port,
13
+ host_name, 1, :INET, ssl_options.merge(
14
+ connect_timeout: 2.4))
24
15
  end
25
16
 
26
- let(:options) do
17
+ let(:ssl_options) do
27
18
  SpecConfig.instance.ssl_options
28
19
  end
29
20
 
@@ -82,7 +73,7 @@ describe Mongo::Socket::SSL, retry: 3 do
82
73
 
83
74
  context 'when a certificate and key are provided as strings' do
84
75
 
85
- let(:options) do
76
+ let(:ssl_options) do
86
77
  {
87
78
  :ssl => true,
88
79
  :ssl_cert_string => cert_string,
@@ -99,7 +90,7 @@ describe Mongo::Socket::SSL, retry: 3 do
99
90
  context 'when certificate and an encrypted key are provided as strings' do
100
91
  require_local_tls
101
92
 
102
- let(:options) do
93
+ let(:ssl_options) do
103
94
  {
104
95
  :ssl => true,
105
96
  :ssl_cert_string => cert_string,
@@ -116,7 +107,7 @@ describe Mongo::Socket::SSL, retry: 3 do
116
107
 
117
108
  context 'when a certificate and key are provided as objects' do
118
109
 
119
- let(:options) do
110
+ let(:ssl_options) do
120
111
  {
121
112
  :ssl => true,
122
113
  :ssl_cert_object => cert_object,
@@ -132,7 +123,7 @@ describe Mongo::Socket::SSL, retry: 3 do
132
123
 
133
124
  context 'when the certificate is specified using both a file and a PEM-encoded string' do
134
125
 
135
- let(:options) do
126
+ let(:ssl_options) do
136
127
  super().merge(
137
128
  :ssl_cert_string => 'This is a random string, not a PEM-encoded certificate'
138
129
  )
@@ -146,7 +137,7 @@ describe Mongo::Socket::SSL, retry: 3 do
146
137
 
147
138
  context 'when the certificate is specified using both a file and an object' do
148
139
 
149
- let(:options) do
140
+ let(:ssl_options) do
150
141
  super().merge(
151
142
  :ssl_cert_object => 'This is a string, not a certificate'
152
143
  )
@@ -160,7 +151,7 @@ describe Mongo::Socket::SSL, retry: 3 do
160
151
 
161
152
  context 'when the certificate is specified using both a PEM-encoded string and an object' do
162
153
 
163
- let(:options) do
154
+ let(:ssl_options) do
164
155
  {
165
156
  :ssl => true,
166
157
  :ssl_cert_string => cert_string,
@@ -178,7 +169,7 @@ describe Mongo::Socket::SSL, retry: 3 do
178
169
 
179
170
  context 'when the key is specified using both a file and a PEM-encoded string' do
180
171
 
181
- let(:options) do
172
+ let(:ssl_options) do
182
173
  super().merge(
183
174
  :ssl_key_string => 'This is a normal string, not a PEM-encoded key'
184
175
  )
@@ -192,7 +183,7 @@ describe Mongo::Socket::SSL, retry: 3 do
192
183
 
193
184
  context 'when the key is specified using both a file and an object' do
194
185
 
195
- let(:options) do
186
+ let(:ssl_options) do
196
187
  super().merge(
197
188
  :ssl_cert_object => 'This is a string, not a key'
198
189
  )
@@ -206,7 +197,7 @@ describe Mongo::Socket::SSL, retry: 3 do
206
197
 
207
198
  context 'when the key is specified using both a PEM-encoded string and an object' do
208
199
 
209
- let(:options) do
200
+ let(:ssl_options) do
210
201
  {
211
202
  :ssl => true,
212
203
  :ssl_cert => SpecConfig.instance.client_cert_path,
@@ -224,7 +215,7 @@ describe Mongo::Socket::SSL, retry: 3 do
224
215
 
225
216
  context 'when a certificate is passed, but it is not of the right type' do
226
217
 
227
- let(:options) do
218
+ let(:ssl_options) do
228
219
  cert = "This is a string, not an X.509 Certificate"
229
220
  {
230
221
  :ssl => true,
@@ -247,38 +238,27 @@ describe Mongo::Socket::SSL, retry: 3 do
247
238
  end
248
239
 
249
240
  context 'when the hostname is verified' do
250
- it 'raises an error' do
251
- error = nil
252
- begin
253
- described_class.new(
254
- resolver.host,
255
- resolver.port,
256
- host_name,
257
- 30,
258
- ::Socket::PF_INET,
259
- options.merge(ssl_verify: false, ssl_verify_hostname: true)
260
- )
261
- rescue => e
262
- error = e
263
- end
264
241
 
265
- expect(error).to be_a(Mongo::Error::SocketError)
266
- expect(error.message).to eq('SSL handshake failed due to a hostname mismatch.')
242
+ let(:ssl_options) do
243
+ SpecConfig.instance.ssl_options.merge(ssl_verify: false, ssl_verify_hostname: true)
244
+ end
245
+
246
+ it 'raises an error' do
247
+ lambda do
248
+ socket
249
+ end.should raise_error(Mongo::Error::SocketError, /SSL handshake failed due to a hostname mismatch/)
267
250
  end
268
251
  end
269
252
 
270
253
  context 'when the hostname is not verified' do
271
- it 'raises an error' do
272
- expect {
273
- described_class.new(
274
- resolver.host,
275
- resolver.port,
276
- host_name,
277
- 30,
278
- ::Socket::PF_INET,
279
- options.merge(ssl_verify: false, ssl_verify_hostname: false)
280
- )
281
- }.not_to raise_error
254
+ let(:ssl_options) do
255
+ SpecConfig.instance.ssl_options.merge(ssl_verify: false, ssl_verify_hostname: false)
256
+ end
257
+
258
+ it 'does not raise an error' do
259
+ lambda do
260
+ socket
261
+ end.should_not raise_error
282
262
  end
283
263
  end
284
264
  end
@@ -288,7 +268,7 @@ describe Mongo::Socket::SSL, retry: 3 do
288
268
 
289
269
  context 'when a key is passed, but it is not of the right type' do
290
270
 
291
- let(:options) do
271
+ let(:ssl_options) do
292
272
  key = "This is a string not a key"
293
273
  {
294
274
  :ssl => true,
@@ -315,7 +295,7 @@ describe Mongo::Socket::SSL, retry: 3 do
315
295
 
316
296
  context 'when a key is passed, but it is not of the right type' do
317
297
 
318
- let(:options) do
298
+ let(:ssl_options) do
319
299
  key = "This is a string not a key"
320
300
  {
321
301
  :ssl => true,
@@ -347,35 +327,82 @@ describe Mongo::Socket::SSL, retry: 3 do
347
327
  end
348
328
  end
349
329
 
350
- context 'when a bad certificate is provided' do
330
+ context 'when a bad certificate/key is provided' do
351
331
 
352
- let(:options) do
353
- super().merge(
354
- :ssl_key => COMMAND_MONITORING_TESTS.first
355
- )
332
+ shared_examples_for 'raises an exception' do
333
+ it 'raises an exception' do
334
+ expect do
335
+ socket
336
+ end.to raise_exception(*expected_exception)
337
+ end
356
338
  end
357
339
 
358
- let(:expected_exception) do
359
- if SpecConfig.instance.jruby?
360
- # java.lang.ClassCastException: org.bouncycastle.asn1.DERApplicationSpecific cannot be cast to org.bouncycastle.asn1.ASN1Sequence
361
- # https://github.com/jruby/jruby-openssl/issues/171
362
- Exception
363
- else
364
- # mri
365
- if RUBY_VERSION >= '2.4.0'
366
- # OpenSSL::PKey::PKeyError: Could not parse PKey: no start line
367
- OpenSSL::OpenSSLError
368
- else
369
- # ArgumentError: Could not parse PKey: no start line
370
- ArgumentError
340
+ context 'mri' do
341
+ only_mri
342
+
343
+ context 'when a bad certificate is provided' do
344
+
345
+ let(:expected_exception) do
346
+ # OpenSSL::X509::CertificateError: nested asn1 error
347
+ [OpenSSL::OpenSSLError, /asn1 error/i]
348
+ end
349
+
350
+ let(:ssl_options) do
351
+ super().merge(
352
+ :ssl_cert => COMMAND_MONITORING_TESTS.first,
353
+ :ssl_key => nil,
354
+ )
355
+ end
356
+
357
+ it_behaves_like 'raises an exception'
358
+ end
359
+
360
+ context 'when a bad key is provided' do
361
+
362
+ let(:expected_exception) do
363
+ if RUBY_VERSION >= '2.4.0'
364
+ # OpenSSL::PKey::PKeyError: Could not parse PKey: no start line
365
+ [OpenSSL::OpenSSLError, /Could not parse PKey/]
366
+ else
367
+ # ArgumentError: Could not parse PKey: no start line
368
+ [ArgumentError, /Could not parse PKey/]
369
+ end
370
+ end
371
+
372
+ let(:ssl_options) do
373
+ super().merge(
374
+ :ssl_cert => nil,
375
+ :ssl_key => COMMAND_MONITORING_TESTS.first,
376
+ )
371
377
  end
378
+
379
+ it_behaves_like 'raises an exception'
372
380
  end
373
381
  end
374
382
 
375
- it 'raises an exception' do
376
- expect do
377
- socket
378
- end.to raise_exception(expected_exception)
383
+ context 'jruby' do
384
+ require_jruby
385
+
386
+ # On JRuby the key does not appear to be parsed, therefore only
387
+ # specifying the bad certificate produces an error.
388
+
389
+ context 'when a bad certificate is provided' do
390
+
391
+ let(:ssl_options) do
392
+ super().merge(
393
+ :ssl_cert => COMMAND_MONITORING_TESTS.first,
394
+ :ssl_key => nil,
395
+ )
396
+ end
397
+
398
+ let(:expected_exception) do
399
+ # java.lang.ClassCastException: org.bouncycastle.asn1.DERApplicationSpecific cannot be cast to org.bouncycastle.asn1.ASN1Sequence
400
+ # OpenSSL::X509::CertificateError: parsing issue: malformed PEM data: no header found
401
+ [OpenSSL::OpenSSLError, /malformed pem data/i]
402
+ end
403
+
404
+ it_behaves_like 'raises an exception'
405
+ end
379
406
  end
380
407
  end
381
408
 
@@ -384,7 +411,7 @@ describe Mongo::Socket::SSL, retry: 3 do
384
411
 
385
412
  context 'as a path to a file' do
386
413
 
387
- let(:options) do
414
+ let(:ssl_options) do
388
415
  super().merge(
389
416
  :ssl_ca_cert => SpecConfig.instance.local_ca_cert_path,
390
417
  :ssl_verify => true
@@ -398,7 +425,7 @@ describe Mongo::Socket::SSL, retry: 3 do
398
425
 
399
426
  context 'as a string containing the PEM-encoded certificate' do
400
427
 
401
- let(:options) do
428
+ let(:ssl_options) do
402
429
  super().merge(
403
430
  :ssl_ca_cert_string => ca_cert_string,
404
431
  :ssl_verify => true
@@ -411,7 +438,7 @@ describe Mongo::Socket::SSL, retry: 3 do
411
438
  end
412
439
 
413
440
  context 'as an array of Certificate objects' do
414
- let(:options) do
441
+ let(:ssl_options) do
415
442
  cert = [OpenSSL::X509::Certificate.new(ca_cert_string)]
416
443
  super().merge(
417
444
  :ssl_ca_cert_object => cert,
@@ -426,7 +453,7 @@ describe Mongo::Socket::SSL, retry: 3 do
426
453
 
427
454
  context 'both as a file and a PEM-encoded parameter' do
428
455
 
429
- let(:options) do
456
+ let(:ssl_options) do
430
457
  super().merge(
431
458
  :ssl_ca_cert => SpecConfig.instance.local_ca_cert_path,
432
459
  :ssl_ca_cert_string => 'This is a string, not a certificate',
@@ -442,7 +469,7 @@ describe Mongo::Socket::SSL, retry: 3 do
442
469
 
443
470
  context 'both as a file and as object parameter' do
444
471
 
445
- let(:options) do
472
+ let(:ssl_options) do
446
473
  super().merge(
447
474
  :ssl_ca_cert => SpecConfig.instance.local_ca_cert_path,
448
475
  :ssl_ca_cert_object => 'This is a string, not an array of certificates',
@@ -457,7 +484,7 @@ describe Mongo::Socket::SSL, retry: 3 do
457
484
 
458
485
  context 'both as a PEM-encoded string and as object parameter' do
459
486
 
460
- let(:options) do
487
+ let(:ssl_options) do
461
488
  cert = File.read(SpecConfig.instance.local_ca_cert_path)
462
489
  super().merge(
463
490
  :ssl_ca_cert_string => cert,
@@ -480,11 +507,11 @@ describe Mongo::Socket::SSL, retry: 3 do
480
507
  end
481
508
 
482
509
  let(:connection) do
483
- Mongo::Server::Connection.new(server, options.merge(socket_timeout: 2))
510
+ Mongo::Server::Connection.new(server, ssl_options.merge(socket_timeout: 2))
484
511
  end
485
512
 
486
513
  context 'as a file' do
487
- let(:options) do
514
+ let(:ssl_options) do
488
515
  SpecConfig.instance.test_options.merge(
489
516
  ssl: true,
490
517
  ssl_cert: SpecConfig.instance.client_cert_path,
@@ -511,11 +538,11 @@ describe Mongo::Socket::SSL, retry: 3 do
511
538
  end
512
539
 
513
540
  let(:connection) do
514
- Mongo::Server::Connection.new(server, options.merge(socket_timeout: 2))
541
+ Mongo::Server::Connection.new(server, ssl_options.merge(socket_timeout: 2))
515
542
  end
516
543
 
517
544
  context 'as a file' do
518
- let(:options) do
545
+ let(:ssl_options) do
519
546
  SpecConfig.instance.test_options.merge(
520
547
  ssl: true,
521
548
  ssl_cert: SpecConfig.instance.client_cert_path,
@@ -537,7 +564,7 @@ describe Mongo::Socket::SSL, retry: 3 do
537
564
  context 'when a CA certificate is not provided' do
538
565
  require_local_tls
539
566
 
540
- let(:options) do
567
+ let(:ssl_options) do
541
568
  super().merge(
542
569
  :ssl_verify => true
543
570
  )
@@ -566,12 +593,12 @@ describe Mongo::Socket::SSL, retry: 3 do
566
593
  end
567
594
 
568
595
  let(:connection) do
569
- Mongo::Server::Connection.new(server, options.merge(socket_timeout: 2))
596
+ Mongo::Server::Connection.new(server, ssl_options.merge(socket_timeout: 2))
570
597
  end
571
598
 
572
599
  context 'as a path to a file' do
573
600
  context 'standalone' do
574
- let(:options) do
601
+ let(:ssl_options) do
575
602
  SpecConfig.instance.test_options.merge(
576
603
  ssl_cert: SpecConfig.instance.second_level_cert_path,
577
604
  ssl_key: SpecConfig.instance.second_level_key_path,
@@ -581,6 +608,13 @@ describe Mongo::Socket::SSL, retry: 3 do
581
608
  end
582
609
 
583
610
  it 'fails' do
611
+ # This test provides a second level client certificate to the
612
+ # server *without* providing the intermediate certificate.
613
+ # If the server performs certificate verification, it will
614
+ # reject the connection (seen from the driver as a SocketError)
615
+ # and the test will succeed. If the server does not perform
616
+ # certificate verification, it will accept the connection,
617
+ # no SocketError will be raised and the test will fail.
584
618
  connection
585
619
  expect do
586
620
  connection.connect!
@@ -593,7 +627,7 @@ describe Mongo::Socket::SSL, retry: 3 do
593
627
  # https://github.com/jruby/jruby-openssl/issues/181
594
628
  only_mri
595
629
 
596
- let(:options) do
630
+ let(:ssl_options) do
597
631
  SpecConfig.instance.test_options.merge(
598
632
  ssl: true,
599
633
  ssl_cert: SpecConfig.instance.second_level_cert_bundle_path,
@@ -614,7 +648,7 @@ describe Mongo::Socket::SSL, retry: 3 do
614
648
 
615
649
  context 'as a string' do
616
650
  context 'standalone' do
617
- let(:options) do
651
+ let(:ssl_options) do
618
652
  SpecConfig.instance.test_options.merge(
619
653
  ssl_cert: nil,
620
654
  ssl_cert_string: File.read(SpecConfig.instance.second_level_cert_path),
@@ -638,7 +672,7 @@ describe Mongo::Socket::SSL, retry: 3 do
638
672
  # https://github.com/jruby/jruby-openssl/issues/181
639
673
  only_mri
640
674
 
641
- let(:options) do
675
+ let(:ssl_options) do
642
676
  SpecConfig.instance.test_options.merge(
643
677
  ssl: true,
644
678
  ssl_cert: nil,
@@ -668,11 +702,11 @@ describe Mongo::Socket::SSL, retry: 3 do
668
702
  end
669
703
 
670
704
  let(:connection) do
671
- Mongo::Server::Connection.new(server, options.merge(socket_timeout: 2))
705
+ Mongo::Server::Connection.new(server, ssl_options.merge(socket_timeout: 2))
672
706
  end
673
707
 
674
- let(:options) do
675
- SpecConfig.instance.test_options.merge(
708
+ let(:ssl_options) do
709
+ SpecConfig.instance.ssl_options.merge(
676
710
  ssl: true,
677
711
  ssl_cert: SpecConfig.instance.client_pem_path,
678
712
  ssl_key: SpecConfig.instance.client_pem_path,
@@ -692,7 +726,7 @@ describe Mongo::Socket::SSL, retry: 3 do
692
726
  context 'when ssl_verify is not specified' do
693
727
  require_local_tls
694
728
 
695
- let(:options) do
729
+ let(:ssl_options) do
696
730
  super().merge(
697
731
  :ssl_ca_cert => SpecConfig.instance.local_ca_cert_path
698
732
  ).tap { |options| options.delete(:ssl_verify) }
@@ -706,7 +740,7 @@ describe Mongo::Socket::SSL, retry: 3 do
706
740
  context 'when ssl_verify is true' do
707
741
  require_local_tls
708
742
 
709
- let(:options) do
743
+ let(:ssl_options) do
710
744
  super().merge(
711
745
  :ssl_ca_cert => SpecConfig.instance.local_ca_cert_path,
712
746
  :ssl_verify => true
@@ -720,7 +754,7 @@ describe Mongo::Socket::SSL, retry: 3 do
720
754
 
721
755
  context 'when ssl_verify is false' do
722
756
 
723
- let(:options) do
757
+ let(:ssl_options) do
724
758
  super().merge(
725
759
  :ssl_ca_cert => 'invalid',
726
760
  :ssl_verify => false