Class: Tor::Circuit
- Inherits:
-
Object
- Object
- Tor::Circuit
- Defined in:
- lib/circuits.rb
Overview
This is a single (sub-)circuit object over exactly 3 nodes.Suitable nodes must be chosesn to allow the creation of a successful circuit.
Instance Method Summary collapse
-
#attach_streams ⇒ Object
This tries to attach all streams to the circuit.
-
#built? ⇒ Boolean
This methods checks if the circuit has been built.
-
#circuit ⇒ Object
Returns the nodes that make up the circuit.
-
#cirnum ⇒ Object
Returns the circuit number.
-
#close_apps ⇒ Object
Closes the Tor and Polipo launched by the instance of this class, and removes the tmp directory.
-
#closecir ⇒ Object
Closes the circuit.
-
#closed? ⇒ Boolean
Checks if the application instances for Tor and polipo have been closed.
-
#controller ⇒ Object
Returns the Tor:Controller used for the circuit.
-
#extend ⇒ Object
This creates / builds the actual circuit using @circuitarray.
-
#get_bridges(cacheddesc, *config) ⇒ Object
Tor::Circuit.get_bridges( Tor::Cacheddesc, :proxytype=>‘polipo’,:proxyport=>8118,:proxyaddr=>‘127:proxytype=>‘polipo’,:proxyport=>8118,:proxyaddr=>‘127.0:proxytype=>‘polipo’,:proxyport=>8118,:proxyaddr=>‘127.0.0:proxytype=>‘polipo’,:proxyport=>8118,:proxyaddr=>‘127.0.0.1’ ).
-
#initialize(ctrller_config, circuitarray, proxyconfig) ⇒ Circuit
constructor
Initialises a Tor::Circuit instance variable with attibutes including the @built, @cirnum and @torcontroller Use nil for proxyport if Tor is running already.
-
#launch ⇒ Object
Run this after initializing a Tor::Circuit instaance.
-
#launched? ⇒ Boolean
Checks if the launched method has been called.
-
#start ⇒ Object
This attaches all streams on this controller to a prebuilt circuit that has been.
Constructor Details
#initialize(ctrller_config, circuitarray, proxyconfig) ⇒ Circuit
Initialises a Tor::Circuit instance variable with attibutes including the @built, @cirnum and @torcontroller
Use nil for proxyport if Tor is running already.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/circuits.rb', line 8 def initialize(ctrller_config, circuitarray, proxyconfig) @built = true @closed = true @circuitarray = circuitarray @cirnum = nil @ctrller_config = ctrller_config @proxyconfig = proxyconfig if @proxyconfig.nil? # When proxyconfig.nil?, then it's an existing @launched = true @torcontroller = Tor::TController.new(@ctrller_config) else @launched = false end end |
Instance Method Details
#attach_streams ⇒ Object
This tries to attach all streams to the circuit.
164 165 166 167 168 |
# File 'lib/circuits.rb', line 164 def attach_streams controller.newstreams.each{|z| controller.attach_stream(z,@cirnum) } end |
#built? ⇒ Boolean
This methods checks if the circuit has been built. It only reflects a single segment of the circuit
76 77 78 79 80 81 82 |
# File 'lib/circuits.rb', line 76 def built? if defined?(@torcontroller) # cant check built? before launching. @built = ! @torcontroller.cir_status.detect{|z| z =~ /#{@cirnum} BUILT/ }.nil? if not @cirnum.nil? else false end end |
#circuit ⇒ Object
Returns the nodes that make up the circuit.
24 25 26 |
# File 'lib/circuits.rb', line 24 def circuit @circuitarray end |
#cirnum ⇒ Object
Returns the circuit number. Returns 0 if it has not been attached
36 37 38 |
# File 'lib/circuits.rb', line 36 def cirnum @cirnum end |
#close_apps ⇒ Object
Closes the Tor and Polipo launched by the instance of this class, and removes the tmp directory
152 153 154 155 156 157 158 159 160 161 |
# File 'lib/circuits.rb', line 152 def close_apps if defined?(@pid) @torcontroller.signal("SHUTDOWN") Process.kill("KILL",@pid[:polipo]) FileUtils.remove_entry_secure @path # srm path ( delete tmp directory recursively ) @launched=false @built=false end @closed = true end |
#closecir ⇒ Object
Closes the circuit
146 147 148 149 |
# File 'lib/circuits.rb', line 146 def closecir @torcontroller.closecircuit(@cirnum) if ! @cirnum.nil? @built=false end |
#closed? ⇒ Boolean
Checks if the application instances for Tor and polipo have been closed
41 42 43 |
# File 'lib/circuits.rb', line 41 def closed? @closed end |
#controller ⇒ Object
Returns the Tor:Controller used for the circuit.
29 30 31 32 33 |
# File 'lib/circuits.rb', line 29 def controller if defined?(@torcontroller) @torcontroller end end |
#extend ⇒ Object
This creates / builds the actual circuit using @circuitarray.
46 47 48 49 50 51 52 53 |
# File 'lib/circuits.rb', line 46 def extend if defined?(@torcontroller) @cirnum = @torcontroller.extendcir(0,@circuitarray) else puts "launch before extending\n" return nil end end |
#get_bridges(cacheddesc, *config) ⇒ Object
Tor::Circuit.get_bridges( Tor::Cacheddesc, Tor::Circuit.:proxytype=>‘polipo’,:proxyport=>8118,:proxyaddr=>‘127:proxytype=>‘polipo’,:proxyport=>8118,:proxyaddr=>‘127.0:proxytype=>‘polipo’,:proxyport=>8118,:proxyaddr=>‘127.0.0:proxytype=>‘polipo’,:proxyport=>8118,:proxyaddr=>‘127.0.0.1’ )
cachedDesc can be nil if the Google Earth file is not needed.
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/circuits.rb', line 181 def get_bridges(cacheddesc, *config) url = URI.parse "https://bridges.torproject.org/" if config.empty? proxyconfig={:type=>'polipo' ,:port=>8118,:addr=>'127.0.0.1'} else proxyconfig = config[0] end if ! defined?(@myhttperrors) @myhttperrors=0 end case proxyconfig[:type] when /none/i,nil http_session=Net::HTTP.new(url.host,url.port) when /socks/i,/tor/i http_session=Net::HTTP.SOCKSProxy(proxyconfig[:addr], proxyconfig[:port]).new(url.host,url.port) when /http/i,/https/i,/polipo/i http_session=Net::HTTP::Proxy(proxyconfig[:addr], proxyconfig[:port]).new(url.host,url.port) end if url.scheme=="https" http_session.use_ssl = true http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE else http_session.use_ssl=false end bridges=[] # Rescue from http error begin resp = http_session.get2 url.path # Let Tor choose circuit itself # Additional code will be added shortly to attach the stream to the circuit directly puts "#{resp.code} HTTP response" # puts resp.body respcode= resp.code=="200" ? 200:nil if resp.code == "200" torbridgeip=resp.body.scan(/\d+\.\d+\.\d+\.\d+\:\d+/) torbridgeip.each{|eachbridge| bridgeip,bridgeport= eachbridge.split(':') x = Tor::Bridge.where(:ipaddr=>bridgeip, :port =>bridgeport) if x.empty? if cacheddesc.nil? or (bridge_geoip = cacheddesc.get_geoiprecord(bridgeip)).nil? Tor::Bridge.create(:ipaddr=>bridgeip, :port =>bridgeport, :lat=>0, :lng=>0) else Tor::Bridge.create(:ipaddr=>bridgeip, :port =>bridgeport, :lat=>bridge_geoip.latitude.to_f, :lng=>bridge_geoip.longitude.to_f ) end end } end bridges = torbridgeip rescue @myhttperrors +=1 respcode=nil bridges=[] end bridges.nil? ? [] : bridges #Return array of all bridges end |
#launch ⇒ Object
Run this after initializing a Tor::Circuit instaance. This writes the following Tor configuration options to a temp file if proxyport not nil: Write HttpProxy, HttpsProxy , DataDirectory /tmp/dir, __LeaveStreamUnattached 1.
This also writes polipoo configuration to a temporary file and executes polipo
It executes Tor and polipo if proxyport is not nil
Note: The applicaitons will continue running even if the ruby shell is exited. The Circuit.close_apps method can be used to terminate the application and remove the temp dir
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/circuits.rb', line 93 def launch # should I use popen3? dont need stdin and stderror from tor or polipo if ! @proxyconfig.nil? @path = Dir.mktmpdir if not defined?(@path) @pid= {} torrc_filename = File.join(@path,"torrc") torrc = File.new( torrc_filename, "w") # populate torrc socks_port = @ctrller_config[:port] - 1 torrc.puts "ControlPort #{@ctrller_config[:port]}\n" torrc.puts "DataDirectory #{@path}\n" torrc.puts "HttpProxy 127.0.0.1:#{@proxyconfig - 1}\n" # Use the preceeding polipo port torrc.puts "HttpsProxy 127.0.0.1:#{@proxyconfig - 1}\n" torrc.puts "RunAsDaemon 1\n" torrc.puts "SocksPort #{socks_port}\n" torrc.puts "SocksListenAddress 127.0.0.1\n" # can add a random password and call tor --hashcontrolpassword read stdout..but feels like long thing. Or ruby implementation of hash torrc.close puts "Torrc config written \n" #puts @tor_io=Process.spawn("tor","-f",torrc_filename) # stdin, stdout, stderr, thread #puts @tor_io=Open3.popen3("tor","-f",torrc_filename) # stdin, stdout, stderr, thread @pid[:tor] = Process.spawn("tor","-f",torrc_filename) sleep(7) # wait 7 seconds to download cached consensus and descriptors. -Consider copuing the existing one from the previous directory # check here # **************** why sleep? can I use the cached desc from the first tor process @torcontroller = Tor::TController.new(@ctrller_config) # write proxyconfig to polipo polipo_filename = File.join(@path,"polipo_config") polipo_config = File.new( polipo_filename , "w") polipo_config.puts "proxyPort = #{@proxyconfig}\n" polipo_config.puts "socksParentProxy = localhost:#{socks_port}\n" polipo_config.puts "socksProxyType = socks5\n" polipo_config.puts "daemonise = true\n" polipo_log = File.join(@path,"polipo_log") polipo_pid = File.join(@path,"polipo.pid") polipo_forbid = File.join(@path,"forbidden") polipo_config.puts "logFile = #{polipo_log}\n" polipo_config.puts "pidFile = #{polipo_pid}\n" polipo_config.puts "forbiddenFile = #{polipo_forbid}\n" polipo_config.close @pid[:polipo]= Process.spawn( "polipo", "-c", polipo_filename) end @torcontroller = Tor::TController.new(@ctrller_config) # @path = @torcontroller.getconf("DataDirectory") when proxyconfig==nil # dont need path for the first Tor @torcontroller.setconf("__DisablePredictedCircuits",1) @torcontroller.setconf("newcircuitperiod",999999999) @torcontroller.setconf("maxcircuitdirtiness",999999999) @torcontroller.setconf("MaxOnionsPending",0) @torcontroller.setconf("__LeaveStreamsUnattached",1) @launched = true @closed = false end |
#launched? ⇒ Boolean
Checks if the launched method has been called
85 86 87 |
# File 'lib/circuits.rb', line 85 def launched? @launched end |
#start ⇒ Object
This attaches all streams on this controller to a prebuilt circuit that has been
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/circuits.rb', line 56 def start if ! launched? launch end if ! built? extend end # sleep(3.5) ###################### wait 3 seconds before checking if built. # May not be needed # use events here instead to (build) no matter what. or (launch and build). If built, attach existing streams from preceeding subcircuit if built? streams_array = @torcontroller.newstreams if ! streams_array.empty? and ! @cirnum.nil? streams_array.each{|each_stream| @torcontroller.attach_stream(each_stream, @cirnum) } end end end |