Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/spec/lib/rex/proto/postgresql/client_spec.rb
24821 views
1
# -*- coding: binary -*-
2
3
require 'spec_helper'
4
require 'postgres/postgres-pr/connection'
5
6
RSpec.describe Msf::Db::PostgresPR::Connection do
7
let(:host) { '127.0.0.1' }
8
let(:port) { 1234 }
9
let(:info) { "#{host}:#{port}" }
10
let(:db_name) { 'my_db_name' }
11
let(:socket) { double(Rex::Socket, peerhost: host, peerport: port) }
12
let(:message) { Msf::Db::PostgresPR::ReadyForQuery.new('') }
13
14
before do
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)
20
allow(Msf::Db::PostgresPR::Message).to receive(:read).and_return(message)
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}")
26
end
27
28
it_behaves_like 'session compatible SQL client'
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
89
describe '#map_compile_os_to_platform' do
90
[
91
{ info: 'linux', expected: Msf::Platform::Linux.realname },
92
{ info: 'linux2.6', expected: Msf::Platform::Linux.realname },
93
{ info: 'debian-linux-gnu', expected: Msf::Platform::Linux.realname },
94
{ info: 'win', expected: Msf::Platform::Windows.realname },
95
{ info: 'windows', expected: Msf::Platform::Windows.realname },
96
{ info: 'darwin', expected: Msf::Platform::OSX.realname },
97
{ info: 'osx', expected: Msf::Platform::OSX.realname },
98
{ info: 'macos', expected: Msf::Platform::OSX.realname },
99
{ info: 'solaris', expected: Msf::Platform::Solaris.realname },
100
{ info: 'aix', expected: Msf::Platform::AIX.realname },
101
{ info: 'hpux', expected: Msf::Platform::HPUX.realname },
102
{ info: 'irix', expected: Msf::Platform::Irix.realname },
103
].each do |test|
104
it "correctly identifies '#{test[:info]}' as '#{test[:expected]}'" do
105
expect(subject.map_compile_os_to_platform(test[:info])).to eq(test[:expected])
106
end
107
end
108
end
109
110
describe '#map_compile_arch_to_architecture' do
111
[
112
{ info: 'x86_64', expected: ARCH_X86_64 },
113
{ info: 'x86_x64', expected: ARCH_X86_64 },
114
{ info: 'x64', expected: ARCH_X86_64 },
115
{ info: '64', expected: ARCH_X86_64 },
116
{ info: 'x86', expected: ARCH_X86 },
117
{ info: '86', expected: ARCH_X86 },
118
{ info: 'i686', expected: ARCH_X86 },
119
{ info: 'arm64', expected: ARCH_AARCH64 },
120
{ info: 'arm', expected: ARCH_ARMLE },
121
{ info: 'sparc', expected: ARCH_SPARC },
122
{ info: 'sparc64', expected: ARCH_SPARC64 },
123
{ info: 'ppc', expected: ARCH_PPC },
124
{ info: 'mips', expected: ARCH_MIPS },
125
].each do |test|
126
it "correctly identifies '#{test[:info]}' as '#{test[:expected]}'" do
127
expect(subject.map_compile_arch_to_architecture(test[:info])).to eq(test[:expected])
128
end
129
end
130
end
131
132
describe '#detect_platform_and_arch' do
133
[
134
{ version: 'PostgreSQL 9.4.26 on x86_64-pc-linux-gnu (Debian 9.4.26-1.pgdg90+1), compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit', expected: { arch: 'x86_64', platform: 'Linux' } },
135
{ version: 'PostgreSQL 14.11 (Debian 14.11-1.pgdg120+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit', expected: { arch: 'x86_64', platform: 'Linux' } },
136
{ version: 'PostgreSQL 14.11 (Homebrew) on x86_64-apple-darwin22.6.0, compiled by Apple clang version 15.0.0 (clang-1500.1.0.2.5), 64-bit', expected: { arch: 'x86_64', platform: 'OSX' } },
137
{
138
version: 'PostgreSQL 14.11 (Homebrew) <arch>-<platform>, compiled by <platform> clang version 15.0.0 (clang-1500.1.0.2.5), <arch>',
139
expected: {
140
arch: 'postgresql 14.11 (homebrew) <arch>-<platform>, compiled by <platform> clang version 15.0.0 (clang-1500.1.0.2.5), <arch>',
141
platform: 'postgresql 14.11 (homebrew) <arch>-<platform>, compiled by <platform> clang version 15.0.0 (clang-1500.1.0.2.5), <arch>'
142
}
143
}
144
].each do |test|
145
context "when the database is version #{test[:version]}" do
146
it "returns #{test[:expected]}" do
147
mock_query_result = instance_double Msf::Db::PostgresPR::Connection::Result, rows: [[test[:version]]]
148
allow(subject).to receive(:query).with('select version()').and_return(mock_query_result)
149
150
expect(subject.detect_platform_and_arch).to eq test[:expected]
151
end
152
end
153
end
154
end
155
end
156
157