tor_extend 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. data/Change.log +12 -0
  2. data/ReadME.txt +190 -0
  3. data/doc/ReadME_txt.html +301 -0
  4. data/doc/Tor.html +140 -0
  5. data/doc/Tor/Bridge.html +145 -0
  6. data/doc/Tor/CachedDesc.html +472 -0
  7. data/doc/Tor/Constants.html +185 -0
  8. data/doc/Tor/Router.html +146 -0
  9. data/doc/Tor/StatsObj.html +1209 -0
  10. data/doc/Tor/TController.html +1111 -0
  11. data/doc/created.rid +7 -0
  12. data/doc/images/add.png +0 -0
  13. data/doc/images/brick.png +0 -0
  14. data/doc/images/brick_link.png +0 -0
  15. data/doc/images/bug.png +0 -0
  16. data/doc/images/bullet_black.png +0 -0
  17. data/doc/images/bullet_toggle_minus.png +0 -0
  18. data/doc/images/bullet_toggle_plus.png +0 -0
  19. data/doc/images/date.png +0 -0
  20. data/doc/images/delete.png +0 -0
  21. data/doc/images/find.png +0 -0
  22. data/doc/images/loadingAnimation.gif +0 -0
  23. data/doc/images/macFFBgHack.png +0 -0
  24. data/doc/images/package.png +0 -0
  25. data/doc/images/page_green.png +0 -0
  26. data/doc/images/page_white_text.png +0 -0
  27. data/doc/images/page_white_width.png +0 -0
  28. data/doc/images/plugin.png +0 -0
  29. data/doc/images/ruby.png +0 -0
  30. data/doc/images/tag_blue.png +0 -0
  31. data/doc/images/tag_green.png +0 -0
  32. data/doc/images/transparent.png +0 -0
  33. data/doc/images/wrench.png +0 -0
  34. data/doc/images/wrench_orange.png +0 -0
  35. data/doc/images/zoom.png +0 -0
  36. data/doc/index.html +90 -0
  37. data/doc/js/darkfish.js +153 -0
  38. data/doc/js/jquery.js +18 -0
  39. data/doc/js/navigation.js +142 -0
  40. data/doc/js/search.js +94 -0
  41. data/doc/js/search_index.js +1 -0
  42. data/doc/js/searcher.js +228 -0
  43. data/doc/lib/constants_rb.html +96 -0
  44. data/doc/lib/httpmod_rb.html +95 -0
  45. data/doc/lib/tcontroller_rb.html +93 -0
  46. data/doc/lib/tor_extend_rb.html +97 -0
  47. data/doc/lib/tstats_rb.html +93 -0
  48. data/doc/rdoc.css +543 -0
  49. data/doc/table_of_contents.html +159 -0
  50. data/lib/constants.rb +106 -0
  51. data/lib/httpmod.rb +89 -0
  52. data/lib/tcontroller.rb +475 -0
  53. data/lib/tor_extend.rb +189 -0
  54. data/lib/tstats.rb +514 -0
  55. data/tor_extend.gemspec +26 -0
  56. metadata +138 -0
@@ -0,0 +1,159 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
6
+
7
+ <title>Table of Contents</title>
8
+
9
+ <link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet">
10
+
11
+ <script type="text/javascript">
12
+ var rdoc_rel_prefix = "./";
13
+ </script>
14
+
15
+ <script type="text/javascript" charset="utf-8" src="./js/jquery.js"></script>
16
+ <script type="text/javascript" charset="utf-8" src="./js/navigation.js"></script>
17
+ <script type="text/javascript" charset="utf-8" src="./js/search_index.js"></script>
18
+ <script type="text/javascript" charset="utf-8" src="./js/search.js"></script>
19
+ <script type="text/javascript" charset="utf-8" src="./js/searcher.js"></script>
20
+ <script type="text/javascript" charset="utf-8" src="./js/darkfish.js"></script>
21
+
22
+
23
+ <body class="indexpage">
24
+ <h1>Table of Contents</h1>
25
+
26
+ <h2>Pages</h2>
27
+ <ul>
28
+ <li class="file">
29
+ <a href="ReadME_txt.html">ReadME</a>
30
+ </li>
31
+
32
+ </ul>
33
+
34
+ <h2 id="classes">Classes/Modules</h2>
35
+ <ul>
36
+ <li class="module">
37
+ <a href="Tor.html">Tor</a>
38
+ </li>
39
+ <li class="class">
40
+ <a href="Tor/Bridge.html">Tor::Bridge</a>
41
+ </li>
42
+ <li class="class">
43
+ <a href="Tor/CachedDesc.html">Tor::CachedDesc</a>
44
+ </li>
45
+ <li class="module">
46
+ <a href="Tor/Constants.html">Tor::Constants</a>
47
+ </li>
48
+ <li class="class">
49
+ <a href="Tor/Router.html">Tor::Router</a>
50
+ </li>
51
+ <li class="class">
52
+ <a href="Tor/StatsObj.html">Tor::StatsObj</a>
53
+ </li>
54
+ <li class="class">
55
+ <a href="Tor/TController.html">Tor::TController</a>
56
+ </li>
57
+
58
+ </ul>
59
+
60
+ <h2 id="methods">Methods</h2>
61
+ <ul>
62
+
63
+ <li class="method"><a href="Tor/CachedDesc.html#method-c-new">::new &mdash; Tor::CachedDesc</a>
64
+
65
+ <li class="method"><a href="Tor/TController.html#method-i-attach_stream">#attach_stream &mdash; Tor::TController</a>
66
+
67
+ <li class="method"><a href="Tor/TController.html#method-i-bridges">#bridges &mdash; Tor::TController</a>
68
+
69
+ <li class="method"><a href="Tor/TController.html#method-i-cir_status">#cir_status &mdash; Tor::TController</a>
70
+
71
+ <li class="method"><a href="Tor/TController.html#method-i-closeallcircuits">#closeallcircuits &mdash; Tor::TController</a>
72
+
73
+ <li class="method"><a href="Tor/TController.html#method-i-closecircuit">#closecircuit &mdash; Tor::TController</a>
74
+
75
+ <li class="method"><a href="Tor/StatsObj.html#method-i-continent_count">#continent_count &mdash; Tor::StatsObj</a>
76
+
77
+ <li class="method"><a href="Tor/StatsObj.html#method-i-continent_count_uniq">#continent_count_uniq &mdash; Tor::StatsObj</a>
78
+
79
+ <li class="method"><a href="Tor/StatsObj.html#method-i-continent_getfingerprint">#continent_getfingerprint &mdash; Tor::StatsObj</a>
80
+
81
+ <li class="method"><a href="Tor/StatsObj.html#method-i-continent_list">#continent_list &mdash; Tor::StatsObj</a>
82
+
83
+ <li class="method"><a href="Tor/StatsObj.html#method-i-continent_stat">#continent_stat &mdash; Tor::StatsObj</a>
84
+
85
+ <li class="method"><a href="Tor/StatsObj.html#method-i-continent_stat_uniq">#continent_stat_uniq &mdash; Tor::StatsObj</a>
86
+
87
+ <li class="method"><a href="Tor/StatsObj.html#method-i-country_count">#country_count &mdash; Tor::StatsObj</a>
88
+
89
+ <li class="method"><a href="Tor/StatsObj.html#method-i-country_count_uniq">#country_count_uniq &mdash; Tor::StatsObj</a>
90
+
91
+ <li class="method"><a href="Tor/StatsObj.html#method-i-country_getfingerprint">#country_getfingerprint &mdash; Tor::StatsObj</a>
92
+
93
+ <li class="method"><a href="Tor/StatsObj.html#method-i-country_getip">#country_getip &mdash; Tor::StatsObj</a>
94
+
95
+ <li class="method"><a href="Tor/StatsObj.html#method-i-country_list">#country_list &mdash; Tor::StatsObj</a>
96
+
97
+ <li class="method"><a href="Tor/StatsObj.html#method-i-country_stat">#country_stat &mdash; Tor::StatsObj</a>
98
+
99
+ <li class="method"><a href="Tor/StatsObj.html#method-i-country_stat_uniq">#country_stat_uniq &mdash; Tor::StatsObj</a>
100
+
101
+ <li class="method"><a href="Tor/CachedDesc.html#method-i-dbconnect">#dbconnect &mdash; Tor::CachedDesc</a>
102
+
103
+ <li class="method"><a href="Tor/TController.html#method-i-ds">#ds &mdash; Tor::TController</a>
104
+
105
+ <li class="method"><a href="Tor/TController.html#method-i-extendcir">#extendcir &mdash; Tor::TController</a>
106
+
107
+ <li class="method"><a href="Tor/TController.html#method-i-extendcir_slowly">#extendcir_slowly &mdash; Tor::TController</a>
108
+
109
+ <li class="method"><a href="Tor/StatsObj.html#method-i-genkml">#genkml &mdash; Tor::StatsObj</a>
110
+
111
+ <li class="method"><a href="Tor/TController.html#method-i-get_bridges">#get_bridges &mdash; Tor::TController</a>
112
+
113
+ <li class="method"><a href="Tor/StatsObj.html#method-i-get_countryname">#get_countryname &mdash; Tor::StatsObj</a>
114
+
115
+ <li class="method"><a href="Tor/TController.html#method-i-get_entryguards">#get_entryguards &mdash; Tor::TController</a>
116
+
117
+ <li class="method"><a href="Tor/CachedDesc.html#method-i-get_geoiprecord">#get_geoiprecord &mdash; Tor::CachedDesc</a>
118
+
119
+ <li class="method"><a href="Tor/TController.html#method-i-get_httperrors">#get_httperrors &mdash; Tor::TController</a>
120
+
121
+ <li class="method"><a href="Tor/StatsObj.html#method-i-get_latlng">#get_latlng &mdash; Tor::StatsObj</a>
122
+
123
+ <li class="method"><a href="Tor/TController.html#method-i-get_purposeip">#get_purposeip &mdash; Tor::TController</a>
124
+
125
+ <li class="method"><a href="Tor/StatsObj.html#method-i-get_uniqid">#get_uniqid &mdash; Tor::StatsObj</a>
126
+
127
+ <li class="method"><a href="Tor/TController.html#method-i-getconf">#getconf &mdash; Tor::TController</a>
128
+
129
+ <li class="method"><a href="Tor/TController.html#method-i-getinfo">#getinfo &mdash; Tor::TController</a>
130
+
131
+ <li class="method"><a href="Tor/TController.html#method-i-net_status">#net_status &mdash; Tor::TController</a>
132
+
133
+ <li class="method"><a href="Tor/TController.html#method-i-newstreams">#newstreams &mdash; Tor::TController</a>
134
+
135
+ <li class="method"><a href="Tor/CachedDesc.html#method-i-ors">#ors &mdash; Tor::CachedDesc</a>
136
+
137
+ <li class="method"><a href="Tor/CachedDesc.html#method-i-readall">#readall &mdash; Tor::CachedDesc</a>
138
+
139
+ <li class="method"><a href="Tor/TController.html#method-i-setconf">#setconf &mdash; Tor::TController</a>
140
+
141
+ <li class="method"><a href="Tor/TController.html#method-i-signal">#signal &mdash; Tor::TController</a>
142
+
143
+ <li class="method"><a href="Tor/TController.html#method-i-sr">#sr &mdash; Tor::TController</a>
144
+
145
+ <li class="method"><a href="Tor/CachedDesc.html#method-i-stat">#stat &mdash; Tor::CachedDesc</a>
146
+
147
+ <li class="method"><a href="Tor/StatsObj.html#method-i-topcountries">#topcountries &mdash; Tor::StatsObj</a>
148
+
149
+ <li class="method"><a href="Tor/StatsObj.html#method-i-topcountries_uniq">#topcountries_uniq &mdash; Tor::StatsObj</a>
150
+
151
+ </ul>
152
+
153
+
154
+ <footer id="validator-badges">
155
+ <p><a href="http://validator.w3.org/check/referer">[Validate]</a>
156
+ <p>Generated by <a href="https://github.com/rdoc/rdoc">RDoc</a> 3.11.
157
+ <p>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish Rdoc Generator</a> 3.
158
+ </footer>
159
+
@@ -0,0 +1,106 @@
1
+
2
+ # This module contains constants for the Tor module such as a COUNLATLNG
3
+ module Tor::Constants
4
+
5
+
6
+ # This maps the coordinates of each country to its country code.
7
+ #
8
+ # *Get* *Coordinates* *for* *countries*
9
+ # Tor::Constants::COUNLATLNG["FR"] =>{:lat=>46.0, :lng=>2.0}
10
+ # Tor::Constants::COUNLATLNG["GB"] =>{:lat=>54.0, :lng=>-2.0}
11
+ # Tor::Constants::COUNLATLNG["FR"][:lat] =>46.0
12
+ # Tor::Constants::COUNLATLNG["GB"][lng] =>-2.0
13
+ #
14
+ # A1 and A2 - anonymous proxies and satelite providers - added using cordinates (0,0)
15
+ # IM, AX, JE added from the CIA factbook, the others from the Maxmind page
16
+ # <b>NOTE:</b> See the following links for more details
17
+ # CIA Factbook online [https://www.cia.gov/library/publications/the-world-factbook/fields/2011.html]
18
+ # Maxmind(2007) - Average Latitude and longitude for countries [http://www.maxmind.com/app/country_latlon]
19
+ COUNLATLNG = {
20
+ "AD"=>{:lat=>42.5, :lng=>1.5}, "AE"=>{:lat=>24.0, :lng=>54.0}, "AF"=>{:lat=>33.0, :lng=>65.0}, "AG"=>{:lat=>17.05, :lng=>-61.8},"AI"=>{:lat=>18.25, :lng=>-63.1667},
21
+ "AL"=>{:lat=>41.0, :lng=>20.0}, "AM"=>{:lat=>40.0, :lng=>45.0},"AN"=>{:lat=>12.25, :lng=>-68.75}, "AO"=>{:lat=>-12.5, :lng=>18.5},
22
+ "AP"=>{:lat=>35.0, :lng=>105.0}, "AQ"=>{:lat=>-90.0, :lng=>0.0}, "AR"=>{:lat=>-34.0, :lng=>-64.0}, "AS"=>{:lat=>-14.3333, :lng=>-170.0},
23
+ "AT"=>{:lat=>47.3333, :lng=>13.3333}, "AU"=>{:lat=>-27.0, :lng=>133.0}, "AW"=>{:lat=>12.5, :lng=>-69.9667}, "AZ"=>{:lat=>40.5, :lng=>47.5},
24
+ "BA"=>{:lat=>44.0, :lng=>18.0}, "BB"=>{:lat=>13.1667, :lng=>-59.5333}, "BD"=>{:lat=>24.0, :lng=>90.0}, "BE"=>{:lat=>50.8333, :lng=>4.0},
25
+ "BF"=>{:lat=>13.0, :lng=>-2.0}, "BG"=>{:lat=>43.0, :lng=>25.0}, "BH"=>{:lat=>26.0, :lng=>50.55}, "BI"=>{:lat=>-3.5, :lng=>30.0},
26
+ "BJ"=>{:lat=>9.5, :lng=>2.25}, "BM"=>{:lat=>32.3333, :lng=>-64.75}, "BN"=>{:lat=>4.5, :lng=>114.6667}, "BO"=>{:lat=>-17.0, :lng=>-65.0},
27
+ "BR"=>{:lat=>-10.0, :lng=>-55.0}, "BS"=>{:lat=>24.25, :lng=>-76.0}, "BT"=>{:lat=>27.5, :lng=>90.5}, "BV"=>{:lat=>-54.4333, :lng=>3.4},
28
+ "BW"=>{:lat=>-22.0, :lng=>24.0}, "BY"=>{:lat=>53.0, :lng=>28.0}, "BZ"=>{:lat=>17.25, :lng=>-88.75}, "CA"=>{:lat=>60.0, :lng=>-95.0},
29
+ "CC"=>{:lat=>-12.5, :lng=>96.8333}, "CD"=>{:lat=>0.0, :lng=>25.0}, "CF"=>{:lat=>7.0, :lng=>21.0}, "CG"=>{:lat=>-1.0, :lng=>15.0},
30
+ "CH"=>{:lat=>47.0, :lng=>8.0}, "CI"=>{:lat=>8.0, :lng=>-5.0}, "CK"=>{:lat=>-21.2333, :lng=>-159.7667}, "CL"=>{:lat=>-30.0, :lng=>-71.0},
31
+ "CM"=>{:lat=>6.0, :lng=>12.0}, "CN"=>{:lat=>35.0, :lng=>105.0}, "CO"=>{:lat=>4.0, :lng=>-72.0}, "CR"=>{:lat=>10.0, :lng=>-84.0},
32
+ "CU"=>{:lat=>21.5, :lng=>-80.0}, "CV"=>{:lat=>16.0, :lng=>-24.0}, "CX"=>{:lat=>-10.5, :lng=>105.6667}, "CY"=>{:lat=>35.0, :lng=>33.0},
33
+ "CZ"=>{:lat=>49.75, :lng=>15.5}, "DE"=>{:lat=>51.0, :lng=>9.0}, "DJ"=>{:lat=>11.5, :lng=>43.0}, "DK"=>{:lat=>56.0, :lng=>10.0},
34
+ "DM"=>{:lat=>15.4167, :lng=>-61.3333}, "DO"=>{:lat=>19.0, :lng=>-70.6667}, "DZ"=>{:lat=>28.0, :lng=>3.0}, "EC"=>{:lat=>-2.0, :lng=>-77.5},
35
+ "EE"=>{:lat=>59.0, :lng=>26.0}, "EG"=>{:lat=>27.0, :lng=>30.0}, "EH"=>{:lat=>24.5, :lng=>-13.0}, "ER"=>{:lat=>15.0, :lng=>39.0},
36
+ "ES"=>{:lat=>40.0, :lng=>-4.0}, "ET"=>{:lat=>8.0, :lng=>38.0}, "EU"=>{:lat=>47.0, :lng=>8.0}, "FI"=>{:lat=>64.0, :lng=>26.0},
37
+ "FJ"=>{:lat=>-18.0, :lng=>175.0}, "FK"=>{:lat=>-51.75, :lng=>-59.0}, "FM"=>{:lat=>6.9167, :lng=>158.25}, "FO"=>{:lat=>62.0, :lng=>-7.0},
38
+ "FR"=>{:lat=>46.0, :lng=>2.0}, "GA"=>{:lat=>-1.0, :lng=>11.75}, "GB"=>{:lat=>54.0, :lng=>-2.0}, "GD"=>{:lat=>12.1167, :lng=>-61.6667},
39
+ "GE"=>{:lat=>42.0, :lng=>43.5}, "GF"=>{:lat=>4.0, :lng=>-53.0}, "GH"=>{:lat=>8.0, :lng=>-2.0}, "GI"=>{:lat=>36.1833, :lng=>-5.3667},
40
+ "GL"=>{:lat=>72.0, :lng=>-40.0}, "GM"=>{:lat=>13.4667, :lng=>-16.5667}, "GN"=>{:lat=>11.0, :lng=>-10.0}, "GP"=>{:lat=>16.25,:lng=>-61.5833},
41
+ "GQ"=>{:lat=>2.0, :lng=>10.0}, "GR"=>{:lat=>39.0, :lng=>22.0}, "GS"=>{:lat=>-54.5, :lng=>-37.0}, "GT"=>{:lat=>15.5, :lng=>-90.25},
42
+ "GU"=>{:lat=>13.4667, :lng=>144.7833}, "GW"=>{:lat=>12.0, :lng=>-15.0}, "GY"=>{:lat=>5.0, :lng=>-59.0}, "HK"=>{:lat=>22.25, :lng=>114.1667}, "HM"=>{:lat=>-53.1, :lng=>72.5167}, "HN"=>{:lat=>15.0, :lng=>-86.5}, "HR"=>{:lat=>45.1667, :lng=>15.5}, "HT"=>{:lat=>19.0, :lng=>-72.4167},
43
+ "HU"=>{:lat=>47.0, :lng=>20.0}, "ID"=>{:lat=>-5.0, :lng=>120.0}, "IE"=>{:lat=>53.0, :lng=>-8.0}, "IL"=>{:lat=>31.5, :lng=>34.75},
44
+ "IN"=>{:lat=>20.0, :lng=>77.0}, "IO"=>{:lat=>-6.0, :lng=>71.5}, "IQ"=>{:lat=>33.0, :lng=>44.0}, "IR"=>{:lat=>32.0, :lng=>53.0},
45
+ "IS"=>{:lat=>65.0, :lng=>-18.0}, "IT"=>{:lat=>42.8333, :lng=>12.8333}, "JM"=>{:lat=>18.25, :lng=>-77.5}, "JO"=>{:lat=>31.0, :lng=>36.0},
46
+ "JP"=>{:lat=>36.0, :lng=>138.0}, "KE"=>{:lat=>1.0, :lng=>38.0}, "KG"=>{:lat=>41.0, :lng=>75.0}, "KH"=>{:lat=>13.0, :lng=>105.0},
47
+ "KI"=>{:lat=>1.4167, :lng=>173.0}, "KM"=>{:lat=>-12.1667, :lng=>44.25}, "KN"=>{:lat=>17.3333, :lng=>-62.75}, "KP"=>{:lat=>40.0, :lng=>127.0},
48
+ "KR"=>{:lat=>37.0, :lng=>127.5}, "KW"=>{:lat=>29.3375, :lng=>47.6581}, "KY"=>{:lat=>19.5, :lng=>-80.5}, "KZ"=>{:lat=>48.0, :lng=>68.0},
49
+ "LA"=>{:lat=>18.0, :lng=>105.0}, "LB"=>{:lat=>33.8333, :lng=>35.8333}, "LC"=>{:lat=>13.8833, :lng=>-61.1333}, "LI"=>{:lat=>47.1667, :lng=>9.5333},
50
+ "LK"=>{:lat=>7.0, :lng=>81.0}, "LR"=>{:lat=>6.5, :lng=>-9.5}, "LS"=>{:lat=>-29.5, :lng=>28.5}, "LT"=>{:lat=>56.0, :lng=>24.0},
51
+ "LU"=>{:lat=>49.75, :lng=>6.1667}, "LV"=>{:lat=>57.0, :lng=>25.0}, "LY"=>{:lat=>25.0, :lng=>17.0}, "MA"=>{:lat=>32.0, :lng=>-5.0},
52
+ "MC"=>{:lat=>43.7333, :lng=>7.4}, "MD"=>{:lat=>47.0, :lng=>29.0}, "ME"=>{:lat=>42.0, :lng=>19.0}, "MG"=>{:lat=>-20.0, :lng=>47.0},
53
+ "MH"=>{:lat=>9.0, :lng=>168.0}, "MK"=>{:lat=>41.8333, :lng=>22.0}, "ML"=>{:lat=>17.0, :lng=>-4.0}, "MM"=>{:lat=>22.0, :lng=>98.0},
54
+ "MN"=>{:lat=>46.0, :lng=>105.0}, "MO"=>{:lat=>22.1667, :lng=>113.55}, "MP"=>{:lat=>15.2, :lng=>145.75}, "MQ"=>{:lat=>14.6667, :lng=>-61.0},
55
+ "MR"=>{:lat=>20.0, :lng=>-12.0}, "MS"=>{:lat=>16.75, :lng=>-62.2}, "MT"=>{:lat=>35.8333, :lng=>14.5833}, "MU"=>{:lat=>-20.2833, :lng=>57.55},
56
+ "MV"=>{:lat=>3.25, :lng=>73.0}, "MW"=>{:lat=>-13.5, :lng=>34.0}, "MX"=>{:lat=>23.0, :lng=>-102.0}, "MY"=>{:lat=>2.5, :lng=>112.5},
57
+ "MZ"=>{:lat=>-18.25, :lng=>35.0}, "NA"=>{:lat=>-22.0, :lng=>17.0}, "NC"=>{:lat=>-21.5, :lng=>165.5}, "NE"=>{:lat=>16.0, :lng=>8.0},
58
+ "NF"=>{:lat=>-29.0333, :lng=>167.95}, "NG"=>{:lat=>10.0, :lng=>8.0}, "NI"=>{:lat=>13.0, :lng=>-85.0}, "NL"=>{:lat=>52.5, :lng=>5.75},
59
+ "NO"=>{:lat=>62.0, :lng=>10.0}, "NP"=>{:lat=>28.0, :lng=>84.0}, "NR"=>{:lat=>-0.5333, :lng=>166.9167}, "NU"=>{:lat=>-19.0333, :lng=>-169.8667},
60
+ "NZ"=>{:lat=>-41.0, :lng=>174.0}, "OM"=>{:lat=>21.0, :lng=>57.0}, "PA"=>{:lat=>9.0, :lng=>-80.0}, "PE"=>{:lat=>-10.0, :lng=>-76.0},
61
+ "PF"=>{:lat=>-15.0, :lng=>-140.0}, "PG"=>{:lat=>-6.0, :lng=>147.0}, "PH"=>{:lat=>13.0, :lng=>122.0}, "PK"=>{:lat=>30.0, :lng=>70.0},
62
+ "PL"=>{:lat=>52.0, :lng=>20.0}, "PM"=>{:lat=>46.8333, :lng=>-56.3333}, "PR"=>{:lat=>18.25, :lng=>-66.5}, "PS"=>{:lat=>32.0, :lng=>35.25},
63
+ "PT"=>{:lat=>39.5, :lng=>-8.0}, "PW"=>{:lat=>7.5, :lng=>134.5}, "PY"=>{:lat=>-23.0, :lng=>-58.0}, "QA"=>{:lat=>25.5, :lng=>51.25},
64
+ "RE"=>{:lat=>-21.1, :lng=>55.6}, "RO"=>{:lat=>46.0, :lng=>25.0}, "RS"=>{:lat=>44.0, :lng=>21.0}, "RU"=>{:lat=>60.0, :lng=>100.0},
65
+ "RW"=>{:lat=>-2.0, :lng=>30.0}, "SA"=>{:lat=>25.0, :lng=>45.0}, "SB"=>{:lat=>-8.0, :lng=>159.0}, "SC"=>{:lat=>-4.5833, :lng=>55.6667},
66
+ "SD"=>{:lat=>15.0, :lng=>30.0}, "SE"=>{:lat=>62.0, :lng=>15.0}, "SG"=>{:lat=>1.3667, :lng=>103.8}, "SH"=>{:lat=>-15.9333, :lng=>-5.7},
67
+ "SI"=>{:lat=>46.0, :lng=>15.0}, "SJ"=>{:lat=>78.0, :lng=>20.0}, "SK"=>{:lat=>48.6667, :lng=>19.5}, "SL"=>{:lat=>8.5, :lng=>-11.5},
68
+ "SM"=>{:lat=>43.7667, :lng=>12.4167}, "SN"=>{:lat=>14.0, :lng=>-14.0}, "SO"=>{:lat=>10.0, :lng=>49.0}, "SR"=>{:lat=>4.0, :lng=>-56.0},
69
+ "ST"=>{:lat=>1.0, :lng=>7.0}, "SV"=>{:lat=>13.8333, :lng=>-88.9167}, "SY"=>{:lat=>35.0, :lng=>38.0}, "SZ"=>{:lat=>-26.5, :lng=>31.5},
70
+ "TC"=>{:lat=>21.75, :lng=>-71.5833}, "TD"=>{:lat=>15.0, :lng=>19.0}, "TF"=>{:lat=>-43.0, :lng=>67.0}, "TG"=>{:lat=>8.0, :lng=>1.1667},
71
+ "TH"=>{:lat=>15.0, :lng=>100.0}, "TJ"=>{:lat=>39.0, :lng=>71.0}, "TK"=>{:lat=>-9.0, :lng=>-172.0}, "TM"=>{:lat=>40.0, :lng=>60.0},
72
+ "TN"=>{:lat=>34.0, :lng=>9.0}, "TO"=>{:lat=>-20.0, :lng=>-175.0}, "TR"=>{:lat=>39.0, :lng=>35.0}, "TT"=>{:lat=>11.0, :lng=>-61.0},
73
+ "TV"=>{:lat=>-8.0, :lng=>178.0}, "TW"=>{:lat=>23.5, :lng=>121.0}, "TZ"=>{:lat=>-6.0, :lng=>35.0}, "UA"=>{:lat=>49.0, :lng=>32.0},
74
+ "UG"=>{:lat=>1.0, :lng=>32.0}, "UM"=>{:lat=>19.2833, :lng=>166.6}, "US"=>{:lat=>38.0, :lng=>-97.0}, "UY"=>{:lat=>-33.0, :lng=>-56.0},
75
+ "UZ"=>{:lat=>41.0, :lng=>64.0}, "VA"=>{:lat=>41.9, :lng=>12.45}, "VC"=>{:lat=>13.25, :lng=>-61.2}, "VE"=>{:lat=>8.0, :lng=>-66.0},
76
+ "VG"=>{:lat=>18.5, :lng=>-64.5}, "VI"=>{:lat=>18.3333, :lng=>-64.8333}, "VN"=>{:lat=>16.0, :lng=>106.0}, "VU"=>{:lat=>-16.0, :lng=>167.0},
77
+ "WF"=>{:lat=>-13.3, :lng=>-176.2}, "WS"=>{:lat=>-13.5833, :lng=>-172.3333}, "YE"=>{:lat=>15.0, :lng=>48.0}, "YT"=>{:lat=>-12.8333, :lng=>45.1667},
78
+ "ZA"=>{:lat=>-29.0, :lng=>24.0}, "ZM"=>{:lat=>-15.0, :lng=>30.0}, "ZW"=>{:lat=>-20.0, :lng=>30.0}, "JE"=>{:lat=>49.25, :lng=>-2.16},
79
+ "IM"=>{:lat=>54.25, :lng=>4.5}, "AX"=>{:lat=>60.25, :lng=> 20},"A1"=>{:lat=>0, :lng=> 0},"A2"=>{:lat=>0, :lng=> 0}
80
+ }
81
+
82
+ # This determines where the tour goes to and which placemark ballons come up
83
+ # centres: South Africa, Benin, Switz, Ukraine, India, Australia, Paraguay, United States,France
84
+ #
85
+ WORLDTOUR={"ZA" => ["ZA1","NA1","KE1"],
86
+ "BJ" => ["BJ1","A11","NG1","CI1","SN1","DZ1","MA1","EG1","TN1"],
87
+ "CH" => ["FR1","ES1","LU1","GB1","BE1","NL1","DE1","IT1","IE1","AT1","SE1","DK1","UA1"],
88
+ "UA" => ["SA1","TR1","SY1","RU1","IR1"],
89
+ "IN" => ["IN1","KZ1","CN1","TH1","PK1"],
90
+ "AU" => ["AU1","NC1"],
91
+ "PY" => ["PY1","BR1","AR1","CL1"],
92
+ "US" => ["US1","US2","US3","US4","CA1","MX1"],
93
+ "FR" => ["FR1"] }
94
+
95
+ # FR1 is the centre, by default, centres 1 to 90 are read by default, and 91-200 change to black after 2seconds
96
+ # This can be changed using a the mix-in features of Ruby, using the keys {:lat , :lng,"red", "black"}
97
+ ATTACK_TOUR = {:lat => 46.0,
98
+ :lng => 2.0,
99
+ "red"=> (1..90).collect{|eachnum| "FR" + eachnum.to_s},
100
+ "black"=> (91..200).collect{|eachnum| "FR" + eachnum.to_s} }
101
+ #"red"=> ["FR240", "FR221", "FR46", "FR72", "FR226","FR4","FR179","FR182",],
102
+ #"black"=> ["FR92", "FR159", "FR196", "FR210", "FR17","218", "FR175","FR41" ] }
103
+
104
+ # This determines how long the program Tor::TController.extendcir_slowly() waits between each extension.
105
+ EXTEND_DELAY = 2.0
106
+ end
@@ -0,0 +1,89 @@
1
+ # httpmod functions - extends net/http
2
+
3
+ module Net #:nodoc:
4
+ class HTTP #:nodoc:
5
+
6
+ # Sends an HTTPRequest object REQUEST to the HTTP proxy such as polipo, and attach all new streams to the circuit specified in torctrl_cir.
7
+ # torctrl_cir = {:torctrl, :cirnum,:hop}
8
+ # Tor config must already be set to allow leaky circuits and attaching streams to the nodes other than the 3rd node.
9
+ # Similar to HTTP.request
10
+ # When called with a block, yields an HTTPResponse object.
11
+ # The body of this response will not have been read yet;
12
+ # the caller can process it using HTTPResponse#read_body,
13
+ # if desired.
14
+ #
15
+ # Returns a HTTPResponse object.
16
+ #
17
+ # This method never raises Net::* exceptions.
18
+ # The method has been implemented, but a circuit have been built to successfullty attach a stream to it.
19
+ #
20
+ def request_tor(req,torctrl_cir, body = nil, &block)
21
+ unless started?
22
+ start {
23
+ req['connection'] ||= 'close'
24
+ return request(req, body, &block)
25
+ }
26
+ end
27
+ if proxy_user()
28
+ req.proxy_basic_auth proxy_user(), proxy_pass() unless use_ssl?
29
+ end
30
+ req.set_body_internal body
31
+ res = transport_request_tor(req, torctrl_cir, &block)
32
+ if sspi_auth?(res)
33
+ sspi_auth(req)
34
+ res = transport_request_tor(req, torctrl_cir, &block)
35
+ end
36
+ res
37
+ end
38
+
39
+ # Sends an HTTPRequest object GET REQUEST to the HTTP proxy such as polipo, and attach all new streams to the circuit specified in torctrl_cir.
40
+ # torctrl_cir = {:torctrl, :cirnum,:hop}
41
+ # Tor config must already be set to allow leaky circuits and attaching streams to the nodes other than the 3rd node.
42
+ # Similar to HTTP.request_get
43
+ # The method has been implemented, but a circuit have been built to successfullty attach a stream to it.
44
+ #
45
+ def request_torget(path, torctrl_cir, initheader = nil, &block)
46
+ request_tor(Get.new(path, initheader),torctrl_cir, &block)
47
+ end
48
+
49
+ private
50
+
51
+ # This transports requests to the proxy specified in the HTTP request, and then attaches all new streams to a prespecified circuit.
52
+ # It works behind the scene when making requests using HTTP.request_torget and HTTP.request_tor
53
+ # Further development in progress.
54
+ # - Must create new stream if cirnum==0
55
+ # - Attempt to recreate the same circuit if the circuit is closed. support sending Circuit instance in the hash instead of just cirnum
56
+ # ...more work to be done probably be used to make a browser for Tor, with limited functionality. No flash/javascript/cookies to start with, so no tracking.
57
+ #
58
+ def transport_request_tor(req, torctrl_cir) #:nodoc:
59
+ # torctrl_cir = {:torctrl, :cirnum,:hop}
60
+ tcontrl = torctrl_cir[:torctrl]
61
+ cir_num = torctrl_cir[:cirnum]
62
+ hop_count = torctrl_cir[:hop] ? torctrl_cir[:hop] : 0
63
+
64
+ begin_transport req
65
+ req.exec @socket, @curr_http_version, edit_path(req.path)
66
+
67
+ #Get all new streams since the request was sent
68
+ b = tcontrl.newstreams
69
+ # attach all new streams to cir_num
70
+ b.each{|k|
71
+ tcontrl.attach_stream(k, cir_num,hop_count)
72
+ }
73
+
74
+ begin
75
+ res = HTTPResponse.read_new(@socket)
76
+ end while res.kind_of?(HTTPContinue)
77
+ res.reading_body(@socket, req.response_body_permitted?) {
78
+ yield res if block_given?
79
+ }
80
+ end_transport req, res
81
+ res
82
+ rescue => exception
83
+ D "Conn close because of error #{exception}"
84
+ @socket.close if @socket and not @socket.closed?
85
+ raise exception
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,475 @@
1
+ module Tor
2
+
3
+ require 'socksify/http'
4
+
5
+
6
+ # Tor:TController is an extension of the Tor::Controller class, providing more methods.
7
+ # It inherits all methods from Tor::Controller and can be used to interact with Tor.
8
+ #
9
+ # <b>TController examples</b>
10
+ #
11
+ # require 'tor_extend'
12
+ # Tor::TController.new(:host=>@getbridge_config[:torcontrolhost],
13
+ # :port=>@getbridge_config[:torcontrolport])
14
+ # Tor::TController.new(:host=>"127.0.0.1",:port=>9051)
15
+ # Tor::TController.connect
16
+ # Tor::TController.authenticate("\"tor_control_password\"")
17
+ # Tor::TController.sr(:signal,"HUP")
18
+ # Tor::TController.sr(:signal,"newnym")
19
+ # Tor::TController.getinfo("ns/all")
20
+ # Tor::TController.net_status
21
+ # Tor::TController.closecircuit(15)
22
+ # Tor::TController.closeallcircuits
23
+ # Tor::TController.signal("reload"
24
+ # Tor::TController.extendcir(0,['or1','or2','or3'])
25
+ # Tor::TController.setconf("__DisablePredictedCircuits",1)
26
+ # Tor::TController.setconf("__LeaveStreamsUnattached",1)
27
+ # Tor::TController.getconf("ORPort")
28
+ # Tor::TController.getconf("__LeaveStreamsUnattached")
29
+ # Tor::TController.get_bridges( {:type=>'http',:port=>9050,:addr=>'127.0.0.1'} )
30
+ #
31
+ #
32
+ # For more details, visit [https://github.com/bendiken/tor-ruby#readme], [https://gitweb.torproject.org/torspec.git/tree]
33
+ #
34
+ class TController < Tor::Controller
35
+
36
+ # This returns the circuit-status in an array, or an empty array on failure
37
+ #
38
+ # <b>Get the circuit-status from Tor</b>.
39
+ #
40
+ # Tor::TController.cir_status
41
+ # ["46 BUILT ORa,ORb,ORc PURPOSE=GENERAL"]
42
+ def cir_status
43
+ cirstatus=getinfo("circuit-status")
44
+ end
45
+
46
+
47
+ # This attempts to close a single circuit.
48
+ #
49
+ # <b>Closing circuits</b>
50
+ # Tor::TController.closecircuit(15)
51
+ def closecircuit (circnum)
52
+ errorstate,ans=sr(:closecircuit," #{circnum}")
53
+ end
54
+
55
+ # This attempts to close all open circuits.
56
+ #
57
+ # <b>Closing all circuits</b>
58
+ #
59
+ # Tor::TController.closeallcircuits
60
+ def closeallcircuits
61
+ x=cir_status
62
+ if !x.empty?
63
+ x.each{|eachcircuit|
64
+ circnum = eachcircuit.match(/^\d+/)
65
+ closecircuit(circnum)
66
+ }
67
+ end
68
+ end
69
+
70
+ # Returns the an array of of directory servers from the consensus.
71
+ #
72
+ # Tor::TController.ds => [w.x.y.z:port, ...]
73
+ #
74
+ def ds
75
+ reply=[]
76
+ s = getinfo("ns/all")
77
+ case version
78
+ when /0.2.[01]/
79
+ z=2
80
+ when/0.2.2/
81
+ z = 4 # To accommodate r, s , w and p]
82
+ end
83
+ s.collect!{|eachs| eachs.start_with?("r ") ? eachs : nil }
84
+ s.delete nil
85
+ s.each{|eachs|
86
+ dsport=eachs.split[8].to_i
87
+ rip=eachs.split[6]
88
+ reply << "#{rip}:#{dsport}" if dsport!= 0
89
+ }
90
+ reply
91
+ end
92
+
93
+
94
+ # This creates/extends a circuit over multiple nodes. A new circuit is created if cir_num == 0.
95
+ #
96
+ # <b>Creating a new circuit</b>
97
+ #
98
+ # create_circ = Tor::TController.extendcir(0,['or1','or2','or3'])
99
+ def extendcir(circnum,or_list)
100
+ argor=" #{circnum} #{or_list.join(',')}"
101
+ extendcir=send_command(:extendcircuit,argor)
102
+ circuit_id=nil
103
+ readterm=true
104
+ while readterm do
105
+ case msg=read_reply
106
+ when /^\d+ CIRC \d+ BUILT/,/250 / #/^\d+ CIRC \d+ BUILT/
107
+ circuit_id=msg.scan(/\d+\Z/)[0]
108
+ readterm=false
109
+ when /^5\d\d /
110
+ readterm=false
111
+ when /^\d+ /
112
+ puts msg #like extended launched
113
+ else
114
+ puts msg,"\n"
115
+ end
116
+ end
117
+ #sr(:signal,"newnym")
118
+ circuit_id
119
+ end
120
+
121
+ # This builds a circuit to each member of the array argument, skipping any node that fails to connect.
122
+ # It returns the circuit number, and the longest successful circuit that was successfully built.
123
+ # There is a delay of 2.0 seconds after each extension, but this can be altered by defining Tor::EXTEND_DELAY constant.
124
+ #
125
+ # <b>Create a circuit as long as possible using 10 elements in an array</b>
126
+ # testarray = [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]
127
+ # Tor::TController.extendcir_slowly(testarray)
128
+ def extendcir_slowly(orarray)
129
+ ordelay = defined?(EXTEND_DELAY) ? EXTEND_DELAY : Constants::EXTEND_DELAY
130
+ cirnum = 0
131
+ circuit = []
132
+ orarray.each{|eachor|
133
+ cirnum=extendcir(cirnum,[eachor])
134
+ sleep(ordelay) # wait for a few seconds, and check if the circuit is was successful
135
+ p=cir_status.detect{|i| i =~ (/^#{cirnum} / )}
136
+ case p
137
+ when /FAILED/,nil
138
+ puts "cirnum=nil"
139
+ if eachor != circuit.last
140
+ cirnum = extendcir(0,circuit)
141
+ sleep(circuit.count)
142
+ elsif circuit.empty?
143
+ return nil # failed to build circuit at start, make sure orarray[0] is up
144
+ end
145
+ when /EXTENDED/, /BUILT/
146
+ circuit << eachor
147
+ puts "Extended! cirnum = #{cirnum}, circuit length = #{circuit.count}"
148
+ when /LAUNCHED/
149
+ sleep(1)
150
+ puts x=cir_status.detect{|a| a =~ /^#{cirnum}/}
151
+ circuit << eachor if (x =~ /BUILT/) or (x =~/EXTENDED/)
152
+ end
153
+ }
154
+ [cirnum,circuit]
155
+ end
156
+
157
+ # This gets 3 bridge IP addresses from the Tor bridge website. proxyconfig is optional.
158
+ # default proxyconfig = {:type=>'tor' ,:port=>9050,:addr=>'127.0.0.1'}
159
+ # The return format is fo the form:
160
+ # [HTTPcode, [{:bridgeip, :bridgeport},{:bridgeip, :bridgeport},{:bridgeip, :bridgeport}].
161
+ # The types can be one of 'tor', 'polipo', 'socks', 'http', 'https',nil, 'none'.
162
+ # torctrl_cirnum must have the form:
163
+ # torctrl_cirnum ={:torctrl=>Tor::TController, :cirnum=>cirnum,:hop=>hopcount}
164
+ #
165
+ # <b>Get 3 bridges</b>
166
+ #
167
+ # Tor::TController.get_bridges( {:proxytype=>'tor',:proxyport=>9050,:proxyaddr=>'127.0.0.1'} )
168
+ def get_bridges(url, cacheddesc, *config)
169
+ if config.empty?
170
+ proxyconfig={:type=>'tor' ,:port=>9050,:addr=>'127.0.0.1'}
171
+ else
172
+ proxyconfig = config[0]
173
+ end
174
+ if ! defined?(@myhttperrors)
175
+ @myhttperrors=0
176
+ end
177
+ case proxyconfig[:type]
178
+ when /none/i,nil
179
+ http_session=Net::HTTP.new(url.host,url.port)
180
+ when /socks/i,/tor/i
181
+ http_session=Net::HTTP.SOCKSProxy(proxyconfig[:addr], proxyconfig[:port]).new(url.host,url.port)
182
+ when /http/i,/https/i,/polipo/i
183
+ http_session=Net::HTTP::Proxy(proxyconfig[:addr], proxyconfig[:port]).new(url.host,url.port)
184
+ end
185
+ if url.scheme=="https"
186
+ http_session.use_ssl = true
187
+ http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE
188
+ else
189
+ http_session.use_ssl=false
190
+ end
191
+ bridges=[]
192
+ # Rescue from http error
193
+ begin
194
+ resp = http_session.get2 url.path # Let Tor choose circuit itself
195
+ # Additional code will be added shortly to attach the stream to the circuit directly
196
+ puts "#{resp.code} HTTP response"
197
+ #puts resp.body
198
+ respcode= resp.code=="200" ? 200:nil
199
+ if resp.code == "200"
200
+ torbridgeip=resp.body.scan(/\d+\.\d+\.\d+\.\d+\:\d+/)
201
+ torbridgeip.each{|eachbridge|
202
+ bridgeip,bridgeport= eachbridge.split(':')
203
+ x=Bridge.where(:ipaddr=>bridgeip, :port =>bridgeport)
204
+ if x.empty?
205
+ if (bridge_geoip=cacheddesc.get_geoiprecord(bridgeip)).nil?
206
+ Bridge.create(:ipaddr=>bridgeip, :port =>bridgeport,
207
+ :lat=>0, :lng=>0)
208
+ else
209
+ Bridge.create(:ipaddr=>bridgeip, :port =>bridgeport,
210
+ :lat=>bridge_geoip.latitude.to_f,
211
+ :lng=>bridge_geoip.longitude.to_f )
212
+ end
213
+ end
214
+ }
215
+ end
216
+ bridges = torbridgeip
217
+ rescue
218
+ @myhttperrors +=1
219
+ respcode=nil
220
+ bridges=[]
221
+ end
222
+ bridges #Return array of all bridges
223
+ end
224
+
225
+ # Returns all the brdiges in the database as an array.
226
+ #
227
+ # Tor::TController.bridges => [{:ipaddr, :port, :lat, :lng},...]
228
+ def bridges
229
+ Bridges.all
230
+ end
231
+
232
+ # This returns all the new streams that have not been assigned to a circuit
233
+ def newstreams
234
+ reply=[]
235
+ getinfo("stream-status").each{|eachstream|
236
+ case eachstream
237
+ when /\d+ NEW 0/
238
+ # It might be simpler to use this /\d+ NEW/
239
+ reply << eachstream.scan(/\d+/)[0]
240
+ end
241
+ }
242
+ reply
243
+ end
244
+
245
+ # This attaches streams to circuits. No documentation yet.
246
+ def attach_stream(stream_no, cir_num ,hop_count)
247
+ puts "attachstream"
248
+ if hop_count==0
249
+ sr(:attachstream,"#{stream_no} #{cir_num}")
250
+ else
251
+ sr(:attachstream,"#{stream_no} #{cir_num} HOP=#{hop_count}")
252
+ end
253
+ end
254
+
255
+
256
+ # This gets enty guards from the control port of tor using the getinfo "entry-guards" command
257
+ # and returns just the fingerprints in an array.
258
+ #
259
+ # <b>Get entry-guards</b>
260
+ #
261
+ # Tor::TController.get_entryguards #=> ["$abc123","$def456"...]
262
+ def get_entryguards
263
+ rslt = getinfo "entry-guards"
264
+ reply = rslt.collect{|eachguard|
265
+ case eachguard
266
+ when / unusable/
267
+ nil
268
+ else
269
+ "$"+ eachguard.split(/[~ =]/)[0]
270
+ end
271
+ }
272
+ reply.delete(nil)
273
+ reply
274
+ end
275
+
276
+ # This returns the number of HTTP errors from the Tor::TController.get_bridges command
277
+ #
278
+ def get_httperrors
279
+ @myhttperrors
280
+ end
281
+
282
+ # This gets the IP addresses for ORs based on the characteristics of the OR.
283
+ # Example of the properties include: _Fast_, _Guard_, _HSDir_, _Named_, _Running_, _Stable_, _V2Dir_, _Valid_, _Exit_.
284
+ #
285
+ # <b>Get all Exit, Fast and entry Guard ORs</b>
286
+ #
287
+ # Tor::TController.get_purposeip("Exit") #=> ["a.b.c.d","e.f.g.h"...]
288
+ # Tor::TController.get_purposeip("fast exit")
289
+ # Tor::TController.get_purposeip("Guard")
290
+ def get_purposeip(nodetype)
291
+ reply=[]
292
+ s = getinfo("ns/all")
293
+ ctr_i= s.size / 2
294
+ ctr_i.times{|j|
295
+ rip=s[j*2].split[6]
296
+ x=Router.where(:ipaddr=>rip)
297
+ if !x.empty?
298
+ finprint = "$" + x[0].fingerprint
299
+ matcharray=nodetype.split.collect{|eachtype|
300
+ if eachtype.start_with? '!'
301
+ matchme = eachtype[1..(eachtype.length-1)]
302
+ rslt = !(s[j*2+1] =~ (/#{matchme}/i))
303
+ rslt ? rslt : nil #return nil if false, or return the number
304
+ else
305
+ s[j*2+1] =~ (/#{eachtype}/i)
306
+ end
307
+ }
308
+ reply << finprint if !matcharray.include? nil
309
+ end
310
+ }
311
+ reply
312
+ end
313
+
314
+ # This gets a configuration from Tor. The arguments of this command might be case sensitive. It returns the protocol error message if it fails.
315
+ #
316
+ # <b>Get the present ORport Tor is using</b>
317
+ #
318
+ # Tor::TController.getconf("ORPort") #=>"9001"
319
+ # Tor::TController.getconf("__LeaveStreamsUnattached") #=>"1"
320
+ #
321
+ # For more details, see [https://gitweb.torproject.org/torspec.git/blob/HEAD:/control-spec.txt]
322
+ def getconf(confname)
323
+ send_command(:getconf, confname)
324
+ reply=[]
325
+ case msg=read_reply
326
+ when /250 /
327
+ msg.split(/250 \S*=/).last
328
+ else
329
+ msg
330
+ end
331
+ end
332
+
333
+
334
+ # This method sends the "GETINFO" protocol message with the arguments.
335
+ #
336
+ # <b>Getting more information from Tor</b>
337
+ #
338
+ # Tor::TController.getinfo("ns/all")
339
+ def getinfo(*args)
340
+ errorcode,ans = sr(:getinfo,*args)
341
+ ans
342
+ end
343
+
344
+ # This returns an array of hash tables with the fingerprints of all onion routers that have not been marked as down.
345
+ #
346
+ # <b>Get the network status from Tor</b>
347
+ #
348
+ # Tor::TController.net_status => [ {:fingerprint=>"$ABCD"},{:fingerprint=>"$EFGH"}...]
349
+ def net_status
350
+ case version
351
+ when /0.2.[01]/
352
+ net_status1
353
+ when/0.2.2/
354
+ net_status2
355
+ end
356
+ end
357
+
358
+ private
359
+ def net_status1 #:nodoc:
360
+ nstatus_array=getinfo("network-status")
361
+ sorted_networkstatus=[]
362
+ if !nstatus_array.empty?
363
+ netstatus=nstatus_array[0]
364
+ fingerprint=netstatus.split(/\S+=/)
365
+ fingerprint.delete_at(0) #delete the fingerprint stored for nickname=network-status
366
+ fingerprint.each{|eachfingerprint|
367
+ tmpfarray = eachfingerprint.split
368
+ tmpb=tmpfarray.collect{|element|
369
+ element.start_with?("!") ? nil:element
370
+ }
371
+ tmpb.delete(nil)
372
+ if tmpb.empty?
373
+ net_status = nil
374
+ else
375
+ sorted_networkstatus << {:fingerprint=>tmpb[0] }
376
+ end
377
+ }
378
+ end
379
+ sorted_networkstatus
380
+ end
381
+
382
+ def net_status2 #:nodoc:
383
+ @myhttperrors=0
384
+ nstatus_array=getinfo("network-status")
385
+ sorted_networkstatus=[]
386
+ if !nstatus_array.empty?
387
+ netstatus=nstatus_array[0]
388
+ fingerprint=netstatus.split.collect{|asd|
389
+ element = asd.split(/[=~]/)[0]
390
+ element.start_with?("!") ? nil:element
391
+ }
392
+ fingerprint.delete(nil)
393
+ #fingerprint.delete_at(0) #delete the fingerprint stored for nickname=network-status
394
+ fingerprint.each{|eachfingerprint|
395
+ sorted_networkstatus << {:fingerprint=>eachfingerprint }
396
+ }
397
+ end
398
+ sorted_networkstatus
399
+ end
400
+
401
+ public
402
+ # This sets a configuration in Tor to a value.
403
+ #
404
+ # <b>Setting Tor config</b>
405
+ #
406
+ # Tor::TController.setconf("__DisablePredictedCircuits",1) =>["OK", []]
407
+ # Tor::TController.setconf("__LeaveStreamsUnattached",1) =>["OK", []]
408
+ # Tor::TController.setconf("ORPort",9001) =>["OK", []]
409
+ def setconf(confname,value)
410
+ sr(:setconf,"#{confname}=#{value}")
411
+ end
412
+
413
+ # This method sends "signals" protocol message with the arguments.
414
+ #
415
+ # <b>Reload Tor config from file</b>
416
+ #
417
+ # Tor::TController.signal("RELOAD")
418
+ # Tor::TController.signal("HUP")
419
+ def signal(args)
420
+ reply=[]
421
+ case (args)
422
+ when /NEWNYM/i,/CLEARDNSCACHE/i,/RELOAD/i,/HUP/i,/DUMP/i,/USR1/i,/DEBUG/i,/USR2/i,/shutdown/i,/INT/i
423
+ errorcode,reply=sr(:signal, args)
424
+ close if args =~ /shutdown/i or args =~ /INT/i
425
+ when /HALT/i,/TERM/i
426
+ send_command(:signal, "HALT")
427
+ close
428
+ else
429
+ puts "#{args} not recognised by the at library development. Sending the signal nonetheless"
430
+ reply=sr(:signal,args)
431
+ end
432
+ reply
433
+ end
434
+
435
+ # This sends commands and returns the protocol response code along with an array
436
+ # containing the results with the following format \[errorcode,\[array_of_results]].
437
+ #
438
+ # <b>Send and receive commands</b>.
439
+ #
440
+ # Tor::TController.sr(:signal,"reload")
441
+ # Tor::TController.sr(:signal,"newnym")
442
+ def sr(command, *args)
443
+ send_command(command, *args)
444
+ reply=[]
445
+ readterm=true
446
+ while readterm do
447
+ # Read as much as possible until '250 OK' or error 5YZ
448
+ case msg=read_reply
449
+ when /^250 OK/
450
+ readterm=false
451
+ puts errorstate="OK"
452
+ when /^250[\+,\-,\s]/
453
+ reply << msg.split(/^\d+[\+,\-,\s]\S*=/).last unless msg=~/250\+/
454
+ errorstate = "OK"
455
+ when /^\./
456
+ when /^5\d\d /
457
+ if errorstate == "OK" # if a "2yz " code came before this then msg is part of response
458
+ reply << msg
459
+ else
460
+ puts msg
461
+ errorstate = msg.match(/^5\d\d/)
462
+ readterm=false
463
+ end
464
+ else
465
+ reply << msg
466
+ end
467
+ end
468
+ reply.delete(nil)
469
+ reply = errorstate=="OK" ? reply : []
470
+ [errorstate,reply]
471
+ end
472
+
473
+
474
+ end # end of class
475
+ end # end of module