PageRenderTime 37ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/spec/unit/network/authstore_spec.rb

https://github.com/david-caro/puppet
Ruby | 424 lines | 393 code | 30 blank | 1 comment | 6 complexity | c361b24b6cf556db6152a678076265db MD5 | raw file
Possible License(s): Apache-2.0, CC-BY-3.0
  1. #! /usr/bin/env ruby
  2. require 'spec_helper'
  3. require 'rbconfig'
  4. require 'puppet/network/authconfig'
  5. describe Puppet::Network::AuthStore do
  6. before :each do
  7. @authstore = Puppet::Network::AuthStore.new
  8. @authstore.reset_interpolation
  9. end
  10. describe "when checking if the acl has some entries" do
  11. it "should be empty if no ACE have been entered" do
  12. @authstore.should be_empty
  13. end
  14. it "should not be empty if it is a global allow" do
  15. @authstore.allow('*')
  16. @authstore.should_not be_empty
  17. end
  18. it "should not be empty if at least one allow has been entered" do
  19. @authstore.allow_ip('1.1.1.*')
  20. @authstore.should_not be_empty
  21. end
  22. it "should not be empty if at least one deny has been entered" do
  23. @authstore.deny_ip('1.1.1.*')
  24. @authstore.should_not be_empty
  25. end
  26. end
  27. describe "when checking global allow" do
  28. it "should not be enabled by default" do
  29. @authstore.should_not be_globalallow
  30. @authstore.should_not be_allowed('foo.bar.com', '192.168.1.1')
  31. end
  32. it "should always allow when enabled" do
  33. @authstore.allow('*')
  34. @authstore.should be_globalallow
  35. @authstore.should be_allowed('foo.bar.com', '192.168.1.1')
  36. end
  37. end
  38. describe "when checking a regex type of allow" do
  39. before :each do
  40. @authstore.allow('/^(test-)?host[0-9]+\.other-domain\.(com|org|net)$|some-domain\.com/')
  41. @ip = '192.168.1.1'
  42. end
  43. ['host5.other-domain.com', 'test-host12.other-domain.net', 'foo.some-domain.com'].each { |name|
  44. it "should allow the host #{name}" do
  45. @authstore.should be_allowed(name, @ip)
  46. end
  47. }
  48. ['host0.some-other-domain.com',''].each { |name|
  49. it "should not allow the host #{name}" do
  50. @authstore.should_not be_allowed(name, @ip)
  51. end
  52. }
  53. end
  54. end
  55. describe Puppet::Network::AuthStore::Declaration do
  56. ['100.101.99.98','100.100.100.100','1.2.3.4','11.22.33.44'].each { |ip|
  57. describe "when the pattern is a simple numeric IP such as #{ip}" do
  58. before :each do
  59. @declaration = Puppet::Network::AuthStore::Declaration.new(:allow_ip,ip)
  60. end
  61. it "should match the specified IP" do
  62. @declaration.should be_match('www.testsite.org',ip)
  63. end
  64. it "should not match other IPs" do
  65. @declaration.should_not be_match('www.testsite.org','200.101.99.98')
  66. end
  67. end
  68. (1..3).each { |n|
  69. describe "when the pattern is a IP mask with #{n} numeric segments and a *" do
  70. before :each do
  71. @ip_pattern = ip.split('.')[0,n].join('.')+'.*'
  72. @declaration = Puppet::Network::AuthStore::Declaration.new(:allow_ip,@ip_pattern)
  73. end
  74. it "should match an IP in the range" do
  75. @declaration.should be_match('www.testsite.org',ip)
  76. end
  77. it "should not match other IPs" do
  78. @declaration.should_not be_match('www.testsite.org','200.101.99.98')
  79. end
  80. it "should not match IPs that differ in the last non-wildcard segment" do
  81. other = ip.split('.')
  82. other[n-1].succ!
  83. @declaration.should_not be_match('www.testsite.org',other.join('.'))
  84. end
  85. end
  86. }
  87. }
  88. describe "when the pattern is a numeric IP with a back reference" do
  89. pending("implementation of backreferences for IP") do
  90. before :each do
  91. @ip = '100.101.$1'
  92. @declaration = Puppet::Network::AuthStore::Declaration.new(:allow_ip,@ip).interpolate('12.34'.match(/(.*)/))
  93. end
  94. it "should match an IP with the appropriate interpolation" do
  95. @declaration.should be_match('www.testsite.org',@ip.sub(/\$1/,'12.34'))
  96. end
  97. it "should not match other IPs" do
  98. @declaration.should_not be_match('www.testsite.org',@ip.sub(/\$1/,'66.34'))
  99. end
  100. end
  101. end
  102. [
  103. "02001:0000:1234:0000:0000:C1C0:ABCD:0876",
  104. "2001:0000:1234:0000:00001:C1C0:ABCD:0876",
  105. " 2001:0000:1234:0000:0000:C1C0:ABCD:0876 0",
  106. "2001:0000:1234: 0000:0000:C1C0:ABCD:0876",
  107. "3ffe:0b00:0000:0001:0000:0000:000a",
  108. "FF02:0000:0000:0000:0000:0000:0000:0000:0001",
  109. "3ffe:b00::1::a",
  110. "1:2:3::4:5::7:8",
  111. "12345::6:7:8",
  112. "1::5:400.2.3.4",
  113. "1::5:260.2.3.4",
  114. "1::5:256.2.3.4",
  115. "1::5:1.256.3.4",
  116. "1::5:1.2.256.4",
  117. "1::5:1.2.3.256",
  118. "1::5:300.2.3.4",
  119. "1::5:1.300.3.4",
  120. "1::5:1.2.300.4",
  121. "1::5:1.2.3.300",
  122. "1::5:900.2.3.4",
  123. "1::5:1.900.3.4",
  124. "1::5:1.2.900.4",
  125. "1::5:1.2.3.900",
  126. "1::5:300.300.300.300",
  127. "1::5:3000.30.30.30",
  128. "1::400.2.3.4",
  129. "1::260.2.3.4",
  130. "1::256.2.3.4",
  131. "1::1.256.3.4",
  132. "1::1.2.256.4",
  133. "1::1.2.3.256",
  134. "1::300.2.3.4",
  135. "1::1.300.3.4",
  136. "1::1.2.300.4",
  137. "1::1.2.3.300",
  138. "1::900.2.3.4",
  139. "1::1.900.3.4",
  140. "1::1.2.900.4",
  141. "1::1.2.3.900",
  142. "1::300.300.300.300",
  143. "1::3000.30.30.30",
  144. "::400.2.3.4",
  145. "::260.2.3.4",
  146. "::256.2.3.4",
  147. "::1.256.3.4",
  148. "::1.2.256.4",
  149. "::1.2.3.256",
  150. "::300.2.3.4",
  151. "::1.300.3.4",
  152. "::1.2.300.4",
  153. "::1.2.3.300",
  154. "::900.2.3.4",
  155. "::1.900.3.4",
  156. "::1.2.900.4",
  157. "::1.2.3.900",
  158. "::300.300.300.300",
  159. "::3000.30.30.30",
  160. "2001:DB8:0:0:8:800:200C:417A:221", # unicast, full
  161. "FF01::101::2" # multicast, compressed
  162. ].each { |invalid_ip|
  163. describe "when the pattern is an invalid IPv6 address such as #{invalid_ip}" do
  164. it "should raise an exception" do
  165. lambda { Puppet::Network::AuthStore::Declaration.new(:allow,invalid_ip) }.should raise_error
  166. end
  167. end
  168. }
  169. [
  170. "1.2.3.4",
  171. "2001:0000:1234:0000:0000:C1C0:ABCD:0876",
  172. "3ffe:0b00:0000:0000:0001:0000:0000:000a",
  173. "FF02:0000:0000:0000:0000:0000:0000:0001",
  174. "0000:0000:0000:0000:0000:0000:0000:0001",
  175. "0000:0000:0000:0000:0000:0000:0000:0000",
  176. "::ffff:192.168.1.26",
  177. "2::10",
  178. "ff02::1",
  179. "fe80::",
  180. "2002::",
  181. "2001:db8::",
  182. "2001:0db8:1234::",
  183. "::ffff:0:0",
  184. "::1",
  185. "::ffff:192.168.1.1",
  186. "1:2:3:4:5:6:7:8",
  187. "1:2:3:4:5:6::8",
  188. "1:2:3:4:5::8",
  189. "1:2:3:4::8",
  190. "1:2:3::8",
  191. "1:2::8",
  192. "1::8",
  193. "1::2:3:4:5:6:7",
  194. "1::2:3:4:5:6",
  195. "1::2:3:4:5",
  196. "1::2:3:4",
  197. "1::2:3",
  198. "1::8",
  199. "::2:3:4:5:6:7",
  200. "::2:3:4:5:6",
  201. "::2:3:4:5",
  202. "::2:3:4",
  203. "::2:3",
  204. "::8",
  205. "1:2:3:4:5:6::",
  206. "1:2:3:4:5::",
  207. "1:2:3:4::",
  208. "1:2:3::",
  209. "1:2::",
  210. "1::",
  211. "1:2:3:4:5::7:8",
  212. "1:2:3:4::7:8",
  213. "1:2:3::7:8",
  214. "1:2::7:8",
  215. "1::7:8",
  216. "1:2:3:4:5:6:1.2.3.4",
  217. "1:2:3:4:5::1.2.3.4",
  218. "1:2:3:4::1.2.3.4",
  219. "1:2:3::1.2.3.4",
  220. "1:2::1.2.3.4",
  221. "1::1.2.3.4",
  222. "1:2:3:4::5:1.2.3.4",
  223. "1:2:3::5:1.2.3.4",
  224. "1:2::5:1.2.3.4",
  225. "1::5:1.2.3.4",
  226. "1::5:11.22.33.44",
  227. "fe80::217:f2ff:254.7.237.98",
  228. "fe80::217:f2ff:fe07:ed62",
  229. "2001:DB8:0:0:8:800:200C:417A", # unicast, full
  230. "FF01:0:0:0:0:0:0:101", # multicast, full
  231. "0:0:0:0:0:0:0:1", # loopback, full
  232. "0:0:0:0:0:0:0:0", # unspecified, full
  233. "2001:DB8::8:800:200C:417A", # unicast, compressed
  234. "FF01::101", # multicast, compressed
  235. "::1", # loopback, compressed, non-routable
  236. "::", # unspecified, compressed, non-routable
  237. "0:0:0:0:0:0:13.1.68.3", # IPv4-compatible IPv6 address, full, deprecated
  238. "0:0:0:0:0:FFFF:129.144.52.38", # IPv4-mapped IPv6 address, full
  239. "::13.1.68.3", # IPv4-compatible IPv6 address, compressed, deprecated
  240. "::FFFF:129.144.52.38", # IPv4-mapped IPv6 address, compressed
  241. "2001:0DB8:0000:CD30:0000:0000:0000:0000/60", # full, with prefix
  242. "2001:0DB8::CD30:0:0:0:0/60", # compressed, with prefix
  243. "2001:0DB8:0:CD30::/60", # compressed, with prefix #2
  244. "::/128", # compressed, unspecified address type, non-routable
  245. "::1/128", # compressed, loopback address type, non-routable
  246. "FF00::/8", # compressed, multicast address type
  247. "FE80::/10", # compressed, link-local unicast, non-routable
  248. "FEC0::/10", # compressed, site-local unicast, deprecated
  249. "127.0.0.1", # standard IPv4, loopback, non-routable
  250. "0.0.0.0", # standard IPv4, unspecified, non-routable
  251. "255.255.255.255", # standard IPv4
  252. "fe80:0000:0000:0000:0204:61ff:fe9d:f156",
  253. "fe80:0:0:0:204:61ff:fe9d:f156",
  254. "fe80::204:61ff:fe9d:f156",
  255. "fe80:0000:0000:0000:0204:61ff:254.157.241.086",
  256. "fe80:0:0:0:204:61ff:254.157.241.86",
  257. "fe80::204:61ff:254.157.241.86",
  258. "::1",
  259. "fe80::",
  260. "fe80::1"
  261. ].each { |ip|
  262. describe "when the pattern is a valid IP such as #{ip}" do
  263. before :each do
  264. @declaration = Puppet::Network::AuthStore::Declaration.new(:allow_ip,ip)
  265. end
  266. it "should match the specified IP" do
  267. @declaration.should be_match('www.testsite.org',ip)
  268. end
  269. it "should not match other IPs" do
  270. @declaration.should_not be_match('www.testsite.org','200.101.99.98')
  271. end
  272. end unless ip =~ /:.*\./ # Hybrid IPs aren't supported by ruby's ipaddr
  273. }
  274. [
  275. "::2:3:4:5:6:7:8",
  276. ].each { |ip|
  277. describe "when the pattern is a valid IP such as #{ip}" do
  278. let(:declaration) do
  279. Puppet::Network::AuthStore::Declaration.new(:allow_ip,ip)
  280. end
  281. issue_7477 = !(IPAddr.new(ip) rescue false)
  282. it "should match the specified IP" do
  283. pending "resolution of ruby issue [7477](http://goo.gl/Bb1LU)", :if => issue_7477
  284. declaration.should be_match('www.testsite.org',ip)
  285. end
  286. it "should not match other IPs" do
  287. pending "resolution of ruby issue [7477](http://goo.gl/Bb1LU)", :if => issue_7477
  288. declaration.should_not be_match('www.testsite.org','200.101.99.98')
  289. end
  290. end
  291. }
  292. {
  293. 'spirit.mars.nasa.gov' => 'a PQDN',
  294. 'ratchet.2ndsiteinc.com' => 'a PQDN with digits',
  295. 'a.c.ru' => 'a PQDN with short segments',
  296. }.each {|pqdn,desc|
  297. describe "when the pattern is #{desc}" do
  298. before :each do
  299. @host = pqdn
  300. @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,@host)
  301. end
  302. it "should match the specified PQDN" do
  303. @declaration.should be_match(@host,'200.101.99.98')
  304. end
  305. it "should not match a similar FQDN" do
  306. pending "FQDN consensus"
  307. @declaration.should_not be_match(@host+'.','200.101.99.98')
  308. end
  309. end
  310. }
  311. ['abc.12seps.edu.phisher.biz','www.google.com','slashdot.org'].each { |host|
  312. (1...(host.split('.').length)).each { |n|
  313. describe "when the pattern is #{"*."+host.split('.')[-n,n].join('.')}" do
  314. before :each do
  315. @pattern = "*."+host.split('.')[-n,n].join('.')
  316. @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,@pattern)
  317. end
  318. it "should match #{host}" do
  319. @declaration.should be_match(host,'1.2.3.4')
  320. end
  321. it "should not match www.testsite.gov" do
  322. @declaration.should_not be_match('www.testsite.gov','200.101.99.98')
  323. end
  324. it "should not match hosts that differ in the first non-wildcard segment" do
  325. other = host.split('.')
  326. other[-n].succ!
  327. @declaration.should_not be_match(other.join('.'),'1.2.3.4')
  328. end
  329. end
  330. }
  331. }
  332. describe "when the pattern is a FQDN" do
  333. before :each do
  334. @host = 'spirit.mars.nasa.gov.'
  335. @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,@host)
  336. end
  337. it "should match the specified FQDN" do
  338. pending "FQDN consensus"
  339. @declaration.should be_match(@host,'200.101.99.98')
  340. end
  341. it "should not match a similar PQDN" do
  342. @declaration.should_not be_match(@host[0..-2],'200.101.99.98')
  343. end
  344. end
  345. describe "when the pattern is an opaque string with a back reference" do
  346. before :each do
  347. @host = 'c216f41a-f902-4bfb-a222-850dd957bebb'
  348. @item = "/catalog/#{@host}"
  349. @pattern = %{^/catalog/([^/]+)$}
  350. @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,'$1')
  351. end
  352. it "should match an IP with the appropriate interpolation" do
  353. @declaration.interpolate(@item.match(@pattern)).should be_match(@host,'10.0.0.5')
  354. end
  355. end
  356. describe "when the pattern is an opaque string with a back reference and the matched data contains dots" do
  357. before :each do
  358. @host = 'admin.mgmt.nym1'
  359. @item = "/catalog/#{@host}"
  360. @pattern = %{^/catalog/([^/]+)$}
  361. @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,'$1')
  362. end
  363. it "should match a name with the appropriate interpolation" do
  364. @declaration.interpolate(@item.match(@pattern)).should be_match(@host,'10.0.0.5')
  365. end
  366. end
  367. describe "when the pattern is an opaque string with a back reference and the matched data contains dots with an initial prefix that looks like an IP address" do
  368. before :each do
  369. @host = '01.admin.mgmt.nym1'
  370. @item = "/catalog/#{@host}"
  371. @pattern = %{^/catalog/([^/]+)$}
  372. @declaration = Puppet::Network::AuthStore::Declaration.new(:allow,'$1')
  373. end
  374. it "should match a name with the appropriate interpolation" do
  375. @declaration.interpolate(@item.match(@pattern)).should be_match(@host,'10.0.0.5')
  376. end
  377. end
  378. describe "when comparing patterns" do
  379. before :each do
  380. @ip = Puppet::Network::AuthStore::Declaration.new(:allow,'127.0.0.1')
  381. @host_name = Puppet::Network::AuthStore::Declaration.new(:allow,'www.hard_knocks.edu')
  382. @opaque = Puppet::Network::AuthStore::Declaration.new(:allow,'hey_dude')
  383. end
  384. it "should consider ip addresses before host names" do
  385. (@ip < @host_name).should be_true
  386. end
  387. it "should consider ip addresses before opaque strings" do
  388. (@ip < @opaque).should be_true
  389. end
  390. it "should consider host_names before opaque strings" do
  391. (@host_name < @opaque).should be_true
  392. end
  393. end
  394. end