ronin-support 0.4.0.rc1 → 0.4.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. data/.yardopts +1 -0
  2. data/ChangeLog.md +10 -0
  3. data/Gemfile +1 -1
  4. data/README.md +1 -1
  5. data/Rakefile +8 -0
  6. data/gemspec.yml +2 -1
  7. data/lib/ronin/extensions.rb +1 -1
  8. data/lib/ronin/extensions/enumerable.rb +1 -1
  9. data/lib/ronin/extensions/file.rb +1 -1
  10. data/lib/ronin/extensions/ip_addr.rb +1 -1
  11. data/lib/ronin/extensions/kernel.rb +1 -1
  12. data/lib/ronin/extensions/meta.rb +1 -1
  13. data/lib/ronin/extensions/regexp.rb +1 -1
  14. data/lib/ronin/extensions/resolv.rb +1 -1
  15. data/lib/ronin/extensions/string.rb +1 -1
  16. data/lib/ronin/formatting.rb +1 -1
  17. data/lib/ronin/formatting/binary.rb +1 -1
  18. data/lib/ronin/formatting/digest.rb +1 -1
  19. data/lib/ronin/formatting/extensions.rb +1 -1
  20. data/lib/ronin/formatting/extensions/binary.rb +1 -1
  21. data/lib/ronin/formatting/extensions/binary/file.rb +1 -1
  22. data/lib/ronin/formatting/extensions/binary/integer.rb +1 -1
  23. data/lib/ronin/formatting/extensions/binary/string.rb +1 -1
  24. data/lib/ronin/formatting/extensions/digest.rb +1 -1
  25. data/lib/ronin/formatting/extensions/digest/file.rb +1 -1
  26. data/lib/ronin/formatting/extensions/digest/string.rb +1 -1
  27. data/lib/ronin/formatting/extensions/html.rb +1 -1
  28. data/lib/ronin/formatting/extensions/html/integer.rb +1 -1
  29. data/lib/ronin/formatting/extensions/html/string.rb +1 -1
  30. data/lib/ronin/formatting/extensions/http.rb +1 -1
  31. data/lib/ronin/formatting/extensions/http/integer.rb +1 -1
  32. data/lib/ronin/formatting/extensions/http/string.rb +1 -1
  33. data/lib/ronin/formatting/extensions/sql.rb +1 -1
  34. data/lib/ronin/formatting/extensions/sql/string.rb +1 -1
  35. data/lib/ronin/formatting/extensions/text.rb +1 -1
  36. data/lib/ronin/formatting/extensions/text/array.rb +1 -1
  37. data/lib/ronin/formatting/extensions/text/string.rb +1 -1
  38. data/lib/ronin/formatting/html.rb +1 -1
  39. data/lib/ronin/formatting/http.rb +1 -1
  40. data/lib/ronin/formatting/sql.rb +1 -1
  41. data/lib/ronin/formatting/text.rb +1 -1
  42. data/lib/ronin/fuzzing.rb +1 -1
  43. data/lib/ronin/fuzzing/extensions.rb +1 -1
  44. data/lib/ronin/fuzzing/extensions/string.rb +1 -1
  45. data/lib/ronin/fuzzing/fuzzing.rb +1 -1
  46. data/lib/ronin/mixin.rb +1 -1
  47. data/lib/ronin/network.rb +1 -1
  48. data/lib/ronin/network/esmtp.rb +1 -1
  49. data/lib/ronin/network/extensions.rb +1 -1
  50. data/lib/ronin/network/extensions/esmtp.rb +1 -1
  51. data/lib/ronin/network/extensions/esmtp/net.rb +1 -1
  52. data/lib/ronin/network/extensions/http.rb +1 -1
  53. data/lib/ronin/network/extensions/http/net.rb +1 -1
  54. data/lib/ronin/network/extensions/http/uri/http.rb +1 -1
  55. data/lib/ronin/network/extensions/imap.rb +1 -1
  56. data/lib/ronin/network/extensions/imap/net.rb +1 -1
  57. data/lib/ronin/network/extensions/pop3.rb +1 -1
  58. data/lib/ronin/network/extensions/pop3/net.rb +1 -1
  59. data/lib/ronin/network/extensions/smtp.rb +1 -1
  60. data/lib/ronin/network/extensions/smtp/net.rb +1 -1
  61. data/lib/ronin/network/extensions/ssl.rb +1 -1
  62. data/lib/ronin/network/extensions/ssl/net.rb +1 -1
  63. data/lib/ronin/network/extensions/tcp.rb +1 -1
  64. data/lib/ronin/network/extensions/tcp/net.rb +1 -1
  65. data/lib/ronin/network/extensions/telnet.rb +1 -1
  66. data/lib/ronin/network/extensions/telnet/net.rb +1 -1
  67. data/lib/ronin/network/extensions/udp.rb +1 -1
  68. data/lib/ronin/network/extensions/udp/net.rb +1 -1
  69. data/lib/ronin/network/http.rb +1 -1
  70. data/lib/ronin/network/http/exceptions.rb +1 -1
  71. data/lib/ronin/network/http/exceptions/unknown_request.rb +1 -1
  72. data/lib/ronin/network/http/http.rb +103 -72
  73. data/lib/ronin/network/http/proxy.rb +1 -1
  74. data/lib/ronin/network/imap.rb +1 -1
  75. data/lib/ronin/network/mixins.rb +1 -1
  76. data/lib/ronin/network/mixins/esmtp.rb +1 -1
  77. data/lib/ronin/network/mixins/http.rb +3 -3
  78. data/lib/ronin/network/mixins/imap.rb +1 -1
  79. data/lib/ronin/network/mixins/mixin.rb +1 -1
  80. data/lib/ronin/network/mixins/pop3.rb +1 -1
  81. data/lib/ronin/network/mixins/smtp.rb +1 -1
  82. data/lib/ronin/network/mixins/ssl.rb +144 -0
  83. data/lib/ronin/network/mixins/tcp.rb +6 -5
  84. data/lib/ronin/network/mixins/telnet.rb +1 -1
  85. data/lib/ronin/network/mixins/udp.rb +29 -3
  86. data/lib/ronin/network/network.rb +1 -1
  87. data/lib/ronin/network/pop3.rb +1 -1
  88. data/lib/ronin/network/smtp.rb +1 -1
  89. data/lib/ronin/network/smtp/email.rb +1 -1
  90. data/lib/ronin/network/smtp/smtp.rb +1 -1
  91. data/lib/ronin/network/ssl.rb +3 -6
  92. data/lib/ronin/network/tcp.rb +27 -28
  93. data/lib/ronin/network/telnet.rb +1 -1
  94. data/lib/ronin/network/udp.rb +56 -19
  95. data/lib/ronin/path.rb +1 -1
  96. data/lib/ronin/spec/ui/output.rb +1 -1
  97. data/lib/ronin/support.rb +1 -1
  98. data/lib/ronin/support/inflector.rb +1 -1
  99. data/lib/ronin/support/support.rb +1 -1
  100. data/lib/ronin/support/version.rb +2 -2
  101. data/lib/ronin/templates.rb +1 -1
  102. data/lib/ronin/templates/erb.rb +1 -1
  103. data/lib/ronin/templates/template.rb +1 -1
  104. data/lib/ronin/ui/output.rb +1 -1
  105. data/lib/ronin/ui/output/helpers.rb +1 -1
  106. data/lib/ronin/ui/output/output.rb +1 -1
  107. data/lib/ronin/ui/output/terminal.rb +1 -1
  108. data/lib/ronin/ui/output/terminal/color.rb +1 -1
  109. data/lib/ronin/ui/output/terminal/raw.rb +1 -1
  110. data/lib/ronin/ui/shell.rb +67 -7
  111. data/lib/ronin/wordlist.rb +51 -1
  112. data/spec/extensions/ip_addr_spec.rb +1 -1
  113. data/spec/network/http/http_spec.rb +193 -0
  114. data/spec/network/tcp_spec.rb +244 -0
  115. data/spec/network/udp_spec.rb +245 -0
  116. data/spec/spec_helper.rb +5 -0
  117. data/spec/ui/shell_spec.rb +7 -3
  118. data/spec/wordlist_spec.rb +25 -0
  119. metadata +35 -19
@@ -270,4 +270,197 @@ describe Network::HTTP do
270
270
  }.should raise_error(ArgumentError)
271
271
  end
272
272
  end
273
+
274
+ describe "helper methods", :network do
275
+ let(:host) { 'www.google.com' }
276
+ let(:port) { 80 }
277
+ let(:path) { '/' }
278
+ let(:uri) { URI::HTTP.build(:host => host, :port => 80, :path => path) }
279
+
280
+ subject do
281
+ obj = Object.new
282
+ obj.extend described_class
283
+ obj
284
+ end
285
+
286
+ describe "#http_connect" do
287
+ it "should create a Net::HTTP session" do
288
+ http = subject.http_connect(:host => host, :port => port)
289
+
290
+ http.should be_kind_of(Net::HTTP)
291
+ http.should be_started
292
+
293
+ http.finish
294
+ end
295
+
296
+ it "should yield the new Net::HTTP session" do
297
+ http = nil
298
+
299
+ subject.http_connect(:url => uri) do |session|
300
+ http = session
301
+ end
302
+
303
+ http.should be_kind_of(Net::HTTP)
304
+ end
305
+
306
+ it "should allow yielding the expanded options" do
307
+ expanded_options = nil
308
+
309
+ subject.http_connect(:url => uri) do |session,options|
310
+ expanded_options = options
311
+ end
312
+
313
+ expanded_options[:host].should == host
314
+ expanded_options[:port].should == port
315
+ expanded_options[:path].should == path
316
+ end
317
+ end
318
+
319
+ describe "#http_session" do
320
+ it "should start and then finish a Net::HTTP session" do
321
+ http = nil
322
+
323
+ subject.http_session(:host => host, :port => port) do |session|
324
+ http = session
325
+ end
326
+
327
+ http.should be_kind_of(Net::HTTP)
328
+ http.should_not be_started
329
+ end
330
+
331
+ it "should allow yielding the Net::HTTP session" do
332
+ http = nil
333
+
334
+ subject.http_session(:url => uri) do |session|
335
+ http = session
336
+ end
337
+
338
+ http.should be_kind_of(Net::HTTP)
339
+ end
340
+
341
+ it "should allow yielding the expanded options" do
342
+ expanded_options = nil
343
+
344
+ subject.http_session(:url => uri) do |session,options|
345
+ expanded_options = options
346
+ end
347
+
348
+ expanded_options[:host].should == host
349
+ expanded_options[:port].should == port
350
+ expanded_options[:path].should == path
351
+ end
352
+ end
353
+
354
+ describe "#http_request" do
355
+ it "should send an arbitrary request and return the response" do
356
+ response = subject.http_request(:url => uri, :method => :options)
357
+
358
+ response.should be_kind_of(Net::HTTPMethodNotAllowed)
359
+ end
360
+
361
+ it "should allow yielding the request" do
362
+ request = nil
363
+
364
+ subject.http_request(:url => uri, :method => :options) do |req|
365
+ request = req
366
+ end
367
+
368
+ request.should be_kind_of(Net::HTTP::Options)
369
+ end
370
+
371
+ it "should allow yielding the expanded options" do
372
+ expanded_options = nil
373
+
374
+ subject.http_request(:url => uri, :method => :options) do |req,options|
375
+ expanded_options = options
376
+ end
377
+
378
+ expanded_options[:host].should == host
379
+ expanded_options[:port].should == port
380
+ expanded_options[:path].should == path
381
+ end
382
+ end
383
+
384
+ describe "#http_status" do
385
+ it "should return an Integer" do
386
+ subject.http_status(:url => uri).should be_kind_of(Integer)
387
+ end
388
+
389
+ it "should return the status-code of the Response" do
390
+ subject.http_status(:url => uri).should == 200
391
+ end
392
+ end
393
+
394
+ describe "#http_ok?" do
395
+ it "should check if the Response has code 200" do
396
+ subject.http_ok?(:url => uri).should == true
397
+ end
398
+ end
399
+
400
+ describe "#http_server" do
401
+ let(:url) { "http://www.php.net/" }
402
+ let(:headers) { subject.http_get_headers(:url => url) }
403
+
404
+ it "should return the 'Server' header" do
405
+ subject.http_server(:url => url).should == headers['Server']
406
+ end
407
+ end
408
+
409
+ describe "#http_powered_by" do
410
+ let(:url) { "http://www.php.net/" }
411
+ let(:headers) { subject.http_get_headers(:url => url) }
412
+
413
+ it "should return the 'X-Powered-By' header" do
414
+ subject.http_powered_by(:url => url).should == headers['X-Powered-By']
415
+ end
416
+ end
417
+
418
+ describe "#http_get_headers" do
419
+ let(:headers) { subject.http_get_headers(:url => uri) }
420
+
421
+ it "should return HTTP Headers" do
422
+ headers.should_not be_empty
423
+ end
424
+
425
+ it "should format the HTTP Headers accordingly" do
426
+ format = /^[A-Z][a-z0-9]*(-[A-Z][a-z0-9]*)*$/
427
+ bad_headers = headers.keys.reject { |name| name =~ format }
428
+
429
+ bad_headers.should == []
430
+ end
431
+ end
432
+
433
+ describe "#http_get_body" do
434
+ it "should return the response body" do
435
+ body = subject.http_get_body(:url => uri)
436
+
437
+ body.should be_kind_of(String)
438
+ body.should_not be_empty
439
+ end
440
+ end
441
+
442
+ describe "#http_post_headers" do
443
+ let(:headers) { subject.http_post_headers(:url => uri) }
444
+
445
+ it "should return HTTP Headers" do
446
+ headers.should_not be_empty
447
+ end
448
+
449
+ it "should format the HTTP Headers accordingly" do
450
+ format = /^[A-Z][a-z0-9]*(-[A-Z][a-z0-9]*)*$/
451
+ bad_headers = headers.keys.reject { |name| name =~ format }
452
+
453
+ bad_headers.should == []
454
+ end
455
+ end
456
+
457
+ describe "#http_post_body" do
458
+ it "should return the response body" do
459
+ body = subject.http_post_body(:url => uri)
460
+
461
+ body.should be_kind_of(String)
462
+ body.should_not be_empty
463
+ end
464
+ end
465
+ end
273
466
  end
@@ -0,0 +1,244 @@
1
+ require 'spec_helper'
2
+ require 'ronin/network/tcp'
3
+
4
+ require 'resolv'
5
+
6
+ describe Network::TCP do
7
+ describe "helper methods", :network do
8
+ let(:host) { 'smtp.gmail.com' }
9
+ let(:port) { 25 }
10
+
11
+ let(:server_host) { 'localhost' }
12
+ let(:server_ip) { Resolv.getaddress(server_host) }
13
+
14
+ subject do
15
+ obj = Object.new
16
+ obj.extend described_class
17
+ obj
18
+ end
19
+
20
+ describe "#tcp_connect" do
21
+ let(:local_port) { 1024 + rand(65535 - 1024) }
22
+
23
+ it "should open a TCPSocket" do
24
+ socket = subject.tcp_connect(host,port)
25
+
26
+ socket.should be_kind_of(TCPSocket)
27
+ socket.should_not be_closed
28
+
29
+ socket.close
30
+ end
31
+
32
+ it "should bind to a local host and port" do
33
+ socket = subject.tcp_connect(host,port,nil,local_port)
34
+
35
+ local_address = socket.local_address
36
+ local_address.ip_port.should == local_port
37
+
38
+ socket.close
39
+ end
40
+
41
+ it "should yield the new TCPSocket" do
42
+ socket = nil
43
+
44
+ subject.tcp_connect(host,port) do |yielded_socket|
45
+ socket = yielded_socket
46
+ end
47
+
48
+ socket.should_not be_closed
49
+ socket.close
50
+ end
51
+ end
52
+
53
+ describe "#tcp_connect_and_send" do
54
+ let(:data) { "HELO ronin\n" }
55
+ let(:local_port) { 1024 + rand(65535 - 1024) }
56
+
57
+ it "should connect and then send data" do
58
+ socket = subject.tcp_connect_and_send(data,host,port)
59
+ banner = socket.readline
60
+ response = socket.readline
61
+
62
+ response.start_with?('250').should be_true
63
+
64
+ socket.close
65
+ end
66
+
67
+ it "should bind to a local host and port" do
68
+ socket = subject.tcp_connect_and_send(data,host,port,nil,local_port)
69
+
70
+ local_address = socket.local_address
71
+ local_address.ip_port.should == local_port
72
+
73
+ socket.close
74
+ end
75
+
76
+ it "should yield the TCPSocket" do
77
+ response = nil
78
+
79
+ socket = subject.tcp_connect_and_send(data,host,port) do |socket|
80
+ banner = socket.readline
81
+ response = socket.readline
82
+ end
83
+
84
+ response.start_with?('250').should be_true
85
+
86
+ socket.close
87
+ end
88
+ end
89
+
90
+ describe "#tcp_session" do
91
+ let(:local_port) { 1024 + rand(65535 - 1024) }
92
+
93
+ it "should open then close a TCPSocket" do
94
+ socket = nil
95
+
96
+ subject.tcp_session(host,port) do |yielded_socket|
97
+ socket = yielded_socket
98
+ end
99
+
100
+ socket.should be_kind_of(TCPSocket)
101
+ socket.should be_closed
102
+ end
103
+
104
+ it "should bind to a local host and port" do
105
+ local_address = nil
106
+
107
+ subject.tcp_session(host,port,nil,local_port) do |socket|
108
+ local_address = socket.local_address
109
+ end
110
+
111
+ local_address.ip_port.should == local_port
112
+ end
113
+ end
114
+
115
+ describe "#tcp_banner" do
116
+ let(:host) { 'smtp.gmail.com' }
117
+ let(:port) { 25 }
118
+
119
+ let(:local_port) { 1024 + rand(65535 - 1024) }
120
+
121
+ it "should read the service banner" do
122
+ banner = subject.tcp_banner(host,port)
123
+
124
+ banner.start_with?('220').should be_true
125
+ end
126
+
127
+ it "should bind to a local host and port" do
128
+ banner = subject.tcp_banner(host,port,nil,local_port)
129
+
130
+ banner.start_with?('220').should be_true
131
+ end
132
+
133
+ it "should yield the banner" do
134
+ banner = nil
135
+
136
+ subject.tcp_banner(host,port) do |yielded_banner|
137
+ banner = yielded_banner
138
+ end
139
+
140
+ banner.start_with?('220').should be_true
141
+ end
142
+ end
143
+
144
+ describe "#tcp_send" do
145
+ let(:server) { TCPServer.new(server_host,nil) }
146
+ let(:server_port) { server.local_address.ip_port }
147
+
148
+ let(:data) { "hello\n" }
149
+ let(:local_port) { 1024 + rand(65535 - 1024) }
150
+
151
+ after(:all) { server.close }
152
+
153
+ it "should send data to a service" do
154
+ subject.tcp_send(data,server_host,server_port)
155
+
156
+ client = server.accept
157
+ sent = client.readline
158
+
159
+ client.close
160
+
161
+ sent.should == data
162
+ end
163
+
164
+ it "should bind to a local host and port" do
165
+ subject.tcp_send(data,server_host,server_port,nil,local_port)
166
+
167
+ client = server.accept
168
+
169
+ client_address = client.remote_address
170
+ client_address.ip_port.should == local_port
171
+
172
+ client.close
173
+ end
174
+ end
175
+
176
+ describe "#tcp_server" do
177
+ let(:server_port) { 1024 + rand(65535 - 1024) }
178
+
179
+ it "should create a new TCPServer" do
180
+ server = subject.tcp_server
181
+
182
+ server.should be_kind_of(TCPServer)
183
+ server.should_not be_closed
184
+
185
+ server.close
186
+ end
187
+
188
+ it "should bind to a specific port and host" do
189
+ server = subject.tcp_server(server_port,server_host)
190
+
191
+ local_address = server.local_address
192
+ local_address.ip_address.should == server_ip
193
+ local_address.ip_port.should == server_port
194
+
195
+ server.close
196
+ end
197
+
198
+ it "should yield the new TCPServer" do
199
+ server = nil
200
+
201
+ subject.tcp_server do |yielded_server|
202
+ server = yielded_server
203
+ end
204
+
205
+ server.should be_kind_of(TCPServer)
206
+ server.should_not be_closed
207
+
208
+ server.close
209
+ end
210
+ end
211
+
212
+ describe "#tcp_server_session" do
213
+ let(:server_port) { 1024 + rand(65535 - 1024) }
214
+
215
+ it "should create a temporary TCPServer" do
216
+ server = nil
217
+
218
+ subject.tcp_server_session do |yielded_server|
219
+ server = yielded_server
220
+ end
221
+
222
+ server.should be_kind_of(TCPServer)
223
+ server.should be_closed
224
+ end
225
+
226
+ it "should bind to a specific port and host" do
227
+ local_address = nil
228
+
229
+ subject.tcp_server_session(server_port,server_host) do |yielded_server|
230
+ local_address = yielded_server.local_address
231
+ end
232
+
233
+ local_address.ip_address.should == server_ip
234
+ local_address.ip_port.should == server_port
235
+ end
236
+ end
237
+
238
+ describe "#tcp_single_server" do
239
+ let(:server_port) { 1024 + rand(65535 - 1024) }
240
+
241
+ pending "need to automate connecting to the TCPServer"
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,245 @@
1
+ require 'spec_helper'
2
+ require 'ronin/network/udp'
3
+
4
+ require 'resolv'
5
+
6
+ describe Network::UDP do
7
+ describe "helper methods", :network do
8
+ let(:host) { 'scanme.nmap.org' }
9
+ let(:port) { 123 }
10
+
11
+ let(:server_host) { 'localhost' }
12
+ let(:server_ip) { Resolv.getaddress(server_host) }
13
+
14
+ subject do
15
+ obj = Object.new
16
+ obj.extend described_class
17
+ obj
18
+ end
19
+
20
+ describe "#udp_connect" do
21
+ let(:local_port) { 1024 + rand(65535 - 1024) }
22
+
23
+ it "should open a UDPSocket" do
24
+ socket = subject.udp_connect(host,port)
25
+
26
+ socket.should be_kind_of(UDPSocket)
27
+ socket.should_not be_closed
28
+
29
+ socket.close
30
+ end
31
+
32
+ it "should bind to a local host and port" do
33
+ socket = subject.udp_connect(host,port,nil,local_port)
34
+
35
+ local_address = socket.local_address
36
+ local_address.ip_port.should == local_port
37
+
38
+ socket.close
39
+ end
40
+
41
+ it "should yield the new UDPSocket" do
42
+ socket = nil
43
+
44
+ subject.udp_connect(host,port) do |yielded_socket|
45
+ socket = yielded_socket
46
+ end
47
+
48
+ socket.should_not be_closed
49
+ socket.close
50
+ end
51
+ end
52
+
53
+ describe "#udp_connect_and_send" do
54
+ pending "need to find a UDP Service for these specs" do
55
+ let(:data) { "HELO ronin\n" }
56
+ let(:local_port) { 1024 + rand(65535 - 1024) }
57
+
58
+ it "should connect and then send data" do
59
+ socket = subject.udp_connect_and_send(data,host,port)
60
+ banner = socket.readline
61
+ response = socket.readline
62
+
63
+ response.start_with?('250').should be_true
64
+
65
+ socket.close
66
+ end
67
+
68
+ it "should bind to a local host and port" do
69
+ socket = subject.udp_connect_and_send(data,host,port,nil,local_port)
70
+
71
+ local_address = socket.local_address
72
+ local_address.ip_port.should == local_port
73
+
74
+ socket.close
75
+ end
76
+
77
+ it "should yield the UDPSocket" do
78
+ response = nil
79
+
80
+ socket = subject.udp_connect_and_send(data,host,port) do |socket|
81
+ banner = socket.readline
82
+ response = socket.readline
83
+ end
84
+
85
+ response.start_with?('250').should be_true
86
+
87
+ socket.close
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#udp_session" do
93
+ let(:local_port) { 1024 + rand(65535 - 1024) }
94
+
95
+ it "should open then close a UDPSocket" do
96
+ socket = nil
97
+
98
+ subject.udp_session(host,port) do |yielded_socket|
99
+ socket = yielded_socket
100
+ end
101
+
102
+ socket.should be_kind_of(UDPSocket)
103
+ socket.should be_closed
104
+ end
105
+
106
+ it "should bind to a local host and port" do
107
+ local_address = nil
108
+
109
+ subject.udp_session(host,port,nil,local_port) do |socket|
110
+ local_address = socket.local_address
111
+ end
112
+
113
+ local_address.ip_port.should == local_port
114
+ end
115
+ end
116
+
117
+ describe "#udp_banner" do
118
+ pending "need to find a UDP service that sends a banner" do
119
+ let(:host) { 'smtp.gmail.com' }
120
+ let(:port) { 25 }
121
+
122
+ let(:local_port) { 1024 + rand(65535 - 1024) }
123
+
124
+ it "should read the service banner" do
125
+ banner = subject.udp_banner(host,port)
126
+
127
+ banner.start_with?('220').should be_true
128
+ end
129
+
130
+ it "should bind to a local host and port" do
131
+ banner = subject.udp_banner(host,port,nil,local_port)
132
+
133
+ banner.start_with?('220').should be_true
134
+ end
135
+
136
+ it "should yield the banner" do
137
+ banner = nil
138
+
139
+ subject.udp_banner(host,port) do |yielded_banner|
140
+ banner = yielded_banner
141
+ end
142
+
143
+ banner.start_with?('220').should be_true
144
+ end
145
+ end
146
+ end
147
+
148
+ describe "#udp_send" do
149
+ let(:server) do
150
+ socket = UDPSocket.new
151
+ socket.bind(server_host,nil)
152
+ socket
153
+ end
154
+ let(:server_port) { server.local_address.ip_port }
155
+
156
+ let(:data) { "hello\n" }
157
+ let(:local_port) { 1024 + rand(65535 - 1024) }
158
+
159
+ after(:all) { server.close }
160
+
161
+ it "should send data to a service" do
162
+ subject.udp_send(data,server_host,server_port)
163
+
164
+ mesg = server.recvfrom(data.length)
165
+
166
+ mesg[0].should == data
167
+ end
168
+
169
+ it "should bind to a local host and port" do
170
+ subject.udp_send(data,server_host,server_port,nil,local_port)
171
+
172
+ mesg = server.recvfrom(data.length)
173
+
174
+ client_address = mesg[1]
175
+ client_address[1].should == local_port
176
+ end
177
+ end
178
+
179
+ describe "#udp_server" do
180
+ let(:server_port) { 1024 + rand(65535 - 1024) }
181
+
182
+ it "should create a new UDPSocket" do
183
+ server = subject.udp_server
184
+
185
+ server.should be_kind_of(UDPSocket)
186
+ server.should_not be_closed
187
+
188
+ server.close
189
+ end
190
+
191
+ it "should bind to a specific port and host" do
192
+ server = subject.udp_server(server_port,server_host)
193
+
194
+ local_address = server.local_address
195
+ local_address.ip_address.should == server_ip
196
+ local_address.ip_port.should == server_port
197
+
198
+ server.close
199
+ end
200
+
201
+ it "should yield the new UDPSocket" do
202
+ server = nil
203
+
204
+ subject.udp_server do |yielded_server|
205
+ server = yielded_server
206
+ end
207
+
208
+ server.should be_kind_of(UDPSocket)
209
+ server.should_not be_closed
210
+
211
+ server.close
212
+ end
213
+ end
214
+
215
+ describe "#udp_server_session" do
216
+ let(:server_port) { 1024 + rand(65535 - 1024) }
217
+
218
+ it "should create a temporary UDPSocket" do
219
+ server = nil
220
+
221
+ subject.udp_server_session do |yielded_server|
222
+ server = yielded_server
223
+ end
224
+
225
+ server.should be_kind_of(UDPSocket)
226
+ server.should be_closed
227
+ end
228
+
229
+ it "should bind to a specific port and host" do
230
+ local_address = nil
231
+
232
+ subject.udp_server_session(server_port,server_host) do |yielded_server|
233
+ local_address = yielded_server.local_address
234
+ end
235
+
236
+ local_address.ip_address.should == server_ip
237
+ local_address.ip_port.should == server_port
238
+ end
239
+ end
240
+
241
+ describe "#udp_single_server" do
242
+ let(:server_port) { 1024 + rand(65535 - 1024) }
243
+ end
244
+ end
245
+ end