mongo 2.11.3 → 2.11.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongo/address.rb +53 -37
- data/lib/mongo/server/connection.rb +1 -2
- data/lib/mongo/server/monitor/connection.rb +1 -2
- data/lib/mongo/socket.rb +10 -1
- data/lib/mongo/version.rb +1 -1
- data/spec/integration/bson_symbol_spec.rb +34 -0
- data/spec/integration/connection_spec.rb +57 -9
- data/spec/integration/retryable_errors_spec.rb +2 -2
- data/spec/mongo/address_spec.rb +19 -13
- data/spec/mongo/auth/scram/conversation_spec.rb +2 -0
- data/spec/mongo/collection_spec.rb +2 -2
- data/spec/mongo/server/connection_spec.rb +6 -6
- data/spec/mongo/server/monitor/connection_spec.rb +6 -6
- data/spec/mongo/socket/ssl_spec.rb +132 -98
- data/spec/mongo/socket/tcp_spec.rb +1 -9
- data/spec/support/cluster_tools.rb +5 -3
- data/spec/support/lite_constraints.rb +8 -0
- metadata +632 -630
- metadata.gz.sig +0 -0
@@ -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(:
|
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
|
-
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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
|
-
|
266
|
-
|
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
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
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(:
|
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(:
|
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
|
-
|
353
|
-
|
354
|
-
|
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
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
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
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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,
|
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(:
|
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,
|
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(:
|
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(:
|
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,
|
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(:
|
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(:
|
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(:
|
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(:
|
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,
|
705
|
+
Mongo::Server::Connection.new(server, ssl_options.merge(socket_timeout: 2))
|
672
706
|
end
|
673
707
|
|
674
|
-
let(:
|
675
|
-
SpecConfig.instance.
|
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(:
|
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(:
|
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(:
|
757
|
+
let(:ssl_options) do
|
724
758
|
super().merge(
|
725
759
|
:ssl_ca_cert => 'invalid',
|
726
760
|
:ssl_verify => false
|