CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/spec/lib/rex/proto/ldap/server_spec.rb
Views: 11788
1
# frozen_string_literal: true
2
require 'rex/text'
3
4
RSpec.describe Rex::Proto::LDAP::Server do
5
6
subject(:ldif) { nil }
7
8
subject(:auth_provider) do
9
Rex::Proto::LDAP::Auth.new(nil, nil, nil, nil, nil)
10
end
11
12
subject(:server) do
13
described_class.new('0.0.0.0', 40000, true, true, ldif, nil, auth_provider)
14
end
15
16
let(:response) {}
17
18
let(:tcp_server_socket) do
19
double :tcp_server_socket,
20
start: nil,
21
:on_client_connect_proc= => nil,
22
:on_client_data_proc= => nil,
23
closed?: false,
24
close: nil
25
end
26
27
let(:udp_server_socket) do
28
double :udp_server_socket,
29
start: nil,
30
:on_client_connect_proc= => nil,
31
:on_client_data_proc= => nil,
32
closed?: false,
33
close: nil
34
end
35
36
let(:udp_monitor_thread) do
37
instance_double ::Thread, alive?: true
38
end
39
40
before do
41
allow(Rex::Socket::TcpServer).to receive(:create).and_return(tcp_server_socket)
42
allow(Rex::Socket::Udp).to receive(:create).and_return(udp_server_socket)
43
allow(Rex::ThreadFactory).to receive(:spawn).with('UDPLDAPServerListener', false).and_return(udp_monitor_thread)
44
server.processed_pdu_handler(Net::LDAP::PDU::BindRequest) do |processed_data|
45
processed_data = 'Processed Data'
46
end
47
end
48
49
context 'initialize' do
50
it 'sets the server options correctly' do
51
expect(server.serve_udp).to eq(true)
52
expect(server.serve_tcp).to eq(true)
53
expect(server.sock_options).to include('LocalHost' => '0.0.0.0', 'LocalPort' => 40000, 'Comm' => nil)
54
expect(server.ldif).to eq(ldif)
55
expect(server.instance_variable_get(:@auth_provider)).to eq(auth_provider)
56
expect(server.instance_variable_get(:@auth_provider)).to be_a(Rex::Proto::LDAP::Auth)
57
end
58
end
59
60
describe '#running?' do
61
context 'when the server is not running' do
62
it 'returns false' do
63
expect(server.running?).to be_nil
64
end
65
end
66
67
context 'when the server is running' do
68
before { server.start }
69
70
it 'returns true' do
71
expect(server.running?).not_to be_nil
72
end
73
74
after { server.stop }
75
end
76
end
77
78
describe '#start' do
79
context 'start server with the provided options' do
80
before { server.start }
81
82
it 'starts the UDP server if serve_udp is true' do
83
if server.serve_udp
84
expect(server.udp_sock).to be udp_server_socket
85
expect(server.running?).to be true
86
end
87
end
88
89
it 'starts the TCP server if serve_tcp is true' do
90
if server.serve_tcp
91
expect(server.tcp_sock).to be tcp_server_socket
92
expect(server.running?).to be true
93
end
94
end
95
96
after { server.stop }
97
end
98
end
99
100
describe '#stop' do
101
before { server.start }
102
103
it 'stops the server when running' do
104
server.stop
105
expect(server.running?).to be nil
106
end
107
end
108
109
describe '#dispatch_request' do
110
it 'calls dispatch_request_proc if it is set' do
111
client = double('client')
112
allow(client).to receive(:peerhost) { '1.1.1.1' }
113
allow(client).to receive(:peerport) { '389' }
114
allow(client).to receive(:write).with(response)
115
allow(client).to receive(:close)
116
117
block_called = false
118
server.dispatch_request_proc = proc { block_called = true }
119
server.dispatch_request(client, 'LDAP request data')
120
expect(block_called).to be true
121
end
122
123
it 'calls default_dispatch_request if dispatch_request_proc is not set' do
124
client = double('client')
125
allow(client).to receive(:peerhost) { '1.1.1.1' }
126
allow(client).to receive(:peerport) { '389' }
127
allow(client).to receive(:write).with(any_args)
128
allow(client).to receive(:close)
129
130
expect { server.dispatch_request(client, String.new("02\x02\x01\x01`-\x02\x01\x03\x04\"cn=user,dc=example,dc=com\x80\x04kali").force_encoding('ASCII-8BIT')) }.not_to raise_error
131
end
132
end
133
134
describe '#default_dispatch_request' do
135
it 'returns nil for empty request data' do
136
client = double('client')
137
allow(client).to receive(:peerhost) { '1.1.1.1' }
138
allow(client).to receive(:peerport) { '389' }
139
allow(client).to receive(:write).with(any_args)
140
allow(client).to receive(:close)
141
data = ''
142
expect { server.default_dispatch_request(client, data) }.not_to raise_error
143
end
144
end
145
146
describe '#encode_ldap_response' do
147
it 'encodes an LDAP response correctly' do
148
msgid = 1
149
code = Net::LDAP::ResultCodeSuccess
150
dn = ''
151
msg = Net::LDAP::ResultStrings[Net::LDAP::ResultCodeSuccess]
152
tag = Net::LDAP::PDU::BindResult
153
context_data = nil
154
context_code = nil
155
156
response = server.encode_ldap_response(msgid, code, dn, msg, tag, context_data, context_code)
157
expect(response).to be_a(String)
158
end
159
end
160
161
describe '#search_result' do
162
context 'when searching with no LDIF data' do
163
it 'returns a random search result' do
164
result = server.search_result(nil, 1)
165
166
expect(result).to be_nil
167
end
168
end
169
end
170
171
describe '#processed_pdu_handler' do
172
it 'sets the processed_pdu_handler correctly' do
173
174
expect(server.instance_variable_get(:@pdu_process)[Net::LDAP::PDU::BindRequest]).to be_a(Proc)
175
expect((server.instance_variable_get(:@pdu_process)[Net::LDAP::PDU::BindRequest]).call({})).to eq('Processed Data')
176
end
177
end
178
179
describe '#suitable_response' do
180
it 'returns the appropriate response type for a given request type' do
181
expect(server.suitable_response(Net::LDAP::PDU::BindRequest)).to eq(Net::LDAP::PDU::BindResult)
182
expect(server.suitable_response(Net::LDAP::PDU::SearchRequest)).to eq(Net::LDAP::PDU::SearchResult)
183
end
184
end
185
end
186
187