def waitForty(v,q): #pragma: no cover stamp = time() while q.empty(): if time() - 10 > stamp: break #pragma: no cover try: feedback = q.get(False) except: #pragma: no cover safeprint("No feedback received from listener") safeprint("YOUR IP IS " + get_lan_ip() + ":44566") requestPeerlist((get_lan_ip(),44566)) sleep(4) requestPeerlist(("localhost",44566)) sleep(4) if sys.version_info[0] == 3: requestBounties((get_lan_ip(),44566)) sleep(4) requestBounties(("localhost",44566)) sleep(4) safeprint(bounty.getBountyList()) #TODO move test incoming_bounty here #TODO move test incoming_bounty here safeprint("Sending term signal") v.value = False try: requestPeerlist(("localhost",44566)) except: safeprint("This was supposed to fail. Good job")
def initParallels(): queue = Queue() live = Value('b', True) ear = peers.listener(settings.config['port'], settings.config['outbound'], queue, live, settings.config['server']) ear.daemon = True ear.items = sync() ear.start() mouth = peers.propagator(settings.config['port'] + 1, live) mouth.daemon = True mouth.items = ear.items mouth.start() feedback = [] stamp = time() while queue.empty(): if time() - 15 > stamp: break global ext_ip, ext_port ext_ip = "" ext_port = -1 try: feedback = queue.get(False) settings.outbound = feedback[0] if settings.outbound is not True: ext_ip, ext_port = feedback[1:3] except: safeprint("No feedback received from listener") return live
def isValid(self): """Internal method which checks the Bounty as valid under the most minimal version ip -- Must be in valid range btc -- Must be in valid namespace reward -- Must be in valid range timeout -- Must be greater than the current time """ try: safeprint("Testing IP address", verbosity=1) if not checkIPAddressValid(self.ip): return False safeprint("Testing Bitcoin address", verbosity=1) #The following is a soft check #A deeper check will need to be done in order to assure this is correct if not checkBTCAddressValid(self.btc): return False safeprint("Testing reward and/or signiture validity", verbosity=1) if not self.reward in range( 1440, 100000001) or (not self.reward and self.checkSign()): return False safeprint("Testing timeout", verbosity=1) if self.timeout < getUTC(): #check against current UTC return False safeprint("Testing bounty requirements", verbosity=1) if parse(self.data.get('reqs')): return 1 return -1 except: return False
def isValid(self): """Internal method which checks the Bounty as valid in the most minimal version ip -- Must be in valid range btc -- Must be in valid namespace reward -- Must be in valid range timeout -- Must be greater than the current time """ try: safeprint("Testing IP address", verbosity=1) if not checkIPAddressValid(self.ip): return False safeprint("Testing Bitcoin address", verbosity=1) # The following is a soft check # A deeper check will be needed in order to assure this is correct if not checkBTCAddressValid(self.btc): return False safeprint("Testing reward and/or signiture validity", verbosity=1) if self.reward not in range(1440, 100000001) or (not self.reward and self.checkSign()): return False safeprint("Testing timeout", verbosity=1) if self.timeout < getUTC(): # check against current UTC return False safeprint("Testing bounty requirements", verbosity=1) if parse(self.data.get('reqs')): return 1 return -1 except: return False
def requestPeerlist(address): """Request the peerlist of another node. Currently has additional test commands""" conn = socket.socket() conn.settimeout(5) safeprint(address,verbosity=1) try: conn.connect(address) key = send(peer_request,conn,None) received = recv(conn) safeprint(pickle.loads(received),verbosity=2) if recv(conn) == peer_request: handlePeerRequest(conn,False,key=key,received=pickle.loads(received)) recv(conn) #test section conn = socket.socket() conn.settimeout(5) conn.connect(address) send(incoming_bounty,conn,key) bounty = Bounty(get_lan_ip() + ":44565","1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",1440) bounty = pickle.dumps(bounty,0) if type(bounty) == type("a"): bounty = bounty.encode('utf-8') safeprint(bounty,verbosity=3) send(bounty,conn,key) recv(conn) recv(conn) conn.close() #end test section return pickle.loads(received) except Exception as error: safeprint("Failed:" + str(type(error))) safeprint(error) remove.extend([address]) return []
def requestPeerlist(address): """Request the peerlist of another node. Currently has additional test commands""" conn = socket.socket() conn.settimeout(5) safeprint(address, verbosity=1) try: conn.connect(address) key = send(peer_request, conn, None) received = recv(conn) safeprint(pickle.loads(received), verbosity=2) if recv(conn) == peer_request: handlePeerRequest(conn, False, key=key, received=pickle.loads(received)) recv(conn) # test section conn = socket.socket() conn.settimeout(5) conn.connect(address) send(incoming_bounty, conn, key) bounty = Bounty(get_lan_ip() + ":44565", "1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9", 1440) bounty = pickle.dumps(bounty, 0) if type(bounty) == type("a"): bounty = bounty.encode("utf-8") safeprint(bounty, verbosity=3) send(bounty, conn, key) recv(conn) recv(conn) conn.close() # end test section return pickle.loads(received) except Exception as error: safeprint("Failed:" + str(type(error))) safeprint(error) remove.extend([address]) return []
def verify(string): """External method which checks the Bounty as valid under implementation-specific requirements. This can be defined per user. ip -- Must be in valid range btc -- Must be in valid namespace reward -- Must be in valid range timeout -- Must be greater than the current time """ test = depickle(string) try: safeprint("Testing IP address", verbosity=1) if not checkIPAddressValid(test.ip): return False safeprint("Testing Bitcoin address", verbosity=1) # The following is a soft check # A deeper check will be needed in order to assure this is correct if not checkBTCAddressValid(test.btc): return False safeprint("Testing reward and/or signiture validity", verbosity=1) if test.reward not in range(1440, 100000001) or (not test.reward and test.checkSign()): return False safeprint("Testing timeout", verbosity=1) if test.timeout < getUTC(): # check against current UTC return False safeprint("Testing bounty requirements", verbosity=1) if parse(test.data.get('reqs')): return 1 return -1 except: return False
def verify(string): """External method which checks the Bounty as valid under implementation-specific requirements. This can be defined per user. ip -- Must be in valid range btc -- Must be in valid namespace reward -- Must be in valid range timeout -- Must be greater than the current time """ test = string if type(test) == type(""): test = pickle.loads(string) try: safeprint("Testing IP address", verbosity=1) if not checkIPAddressValid(test.ip): return False safeprint("Testing Bitcoin address", verbosity=1) #The following is a soft check #A deeper check will need to be done in order to assure this is correct if not checkBTCAddressValid(test.btc): return False safeprint("Testing reward and/or signiture validity", verbosity=1) if not test.reward in range(1440, 100000001) or (not test.reward and test.checkSign()): return False safeprint("Testing timeout", verbosity=1) if test.timeout < getUTC(): #check against current UTC return False safeprint("Testing bounty requirements", verbosity=1) if parse(test.data.get('reqs')): return 1 return -1 except: return False
def initParallels(): queue = Queue() live = Value('b', True) ear = peers.listener(settings.config['port'], settings.config['outbound'], queue, live, settings.config['server']) ear.daemon = True ear.items = sync() ear.start() mouth = peers.propagator(settings.config['port'] + 1, live) mouth.daemon = True mouth.items = ear.items mouth.start() feedback = [] stamp = time() while queue.empty(): if time() - 5 > stamp: break #pragma: no cover try: feedback = queue.get(False) except: #pragma: no cover safeprint("No feedback received from listener") global ext_ip, ext_port ext_ip = "" #Does this affect peers? ext_port = -1 #Does this affect peers? if feedback != []: settings.outbound = feedback[0] if settings.outbound is not True: ext_ip, ext_port = feedback[1:3] return live
def waitForty(v, q): #pragma: no cover stamp = time() while q.empty(): if time() - 10 > stamp: break #pragma: no cover try: feedback = q.get(False) except: #pragma: no cover safeprint("No feedback received from listener") safeprint("YOUR IP IS " + get_lan_ip() + ":44566") requestPeerlist((get_lan_ip(), 44566)) sleep(4) requestPeerlist(("localhost", 44566)) sleep(4) if sys.version_info[0] == 3: requestBounties((get_lan_ip(), 44566)) sleep(4) requestBounties(("localhost", 44566)) sleep(4) safeprint(bounty.getBountyList()) #TODO move test incoming_bounty here #TODO move test incoming_bounty here safeprint("Sending term signal") v.value = False try: requestPeerlist(("localhost", 44566)) except: safeprint("This was supposed to fail. Good job")
def checkSign(self): safeprint(keyList) if self.data.get('key') in keyList: expected = str(self).encode('utf-8') if not self.data['key'].size() / 4 + 1 < len(expected): return self.data['key'].verify(expected,self.data['sig']) return False
def loadSettings(): """Load settings from a file""" from common.safeprint import safeprint if os.path.exists(settings_file): try: config.update(pickle.load(open(settings_file, "rb"))) except: safeprint("Could not load from file")
def getFromFile(): """Load peerlist from a file""" if os.path.exists(peers_file): try: peerlist.extend(pickle.load(open(peers_file, "rb"))) trimPeers() except: safeprint("Could not load peerlist from file")
def getFromFile(): """Load peerlist from a file""" if os.path.exists(peers_file): try: peerlist.extend(pickle.load(open(peers_file, "rb"))) trimPeers() except: safeprint("Could not load peerlist from file")
def loadSettings(): """Load settings from a file""" from common.safeprint import safeprint if os.path.exists(settings_file): try: config.update(pickle.load(open(settings_file, "rb"))) except: safeprint("Could not load from file")
def propagate(tup): try: conn = socket.socket() address = tup[1] conn.connect(address) key = send(incoming_bounty, conn, None) send(pickle.dumps(tup[0], 0), conn, key) recv(conn) conn.close() except socket.error as Error: safeprint("Connection to " + str(address) + " failed; cannot propagate")
def propagate(tup): try: conn = socket.socket() address = tup[1] conn.connect(address) key = send(incoming_bounty,conn,None) send(pickle.dumps(tup[0],0),conn,key) recv(conn) conn.close() except socket.error as Error: safeprint("Connection to " + str(address) + " failed; cannot propagate")
def setup(): """Parses and stores the command line arguments given, and override default and saved settings""" parser = optparse.OptionParser() parser.add_option('-c', '--charity', dest='charity', default=None, action="store_true", help='Sets whether you accept rewardless bounties') parser.add_option('-f', '--propagation-factor', dest='propagate_factor', default=None, type="int", help='Minimum funds:reward ratio you\'ll propagate bounties at') parser.add_option('-l', '--latency', dest='accept_latency', default=None, type="int", help='Maximum acceptable latency from a server') parser.add_option('-o', '--outbound-only', dest='outbound', default=None, action="store_false", help='Maximum acceptable latency from a server') parser.add_option('-p', '--listening-port', dest='port', default=None, type="int", help='Port for the program to listen at') parser.add_option('-S', '--server', dest='server', default=None, action="store_true", help='Sets whether you operate as a server or client (Default: client)') (options, args) = parser.parse_args() safeprint("options parsed") overrides = options.__dict__ loadSettings() saveSettings() kill = [] for key in overrides: #Remove keys with None, just to be safe if overrides.get(key) is None: kill += [key] for key in kill: overrides.pop(key) config.update(overrides)
def checkSign(self): """check if the signature attatched to the Bounty is valid""" try: from rsa import verify, PublicKey safeprint(keyList) if self.data.get('cert'): #where key is (PublicKey.n, PublicKey.e) expected = str(self).encode('utf-8') n = self.data.get('key')[0] e = self.data.get('key')[1] if rsa.verify(str((n,e)),self.data.get('cert'),masterKey): return verify(expected,self.data.get('sig'),PublicKey(n,e)) return False except: return False
def main(): settings.setup() try: import miniupnpc except: safeprint("Dependency miniupnpc is not installed. Running in outbound only mode") settings.config['outbound'] = True safeprint("settings are:") safeprint(settings.config) queue = Queue() live = Value('b',True) ear = listener(settings.config['port'],settings.config['outbound'],queue,live,settings.config['server']) ear.daemon = True ear.start() feedback = [] stamp = time() while queue.empty(): if time() - 5 > stamp: break #pragma: no cover try: feedback = queue.get(False) except: #pragma: no cover safeprint("No feedback received from listener") ext_ip = "" #Does this affect peers? ext_port = -1 #Does this affect peers? if feedback != []: settings.outbound = feedback[0] if settings.outbound is not True: ext_ip = feedback[1] ext_port = feedback[2] initializePeerConnections(settings.config['port'], ext_ip, ext_port) live.value = False
def sync(): from multiprocessing import Manager man = Manager() items = {'config': man.dict(), 'peerList': man.list(), 'bountyList': man.list(), 'bountyLock': bounty.bountyLock, 'keyList': man.list()} items['config'].update(settings.config) items['peerList'].extend(peers.peerlist) items['bountyList'].extend(bounty.bountyList) safeprint(items) peers.sync(items) return items
def sync(): from multiprocessing import Manager man = Manager() items = { 'config': man.dict(), 'peerList': man.list(), 'bountyList': man.list(), 'bountyLock': bounty.bountyLock, 'keyList': man.list() } items['config'].update(settings.config) items['peerList'].extend(peers.peerlist) items['bountyList'].extend(bounty.bountyList) safeprint(items) peers.sync(items) return items
def getBounty(charity, factor): """Retrieve the next best bounty from the list""" global bountyList, bountyLock best = None bountyLock.__enter__() temp = bountyList[:] safeprint("bountyList = " + str(temp), verbosity=3) for bounty in temp: if not bounty.timeout < getUTC(): bountyList.remove(bounty) continue elif charity: best = bounty break elif bounty > best: best = bounty bountyLock.__exit__() return best
def getBounty(charity, factor): """Retrieve the next best bounty from the list""" temp = getBountyList() safeprint("bountyList = " + str(temp),verbosity=3) if temp == []: return None elif charity: for bounty in temp: if bounty.isValid(): index = temp.index(bounty) return temp.pop(index) else: best = None for bounty in temp: if best is None: best = bounty elif best < bounty and bounty.isValid() and bounty.isPayable(factor): best = bounty return best
def addBounty(bounty): """Verify a bounty, and add it to the list if it is valid""" bounty = depickle(bounty) safeprint("External verify", verbosity=1) first = verify(bounty) safeprint("Internal verify") second = bounty.isValid() if not second: rval = -3 elif not first: rval = -2 elif bounty in getBountyList(): rval = -1 elif second == -1: rval = 0 else: rval = 1 addValidBounty(bounty) return rval
def send(msg, conn, key): while key is None: safeprint("Key not found. Requesting key") conn.send(key_request) try: key = pickle.loads(conn.recv(1024)) key = rsa.PublicKey(key[0], key[1]) safeprint("Key received") except EOFError: continue if type(msg) != type("a".encode("utf-8")): msg = msg.encode("utf-8") x = 0 while x < len(msg) - 117: conn.sendall(rsa.encrypt(msg[x : x + 117], key)) x += 117 conn.sendall(rsa.encrypt(msg[x:], key)) if msg not in signals: conn.sendall(rsa.encrypt(end_of_message, key)) return key
def send(msg, conn, key): while key is None: safeprint("Key not found. Requesting key") conn.send(key_request) try: key = pickle.loads(conn.recv(1024)) key = rsa.PublicKey(key[0], key[1]) safeprint("Key received") except EOFError: continue if type(msg) != type("a".encode('utf-8')): msg = msg.encode('utf-8') x = 0 while x < len(msg) - 117: conn.sendall(rsa.encrypt(msg[x:x + 117], key)) x += 117 conn.sendall(rsa.encrypt(msg[x:], key)) if msg not in signals: conn.sendall(rsa.encrypt(end_of_message, key)) return key
def sync(): from multiprocessing import Manager from common import bounty, settings, peers from common.safeprint import safeprint man = Manager() items = {'config':man.dict(), 'peerList':man.list(), 'bountyList':man.list(), 'bountyLock':bounty.bountyLock, 'keyList':man.list()} items['config'].update(settings.config) items['peerList'].extend(peers.peerlist) items['bountyList'].extend(bounty.bountyList) safeprint(items) safeprint(items.get('bountyList')) safeprint(items.get('keyList')) if items.get('config') is not None: from common import settings settings.config = items.get('config') if items.get('peerList') is not None: global peerList peers.peerlist = items.get('peerList') if items.get('bountyList') is not None: from common import bounty bounty.bountyList = items.get('bountyList') if items.get('bountyLock') is not None: from common import bounty bounty.bountyLock = items.get('bountyLock') return items
def handlePeerRequest(conn, exchange): """Given a socket, send the proper messages to complete a peer request""" if ext_port != -1: send = pickle.dumps(peerlist + [ext_ip+":"+str(ext_port)],0) send = pickle.dumps(peerlist,0) if type(send) != type("a".encode("utf-8")): safeprint("Test here") send = send.encode("utf-8") conn.send(send) time.sleep(0.01 + 0.001 * len(send)) if exchange: conn.send(peer_request) connected = True received = "".encode('utf-8') while connected: packet = conn.recv(len(close_signal)) safeprint(packet) if packet == close_signal: connected = False else: received += packet peerlist.extend(pickle.loads(received)) trimPeers()
def loadFromFile(): """Load a previous bounty list from a file""" if os.path.exists(bounty_path): with bountyLock: try: safeprint("Loading bounty list from file", verbosity=2) templist = pickle.load(open(bounty_path, "rb")) safeprint(addBounties(templist), verbosity=3) safeprint("Bounty list loaded and added", verbosity=2) except: return False return True return False
def loadFromFile(): """Load a previous bounty list from a file""" if os.path.exists(bounty_path): with bountyLock: try: safeprint("Loading bounty list from file",verbosity=2) templist = pickle.load(open(bounty_path,"rb")) safeprint(addBounties(templist),verbosity=3) safeprint("Bounty list loaded and added",verbosity=2) except: return False return True return False
def handleIncomingBountyP(conn): """Given a socket, store an incoming bounty, and report it valid or invalid""" connected = True received = "".encode('utf-8') while connected: packet = conn.recv(sig_length) safeprint(packet,verbosity=3) if not packet == close_signal: received += packet else: connected = False safeprint("Adding bounty: " + received.decode(),verbosity=2) try: bounty = pickle.loads(received) if bounty.isValid(): from multiprocessing.pool import ThreadPool ThreadPool().map(propagate,[(bounty,x) for x in peerlist[:]]) except Exception as error: safeprint("bounty propagation failed: " + str(type(error))) safeprint(error) traceback.print_exc() return False
def handleIncomingBountyP(conn): """Given a socket, store an incoming bounty, and report it valid or invalid""" connected = True received = "".encode('utf-8') while connected: packet = conn.recv(sig_length) safeprint(packet, verbosity=3) if not packet == close_signal: received += packet else: connected = False safeprint("Adding bounty: " + received.decode(), verbosity=2) try: bounty = pickle.loads(received) if bounty.isValid(): from multiprocessing.pool import ThreadPool ThreadPool().map(propagate, [(bounty, x) for x in peerlist[:]]) except Exception as error: safeprint("bounty propagation failed: " + str(type(error))) safeprint(error) traceback.print_exc() return False
def depickle(string): """Handles the potential errors in unpickling a bounty""" if isinstance(string, Bounty): return string safeprint([sys.version_info[0], sys.version_info[1], sys.version_info[2]]) if sys.version_info[0] == 2 and sys.version_info[1] == 6 and (isinstance(string, str) or isinstance(string, unicode)): safeprint("Fed as string in 2.6; encoding ascii and ignoring errors") try: string = string.encode('ascii', 'ignore') except: string = str(string) elif isinstance(string, str) and sys.version_info[0] >= 3: safeprint("Fed as string; encoding utf-8") string = string.encode('utf-8') try: return pickle.loads(string) except: return None
def requestBounties(address): """Request the bountylist of another node""" conn = socket.socket() conn.settimeout(5) safeprint(address, verbosity=1) try: conn.connect(address) key = send(bounty_request, conn, None) received = recv(conn) if recv(conn) == bounty_request: handleBountyRequest(conn, False, key=key, received=pickle.loads(received)) recv(conn) send(close_signal, conn, key) conn.close() addBounties(pickle.loads(received)) except Exception as error: safeprint("Failed:" + str(type(error))) safeprint(error) remove.extend([address])
def requestBounties(address): """Request the bountylist of another node""" conn = socket.socket() conn.settimeout(5) safeprint(address,verbosity=1) try: conn.connect(address) key = send(bounty_request,conn,None) received = recv(conn) if recv(conn) == bounty_request: handleBountyRequest(conn,False,key=key,received=pickle.loads(received)) recv(conn) send(close_signal,conn,key) conn.close() addBounties(pickle.loads(received)) except Exception as error: safeprint("Failed:" + str(type(error))) safeprint(error) remove.extend([address])
def handleIncomingBounty(conn): """Given a socket, store an incoming bounty, and report it valid or invalid""" connected = True received = "".encode('utf-8') while connected: packet = conn.recv(len(close_signal)) safeprint(packet) if not packet == close_signal: received += packet else: connected = False safeprint("Adding bounty: " + received.decode()) try: if addBounty(received): conn.send(valid_signal) else: conn.send(invalid_signal) except: safeprint("They closed too early")
def recv(conn): received = "".encode('utf-8') a = "" try: while True: a = conn.recv(128) if a == key_request: safeprint("Key requested. Sending key") conn.sendall(pickle.dumps((myPriv.n, myPriv.e), 0)) continue a = rsa.decrypt(a, myPriv) safeprint("Packet = " + str(a), verbosity=3) if a in signals: return a elif a == end_of_message: return received else: received += a except rsa.pkcs1.DecryptionError as error: safeprint("Decryption error---Content: " + str(a)) return "".encode('utf-8')
def recv(conn): received = "".encode("utf-8") a = "" try: while True: a = conn.recv(128) if a == key_request: safeprint("Key requested. Sending key") conn.sendall(pickle.dumps((myPriv.n, myPriv.e), 0)) continue a = rsa.decrypt(a, myPriv) safeprint("Packet = " + str(a), verbosity=3) if a in signals: return a elif a == end_of_message: return received else: received += a except rsa.pkcs1.DecryptionError as error: safeprint("Decryption error---Content: " + str(a)) return "".encode("utf-8")
def handleIncomingBounty(conn, key=None): """Given a socket, store an incoming bounty, and report it valid or invalid""" received = recv(conn) safeprint("Adding bounty: " + received.decode()) try: valid = addBounty(received) if valid >= -1: #If it's valid, even if it's a duplicate, send valid signal send(valid_signal,conn,key) if valid >= 0: #If it's valid and not already received, propagate mouth = socket.socket() from common import settings mouth.connect(("localhost",settings.config['port'] + 1)) mouth.send(incoming_bounty) mouth.send(pad(received)) mouth.send(close_signal) mouth.close() else: send(invalid_signal,conn,key) except Exception as error: safeprint("Incoming failed: " + str(type(error))) safeprint(error) traceback.print_exc() return key
def handleIncomingBounty(conn, key=None): """Given a socket, store an incoming bounty, and report it valid or invalid""" received = recv(conn) safeprint("Adding bounty: " + received.decode()) try: valid = addBounty(received) if valid >= -1: #If it's valid, even if it's a duplicate, send valid signal send(valid_signal, conn, key) if valid >= 0: #If it's valid and not already received, propagate mouth = socket.socket() from common import settings mouth.connect(("localhost", settings.config['port'] + 1)) mouth.send(incoming_bounty) mouth.send(pad(received)) mouth.send(close_signal) mouth.close() else: send(invalid_signal, conn, key) except Exception as error: safeprint("Incoming failed: " + str(type(error))) safeprint(error) traceback.print_exc() return key
def testBounty(ip, btc, rwd, desc, data=None): #pragma: no cover safeprint(desc) test = bounty.Bounty(ip,btc,rwd,dataDict=data) dumped = pickle.dumps(test,1) safeprint(bounty.addBounty(dumped))
def handleBountyRequest(conn, exchange, key=None, received=[]): """Given a socket, send the proper messages to complete a bounty request""" unfiltered = getBountyList() filtered = list(set(unfiltered) - set(received)) toSend = pickle.dumps(filtered, 0) if type(toSend) != type("a".encode("utf-8")): safeprint("Test here") toSend = toSend.encode("utf-8") safeprint("Sending") key = send(toSend, conn, key) if exchange: send(bounty_request, conn, key) received = recv(conn) safeprint("Received exchange") try: safeprint(pickle.loads(received), verbosity=2) bounties = pickle.loads(received) valids = addBounties(bounties) toSend = [] for i in range(len(bounties)): if valids[ i] >= 0: #If the bounty is valid and not a duplicate, add it to propagation list toSend.append(bounties[i]) mouth = socket.socket() from common import settings mouth.connect(("localhost", settings.config.get('port') + 1)) mouth.send(incoming_bounties) mouth.send(pad(pickle.dumps(toSend, 0))) mouth.send(close_signal) mouth.close() except Exception as error: safeprint("Could not add bounties") safeprint(type(error)) traceback.print_exc() #later add function to request without charity bounties return key
if __name__ == "__main__": #pragma: no cover settings.setup() settings.config['port'] = 44566 testBounty(('8.8.8.8',8888),"1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",1440,"Correctly formed bounty") testBounty(('8.8.8.8',-1),"1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",1440,"Malformed bounty 1 (ip failure)") testBounty(('8.8.8',8888),"1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",1440,"Malformed bounty 2 (ip failure)") testBounty(('8.8.8.8',888888888),"1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",1440,"Malformed bounty 3 (ip failure)") testBounty(('8.8.12348.8',8888),"1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",1440,"Malformed bounty 4 (ip failure)") testBounty(('8.8.8.8',8888),"1JTGcHS3GMhBGGww4ZEDmP7u9",1440,"Malformed bounty 5 (btc failure)") testBounty(('8.8.8.8',8888),"1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",-1440,"Malformed bounty 6 (reward failure)") testBounty(('8.8.8.8',8888),"1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",0,"Malformed bounty 7 (signature failure)") testBounty(('8.8.8.8',8888),"1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",1440,"Correctly formed bounty 2", data={'reqs':{("__builtin__","pow",2,2):4}}) testBounty(('8.8.8.8',8888),"1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",1440,"Malformed bounty 8 (requirements failure)", data={'reqs':{("sys","platform","index=2","end=3"):"win33"}}) testBounty(('8.8.8.8',8888),"1JTGcHS3GMhBGLcFRuHLk6Gww4ZEDmP7u9",1440,"Malformed bounty 9 (requirements failure)", data={'reqs':{("__builtin__","pow",2,2):4,("sys","platform"):"win33"}}) safeprint("Malformed bounty 11 (timeout error)") safeprint(addBounty(pickle.dumps(bounty.Bounty(('8.8.8.8',8888),"1LhPsd4ng3AXmVPzrLWprWFx351pW4HJm8",10900,timeout=1),0))) testBounty(('8.8.8.8',8888),"1LhPsd4ng3AXmVPzrLWprWFx351pW4HJm8",10900,"Correctly formed bounty 3") testBounty(('8.8.8.8',8888),"1MWSdYMKEpfWVxC6BGYARxsksaQuyEWzG5",1480,"Correctly formed bounty 4") testBounty(('8.8.8.8',8888),"1EgGfDetymjMzcQ1AEhHjHEyXHjnEavwgg",10290,"Correctly formed bounty 5") safeprint(bounty.getBountyList()) bounty.saveToFile() bounty.loadFromFile() safeprint(bounty.getBountyList()) safeprint("3 bounties should follow") safeprint(bounty.getBounty(settings.config.get('charity'),settings.config.get('propagate_factor'))) safeprint(bounty.getBounty(False,2)) safeprint(bounty.getBounty(True,2)) settings.saveSettings() settings.loadSettings() saveToFile()
def initializePeerConnections(newPort, newip, newport): """Populate the peer list from a previous session, seeds, and from the peer list if its size is less than 12. Then save this new list to a file""" port = newPort #Does this affect the global variable? ext_ip = newip #Does this affect the global variable? ext_port = newport #Does this affect the global variable? safeprint([ext_ip, ext_port]) getFromFile() safeprint("peers fetched from file", verbosity=1) getFromSeeds() safeprint("peers fetched from seedlist", verbosity=1) trimPeers() if len(peerlist) < 12: safeprint(len(peerlist)) newlist = [] for peer in peerlist: newlist.extend(requestPeerlist(peer)) peerlist.extend(newlist) trimPeers() safeprint("getting bounties from peers and seeds", verbosity=1) for peer in peerlist[:] + seedlist[:]: requestBounties(peer) safeprint("peer network extended", verbosity=1) saveToFile() safeprint("peer network saved to file", verbosity=1) safeprint(peerlist) safeprint([ext_ip, ext_port])
def main(): #Begin Init settings.setup() from common.safeprint import safeprint try: import miniupnpc except: safeprint("Dependency miniupnpc is not installed. Running in outbound only mode") settings.config['outbound'] = True safeprint("settings are:") safeprint(settings.config) queue = Queue() live = Value('b',True) ear = listener(settings.config['port'],settings.config['outbound'],queue,live,settings.config['server']) ear.daemon = True ear.items = sync() ear.start() mouth = propagator(settings.config['port'] + 1, live) mouth.daemon = True mouth.items = ear.items mouth.start() feedback = [] stamp = time() while queue.empty(): if time() - 5 > stamp: break #pragma: no cover try: feedback = queue.get(False) except: #pragma: no cover safeprint("No feedback received from listener") ext_ip = "" #Does this affect peers? ext_port = -1 #Does this affect peers? if feedback != []: settings.outbound = feedback[0] if settings.outbound is not True: ext_ip = feedback[1] ext_port = feedback[2] initializePeerConnections(settings.config['port'], ext_ip, ext_port) #End Init #Begin main loop if settings.config.get('seed'): safeprint("Seed mode activated") try: while True and not settings.config.get('test'): sleep(0.1) except KeyboardInterrupt: safeprint("Keyboard Interrupt") elif settings.config.get('server'): safeprint("Server mode activated") else: safeprint("Client mode activated") #End main loop #Begin shutdown safeprint("Beginning exit process") live.value = False settings.saveSettings() saveToFile() bounty.saveToFile()
def portForward(port): """Attempt to forward a port on your router to the specified local port. Prints lots of debug info.""" try: import miniupnpc u = miniupnpc.UPnP(None, None, 200, port) #Begin Debug info safeprint('inital(default) values :') safeprint(' discoverdelay' + str(u.discoverdelay)) safeprint(' lanaddr' + str(u.lanaddr)) safeprint(' multicastif' + str(u.multicastif)) safeprint(' minissdpdsocket' + str(u.minissdpdsocket)) safeprint('Discovering... delay=%ums' % u.discoverdelay) safeprint(str(u.discover()) + 'device(s) detected') #End Debug info u.selectigd() global ext_ip ext_ip = u.externalipaddress() safeprint("external ip is: " + str(ext_ip)) for i in range(0, 20): try: safeprint("Port forward try: " + str(i), verbosity=1) if u.addportmapping(port + i, 'TCP', get_lan_ip(), port, 'Bounty Net', ''): global ext_port ext_port = port + i safeprint("External port is " + str(ext_port)) return True except Exception as error: safeprint("Failed: " + str(type(error))) safeprint(error) except Exception as error: safeprint("Failed: " + str(type(error))) safeprint(error) return False
def addBounties(bounties): """Add a list of bounties in parallel using multiprocessing.Pool for verification""" from multiprocessing.pool import ThreadPool pool = ThreadPool() safeprint("Mapping verifications",verbosity=3) async = pool.map_async(verify,bounties) #defer this for possible efficiency boost internal = pool.map(internalVerify,bounties) safeprint("Waiting for verifications",verbosity=3) external = async.get() safeprint("Received verifications",verbosity=3) rvals = [] safeprint(internal) safeprint(external) for i in range(len(bounties)): safeprint("Finishing the processing of bounty " + str(i+1) + "/" + str(len(bounties)),verbosity=2) if not internal[i]: rvals.append(-3) elif not external[i]: rvals.append(-2) elif bounties[i] in bountyList: rvals.append(-1) elif internal[i] == -1: rvals.append(0) else: rvals.append(1) safeprint("Passed first if",verbosity=3) if rvals[i] == 1: addValidBounty(bounties[i]) safeprint("Verifications parsed",verbosity=3) return rvals
def listen(port, outbound, q, v, serv): """BLOCKING function which should only be run in a daemon thread. Listens and responds to other nodes""" if serv: from server.bounty import verify, addBounty server = socket.socket() server.bind(("0.0.0.0", port)) server.listen(10) server.settimeout(5) if sys.version_info[0] < 3 and sys.platform == "win32": server.setblocking(True) global ext_ip global ext_port if outbound is True: safeprint("UPnP mode is disabled") else: safeprint("UPnP mode is enabled") if not portForward(port): outbound = True safeprint([outbound, ext_ip, ext_port]) q.put([outbound, ext_ip, ext_port]) while v.value: #is True is implicit safeprint("listening on " + str(get_lan_ip()) + ":" + str(port), verbosity=3) if not outbound: safeprint("forwarded from " + ext_ip + ":" + str(ext_port), verbosity=3) try: conn, addr = server.accept() server.setblocking(True) conn.setblocking(True) safeprint("connection accepted") packet = recv(conn) safeprint("Received: " + packet.decode(), verbosity=3) key = None if packet == peer_request: key = handlePeerRequest(conn, True, key=key) elif packet == bounty_request: key = handleBountyRequest(conn, True, key=key) elif packet == incoming_bounty: key = handleIncomingBounty(conn, key=key) send(close_signal, conn, key) conn.close() server.settimeout(5) safeprint("connection closed") except Exception as error: safeprint("Failed: " + str(type(error))) safeprint(error) traceback.print_exc()
def main(): # Begin Init settings.setup() try: import miniupnpc except: safeprint("Miniupnpc is not installed. Running in outbound only mode") settings.config['outbound'] = True safeprint("settings are:") safeprint(settings.config) live = initParallels() global ext_ip, ext_port peers.initializePeerConnections(settings.config['port'], ext_ip, ext_port) # End Init # Begin main loop if settings.config.get('seed'): safeprint("Seed mode activated") try: while True and not settings.config.get('test'): sleep(0.1) except KeyboardInterrupt: safeprint("Keyboard Interrupt") elif settings.config.get('server'): safeprint("Server mode activated") else: safeprint("Client mode activated") # End main loop # Begin shutdown safeprint("Beginning exit process") live.value = False settings.saveSettings() peers.saveToFile() bounty.saveToFile()
def listenp(port, v): """BLOCKING function which should only be run in a daemon thread. Listens and responds to other nodes""" server = socket.socket() server.bind(("0.0.0.0", port)) server.listen(10) server.settimeout(5) if sys.version_info[0] < 3 and sys.platform == "win32": server.setblocking(True) while v.value: #is True is implicit safeprint("listenp-ing on localhost:" + str(port), verbosity=3) try: conn, addr = server.accept() server.setblocking(True) conn.setblocking(True) safeprint("connection accepted on propagator") packet = conn.recv(sig_length) safeprint("Received: " + packet.decode(), verbosity=3) if packet == incoming_bounty: handleIncomingBountyP(conn) conn.send(close_signal) conn.close() server.settimeout(5) safeprint("connection closed") except Exception as error: safeprint("Failed: " + str(type(error))) safeprint(error)
def getFromSeeds(): """Make peer requests to each address on the seedlist""" for seed in seedlist: safeprint(seed, verbosity=1) peerlist.extend(requestPeerlist(seed)) time.sleep(1)
def run(self): safeprint("propagator started") self.sync(self.items) listenp(self.port, self.v) safeprint("propagator stopped")
def run(self): safeprint("listener started") self.sync(self.items) listen(self.port, self.outbound, self.q, self.v, self.serv) safeprint("listener stopped")
def handlePeerRequest(conn, exchange, key=None, received=[]): """Given a socket, send the proper messages to complete a peer request""" if ext_port != -1: unfiltered = peerlist[:] + [((ext_ip, ext_port), myPub.n, myPub.e)] unfiltered = peerlist[:] filtered = list(set(unfiltered) - set(received)) safeprint("Unfiltered: " + str(unfiltered), verbosity=3) safeprint("Filtered: " + str(filtered), verbosity=3) toSend = pickle.dumps(filtered, 0) if type(toSend) != type("a".encode("utf-8")): safeprint("Test here") toSend = toSend.encode("utf-8") safeprint("Sending") key = send(toSend, conn, key) if exchange: send(peer_request, conn, key) received = recv(conn) safeprint("Received exchange", verbosity=1) safeprint(pickle.loads(received), verbosity=3) peerlist.extend(pickle.loads(received)) trimPeers() return key
def setup(): """Parses and stores the command line arguments given, and override default and saved settings""" from common.safeprint import safeprint parser = optparse.OptionParser() parser.add_option('-c', '--charity', dest='charity', default=None, action="store_true", help='Sets whether you accept rewardless bounties') parser.add_option( '-f', '--propagation-factor', dest='propagate_factor', default=None, type="int", help='Minimum funds:reward ratio you\'ll propagate bounties at') parser.add_option('-l', '--latency', dest='accept_latency', default=None, type="int", help='Maximum acceptable latency from a server') parser.add_option('-o', '--outbound-only', dest='outbound', default=None, action="store_false", help='Maximum acceptable latency from a server') parser.add_option('-p', '--listening-port', dest='port', default=None, type="int", help='Port for the program to listen at') parser.add_option( '-s', '--server', dest='server', default=None, action="store_true", help='Sets whether you operate as a server or client (Default: client)' ) parser.add_option( '-S', '--seed', dest='seed', default=None, action="store_true", help= 'Sets whether you operate as a seed server or client (Default: client)' ) parser.add_option( '-t', '--test', dest='test', default=None, action="store_true", help= 'Sets whether you operate in test mode, where loops have a determinate length.' ) parser.add_option( '-v', dest='verbose', default=None, action="count", help='Increments the level of verbosity (up to 3, default 1)') (options, args) = parser.parse_args() safeprint("options parsed") overrides = options.__dict__ loadSettings() saveSettings() kill = [] for key in overrides: #Remove keys with None, just to be safe if overrides.get(key) is None: kill += [key] for key in kill: overrides.pop(key) config.update(overrides)