def died(self, hash): if hash in self.torrent_cache: log_msg( 'DIED: "' + Basic.clean(self.torrent_cache[hash]['path']) + '"', 1) else: log_msg('DIED: "' + Basic.clean(hash) + '"', 1)
def socks_method_CONNECT (self): # Check if we have ip address or domain name # log_msg("socks_method_CONNECT host = " + Basic.clean(self.host), 4, "socks") # The FaceTime SOCKS5 proxy treats IP addr the same way as hostname # if _ip_regex.match (self.host): # # we have dotted quad IP address # addressType = 1 # address = socket.inet_aton (self.host) # else: # # we have host name # address = self.host # addressType = 3 address = self.host addressType = 3 addressLen = len(address) #Protocol version=5, Command=1 (CONNECT), Reserved=0 #command = struct.pack ("!BBBB", 5, 1, 0, addressType) command = struct.pack ("!BBBBB", 5, 1, 0, addressType, addressLen) portstr = struct.pack ("!H", self.port) self.transport.write (command + address + portstr) self.state = "gotConnectReply"
def response(result): if result: read, write = result log_msg( "%s paid us %s for exit stream, now %d / %d" % (Basic.clean(self.baseCircuit.prevHexId[:4]), creditsEarned, read, write), 3, "par")
def get_default_gateway(): #TODO: execing route print is probably a better idea here try: strComputer = "." objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator") objSWbemServices = objWMIService.ConnectServer(strComputer, "root\cimv2") colItems = objSWbemServices.ExecQuery( "Select * from Win32_NetworkAdapterConfiguration") gateways = [] for objItem in colItems: z = objItem.DefaultIPGateway if z: for x in z: gateways.append(x) if len(gateways) > 1: log_msg( "Why are there multiple gateways? :( %s" % (Basic.clean(gateways)), 2) elif len(gateways) == 0: return None return gateways.pop(0) except Exception, e: log_ex(e, "Failed to get default gateway") return "192.168.1.1"
def connectionLost(self, reason): peerId = self.readable_id try: peerId = peerId.decode("hex") #since some peers send in ASCII instead of hex, oh well except TypeError: pass if not self.btApp.is_ready() and not self.btApp.is_starting(): return if self.read == self._read2: stage = 'post handshake' elif self.encrypted: stage = 'before %s' % (self.next_func) else: stage = 'during handshake' log_msg("Lost connection to %s (%s client -- cm: %s) %s." % (Basic.clean(peerId), self.get_client_name(), self.cryptmode, stage), 3, "btconn") if self.Encoder: if self.Encoder.connections and self in self.Encoder.connections: self.sever() #maybe we should retry with encryption? if self.next_func == self.read_header: #did we try connecting via plaintext? if not self.supposedlyEncrypted: log_msg("Ok, retrying with encryption...", 3, "btconn") #ok, lets retry this connection but WITH encryption this time self.Encoder.start_connection((self.get_ip(), self.get_port()), self.id, True) else: log_msg("Failed with encryption too", 3, "btconn") else: self.closed = True
def on_or_event(self, event): """Called by EventHandler when we get an OR event @param event: the ORConnEvent""" #Check for relays that are down: if event.status == "FAILED": #note that we've failed to extend to it: self.connectionFailures += 1.0 log_msg("Failed to extend to another relay (%s) for reason: %s" % (Basic.clean(self.desc.idhex), event.reason), 2)
def _update_ip(address, method): """Call this function when you learn about a new external IP address""" global _externalIP if not Twisted.is_local_ip(address): if not _externalIP: pass elif _externalIP != address: log_msg( "%s reported a different external IP than we already knew about: %s vs %s" % (method, Basic.clean(address), Basic.clean(_externalIP)), 3) else: return _externalIP = address GlobalEvents.throw_event("ip_update", address, method) else: log_msg( "Learned about local address %s via %s, not very helpful..." % (Basic.clean(address), method), 4)
def _update_ip(address, method): """Call this function when you learn about a new external IP address""" global _externalIP if not Twisted.is_local_ip(address): if not _externalIP: pass elif _externalIP != address: log_msg( "%s reported a different external IP than we already knew about: %s vs %s" % (method, Basic.clean(address), Basic.clean(_externalIP)), 3, ) else: return _externalIP = address GlobalEvents.throw_event("ip_update", address, method) else: log_msg("Learned about local address %s via %s, not very helpful..." % (Basic.clean(address), method), 4)
def on_or_event(self, event): """Called by EventHandler when we get an OR event @param event: the ORConnEvent""" #Check for relays that are down: if event.status == "FAILED": #note that we've failed to extend to it: self.connectionFailures += 1.0 log_msg( "Failed to extend to another relay (%s) for reason: %s" % (Basic.clean(self.desc.idhex), event.reason), 2)
def scan(self): #self.rawserver.add_task(self.scan, self.scan_period) r = parsedir(self.torrent_dir, self.torrent_cache, self.file_cache, self.blocked_files, return_metainfo=True, errfunc=self.Output.message) (self.torrent_cache, self.file_cache, self.blocked_files, added, removed) = r for hash, data in removed.items(): log_msg('dropped "' + Basic.clean(data['path']) + '"', 2) self.remove(hash) for hash, data in added.items(): log_msg('added "' + Basic.clean(data['path']) + '"', 2) self.add(hash, data)
def find_or_build_best_circuit(self, host="", port=0, ignoreList=None, force=False, protocol="TCP"): """Find the best Circuit to exit to host:port (or if none exists, build one). @param host: the circuit must be able to exit to this host @type host: hostname or IP address @param port: the circuit must be able to exit to this port @type port: int @param ignoreList: a list of Circuits to ignore @type ignoreList: list @param force: NOT IMPLEMENTED @param protocol: NOT IMPLEMENTED @return: the Circuit, or None if it is not possible.""" assert protocol == "TCP" assert force == False if not ignoreList: ignoreList = [] #find, or failing that, create, a circuit that can exit to host:port possible_circuits = [] #filter out circuits that exit from the wrong country, if we care about that sort of thing: allowableCircuits = self.liveCircuits.copy() if self.exitCountry: allowableCircuits = [ c for c in allowableCircuits if c.get_exit().desc.country == self.exitCountry ] #check if there are any circuits that can exit to here for circ in allowableCircuits: if circ.is_ready() and circ.will_accept_connection( host, port) and circ not in ignoreList: possible_circuits.append(circ) #try reusing circuits currently being built here if len(possible_circuits) <= 0: for circ in allowableCircuits: if circ.is_launching() and circ.will_accept_connection( host, port) and circ not in ignoreList: possible_circuits.append(circ) #if there are still no possible circuits, open a new one: if len(possible_circuits) <= 0: circ = self.build_circuit(host, port, isFast=True) if circ: possible_circuits.append(circ) else: return None #pick the best of the available circuits: best = possible_circuits[0] for i in range(1, len(possible_circuits)): best = self._compare_circuits(possible_circuits[i], best) log_msg( "%d looks like the best circuit for %s:%d" % (best.id, Basic.clean(host), port), 4, "stream") return best
def find_or_build_best_circuit(self, host="", port=0, ignoreList=None, force=False, protocol="TCP"): """Find the best Circuit to exit to host:port (or if none exists, build one). @param host: the circuit must be able to exit to this host @type host: hostname or IP address @param port: the circuit must be able to exit to this port @type port: int @param ignoreList: a list of Circuits to ignore @type ignoreList: list @param force: NOT IMPLEMENTED @param protocol: NOT IMPLEMENTED @return: the Circuit, or None if it is not possible.""" assert protocol == "TCP" assert force == False if not ignoreList: ignoreList = [] #find, or failing that, create, a circuit that can exit to host:port possible_circuits = [] #filter out circuits that exit from the wrong country, if we care about that sort of thing: allowableCircuits = self.liveCircuits.copy() if self.exitCountry: allowableCircuits = [c for c in allowableCircuits if c.get_exit().desc.country == self.exitCountry] #check if there are any circuits that can exit to here for circ in allowableCircuits: if circ.is_ready() and circ.will_accept_connection(host, port) and circ not in ignoreList: possible_circuits.append(circ) #try reusing circuits currently being built here if len(possible_circuits) <= 0: for circ in allowableCircuits: if circ.is_launching() and circ.will_accept_connection(host, port) and circ not in ignoreList: possible_circuits.append(circ) #if there are still no possible circuits, open a new one: if len(possible_circuits) <= 0: circ = self.build_circuit(host, port, isFast=True) if circ: possible_circuits.append(circ) else: return None #pick the best of the available circuits: best = possible_circuits[0] for i in range(1, len(possible_circuits)): best = self._compare_circuits(possible_circuits[i], best) log_msg("%d looks like the best circuit for %s:%d" % (best.id, Basic.clean(host), port), 4, "stream") return best
def get_default_gateway(): #TODO: execing route print is probably a better idea here try: strComputer = "." objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator") objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2") colItems = objSWbemServices.ExecQuery("Select * from Win32_NetworkAdapterConfiguration") gateways = [] for objItem in colItems: z = objItem.DefaultIPGateway if z: for x in z: gateways.append(x) if len(gateways) > 1: log_msg("Why are there multiple gateways? :( %s" % (Basic.clean(gateways)), 2) elif len(gateways) == 0: return None return gateways.pop(0) except Exception, e: log_ex(e, "Failed to get default gateway") return "192.168.1.1"
def externally_handshaked_connection_made(self, connection, options, already_read, encrypted=None): shouldClose = False if self.done: shouldClose = True log_msg("Refusing connection because we are shutting down", 4) #TODO: move this earlier in the connection process, or ideally, get Twisted to listen only from localhost when socks is enabled elif self.config['use_socks'] and connection.get_ip() != "127.0.0.1": shouldClose = True log_msg( "Refusing connection from outside peer because they attempted to connect directly! ip=%s" % (Basic.clean(ip)), 1) elif self.paused: shouldClose = True log_msg("Refusing connection becase we're paused", 4) elif len(self.connections) >= self.max_connections: shouldClose = True log_msg("Refusing connection becase we have too many already", 4) elif self.check_ip(connection=connection): shouldClose = True log_msg("Refusing connection becase check_ip failed", 4) #ok, is there any reason to close? if shouldClose: connection.close() return False #guess not, add this to the connections: self.connect_succeeded(connection) connection.externalHandshakeDone(self, encrypted, options) #TODO: make sure the data is getting handled properly? ##connection.complete = True #if already_read: # #con.data_came_in(con, already_read) # connection.dataReceived(already_read) return True
def __init__(self, bbApp, url, circ, successCB, failureCB=None, progressCB=None, fileName=None, timeout=None): """Signal the main thread to launch an external connection and let us handle which circuit to attach it to. @param url: location to download from @type url: str (URL) @param circ: a circuit to tunnel the request over, if necessary @type circ: Circuit or None @param successCB: function to call when the download has finished successfully @type successCB: function(data, httpDownloadInstance) @param failureCB: function to call when the download has finished successfully @type failureCB: function(reason, httpDownloadInstance) or None if you dont care about failures @param progressCB: function to call as there is periodic progress @type progressCB: function(progress) @param fileName: file to store the data to, if necessary. If None, data will be returned to the success function. If non-None, the filename will be returned instead @type fileName: str @param timeout: how long to wait for a response before assuming that it failed IMPORTANT NOTE: this is how long to wait for the SERVER. Total timeout will be timeout + time to wait for circuit, if there is a circuit Note that circuits have timeouts for being built, and setting up PAR @type timeout: float (seconds) or None""" self.url = url if circ: assert not circ.is_done( ), "Cannot download through a circuit (%s) that is finished" % ( circ.id) self.circ = circ self.fileName = fileName if not self.fileName: self.file = ClosableStringIO() else: self.file = open(self.fileName, "wb") self.successCB = successCB self.failureCB = failureCB self.progressCB = progressCB self.start_time = time.time() self.factory = None #: will eventually point to the protocol object for this test self.protocolInstance = None self.wrappingFactory = None self.requestDone = False #whether to use a TLS connection self.useTLS = False if self.url[0:5].lower() == "https": self.useTLS = True #extract the host to connect to: self.remoteHost = urlparse(self.url)[1] #extract the port to connect to: self.remotePort = 80 if self.useTLS: self.remotePort = 443 if self.remoteHost.find(":") != -1: self.remoteHost, self.remotePort = self.remoteHost.split(":") self.remotePort = int(self.remotePort) log_msg("HTTP REQUEST: %s" % (Basic.clean(self.url)), 4) self.factory = TestHTTPClientFactory(self, self.url, self.file) if self.progressCB: self.factory.protocol = MonitoredHTTPPageDownloader if self.useTLS: wrappingFactory = policies.WrappingFactory(self.factory) def wrap_protocol(factory, wrappedProtocol): checker = SSL.Checker.Checker(host=self.remoteHost) p = SSL.TwistedProtocolWrapper.TLSProtocolWrapper( factory, wrappedProtocol, startPassThrough=0, client=1, contextFactory=ClientContextFactory(), postConnectionCheck=checker) factory.protocolInstance = p return p wrappingFactory.protocol = wrap_protocol wrappingFactory.deferred = self.factory.deferred self.factory = wrappingFactory _httpDownloads.append(self) try: if self.circ: d = bbApp.launch_external_factory(self.remoteHost, self.remotePort, self.factory, self.circ.handle_stream, "REQUEST: %s" % (self.url)) else: Globals.reactor.connectTCP(self.remoteHost, self.remotePort, self.factory) except Exception, e: self.failure(e) return
def externally_handshaked_connection_made(self, connection, options, already_read, encrypted = None): shouldClose = False if self.done: shouldClose = True log_msg("Refusing connection because we are shutting down", 4) #TODO: move this earlier in the connection process, or ideally, get Twisted to listen only from localhost when socks is enabled elif self.config['use_socks'] and connection.get_ip() != "127.0.0.1": shouldClose = True log_msg("Refusing connection from outside peer because they attempted to connect directly! ip=%s" % (Basic.clean(ip)), 1) elif self.paused: shouldClose = True log_msg("Refusing connection becase we're paused", 4) elif len(self.connections) >= self.max_connections: shouldClose = True log_msg("Refusing connection becase we have too many already", 4) elif self.check_ip(connection=connection): shouldClose = True log_msg("Refusing connection becase check_ip failed", 4) #ok, is there any reason to close? if shouldClose: connection.close() return False #guess not, add this to the connections: self.connect_succeeded(connection) connection.externalHandshakeDone(self, encrypted, options) #TODO: make sure the data is getting handled properly? ##connection.complete = True #if already_read: # #con.data_came_in(con, already_read) # connection.dataReceived(already_read) return True
def response(result): if result: read, write = result log_msg("%s paid us %s for exit stream, now %d / %d" % (Basic.clean(self.baseCircuit.prevHexId[:4]), creditsEarned, read, write), 3, "par")
def __init__(self, bbApp, url, circ, successCB, failureCB=None, progressCB=None, fileName=None, timeout=None): """Signal the main thread to launch an external connection and let us handle which circuit to attach it to. @param url: location to download from @type url: str (URL) @param circ: a circuit to tunnel the request over, if necessary @type circ: Circuit or None @param successCB: function to call when the download has finished successfully @type successCB: function(data, httpDownloadInstance) @param failureCB: function to call when the download has finished successfully @type failureCB: function(reason, httpDownloadInstance) or None if you dont care about failures @param progressCB: function to call as there is periodic progress @type progressCB: function(progress) @param fileName: file to store the data to, if necessary. If None, data will be returned to the success function. If non-None, the filename will be returned instead @type fileName: str @param timeout: how long to wait for a response before assuming that it failed IMPORTANT NOTE: this is how long to wait for the SERVER. Total timeout will be timeout + time to wait for circuit, if there is a circuit Note that circuits have timeouts for being built, and setting up PAR @type timeout: float (seconds) or None""" self.url = url if circ: assert not circ.is_done(), "Cannot download through a circuit (%s) that is finished" % (circ.id) self.circ = circ self.fileName = fileName if not self.fileName: self.file = ClosableStringIO() else: self.file = open(self.fileName, "wb") self.successCB = successCB self.failureCB = failureCB self.progressCB = progressCB self.start_time = time.time() self.factory = None #: will eventually point to the protocol object for this test self.protocolInstance = None self.wrappingFactory = None self.requestDone = False #whether to use a TLS connection self.useTLS = False if self.url[0:5].lower() == "https": self.useTLS = True #extract the host to connect to: self.remoteHost = urlparse(self.url)[1] #extract the port to connect to: self.remotePort = 80 if self.useTLS: self.remotePort = 443 if self.remoteHost.find(":") != -1: self.remoteHost, self.remotePort = self.remoteHost.split(":") self.remotePort = int(self.remotePort) log_msg("HTTP REQUEST: %s" % (Basic.clean(self.url)), 4) self.factory = TestHTTPClientFactory(self, self.url, self.file) if self.progressCB: self.factory.protocol = MonitoredHTTPPageDownloader if self.useTLS: wrappingFactory = policies.WrappingFactory(self.factory) def wrap_protocol(factory, wrappedProtocol): checker = SSL.Checker.Checker(host=self.remoteHost) p = SSL.TwistedProtocolWrapper.TLSProtocolWrapper(factory, wrappedProtocol, startPassThrough=0, client=1, contextFactory=ClientContextFactory(), postConnectionCheck=checker) factory.protocolInstance = p return p wrappingFactory.protocol = wrap_protocol wrappingFactory.deferred = self.factory.deferred self.factory = wrappingFactory _httpDownloads.append(self) try: if self.circ: d = bbApp.launch_external_factory(self.remoteHost, self.remotePort, self.factory, self.circ.handle_stream, "REQUEST: %s" % (self.url)) else: Globals.reactor.connectTCP(self.remoteHost, self.remotePort, self.factory) except Exception, e: self.failure(e) return