PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/spec/lib/rex/proto/http/client_request_spec.rb

https://github.com/Jonono2/metasploit-framework
Ruby | 280 lines | 226 code | 50 blank | 4 comment | 7 complexity | cb50e96ac7167cddbb4f3e3bb392a327 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, GPL-3.0, LGPL-2.1, GPL-2.0
  1. # -*- coding:binary -*-
  2. require 'spec_helper'
  3. require 'rex/proto/http/client_request'
  4. shared_context "with no evasions" do
  5. before(:each) do
  6. client_request.opts['uri_dir_self_reference'] = false
  7. client_request.opts['uri_fake_params_start'] = false
  8. client_request.opts['uri_full_url'] = false
  9. end
  10. it "should return the unmodified uri" do
  11. client_request.send(:set_uri).should == "/"
  12. end
  13. end
  14. shared_context "with 'uri_dir_self_reference'" do
  15. before(:each) do
  16. client_request.opts['uri_dir_self_reference'] = true
  17. end
  18. it "should have a self reference" do
  19. client_request.send(:set_uri).should include("/./")
  20. client_request.to_s.should include("/./")
  21. end
  22. end
  23. shared_context "with 'uri_dir_fake_relative'" do
  24. before(:each) do
  25. client_request.opts['uri_dir_fake_relative'] = true
  26. end
  27. it "should contain sequences of '../'" do
  28. client_request.send(:set_uri).should include("../")
  29. client_request.to_s.should include("../")
  30. end
  31. end
  32. shared_context "with 'uri_full_url'" do
  33. before(:each) do
  34. client_request.opts['uri_full_url'] = true
  35. end
  36. before(:each) do
  37. client_request.opts['vhost'] = host
  38. end
  39. context "with ipv4 host" do
  40. let(:host) { '192.0.2.1' }
  41. it_behaves_like "uri_full_url"
  42. end
  43. context "with ipv6 host" do
  44. let(:host) { '2001:DB8::1' }
  45. it_behaves_like "uri_full_url"
  46. end
  47. context "with dns host" do
  48. let(:host) { 'www.example.com' }
  49. it_behaves_like "uri_full_url"
  50. end
  51. end
  52. shared_examples "uri_full_url" do
  53. it "#set_uri should have the host in the URI" do
  54. client_request.send(:set_uri).should start_with("http://#{host}/")
  55. end
  56. end
  57. describe Rex::Proto::Http::ClientRequest do
  58. default_options = {
  59. # All of these should be what you get when you pass in empty
  60. # options, but of course that would make it too easy
  61. 'uri' => '/',
  62. 'method' => "GET",
  63. 'proto' => "HTTP",
  64. 'connection' => "close",
  65. 'version' => "1.1",
  66. 'port' => 80,
  67. }
  68. [
  69. [ "with reasonable default options",
  70. default_options.merge({
  71. 'agent' => "Mozilla/4.0 (compatible; Metasploit RSPEC)",
  72. 'vhost' => 'www.example.com',
  73. }),
  74. {
  75. :set_uri => { :result => "/" },
  76. :set_method => { :result => "GET" },
  77. :set_version => { :result => "HTTP/1.1\r\n" },
  78. :set_uri_prepend => { :result => "" },
  79. :set_uri_append => { :result => "" },
  80. :set_agent_header => { :result => "User-Agent: Mozilla/4.0 (compatible; Metasploit RSPEC)\r\n" },
  81. :set_host_header => { :result => "Host: www.example.com\r\n" },
  82. :set_formatted_header => { :args => ["Foo", "Bar"], :result => "Foo: Bar\r\n" },
  83. :set_formatted_header => { :args => ["foo", "Bar"], :result => "foo: Bar\r\n" },
  84. :set_formatted_header => { :args => ["Foo", "Bar\twith\ttabs"], :result => "Foo: Bar\twith\ttabs\r\n" },
  85. :set_formatted_header => { :args => ["Foo\twith\tabs", "Bar"], :result => "Foo\twith\tabs: Bar\r\n" },
  86. }
  87. ],
  88. [ "with header folding",
  89. default_options.merge({
  90. 'agent' => "Mozilla/4.0 (compatible; Metasploit RSPEC)",
  91. 'header_folding' => true,
  92. }),
  93. {
  94. :set_uri => { :result => "/" },
  95. :set_method => { :result => "GET" },
  96. :set_version => { :result => "HTTP/1.1\r\n" },
  97. :set_agent_header => { :result => "User-Agent:\r\n\tMozilla/4.0 (compatible; Metasploit RSPEC)\r\n" },
  98. :set_cookie_header => { :result => "" },
  99. :set_connection_header => { :result => "Connection:\r\n\tclose\r\n" },
  100. :set_formatted_header => { :args => ["Foo", "Bar"], :result => "Foo:\r\n\tBar\r\n" },
  101. :set_formatted_header => { :args => ["foo", "Bar"], :result => "foo:\r\n\tBar\r\n" },
  102. :set_formatted_header => { :args => ["Foo", "Bar\twith\ttabs"], :result => "Foo:\r\n\tBar\twith\ttabs\r\n" },
  103. :set_formatted_header => { :args => ["Foo\twith\tabs", "Bar"], :result => "Foo\twith\tabs:\r\n\tBar\r\n" },
  104. }
  105. ],
  106. [ "with ipv6 host",
  107. default_options.merge({
  108. 'vhost' => "2001:DB8::1",
  109. }),
  110. {
  111. :set_host_header => { :result => "Host: [2001:DB8::1]\r\n" },
  112. }
  113. ],
  114. [ "with ipv6 host and non-default port",
  115. default_options.merge({
  116. 'port' => 1234,
  117. 'vhost' => "2001:DB8::1",
  118. }),
  119. {
  120. :set_host_header => { :result => "Host: [2001:DB8::1]:1234\r\n" },
  121. }
  122. ]
  123. ].each do |c, opts, expectations|
  124. context c do
  125. subject(:client_request) { Rex::Proto::Http::ClientRequest.new(opts) }
  126. expectations.each do |meth, things|
  127. args = things[:args] || []
  128. result = things[:result]
  129. describe "##{meth}" do
  130. it "should return #{result.inspect}" do
  131. client_request.send(meth, *args).should == result
  132. end
  133. end
  134. end
  135. end
  136. end
  137. subject(:client_request) { Rex::Proto::Http::ClientRequest.new(default_options) }
  138. context "with GET paramaters" do
  139. subject(:client_request) {
  140. options_with_params = default_options.merge({
  141. 'uri_encode_mode' => encode_mode,
  142. 'encode_params' => encode_params,
  143. 'encode' => false,
  144. 'vars_get' => vars_get,
  145. })
  146. Rex::Proto::Http::ClientRequest.new(options_with_params)
  147. }
  148. # default
  149. let(:encode_mode) { 'hex-normal' }
  150. let(:vars_get) do
  151. {
  152. 'foo[]' => 'bar',
  153. 'bar' => 'baz',
  154. 'frobnicate' => 'the froozle?',
  155. 'foshizzle' => 'my/nizzle',
  156. 'asdf' => nil,
  157. 'test' => ''
  158. }
  159. end
  160. context "with 'pad_get_params'" do
  161. let(:encode_params) { true }
  162. it "should ..." do
  163. old = client_request.opts['pad_get_params']
  164. client_request.opts['pad_get_params'] = true
  165. client_request.opts['pad_get_params_count'] = 0
  166. client_request.to_s.split("&").length.should == vars_get.length
  167. client_request.opts['pad_get_params_count'] = 10
  168. client_request.to_s.split("&").length.should == vars_get.length + 10
  169. client_request.opts['pad_get_params'] = old
  170. end
  171. end
  172. context "without 'encode_params'" do
  173. let(:encode_params) { false }
  174. it "should contain the unaltered params" do
  175. str = client_request.to_s
  176. str.should include("foo[]=bar")
  177. str.should include("bar=baz")
  178. str.should include("frobnicate=the froozle?")
  179. str.should include("foshizzle=my/nizzle")
  180. str.should include("asdf&")
  181. str.should include("test=")
  182. end
  183. end
  184. context "with 'encode_params'" do
  185. let(:encode_params) { true }
  186. context "and 'uri_encode_mode' = default (hex-normal)" do
  187. it "should encode special chars" do
  188. str = client_request.to_s
  189. str.should include("foo%5b%5d=bar")
  190. str.should include("bar=baz")
  191. str.should include("frobnicate=the%20froozle%3f")
  192. str.should include("foshizzle=my/nizzle")
  193. str.should include("asdf&")
  194. str.should include("test=")
  195. end
  196. end
  197. context "and 'uri_encode_mode' = hex-noslashes" do
  198. let(:encode_mode) { 'hex-noslashes' }
  199. it "should encode all chars" do
  200. str = client_request.to_s
  201. str.should include("%66%6f%6f%5b%5d=%62%61%72")
  202. str.should include("%62%61%72=%62%61%7a")
  203. str.should include("%66%72%6f%62%6e%69%63%61%74%65=%74%68%65%20%66%72%6f%6f%7a%6c%65%3f")
  204. str.should include("%66%6f%73%68%69%7a%7a%6c%65=%6d%79/%6e%69%7a%7a%6c%65")
  205. end
  206. end
  207. context "and 'uri_encode_mode' = hex-all" do
  208. let(:encode_mode) { 'hex-all' }
  209. it "should encode all chars" do
  210. str = client_request.to_s
  211. str.should include("%66%6f%6f%5b%5d=%62%61%72")
  212. str.should include("%62%61%72=%62%61%7a")
  213. str.should include("%66%72%6f%62%6e%69%63%61%74%65=%74%68%65%20%66%72%6f%6f%7a%6c%65%3f")
  214. str.should include("%66%6f%73%68%69%7a%7a%6c%65=%6d%79%2f%6e%69%7a%7a%6c%65")
  215. end
  216. end
  217. describe "#to_s" do
  218. it "should produce same values if called multiple times with same options" do
  219. client_request.to_s.should == client_request.to_s
  220. end
  221. end
  222. end
  223. end
  224. describe "#set_uri" do
  225. it_behaves_like "with 'uri_full_url'"
  226. it_behaves_like "with 'uri_dir_self_reference'"
  227. it_behaves_like "with 'uri_dir_fake_relative'"
  228. it_behaves_like "with no evasions"
  229. end
  230. end