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
32485 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(:starttls).with(Rex::Socket::Parameters)
45
46
client = described_class.new(db_name, 'username', 'password', "tcp://#{host}:#{port}", nil, true, ssl_opts)
47
expect(client).to be_a(Msf::Db::PostgresPR::Connection)
48
end
49
end
50
51
context 'when SSL is enabled but server does not support SSL' do
52
it 'raises an error when server responds with N' do
53
allow(socket).to receive(:read).with(1).and_return('N')
54
55
expect(socket).to receive(:write).with('ssl_request_data')
56
expect(socket).not_to receive(:extend)
57
58
expect {
59
described_class.new(db_name, 'username', 'password', "tcp://#{host}:#{port}", nil, true, ssl_opts)
60
}.to raise_error("SSL connection requested but server at #{host}:#{port} does not support SSL")
61
end
62
end
63
64
context 'when SSL is enabled but server responds unexpectedly' do
65
it 'raises an error for unexpected SSL response' do
66
allow(socket).to receive(:read).with(1).and_return('X')
67
68
expect(socket).to receive(:write).with('ssl_request_data')
69
expect(socket).not_to receive(:extend)
70
71
expect {
72
described_class.new(db_name, 'username', 'password', "tcp://#{host}:#{port}", nil, true, ssl_opts)
73
}.to raise_error('Unexpected response to SSLRequest: "X"')
74
end
75
end
76
77
context 'when SSL is disabled' do
78
it 'does not attempt SSL handshake' do
79
expect(socket).not_to receive(:write).with('ssl_request_data')
80
expect(socket).not_to receive(:extend).with(Rex::Socket::SslTcp)
81
82
client = described_class.new(db_name, 'username', 'password', "tcp://#{host}:#{port}", nil, false, ssl_opts)
83
expect(client).to be_a(Msf::Db::PostgresPR::Connection)
84
end
85
end
86
end
87
88
describe '#map_compile_os_to_platform' do
89
[
90
{ info: 'linux', expected: Msf::Platform::Linux.realname },
91
{ info: 'linux2.6', expected: Msf::Platform::Linux.realname },
92
{ info: 'debian-linux-gnu', expected: Msf::Platform::Linux.realname },
93
{ info: 'win', expected: Msf::Platform::Windows.realname },
94
{ info: 'windows', expected: Msf::Platform::Windows.realname },
95
{ info: 'darwin', expected: Msf::Platform::OSX.realname },
96
{ info: 'osx', expected: Msf::Platform::OSX.realname },
97
{ info: 'macos', expected: Msf::Platform::OSX.realname },
98
{ info: 'solaris', expected: Msf::Platform::Solaris.realname },
99
{ info: 'aix', expected: Msf::Platform::AIX.realname },
100
{ info: 'hpux', expected: Msf::Platform::HPUX.realname },
101
{ info: 'irix', expected: Msf::Platform::Irix.realname },
102
].each do |test|
103
it "correctly identifies '#{test[:info]}' as '#{test[:expected]}'" do
104
expect(subject.map_compile_os_to_platform(test[:info])).to eq(test[:expected])
105
end
106
end
107
end
108
109
describe '#map_compile_arch_to_architecture' do
110
[
111
{ info: 'x86_64', expected: ARCH_X86_64 },
112
{ info: 'x86_x64', expected: ARCH_X86_64 },
113
{ info: 'x64', expected: ARCH_X86_64 },
114
{ info: '64', expected: ARCH_X86_64 },
115
{ info: 'x86', expected: ARCH_X86 },
116
{ info: '86', expected: ARCH_X86 },
117
{ info: 'i686', expected: ARCH_X86 },
118
{ info: 'arm64', expected: ARCH_AARCH64 },
119
{ info: 'arm', expected: ARCH_ARMLE },
120
{ info: 'sparc', expected: ARCH_SPARC },
121
{ info: 'sparc64', expected: ARCH_SPARC64 },
122
{ info: 'ppc', expected: ARCH_PPC },
123
{ info: 'mips', expected: ARCH_MIPS },
124
].each do |test|
125
it "correctly identifies '#{test[:info]}' as '#{test[:expected]}'" do
126
expect(subject.map_compile_arch_to_architecture(test[:info])).to eq(test[:expected])
127
end
128
end
129
end
130
131
describe '#detect_platform_and_arch' do
132
[
133
{ 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' } },
134
{ 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' } },
135
{ 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' } },
136
{
137
version: 'PostgreSQL 14.11 (Homebrew) <arch>-<platform>, compiled by <platform> clang version 15.0.0 (clang-1500.1.0.2.5), <arch>',
138
expected: {
139
arch: 'postgresql 14.11 (homebrew) <arch>-<platform>, compiled by <platform> clang version 15.0.0 (clang-1500.1.0.2.5), <arch>',
140
platform: 'postgresql 14.11 (homebrew) <arch>-<platform>, compiled by <platform> clang version 15.0.0 (clang-1500.1.0.2.5), <arch>'
141
}
142
}
143
].each do |test|
144
context "when the database is version #{test[:version]}" do
145
it "returns #{test[:expected]}" do
146
mock_query_result = instance_double Msf::Db::PostgresPR::Connection::Result, rows: [[test[:version]]]
147
allow(subject).to receive(:query).with('select version()').and_return(mock_query_result)
148
149
expect(subject.detect_platform_and_arch).to eq test[:expected]
150
end
151
end
152
end
153
end
154
end
155
156