|
11 | 11 | let(:socket) { double(Rex::Socket, peerhost: host, peerport: port) } |
12 | 12 | let(:message) { Msf::Db::PostgresPR::ReadyForQuery.new('') } |
13 | 13 |
|
14 | | - subject do |
| 14 | + before do |
15 | 15 | allow(socket).to receive(:<<) |
| 16 | + allow(socket).to receive(:write) |
| 17 | + allow(socket).to receive(:read).and_return('S') |
| 18 | + allow(socket).to receive(:extend) |
| 19 | + allow(socket).to receive(:initsock_with_ssl_version) |
16 | 20 | allow(Msf::Db::PostgresPR::Message).to receive(:read).and_return(message) |
17 | | - allow(Rex::Socket).to receive(:create).and_return(socket) |
18 | | - client = described_class.new(db_name, 'username', 'password', "tcp://#{host}:#{port}") |
19 | | - client |
| 21 | + allow(Rex::Socket).to receive(:create_param).and_return(socket) |
| 22 | + end |
| 23 | + |
| 24 | + subject do |
| 25 | + described_class.new(db_name, 'username', 'password', "tcp://#{host}:#{port}") |
20 | 26 | end |
21 | 27 |
|
22 | 28 | it_behaves_like 'session compatible SQL client' |
23 | 29 |
|
| 30 | + describe 'SSL connection' do |
| 31 | + let(:ssl_request_message) { instance_double(Msf::Db::PostgresPR::SSLRequest) } |
| 32 | + let(:ssl_opts) { { ssl_version: 'TLS1.2', ssl_verify_mode: 'peer', ssl_cipher: 'AES256' } } |
| 33 | + |
| 34 | + before do |
| 35 | + allow(Msf::Db::PostgresPR::SSLRequest).to receive(:new).with(80877103).and_return(ssl_request_message) |
| 36 | + allow(ssl_request_message).to receive(:dump).and_return('ssl_request_data') |
| 37 | + end |
| 38 | + |
| 39 | + context 'when SSL is enabled and server supports SSL' do |
| 40 | + it 'successfully establishes SSL connection' do |
| 41 | + allow(socket).to receive(:read).with(1).and_return('S') |
| 42 | + |
| 43 | + expect(socket).to receive(:write).with('ssl_request_data') |
| 44 | + expect(socket).to receive(:extend).with(Rex::Socket::SslTcp) |
| 45 | + expect(socket).to receive(:initsock_with_ssl_version) |
| 46 | + |
| 47 | + client = described_class.new(db_name, 'username', 'password', "tcp://#{host}:#{port}", nil, true, ssl_opts) |
| 48 | + expect(client).to be_a(Msf::Db::PostgresPR::Connection) |
| 49 | + end |
| 50 | + end |
| 51 | + |
| 52 | + context 'when SSL is enabled but server does not support SSL' do |
| 53 | + it 'raises an error when server responds with N' do |
| 54 | + allow(socket).to receive(:read).with(1).and_return('N') |
| 55 | + |
| 56 | + expect(socket).to receive(:write).with('ssl_request_data') |
| 57 | + expect(socket).not_to receive(:extend) |
| 58 | + |
| 59 | + expect { |
| 60 | + described_class.new(db_name, 'username', 'password', "tcp://#{host}:#{port}", nil, true, ssl_opts) |
| 61 | + }.to raise_error("SSL connection requested but server at #{host}:#{port} does not support SSL") |
| 62 | + end |
| 63 | + end |
| 64 | + |
| 65 | + context 'when SSL is enabled but server responds unexpectedly' do |
| 66 | + it 'raises an error for unexpected SSL response' do |
| 67 | + allow(socket).to receive(:read).with(1).and_return('X') |
| 68 | + |
| 69 | + expect(socket).to receive(:write).with('ssl_request_data') |
| 70 | + expect(socket).not_to receive(:extend) |
| 71 | + |
| 72 | + expect { |
| 73 | + described_class.new(db_name, 'username', 'password', "tcp://#{host}:#{port}", nil, true, ssl_opts) |
| 74 | + }.to raise_error('Unexpected response to SSLRequest: "X"') |
| 75 | + end |
| 76 | + end |
| 77 | + |
| 78 | + context 'when SSL is disabled' do |
| 79 | + it 'does not attempt SSL handshake' do |
| 80 | + expect(socket).not_to receive(:write).with('ssl_request_data') |
| 81 | + expect(socket).not_to receive(:extend).with(Rex::Socket::SslTcp) |
| 82 | + |
| 83 | + client = described_class.new(db_name, 'username', 'password', "tcp://#{host}:#{port}", nil, false, ssl_opts) |
| 84 | + expect(client).to be_a(Msf::Db::PostgresPR::Connection) |
| 85 | + end |
| 86 | + end |
| 87 | + end |
| 88 | + |
24 | 89 | describe '#map_compile_os_to_platform' do |
25 | 90 | [ |
26 | 91 | { info: 'linux', expected: Msf::Platform::Linux.realname }, |
|
0 commit comments