CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/spec/lib/postgres/postgres-pr/connection_spec.rb
Views: 1904
1
require 'postgres/postgres-pr/connection'
2
3
RSpec.describe Msf::Db::PostgresPR::Connection do
4
describe '#negotiate_sasl' do
5
subject { described_class.allocate }
6
let(:user) { 'postgres' }
7
let(:password) { 'mysecretpassword' }
8
let(:server_responses) { [] }
9
10
before(:each) do
11
allow(subject).to receive(:write_message)
12
read_message_mock = allow(Msf::Db::PostgresPR::Message).to receive(:read)
13
read_message_mock.and_return(*server_responses) if server_responses.any?
14
allow(SecureRandom).to receive(:bytes).with(32).and_return(("\x01" * 32).b)
15
end
16
17
context 'when the mechanism contains SCRAM-SHA-256' do
18
context 'and the negotiation is a success' do
19
let(:server_responses) do
20
[
21
# server-first, containing server nonce, salt, and iteration count
22
Msf::Db::PostgresPR::AuthenticationSASLContinue.new(
23
value: 'r=AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=FUeV3rVpQpa2s8ECj3aXa6vw,s=RwsYP2UCANr95SzCJfmP4A==,i=4096'
24
),
25
# server-final, server signature
26
Msf::Db::PostgresPR::AuthenticationSASLFinal.new(
27
value: 'v=V4CwoEsGBGMe2jGf5lpKbapnqiooWXnoyuHT3VDl6WY='
28
)
29
]
30
end
31
32
it 'negotaites successfully' do
33
message = Msf::Db::PostgresPR::AuthenticationSASL.new(
34
mechanisms: ['SCRAM-SHA-256']
35
)
36
subject.negotiate_sasl(message, user, password)
37
expect(subject).to have_received(:write_message).with(
38
Msf::Db::PostgresPR::SaslInitialResponseMessage.new(
39
mechanism: 'SCRAM-SHA-256',
40
value: 'n,,n=postgres,r=AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE='
41
)
42
).ordered
43
expect(subject).to have_received(:write_message).with(
44
Msf::Db::PostgresPR::SASLResponseMessage.new(
45
value: 'c=biws,r=AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=FUeV3rVpQpa2s8ECj3aXa6vw,p=MN8FiTy5Aqut/H/TOggmlOWXHmpI/+RrnNgQFBk1eBs='
46
)
47
).ordered
48
end
49
end
50
51
context 'and server-final does not contain the expected calculated server proof' do
52
let(:server_responses) do
53
[
54
# server-first, containing server nonce, salt, and iteration count
55
Msf::Db::PostgresPR::AuthenticationSASLContinue.new(
56
value: 'r=AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=FUeV3rVpQpa2s8ECj3aXa6vw,s=RwsYP2UCANr95SzCJfmP4A==,i=4096'
57
),
58
# server-final, server signature
59
Msf::Db::PostgresPR::AuthenticationSASLFinal.new(
60
value: 'v=invalid_server_proof'
61
)
62
]
63
end
64
65
it 'raises an error' do
66
message = Msf::Db::PostgresPR::AuthenticationSASL.new(
67
mechanisms: ['SCRAM-SHA-256']
68
)
69
expect { subject.negotiate_sasl(message, user, password) }.to raise_error 'Server proof failed'
70
end
71
end
72
73
context 'and the password is invalid' do
74
let(:server_responses) do
75
[
76
# server-first, containing server nonce, salt, and iteration count
77
Msf::Db::PostgresPR::AuthenticationSASLContinue.new(
78
value: 'r=2kRpTcHEFyoG+UgDEpRBdVcJLTWh5WtxARhYOHcG27i7YxAi,s=GNpgixWS5E4INbrMf665Kw==,i=4096'
79
),
80
# For auth failure; server-final isn't AuthenticationSASLFinal - but just a generic Postgres ErrorResponse
81
Msf::Db::PostgresPR::ErrorResponse.new(
82
83,
83
["FATAL", "VFATAL", "C28P01", "Mpassword authentication failed for user \"user\"", "Fauth.c", "L326", "Rauth_failed"]
84
)
85
]
86
end
87
88
it 'raises an error' do
89
message = Msf::Db::PostgresPR::AuthenticationSASL.new(
90
mechanisms: ['SCRAM-SHA-256']
91
)
92
# Runtime error raised for consistency with login scanner expectations, but could be changed to a better exception in the future
93
expect { subject.negotiate_sasl(message, user, password) }.to raise_error RuntimeError, "FATAL\tVFATAL\tC28P01\tMpassword authentication failed for user \"user\"\tFauth.c\tL326\tRauth_failed"
94
end
95
end
96
97
context 'and a AuthenticationSASLContinue is not returned' do
98
let(:server_responses) do
99
[
100
nil
101
]
102
end
103
it 'raises' do
104
message = Msf::Db::PostgresPR::AuthenticationSASL.new(
105
mechanisms: ['SCRAM-SHA-256']
106
)
107
expect { subject.negotiate_sasl(message, user, password) }.to raise_error Msf::Db::PostgresPR::AuthenticationMethodMismatch, /Did not receive AuthenticationSASLContinue/
108
end
109
end
110
end
111
112
context 'when the mechanism is not supported' do
113
it 'raises an exception' do
114
message = Msf::Db::PostgresPR::AuthenticationSASL.new(
115
mechanisms: ['SCRAM-SHA-256-PLUS']
116
)
117
expect { subject.negotiate_sasl(message, user, password) }.to raise_error Msf::Db::PostgresPR::AuthenticationMethodMismatch, /unsupported SASL mechanisms/
118
end
119
end
120
end
121
end
122
123