def main(n_processes, fill, test, needs_server): for _ in xrange(n_processes): try: seed = random.choice(kads).node except IndexError: seed = None node = Node(random_32bytes(), port=next(ports)) dht = DHT(node, seed, context=context) kads.append(dht) processes.append(dht.run()) print "%s started." % node if fill: with open('./lipsum.txt') as f: result = re.findall( "[A-Z]{2,}(?![a-z])|[A-Z][a-z]+(?=[A-Z])|[\'\w\-]+", f.read()) for idx in xrange(1, len(result)): first, second = result[idx - 1], result[idx] random.choice(kads)[first] = second if test: n_failures = 0 for idx in xrange(1, len(result)): first, second = result[idx - 1], result[idx] try: print "%s -> %s" % (first, random.choice(kads)[first]) except KeyError: n_failures += 1 print "Failed %s times" % n_failures if needs_server: app.run()
def create(): node = Node(random_32bytes(), port=next(ports)) seed = random.choice(kads).node dht = DHT(node, seed, context=context) kads.append(dht) processes.append(dht.run()) return json.dumps({'n': len(processes) - 1})
def __init__(self, my_ip, my_port, market_id): self._log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) # Connect to database MONGODB_URI = 'mongodb://localhost:27017' _dbclient = MongoClient() self._db = _dbclient.openbazaar self._market_id = market_id self.nick_mapping = {} self._uri = "tcp://%s:%s" % (my_ip, my_port) # Set up self._setup_settings() self._dht = DHT(market_id, self.settings) self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), privkey=self.secret.decode('hex'), curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid) # Set up callbacks self.add_callback('ping', self._dht._on_ping) self.add_callback('findNode', self._dht._on_findNode) self.add_callback('findNodeResponse', self._dht._on_findNodeResponse)
def __init__(self, ob_ctx, db): self.ob_ctx = ob_ctx self.log = logging.getLogger( '[%s] %s' % (ob_ctx.market_id, self.__class__.__name__)) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) self.db = db self.bitmessage_api = None if (ob_ctx.bm_user, ob_ctx.bm_pass, ob_ctx.bm_port) != (None, None, -1): if not self._connect_to_bitmessage(): self.log.info('Bitmessage not installed or started') self.market_id = ob_ctx.market_id self.nick_mapping = {} self.uri = network_util.get_peer_url(ob_ctx.server_ip, ob_ctx.server_port) self.ip = ob_ctx.server_ip self.nickname = "" self.dev_mode = ob_ctx.dev_mode self.all_messages = ('hello', 'findNode', 'findNodeResponse', 'store') self._setup_settings() ob_ctx.market_id = self.market_id self.dht = DHT(self, self.market_id, self.settings, self.db) TransportLayer.__init__(self, ob_ctx, self.guid, self.nickname) self.start_listener() if ob_ctx.enable_ip_checker and not ob_ctx.seed_mode and not ob_ctx.dev_mode: self.start_ip_address_checker()
def test_dht_single_node(): node = DHT(start=True) assert all(node.declare_experts(['e1', 'e2', 'e3'], f"{LOCALHOST}:{1337}")) for expert in node.get_experts(['e3', 'e2']): assert expert.endpoint == f"{LOCALHOST}:{1337}" assert node.first_k_active(['e0', 'e1', 'e3', 'e5', 'e2'], k=2) == ['e1', 'e3']
def main(n_processes, fill, test, needs_server): for _ in xrange(n_processes): try: seed = random.choice(kads).node except IndexError: seed = None node = Node(random_32bytes(), port=next(ports)) dht = DHT(node, seed, context=context) kads.append(dht) processes.append(dht.run()) print "%s started." % node if fill: with open('./lipsum.txt') as f: result = re.findall("[A-Z]{2,}(?![a-z])|[A-Z][a-z]+(?=[A-Z])|[\'\w\-]+", f.read()) for idx in xrange(1, len(result)): first, second = result[idx-1], result[idx] random.choice(kads)[first] = second if test: n_failures = 0 for idx in xrange(1, len(result)): first, second = result[idx-1], result[idx] try: print "%s -> %s" % (first, random.choice(kads)[first]) except KeyError: n_failures += 1 print "Failed %s times" % n_failures if needs_server: app.run()
def create(): node = Node(random_32bytes(), port=next(ports)) seed = random.choice(kads).node dht = DHT(node, seed, context=context) kads.append(dht) processes.append(dht.run()) return json.dumps({ 'n': len(processes)-1 })
def __init__(self, my_ip, my_port, market_id, db, bm_user=None, bm_pass=None, bm_port=None, seed_mode=0, dev_mode=False, disable_ip_update=False): self.log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) # Connect to database self.db = db self.bitmessage_api = None if (bm_user, bm_pass, bm_port) != (None, None, None): if not self._connect_to_bitmessage(bm_user, bm_pass, bm_port): self.log.info('Bitmessage not installed or started') try: socket.inet_pton(socket.AF_INET6, my_ip) my_uri = "tcp://[%s]:%s" % (my_ip, my_port) except (socket.error, ValueError): my_uri = "tcp://%s:%s" % (my_ip, my_port) self.market_id = market_id self.nick_mapping = {} self.uri = my_uri self.ip = my_ip self.nickname = "" self._dev_mode = dev_mode # Set up self._setup_settings() self.dht = DHT(self, self.market_id, self.settings, self.db) # self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), # privkey=self.secret.decode('hex'), # curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid, self.nickname) self.setup_callbacks() self.listen(self.pubkey) if seed_mode == 0 and not dev_mode and not disable_ip_update: self.start_ip_address_checker()
def humid_temp_sensor(read): th = DHT('P23', 0) time.sleep(2) while read: result = th.read() while not result.is_valid(): time.sleep(.5) result = th.read() temperature = result.temperature humidity = result.humidity read = False return (temperature, humidity)
def test_hivemind_dht(): peers = [DHT(start=True)] for i in range(10): neighbors_i = [ f'{LOCALHOST}:{node.port}' for node in random.sample(peers, min(3, len(peers))) ] peers.append(DHT(initial_peers=neighbors_i, start=True)) you: DHT = random.choice(peers) theguyshetoldyounottoworryabout: DHT = random.choice(peers) expert_uids = [str(uuid.uuid4()) for _ in range(110)] batch_size = 10 for batch_start in range(0, len(expert_uids), batch_size): you.declare_experts(expert_uids[batch_start:batch_start + batch_size], 'localhost', 1234) found = theguyshetoldyounottoworryabout.get_experts( random.sample(expert_uids, 5) + ['foo', 'bar']) assert all(res is not None for res in found[:-2]), "Could not find some existing experts" assert all(res is None for res in found[-2:]), "Found non-existing experts" that_guys_expert, that_guys_port = str(uuid.uuid4()), random.randint( 1000, 9999) theguyshetoldyounottoworryabout.declare_experts( [that_guys_expert], f'that_host:{that_guys_port}') you_notfound, you_found = you.get_experts(['foobar', that_guys_expert]) assert isinstance(you_found, dht.RemoteExpert) assert you_found.endpoint == f'that_host:{that_guys_port}' # test first_k_active assert theguyshetoldyounottoworryabout.first_k_active( expert_uids, k=10) == expert_uids[:10] some_permuted_experts = random.sample(expert_uids, k=32) assert theguyshetoldyounottoworryabout.first_k_active( some_permuted_experts, k=32) == some_permuted_experts assert theguyshetoldyounottoworryabout.first_k_active( some_permuted_experts, k=1) == some_permuted_experts[:1] fake_and_real_experts = list( chain(*zip([str(uuid.uuid4()) for _ in some_permuted_experts], some_permuted_experts))) assert theguyshetoldyounottoworryabout.first_k_active( fake_and_real_experts, k=9) == some_permuted_experts[:9] for peer in peers: peer.shutdown()
def __init__(self, my_ip, my_port, market_id, bm_user=None, bm_pass=None, bm_port=None): self._log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) # Connect to database MONGODB_URI = 'mongodb://localhost:27017' _dbclient = MongoClient() self._db = _dbclient.openbazaar self._bitmessage_api = None if (bm_user, bm_pass, bm_port) != (None, None, None): print (bm_user, bm_pass, bm_port) if not self._connect_to_bitmessage(bm_user, bm_pass, bm_port): self._log.info('Bitmessage not available') self._market_id = market_id self.nick_mapping = {} self._uri = "tcp://%s:%s" % (my_ip, my_port) # Set up self._setup_settings() self._dht = DHT(self, market_id, self.settings) self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), privkey=self.secret.decode('hex'), curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid) # Set up callbacks self.add_callback('hello', self._ping) self.add_callback('findNode', self._findNode) self.add_callback('findNodeResponse', self._findNodeResponse) self.add_callback('store', self._storeValue) self.listen(self.pubkey)
def __init__(self, my_ip, my_port, market_id): self._log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) # Connect to database MONGODB_URI = 'mongodb://localhost:27017' _dbclient = MongoClient() self._db = _dbclient.openbazaar self._market_id = market_id self.nick_mapping = {} self._uri = "tcp://%s:%s" % (my_ip, my_port) # Set up self._setup_settings() self._dht = DHT(self, market_id, self.settings) self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), privkey=self.secret.decode('hex'), curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid) # Set up callbacks self.add_callback('hello', self._ping) self.add_callback('findNode', self._findNode) self.add_callback('findNodeResponse', self._findNodeResponse) self.add_callback('store', self._storeValue)
def __init__(self, lcd_rs_pin, lcd_e_pin, lcd_db_pins, button_pin, dht_pin): # LCD self.lcd_rs_pin = lcd_rs_pin self.lcd_e_pin = lcd_e_pin self.lcd_db_pins = lcd_db_pins # Button self.button_pin = button_pin # DHT self.dht_type = Adafruit_DHT.DHT22 self.dht_pin = dht_pin self.dht = DHT(self.dht_pin, self.dht_type) self.lcd = HD44780(self.lcd_e_pin, self.lcd_rs_pin, self.lcd_db_pins) self.cur_transport = 0 self.transports = TRANSPORTS_TO_SHOW[self.cur_transport]
def __init__(self, my_ip, my_port, market_id, bm_user=None, bm_pass=None, bm_port=None, seed_mode=0, dev_mode=False): self._log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) # Connect to database MONGODB_URI = 'mongodb://localhost:27017' _dbclient = MongoClient() self._db = _dbclient.openbazaar self._bitmessage_api = None if (bm_user, bm_pass, bm_port) != (None, None, None): if not self._connect_to_bitmessage(bm_user, bm_pass, bm_port): self._log.info('Bitmessage not available') self._market_id = market_id self.nick_mapping = {} self._uri = "tcp://%s:%s" % (my_ip, my_port) self._ip = my_ip self._nickname = "" # Set up self._setup_settings() self._dht = DHT(self, market_id, self.settings) self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), privkey=self.secret.decode('hex'), curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid, self._nickname) # Set up callbacks self.add_callback('hello', self._ping) self.add_callback('findNode', self._findNode) self.add_callback('findNodeResponse', self._findNodeResponse) self.add_callback('store', self._storeValue) self.listen(self.pubkey) def cb(): r = requests.get(r'http://icanhazip.com') if r and hasattr(r,'text'): ip = r.text ip = ip.strip(' \t\n\r') if ip != self._ip: self._ip = ip self._uri = 'tcp://%s:%s' % (self._ip, self._port) self.stream.close() self.listen(self.pubkey) else: self._log.error('Could not get ip') if seed_mode == 0 and not dev_mode: # Check IP periodically for changes self.caller = PeriodicCallback(cb, 5000, ioloop.IOLoop.instance()) self.caller.start()
def init_sensors(): adc = machine.ADC() # create an ADC object adc.vref(1157) # Set calibration moist_sense1 = adc.channel(pin='P16', attn = machine.ADC.ATTN_11DB) # create an analog pin on P16 moist_sense2 = adc.channel(pin='P18', attn = machine.ADC.ATTN_11DB) # create an analog pin on P18 temp_humid_sens = DHT(machine.Pin('P23', mode=machine.Pin.OPEN_DRAIN), 0) time.sleep(2) return moist_sense1, moist_sense2, temp_humid_sens
def __init__( self, my_ip, my_port, market_id, db, bm_user=None, bm_pass=None, bm_port=None, seed_mode=0, dev_mode=False, disable_ip_update=False, ): self.log = logging.getLogger("[%s] %s" % (market_id, self.__class__.__name__)) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) # Connect to database self.db = db self.bitmessage_api = None if (bm_user, bm_pass, bm_port) != (None, None, None): if not self._connect_to_bitmessage(bm_user, bm_pass, bm_port): self.log.info("Bitmessage not installed or started") try: socket.inet_pton(socket.AF_INET6, my_ip) my_uri = "tcp://[%s]:%s" % (my_ip, my_port) except (socket.error, ValueError): my_uri = "tcp://%s:%s" % (my_ip, my_port) self.market_id = market_id self.nick_mapping = {} self.uri = my_uri self.ip = my_ip self.nickname = "" self._dev_mode = dev_mode # Set up self._setup_settings() self.dht = DHT(self, self.market_id, self.settings, self.db) # self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), # privkey=self.secret.decode('hex'), # curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid, self.nickname) self.setup_callbacks() self.listen(self.pubkey) if seed_mode == 0 and not dev_mode and not disable_ip_update: self.start_ip_address_checker()
def Main(): parser = argparse.ArgumentParser() parser.add_argument("ip", help="Your IP address") parser.add_argument("port", help="Port to run dht on") parser.add_argument("region", help="Your region") args = parser.parse_args() dht = DHT(args.ip, int(args.port), args.region) while True: time.sleep(0.1) pass
def __init__(self, root, bootstrap_node, local_ip='localhost', local_port=8000): self.realroot = realpath(root) self.rwlock = Lock() self.dht = DHT(bootstrap_node, local_ip, local_port) time.sleep(3) # walk dir and update dht files = utils.rgetdir(self.realroot) for path, newval in files.iteritems(): newold = self.dht[path] if newold: utils.rdict_update(newold, newval) self.dht[path] = newold else: self.dht[path] = newval print "done mounting"
class DhtServer: def __init__(self, port): self.dht = DHT(port) self.myPort = port self.fila = queue.Queue() self.t = threading.Thread(target=self.enviando) self.t.start() def enviando(self): while True: time.sleep(1) print('indo travar') try: key, value, peer = self.fila.get(block=False, timeout=2) print('voltando travar') try: requests.get(peer + '/dht/' + key + '/' + value) except Exception as e: print(peer + '/dht/' + key + '/' + value, '<<ERRO:', e) except: time.sleep(1) def envia_dht(self, key, value, peer): self.fila.put((key, value, peer)) # usar este método para fazer as validações necessárias referente a inserção na dht. def insert_dht(self, key, value, peers): if not self.dht.lookup(key): self.dht.insert(key, value) for p in peers: a = urlparse(p) if a.port != int(self.myPort): self.envia_dht(key, value, p) def lookup_dht(self, key): #regra para busca return self.dht.lookup(key) def dht_lookup(self, key): return self.dht.lookup(key) def dht_lookup_dump(self, key): return json.dumps(self.lookup_dht(key)) def dht_insert_dump(self, key, value): self.dht.insert(key, value) return json.dumps(key, value)
def __init__(self, my_ip, my_port, market_id, db, bm_user=None, bm_pass=None, bm_port=None, seed_mode=0, dev_mode=False): self._log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) # Connect to database self._db = db self._bitmessage_api = None if (bm_user, bm_pass, bm_port) != (None, None, None): if not self._connect_to_bitmessage(bm_user, bm_pass, bm_port): self._log.info('Bitmessage not installed or started') self._market_id = market_id self.nick_mapping = {} self._uri = "tcp://%s:%s" % (my_ip, my_port) self._ip = my_ip self._nickname = "" self._dev_mode = dev_mode # Set up self._setup_settings() self._dht = DHT(self, self._market_id, self.settings, self._db) # self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), # privkey=self.secret.decode('hex'), # curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid, self._nickname) self.setup_callbacks() self.listen(self.pubkey) if seed_mode == 0 and not dev_mode: self.start_ip_address_checker()
def __init__(self, ob_ctx, db): self.ob_ctx = ob_ctx self.log = logging.getLogger( '[%s] %s' % (ob_ctx.market_id, self.__class__.__name__) ) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) self.db = db self.bitmessage_api = None if (ob_ctx.bm_user, ob_ctx.bm_pass, ob_ctx.bm_port) != (None, None, -1): if not self._connect_to_bitmessage(): self.log.info('Bitmessage not installed or started') self.market_id = ob_ctx.market_id self.nick_mapping = {} self.uri = network_util.get_peer_url(ob_ctx.server_ip, ob_ctx.server_port) self.ip = ob_ctx.server_ip self.nickname = "" self.dev_mode = ob_ctx.dev_mode self.all_messages = ( 'hello', 'findNode', 'findNodeResponse', 'store' ) self._setup_settings() ob_ctx.market_id = self.market_id self.dht = DHT(self, self.market_id, self.settings, self.db) TransportLayer.__init__(self, ob_ctx, self.guid, self.nickname) self.start_listener() if ob_ctx.enable_ip_checker and not ob_ctx.seed_mode and not ob_ctx.dev_mode: self.start_ip_address_checker()
def verificando_se_tem_dados_local(token,ID_INSTITUTION): while(DHT.tamanhoArray()[0][0] > 0): print "Coletando dados do banco" alldata = DHT.loadAllFromDatabase() json_array = api.montar_array(alldata) result = api.post_dado_formatado(token,json_array,ID_INSTITUTION) if (result == 201): print "201 Dados armazenados localmente foram enviados com sucesso" if (result == 409): print "dado já foi enviado,nao e possivel salva-lo" if (result == 207): print "Status:207, Dados armazenados localmente foram enviados com sucesso" for dados in alldata: DHT.deleteDataById(dados[0]) print "Dado: "+str(dados[0])+ " deletado com sucesso!" else: print "Banco de dados esta vazio!" if(DHT.tamanhoArray()[0][0] == 0): DHT.resetarSequence() print "Resetando Sequencia do PGSQL"
class CryptoTransportLayer(TransportLayer): def __init__(self, my_ip, my_port, market_id, db, bm_user=None, bm_pass=None, bm_port=None, seed_mode=0, dev_mode=False): self.log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) # Connect to database self.db = db self.bitmessage_api = None if (bm_user, bm_pass, bm_port) != (None, None, None): if not self._connect_to_bitmessage(bm_user, bm_pass, bm_port): self.log.info('Bitmessage not installed or started') try: socket.inet_pton(socket.AF_INET6, my_ip) my_uri = "tcp://[%s]:%s" % (my_ip, my_port) except socket.error: my_uri = "tcp://%s:%s" % (my_ip, my_port) self.market_id = market_id self.nick_mapping = {} self.uri = my_uri self.ip = my_ip self.nickname = "" self._dev_mode = dev_mode # Set up self._setup_settings() self.dht = DHT(self, self.market_id, self.settings, self.db) # self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), # privkey=self.secret.decode('hex'), # curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid, self.nickname) self.setup_callbacks() self.listen(self.pubkey) if seed_mode == 0 and not dev_mode: self.start_ip_address_checker() def setup_callbacks(self): self.add_callbacks([('hello', self._ping), ('findNode', self._find_node), ('findNodeResponse', self._find_node_response), ('store', self._store_value)]) def start_ip_address_checker(self): '''Checks for possible public IP change''' self.caller = PeriodicCallback(self._ip_updater_periodic_callback, 5000, ioloop.IOLoop.instance()) self.caller.start() def _ip_updater_periodic_callback(self): try: r = requests.get('https://icanhazip.com') if r and hasattr(r, 'text'): ip = r.text ip = ip.strip(' \t\n\r') if ip != self.ip: self.ip = ip try: socket.inet_pton(socket.AF_INET6, self.ip) my_uri = 'tcp://[%s]:%s' % (self.ip, self.port) except socket.error: my_uri = 'tcp://%s:%s' % (self.ip, self.port) self.uri = my_uri self.stream.close() self.listen(self.pubkey) self.dht._iterativeFind(self.guid, [], 'findNode') else: self.log.error('Could not get IP') except Exception as e: self.log.error('[Requests] error: %s' % e) def save_peer_to_db(self, peer_tuple): uri = peer_tuple[0] pubkey = peer_tuple[1] guid = peer_tuple[2] nickname = peer_tuple[3] # Update query self.db.deleteEntries("peers", {"uri": uri, "guid": guid}, "OR") # if len(results) > 0: # self.db.updateEntries("peers", {"id": results[0]['id']}, {"market_id": self.market_id, "uri": uri, "pubkey": pubkey, "guid": guid, "nickname": nickname}) # else: if guid is not None: self.db.insertEntry( "peers", { "uri": uri, "pubkey": pubkey, "guid": guid, "nickname": nickname, "market_id": self.market_id }) def _connect_to_bitmessage(self, bm_user, bm_pass, bm_port): # Get bitmessage going # First, try to find a local instance result = False try: self.log.info( '[_connect_to_bitmessage] Connecting to Bitmessage on port %s' % bm_port) self.bitmessage_api = xmlrpclib.ServerProxy( "http://{}:{}@localhost:{}/".format(bm_user, bm_pass, bm_port), verbose=0) result = self.bitmessage_api.add(2, 3) self.log.info( "[_connect_to_bitmessage] Bitmessage API is live".format( result)) # If we failed, fall back to starting our own except Exception as e: self.log.info( "Failed to connect to bitmessage instance: {}".format(e)) self.bitmessage_api = None # self._log.info("Spawning internal bitmessage instance") # # Add bitmessage submodule path # sys.path.insert(0, os.path.join( # os.path.dirname(__file__), '..', 'pybitmessage', 'src')) # import bitmessagemain as bitmessage # bitmessage.logger.setLevel(logging.WARNING) # bitmessage_instance = bitmessage.Main() # bitmessage_instance.start(daemon=True) # bminfo = bitmessage_instance.getApiAddress() # if bminfo is not None: # self._log.info("Started bitmessage daemon at %s:%s".format( # bminfo['address'], bminfo['port'])) # bitmessage_api = xmlrpclib.ServerProxy("http://{}:{}@{}:{}/".format( # bm_user, bm_pass, bminfo['address'], bminfo['port'])) # else: # self._log.info("Failed to start bitmessage dameon") # self._bitmessage_api = None return result def _checkok(self, msg): self.log.info('Check ok') def get_guid(self): return self.guid def get_dht(self): return self.dht def get_bitmessage_api(self): return self.bitmessage_api def get_market_id(self): return self.market_id # def get_myself(self): # return self._myself def _ping(self, msg): self.log.info('Pinged %s ' % json.dumps(msg, ensure_ascii=False)) # # pinger = CryptoPeerConnection(self, msg['uri'], msg['pubkey'], msg['senderGUID']) # pinger.send_raw(json.dumps( # {"type": "hello_response", # "senderGUID": self.guid, # "uri": self.uri, # "senderNick": self.nickname, # "pubkey": self.pubkey, # })) def _store_value(self, msg): self.dht._on_storeValue(msg) def _find_node(self, msg): self.dht.on_find_node(msg) def _find_node_response(self, msg): self.dht.on_findNodeResponse(self, msg) def _setup_settings(self): try: self.settings = self.db.selectEntries( "settings", {"market_id": self.market_id}) except (OperationalError, DatabaseError) as e: print e raise SystemExit( "database file %s corrupt or empty - cannot continue" % self.db.db_path) if len(self.settings) == 0: self.settings = {"market_id": self.market_id, "welcome": "enable"} self.db.insertEntry("settings", self.settings) else: self.settings = self.settings[0] # Generate PGP key during initial setup or if previous PGP gen failed if not ('PGPPubKey' in self.settings and self.settings["PGPPubKey"]): try: self.log.info( 'Generating PGP keypair. This may take several minutes...') print 'Generating PGP keypair. This may take several minutes...' gpg = gnupg.GPG() input_data = gpg.gen_key_input( key_type="RSA", key_length=2048, name_email='*****@*****.**', name_comment="Autogenerated by Open Bazaar", passphrase="P@ssw0rd") assert input_data is not None key = gpg.gen_key(input_data) assert key is not None pubkey_text = gpg.export_keys(key.fingerprint) newsettings = { "PGPPubKey": pubkey_text, "PGPPubkeyFingerprint": key.fingerprint } self.db.updateEntries("settings", {"market_id": self.market_id}, newsettings) self.settings.update(newsettings) self.log.info('PGP keypair generated.') except Exception as e: self.log.error("Encountered a problem with GPG: %s" % e) raise SystemExit("Encountered a problem with GPG: %s" % e) if not ('pubkey' in self.settings and self.settings['pubkey']): # Generate Bitcoin keypair self._generate_new_keypair() if not ('bitmessage' in self.settings and self.settings['bitmessage']): # Generate Bitmessage address if self.bitmessage_api is not None: self._generate_new_bitmessage_address() if not ('nickname' in self.settings and self.settings['nickname']): newsettings = {'nickname': 'Default'} self.db.updateEntries('settings', {"market_id": self.market_id}, newsettings) self.settings.update(newsettings) self.nickname = self.settings[ 'nickname'] if 'nickname' in self.settings else "" self.secret = self.settings[ 'secret'] if 'secret' in self.settings else "" self.pubkey = self.settings[ 'pubkey'] if 'pubkey' in self.settings else "" self.privkey = self.settings.get('privkey') self.btc_pubkey = privkey_to_pubkey(self.privkey) self.guid = self.settings['guid'] if 'guid' in self.settings else "" self.sin = self.settings['sin'] if 'sin' in self.settings else "" self.bitmessage = self.settings[ 'bitmessage'] if 'bitmessage' in self.settings else "" self._myself = ec.ECC(pubkey=pubkey_to_pyelliptic( self.pubkey).decode('hex'), raw_privkey=self.secret.decode('hex'), curve='secp256k1') self.log.debug('Retrieved Settings: \n%s', pformat(self.settings)) def _generate_new_keypair(self): secret = str(random.randrange(2**256)) self.secret = hashlib.sha256(secret).hexdigest() self.pubkey = privtopub(self.secret) self.privkey = random_key() print 'PRIVATE KEY: ', self.privkey self.btc_pubkey = privtopub(self.privkey) print 'PUBLIC KEY: ', self.btc_pubkey # Generate SIN sha_hash = hashlib.sha256() sha_hash.update(self.pubkey) ripe_hash = hashlib.new('ripemd160') ripe_hash.update(sha_hash.digest()) self.guid = ripe_hash.digest().encode('hex') self.sin = obelisk.EncodeBase58Check('\x0F\x02%s' + ripe_hash.digest()) newsettings = { "secret": self.secret, "pubkey": self.pubkey, "privkey": self.privkey, "guid": self.guid, "sin": self.sin } self.db.updateEntries("settings", {"market_id": self.market_id}, newsettings) self.settings.update(newsettings) def _generate_new_bitmessage_address(self): # Use the guid generated previously as the key self.bitmessage = self.bitmessage_api.createRandomAddress( self.guid.encode('base64'), False, 1.05, 1.1111) newsettings = {"bitmessage": self.bitmessage} self.db.updateEntries("settings", {"market_id": self.market_id}, newsettings) self.settings.update(newsettings) def join_network(self, seed_peers=[], callback=lambda msg: None): self.log.info('Joining network') known_peers = [] # Connect up through seed servers for idx, seed in enumerate(seed_peers): try: socket.inet_pton(socket.AF_INET6, seed) seed_peers[idx] = "tcp://[%s]:12345" % seed except socket.error: seed_peers[idx] = "tcp://%s:12345" % seed # Connect to persisted peers db_peers = self.get_past_peers() known_peers = list(set(seed_peers)) + list(set(db_peers)) print 'known_peers', known_peers self.connect_to_peers(known_peers) # Populate routing table by searching for self if len(known_peers) > 0: self.search_for_my_node() if callback is not None: callback('Joined') def get_past_peers(self): peers = [] result = self.db.selectEntries("peers", {"market_id": self.market_id}) for peer in result: peers.append(peer['uri']) return peers def search_for_my_node(self): print 'Searching for myself' self.dht._iterativeFind(self.guid, self.dht.knownNodes, 'findNode') def connect_to_peers(self, known_peers): for known_peer in known_peers: t = Thread(target=self.dht.add_peer, args=( self, known_peer, )) t.start() def get_crypto_peer(self, guid=None, uri=None, pubkey=None, nickname=None, callback=None): if guid == self.guid: self.log.error('Cannot get CryptoPeerConnection for your own node') return self.log.debug('Getting CryptoPeerConnection' + '\nGUID:%s\nURI:%s\nPubkey:%s\nNickname:%s' % (guid, uri, pubkey, nickname)) return connection.CryptoPeerConnection(self, uri, pubkey, guid=guid, nickname=nickname, callback=callback) def addCryptoPeer(self, peer_to_add): foundOutdatedPeer = False for idx, peer in enumerate(self.dht.activePeers): if (peer.address, peer.guid, peer.pub) == \ (peer_to_add.address, peer_to_add.guid, peer_to_add.pub): self.log.info('Found existing peer, not adding.') return if peer.guid == peer_to_add.guid or \ peer.pub == peer_to_add.pub or \ peer.address == peer_to_add.address: foundOutdatedPeer = True self.log.info('Found an outdated peer') # Update existing peer self.activePeers[idx] = peer_to_add self.dht.add_peer(self, peer_to_add.address, peer_to_add.pub, peer_to_add.guid, peer_to_add.nickname) if not foundOutdatedPeer and peer_to_add.guid != self.guid: self.log.info('Adding crypto peer at %s' % peer_to_add.nickname) self.dht.add_peer(self, peer_to_add.address, peer_to_add.pub, peer_to_add.guid, peer_to_add.nickname) def get_profile(self): peers = {} self.settings = self.db.selectEntries("settings", {"market_id": self.market_id})[0] for uri, peer in self.peers.iteritems(): if peer.pub: peers[uri] = peer.pub.encode('hex') return { 'uri': self.uri, 'pub': self._myself.get_pubkey().encode('hex'), 'nickname': self.nickname, 'peers': peers } def respond_pubkey_if_mine(self, nickname, ident_pubkey): if ident_pubkey != self.pubkey: self.log.info("Public key does not match your identity") return # Return signed pubkey pubkey = self._myself.pubkey ec_key = obelisk.EllipticCurveKey() ec_key.set_secret(self.secret) digest = obelisk.Hash(pubkey) signature = ec_key.sign(digest) # Send array of nickname, pubkey, signature to transport layer self.send(proto_response_pubkey(nickname, pubkey, signature)) def pubkey_exists(self, pub): for uri, peer in self.peers.iteritems(): self.log.info('PEER: %s Pub: %s' % (peer.pub.encode('hex'), pub.encode('hex'))) if peer.pub.encode('hex') == pub.encode('hex'): return True return False def create_peer(self, uri, pub, node_guid): if pub: pub = pub.decode('hex') # Create the peer if public key is not already in the peer list # if not self.pubkey_exists(pub): self.peers[uri] = connection.CryptoPeerConnection( self, uri, pub, node_guid) # Call 'peer' callbacks on listeners self.trigger_callbacks('peer', self.peers[uri]) # else: # print 'Pub Key is already in peer list' def send(self, data, send_to=None, callback=lambda msg: None): self.log.debug("Outgoing Data: %s %s" % (data, send_to)) # Directed message if send_to is not None: peer = self.dht.routingTable.getContact(send_to) if not peer: for activePeer in self.dht.activePeers: if activePeer.guid == send_to: peer = activePeer break # peer = CryptoPeerConnection(msg['uri']) if peer: self.log.debug('Directed Data (%s): %s' % (send_to, data)) try: peer.send(data, callback=callback) except Exception as e: self.log.error('Not sending message directly to peer %s' % e) else: self.log.error('No peer found') else: # FindKey and then send for peer in self.dht.activePeers: try: peer = self.dht.routingTable.getContact(peer.guid) data['senderGUID'] = self.guid data['pubkey'] = self.pubkey def cb(msg): self.log.debug('Message Back: \n%s' % pformat(msg)) peer.send(data, cb) except: self.log.info("Error sending over peer!") traceback.print_exc() def send_enc(self, uri, msg): peer = self.peers[uri] pub = peer.pub # Now send a hello message to the peer if pub: self.log.info("Sending encrypted [%s] message to %s" % (msg['type'], uri)) peer.send(msg) else: # Will send clear profile on initial if no pub self.log.info("Sending unencrypted [%s] message to %s" % (msg['type'], uri)) self.peers[uri].send_raw(json.dumps(msg)) def _init_peer(self, msg): uri = msg['uri'] pub = msg.get('pub') nickname = msg.get('nickname') msg_type = msg.get('type') guid = msg['guid'] if not self.valid_peer_uri(uri): self.log.error("Invalid Peer: %s " % uri) return if uri not in self.peers: # Unknown peer self.log.info('Add New Peer: %s' % uri) self.create_peer(uri, pub, guid) if not msg_type: self.send_enc(uri, hello_request(self.get_profile())) elif msg_type == 'hello_request': self.send_enc(uri, hello_response(self.get_profile())) else: # Known peer if pub: # test if we have to update the pubkey if not self.peers[uri].pub: self.log.info("Setting public key for seed node") self.peers[uri].pub = pub.decode('hex') self.trigger_callbacks('peer', self.peers[uri]) if self.peers[uri].pub != pub.decode('hex'): self.log.info("Updating public key for node") self.peers[uri].nickname = nickname self.peers[uri].pub = pub.decode('hex') self.trigger_callbacks('peer', self.peers[uri]) if msg_type == 'hello_request': # reply only if necessary self.send_enc(uri, hello_response(self.get_profile())) def _on_message(self, msg): # here goes the application callbacks # we get a "clean" msg which is a dict holding whatever # self.log.info("[On Message] Data received: %s" % msg) pubkey = msg.get('pubkey') uri = msg.get('uri') ip = urlparse(uri).hostname port = urlparse(uri).port guid = msg.get('senderGUID') nickname = msg.get('senderNick')[:120] self.dht.add_known_node((ip, port, guid, nickname)) self.log.info('ON MESSAGE %s' % json.dumps(msg, ensure_ascii=False)) self.dht.add_peer(self, uri, pubkey, guid, nickname) self.log.debug('Callbacks %s' % self.callbacks) t = Thread(target=self.trigger_callbacks, args=( msg['type'], msg, )) t.start() def _on_raw_message(self, serialized): try: # Decompress message serialized = zlib.decompress(serialized) msg = json.loads(serialized) self.log.info("Message Received [%s]" % msg.get('type', 'unknown')) if msg.get('type') is None: data = msg.get('data').decode('hex') sig = msg.get('sig').decode('hex') try: cryptor = makePrivCryptor(self.secret) try: data = cryptor.decrypt(data) except Exception as e: self.log.info('Exception: %s' % e) self.log.debug('Signature: %s' % sig.encode('hex')) self.log.debug('Signed Data: %s' % data) # Check signature data_json = json.loads(data) sigCryptor = makePubCryptor(data_json['pubkey']) if sigCryptor.verify(sig, data): self.log.info('Verified') else: self.log.error( 'Message signature could not be verified %s' % msg) # return msg = json.loads(data) self.log.debug('Message Data %s ' % msg) except Exception as e: self.log.error('Could not decrypt message properly %s' % e) except ValueError: try: # Encrypted? try: msg = self._myself.decrypt(serialized) msg = json.loads(msg) self.log.info("Decrypted Message [%s]" % msg.get('type', 'unknown')) except: self.log.error("Could not decrypt message: %s" % msg) return except: self.log.error('Message probably sent using incorrect pubkey') return if msg.get('type') is not None: self._on_message(msg) else: self.log.error('Received a message with no type') def shutdown(self): print "CryptoTransportLayer.shutdown()!" try: TransportLayer.shutdown(self) print "CryptoTransportLayer.shutdown(): ZMQ sockets destroyed." except Exception as e: self.log.error("Transport shutdown error: " + e.message) print "Notice: explicit DHT Shutdown not implemented." try: self.bitmessage_api.close() except Exception as e: # might not even be open, not much more we can do on our way out if exception thrown here. self.log.error( "Could not shutdown bitmessage_api's ServerProxy. " + e.message)
import time from machine import Pin from dht import DHT th = DHT(Pin('P23', mode=Pin.OPEN_DRAIN), 0) time.sleep(2) def read_data(): result = th.read() while not result.is_valid(): time.sleep(.5) result = th.read() return(result.temperature - 5,result.humidity - 45)
class MasterServer(object): HOST = '127.0.0.1' PORT = 5001 DHT = DHT(50) def __init__(self): print "servidor rodando..." self.waitForConnection() def waitForConnection(self): socketTCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM) orig = (self.HOST, self.PORT) socketTCP.bind(orig) socketTCP.listen(1) while True: con, client = socketTCP.accept() threading.Thread(target=self.clientConnected, args=(con, client)).start() socketTCP.close() def clientConnected(self, socketTCPThread, client): while True: try: #socketTCPThread.settimeout(60) data = socketTCPThread.recv(2048) request = json.loads(data) self.getRequestStatus(request, socketTCPThread, client) except socket.error as msg: print 'Error code: ' + str(msg[0]) + ', Error message: ' + str( msg[1]) socketTCPThread.close() self.DHT.logOutUser(client) return False except: print 'ocorreu algum erro desconhecido, matando thread' socketTCPThread.close() self.DHT.logOutUser(client) return False def getRequestStatus(self, request, socketTCP, client): try: type = request['type'] if type == Define.REGISTER: self.registerUser(request, socketTCP, client) elif type == Define.LOGIN: self.logUser(request, socketTCP, client) elif type == 'keepalive': self.userStillActive(request, socketTCP, client) elif type == Define.UPLOAD: self.uploadFile(request, socketTCP, client) elif type == Define.DOWNLOAD: self.downloadFile(request, socketTCP, client) elif type == Define.DIRINFO: self.sendDirectoriesTree(socketTCP) elif type == Define.INFOFILES: self.infoFiles(request, socketTCP, client) elif type == Define.CREATEDIR: self.createDir(request, socketTCP, client) elif type == Define.RENAMEDIR: self.renameDir(request, socketTCP, client) elif type == Define.REMOVEDIR: self.removeDir(request, socketTCP, client) elif type == Define.REMOVEFILE: self.removeFile(request, socketTCP, client) elif type == Define.RENAMEFILE: self.renameFile(request, socketTCP, client) else: response = dict(responseStatus=Define.ERROR, errormsg='undefined_type') responseJSON = json.dumps(response) socketTCP.send(responseJSON) except: response = dict(responseStatus=Define.ERROR, errormsg='unknown_error') responseJSON = json.dumps(response) socketTCP.send(responseJSON) def registerUser(self, request, socketTCP, client): username = request['username'] id = self.DHT.registerUser(username, client) if id >= 0: response = dict(responseStatus=Define.SUCCESS, id=id) responseJSON = json.dumps(response) socketTCP.send(responseJSON) self.DHT.rebalancing() elif id == -1: response = dict(responseStatus=Define.ERROR, errormsg='dht_overflow') responseJSON = json.dumps(response) socketTCP.send(responseJSON) elif id == -2: response = dict(responseStatus=Define.ERROR, errormsg='user_already_registered') responseJSON = json.dumps(response) socketTCP.send(responseJSON) def logUser(self, request, socketTCP, client): username = request['username'] id = self.DHT.logUser(username, client) if id >= 0: response = dict(responseStatus=Define.SUCCESS, id=id) responseJSON = json.dumps(response) socketTCP.send(responseJSON) self.DHT.sendFilesToUser(id) elif id == -1: response = dict(responseStatus=Define.USERNOTREGISTER, errormsg='user_not_found') responseJSON = json.dumps(response) socketTCP.send(responseJSON) def userStillActive(self, request, socketTCP, client): pass # if self.DHT.getIDForIPPort(client): # response = dict(responseStatus = Define.SUCCESS) # responseJSON = json.dumps(response) # socketTCP.send(responseJSON) # else: # response = dict(responseStatus = Define.USERUNAUTHENTICATED, message = 'you_are_not_logged') # responseJSON = json.dumps(response) # socketTCP.send(responseJSON) def uploadFile(self, request, socketTCP, client): path = str(request['path']) data = str(request['data']) if self.DHT.saveFileAtPath(path, data, client): #salvou response = dict(responseStatus=Define.SUCCESS) responseJSON = json.dumps(response) socketTCP.send(responseJSON) self.DHT.rebalancing() else: response = dict(responseStatus=Define.ERROR, errormsg='error_processing_file') responseJSON = json.dumps(response) socketTCP.send(responseJSON) def downloadFile(self, request, socketTCP, client): method = request['method'] if method == 'hash': self.sendFileToUser(request, socketTCP, client) else: self.sendHostThatWillUpdloadFileToUser(request, socketTCP, client) def sendFileToUser(self, request, socketTCP, client): hash = request['hash'] file = self.DHT.getBase64StringForFileWithHash(hash) response = dict(responseStatus=Define.SUCCESS, type='file', data=file) responseJSON = json.dumps(response) socketTCP.send(responseJSON) def sendHostThatWillUpdloadFileToUser(self, request, socketTCP, client): path = request['path'] hash = self.DHT.getHashForPath(path) id = self.DHT.getUserResponsableForFile(hash) if self.DHT.checkIfUserActive(id): (ip, port) = self.DHT.getIPPortForID(id) response = dict(responseStatus=Define.SUCCESS, type='node', node=(ip, 6000 + id), hashName=hash) responseJSON = json.dumps(response) socketTCP.send(responseJSON) else: request.update(hash=hash) self.sendFileToUser(request, socketTCP, client) def infoFiles(self, request, socketTCP, client): response = dict(responseStatus=Define.SUCCESS, numberOfFiles=self.DHT.getNumberOfFiles(), capacityOfSystem=self.DHT.getCapacityOfSystem(), filesDistribution=self.DHT.getFilesDistribution(), activeNodes=self.DHT.getActiveNodes()) responseJSON = json.dumps(response) socketTCP.send(responseJSON) def createDir(self, request, socketTCP, client): path = request['path'] if self.DHT.createDir(path, client): response = dict(responseStatus=Define.SUCCESS) responseJSON = json.dumps(response) socketTCP.send(responseJSON) else: response = dict(responseStatus=Define.ERROR, errormsg='error_processing_file') responseJSON = json.dumps(response) socketTCP.send(responseJSON) def renameDir(self, request, socketTCP, client): path = request['path'] dir = request['newname'] if self.DHT.renameDir(path, dir, client): response = dict(responseStatus=Define.SUCCESS) responseJSON = json.dumps(response) socketTCP.send(responseJSON) self.DHT.rebalancing() else: response = dict(responseStatus=Define.ERROR, errormsg='error_processing_file') responseJSON = json.dumps(response) socketTCP.send(responseJSON) def removeDir(self, request, socketTCP, client): path = request['path'] if self.DHT.removeDir(path, client): response = dict(responseStatus=Define.SUCCESS) responseJSON = json.dumps(response) socketTCP.send(responseJSON) else: response = dict(responseStatus=Define.ERROR, errormsg='error_processing_file') responseJSON = json.dumps(response) socketTCP.send(responseJSON) def removeFile(self, request, socketTCP, client): path = request['path'] if self.DHT.removeFile(path, client): response = dict(responseStatus=Define.SUCCESS) responseJSON = json.dumps(response) socketTCP.send(responseJSON) else: response = dict(responseStatus=Define.ERROR, errormsg='error_processing_file') responseJSON = json.dumps(response) socketTCP.send(responseJSON) def renameFile(self, request, socketTCP, client): path = request['path'] newName = request['newname'] if self.DHT.renameFile(path, newName, client): response = dict(responseStatus=Define.SUCCESS) responseJSON = json.dumps(response) socketTCP.send(responseJSON) self.DHT.rebalancing() else: response = dict(responseStatus=Define.ERROR, errormsg='error_processing_file') responseJSON = json.dumps(response) socketTCP.send(responseJSON) @staticmethod def sendFilesForUser(userID, ip, files): time.sleep(2) socketTCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM) dest = (ip, 6000 + userID) socketTCP.connect(dest) request = dict(type=Define.DHTFILES, files=files) requestJSON = json.dumps(request) socketTCP.send(requestJSON) def sendDirectoriesTree(self, socketTCP): dictTree = self.DHT.getDirectioriesTree() response = dict(responseStatus=Define.SUCCESS, tree=[dictTree]) responseJSON = json.dumps(response) socketTCP.send(responseJSON)
# Define a GPIO conectada ao pino de dados do sensor pino_sensor = 25 ######################################################################################################## # Efetua a leitura do sensor umidade, temperatura = Adafruit_DHT.read_retry(sensor, pino_sensor) umidade = round(umidade, 2) temperatura = round(temperatura, 2) timestamp = str(datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")) print umidade print temperatura try: print 'Tentando conectar ao servidor' request = req.get(URL,verify=False) print 'Servidor conectado com sucesso!' token = DHT.loadAllToken()[1] # print 'Verificando se tem dados local para enviar' # verificando_se_tem_dados_local(token,ID_INSTITUTION) print 'Atualizando temperatura e umidade' print api.post_environments(token, umidade, temperatura, timestamp,ID_INSTITUTION) except req.exceptions.HTTPError as errh: salvando_dados_local(umidade,temperatura) except req.exceptions.ConnectionError as errc: salvando_dados_local(umidade,temperatura) except req.exceptions.ConnectionTimeout as errt: salvando_dados_local(umidade,temperatura) except req.exceptions.RequestException as err: salvando_dados_local(umidade,temperatura)
class CryptoTransportLayer(TransportLayer): def __init__(self, ob_ctx, db): self.ob_ctx = ob_ctx self.log = logging.getLogger( '[%s] %s' % (ob_ctx.market_id, self.__class__.__name__) ) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) self.db = db self.bitmessage_api = None if (ob_ctx.bm_user, ob_ctx.bm_pass, ob_ctx.bm_port) != (None, None, -1): if not self._connect_to_bitmessage(): self.log.info('Bitmessage not installed or started') self.market_id = ob_ctx.market_id self.nick_mapping = {} self.uri = network_util.get_peer_url(ob_ctx.server_ip, ob_ctx.server_port) self.ip = ob_ctx.server_ip self.nickname = "" self.dev_mode = ob_ctx.dev_mode self.all_messages = ( 'hello', 'findNode', 'findNodeResponse', 'store' ) self._setup_settings() ob_ctx.market_id = self.market_id self.dht = DHT(self, self.market_id, self.settings, self.db) TransportLayer.__init__(self, ob_ctx, self.guid, self.nickname) self.start_listener() if ob_ctx.enable_ip_checker and not ob_ctx.seed_mode and not ob_ctx.dev_mode: self.start_ip_address_checker() def start_listener(self): self.add_callbacks([ ( msg, { 'cb': getattr(self, 'on_%s' % msg), 'validator_cb': getattr(self, 'validate_on_%s' % msg) } ) for msg in self.all_messages ]) self.listener = connection.CryptoPeerListener( self.ip, self.port, self.pubkey, self.secret, self.ctx, self.guid, self._on_message ) self.listener.set_ok_msg({ 'type': 'ok', 'senderGUID': self.guid, 'pubkey': self.pubkey, 'senderNick': self.nickname }) self.listener.listen() def start_ip_address_checker(self): '''Checks for possible public IP change''' if self.ob_ctx.enable_ip_checker: self.caller = PeriodicCallback(self._ip_updater_periodic_callback, 5000, ioloop.IOLoop.instance()) self.caller.start() self.log.info("IP_CHECKER_ENABLED: Periodic IP Address Checker started.") def _ip_updater_periodic_callback(self): if self.ob_ctx.enable_ip_checker: new_ip = network_util.get_my_ip() if not new_ip or new_ip == self.ip: return self.ob_ctx.server_ip = new_ip self.ip = new_ip if self.listener is not None: self.listener.set_ip_address(new_ip) self.dht._iterativeFind(self.guid, [], 'findNode') def save_peer_to_db(self, peer_tuple): uri = peer_tuple[0] pubkey = peer_tuple[1] guid = peer_tuple[2] nickname = peer_tuple[3] # Update query self.db.deleteEntries("peers", {"uri": uri, "guid": guid}, "OR") if guid is not None: self.db.insertEntry("peers", { "uri": uri, "pubkey": pubkey, "guid": guid, "nickname": nickname, "market_id": self.market_id }) def _connect_to_bitmessage(self): # Get bitmessage going # First, try to find a local instance result = False bm_user = self.ob_ctx.bm_user bm_pass = self.ob_ctx.bm_pass bm_port = self.ob_ctx.bm_port try: self.log.info( '[_connect_to_bitmessage] Connecting to Bitmessage on port %s', bm_port ) self.bitmessage_api = xmlrpclib.ServerProxy( "http://{}:{}@localhost:{}/".format(bm_user, bm_pass, bm_port), verbose=0 ) result = self.bitmessage_api.add(2, 3) self.log.info( "[_connect_to_bitmessage] Bitmessage API is live: %s", result ) # If we failed, fall back to starting our own except Exception as e: self.log.info("Failed to connect to bitmessage instance: %s", e) self.bitmessage_api = None return result def validate_on_hello(self, msg): self.log.debug('Validating ping message.') return True def on_hello(self, msg): self.log.info('Pinged %s', json.dumps(msg, ensure_ascii=False)) def validate_on_store(self, msg): self.log.debug('Validating store value message.') return True def on_store(self, msg): self.dht._on_storeValue(msg) def validate_on_findNode(self, msg): self.log.debug('Validating find node message.') return True def on_findNode(self, msg): self.dht.on_find_node(msg) def validate_on_findNodeResponse(self, msg): self.log.debug('Validating find node response message.') return True def on_findNodeResponse(self, msg): self.dht.on_findNodeResponse(self, msg) def _setup_settings(self): try: self.settings = self.db.selectEntries("settings", {"market_id": self.market_id}) except (OperationalError, DatabaseError) as e: print e raise SystemExit("database file %s corrupt or empty - cannot continue" % self.db.db_path) if len(self.settings) == 0: self.settings = {"market_id": self.market_id, "welcome": "enable"} self.db.insertEntry("settings", self.settings) else: self.settings = self.settings[0] # Generate PGP key during initial setup or if previous PGP gen failed if not self.settings.get('PGPPubKey'): try: self.log.info('Generating PGP keypair. This may take several minutes...') print 'Generating PGP keypair. This may take several minutes...' gpg = gnupg.GPG() input_data = gpg.gen_key_input(key_type="RSA", key_length=2048, name_email='*****@*****.**', name_comment="Autogenerated by Open Bazaar", passphrase="P@ssw0rd") assert input_data is not None key = gpg.gen_key(input_data) assert key is not None pubkey_text = gpg.export_keys(key.fingerprint) newsettings = {"PGPPubKey": pubkey_text, "PGPPubkeyFingerprint": key.fingerprint} self.db.updateEntries("settings", newsettings, {"market_id": self.market_id}) self.settings.update(newsettings) self.log.info('PGP keypair generated.') except Exception as e: sys.exit("Encountered a problem with GPG: %s" % e) if not self.settings.get('pubkey'): # Generate Bitcoin keypair self._generate_new_keypair() if not self.settings.get('nickname'): newsettings = {'nickname': 'Default'} self.db.updateEntries('settings', newsettings, {"market_id": self.market_id}) self.settings.update(newsettings) self.nickname = self.settings.get('nickname', '') self.secret = self.settings.get('secret', '') self.pubkey = self.settings.get('pubkey', '') self.privkey = self.settings.get('privkey') self.btc_pubkey = privkey_to_pubkey(self.privkey) self.guid = self.settings.get('guid', '') self.sin = self.settings.get('sin', '') self.bitmessage = self.settings.get('bitmessage', '') if not self.settings.get('bitmessage'): # Generate Bitmessage address if self.bitmessage_api is not None: self._generate_new_bitmessage_address() self.cryptor = Cryptor(pubkey_hex=self.pubkey, privkey_hex=self.secret) # In case user wants to override with command line passed bitmessage values if self.ob_ctx.bm_user is not None and \ self.ob_ctx.bm_pass is not None and \ self.ob_ctx.bm_port is not None: self._connect_to_bitmessage() def _generate_new_keypair(self): secret = str(random.randrange(2 ** 256)) self.secret = hashlib.sha256(secret).hexdigest() self.pubkey = privkey_to_pubkey(self.secret) self.privkey = random_key() self.btc_pubkey = privkey_to_pubkey(self.privkey) print 'PUBLIC KEY: ', self.btc_pubkey # Generate SIN sha_hash = hashlib.sha256() sha_hash.update(self.pubkey) ripe_hash = hashlib.new('ripemd160') ripe_hash.update(sha_hash.digest()) self.guid = ripe_hash.hexdigest() self.sin = obelisk.EncodeBase58Check('\x0F\x02%s' % ripe_hash.digest()) newsettings = { "secret": self.secret, "pubkey": self.pubkey, "privkey": self.privkey, "guid": self.guid, "sin": self.sin } self.db.updateEntries("settings", newsettings, {"market_id": self.market_id}) self.settings.update(newsettings) def _generate_new_bitmessage_address(self): # Use the guid generated previously as the key self.bitmessage = self.bitmessage_api.createRandomAddress( self.guid.encode('base64'), False, 1.05, 1.1111 ) newsettings = {"bitmessage": self.bitmessage} self.db.updateEntries("settings", newsettings, {"market_id": self.market_id}) self.settings.update(newsettings) def join_network(self, seeds=None, callback=None): if seeds is None: seeds = [] self.log.info('Joining network') # Connect up through seed servers for idx, seed in enumerate(seeds): seeds[idx] = network_util.get_peer_url(seed, "12345") # Connect to persisted peers db_peers = self.get_past_peers() known_peers = list(set(seeds).union(db_peers)) for known_peer in known_peers: self.dht.add_peer(self, known_peer) # Populate routing table by searching for self if known_peers: # Check every one second if we are connected # We could use a PeriodicCallback but I think this is simpler # since this will be repeated in most cases less than 10 times def join_callback(): # If we are not connected to any node, reschedule a check if not self.dht.activePeers: ioloop.IOLoop.instance().call_later(1, join_callback) else: self.search_for_my_node() join_callback() if callback is not None: callback('Joined') def get_past_peers(self): result = self.db.selectEntries("peers", {"market_id": self.market_id}) return [peer['uri'] for peer in result] def search_for_my_node(self): self.log.info('Searching for myself') self.dht._iterativeFind(self.guid, self.dht.knownNodes, 'findNode') def get_crypto_peer(self, guid=None, uri=None, pubkey=None, nickname=None): if guid == self.guid: self.log.error('Cannot get CryptoPeerConnection for your own node') return self.log.debug( 'Getting CryptoPeerConnection' '\nGUID: %s' '\nURI: %s' '\nPubkey:%s' '\nNickname:%s', guid, uri, pubkey, nickname ) return connection.CryptoPeerConnection( self, uri, pubkey, guid=guid, nickname=nickname ) def respond_pubkey_if_mine(self, nickname, ident_pubkey): if ident_pubkey != self.pubkey: self.log.info("Public key does not match your identity") return # Return signed pubkey pubkey = self.cryptor.pubkey # XXX: A Cryptor does not have such a field. ec_key = obelisk.EllipticCurveKey() ec_key.set_secret(self.secret) digest = obelisk.Hash(pubkey) signature = ec_key.sign(digest) # Send array of nickname, pubkey, signature to transport layer self.send(proto_response_pubkey(nickname, pubkey, signature)) def send(self, data, send_to=None, callback=None): self.log.debug("Outgoing Data: %s %s", data, send_to) # Directed message if send_to is not None: peer = self.dht.routingTable.getContact(send_to) if peer is None: for activePeer in self.dht.activePeers: if activePeer.guid == send_to: peer = activePeer break if peer: self.log.debug('Directed Data (%s): %s', send_to, data) try: peer.send(data, callback=callback) except Exception as e: self.log.error('Not sending message directly to peer %s', e) else: self.log.error('No peer found') else: # FindKey and then send for peer in self.dht.activePeers: try: routing_peer = self.dht.routingTable.getContact(peer.guid) if routing_peer is None: self.dht.routingTable.addContact(peer) routing_peer = peer data['senderGUID'] = self.guid data['pubkey'] = self.pubkey def cb(msg): self.log.debug('Message Back: \n%s', pformat(msg)) routing_peer.send(data, cb) except Exception: self.log.info("Error sending over peer!") traceback.print_exc() def _on_message(self, msg): # here goes the application callbacks # we get a "clean" msg which is a dict holding whatever pubkey = msg.get('pubkey') uri = msg.get('uri') guid = msg.get('senderGUID') nickname = msg.get('senderNick')[:120] self.log.info('On Message: %s', json.dumps(msg, ensure_ascii=False)) self.dht.add_peer(self, uri, pubkey, guid, nickname) t = Thread(target=self.trigger_callbacks, args=(msg['type'], msg,)) t.start() def store(self, *args, **kwargs): """ Store or republish data. Refer to the dht module (iterativeStore()) for further details. """ self.dht.iterativeStore(*args, **kwargs) def shutdown(self): print "CryptoTransportLayer.shutdown()!" print "Notice: explicit DHT Shutdown not implemented." try: if self.bitmessage_api is not None: self.bitmessage_api.close() except Exception as e: # It might not even be open; we can't do much more on our # way out if exception is thrown here. self.log.error( "Could not shutdown bitmessage_api's ServerProxy: %s", e.message )
class CryptoTransportLayer(TransportLayer): def __init__(self, my_ip, my_port, market_id): self._log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) # Connect to database MONGODB_URI = 'mongodb://localhost:27017' _dbclient = MongoClient() self._db = _dbclient.openbazaar self._market_id = market_id self.nick_mapping = {} self._uri = "tcp://%s:%s" % (my_ip, my_port) # Set up self._setup_settings() self._dht = DHT(self, market_id, self.settings) self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), privkey=self.secret.decode('hex'), curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid) # Set up callbacks self.add_callback('hello', self._ping) self.add_callback('findNode', self._findNode) self.add_callback('findNodeResponse', self._findNodeResponse) self.add_callback('store', self._storeValue) def get_guid(self): return self._guid def getDHT(self): return self._dht def getMarketID(self): return self._market_id def getMyself(self): return self._myself def _ping(self, msg): self._log.info('Pinged %s ' % msg) pinger = CryptoPeerConnection(self,msg['uri'], msg['pubkey'], msg['senderGUID']) msg = pinger.send_raw(json.dumps( {"type": "hello_response", "senderGUID": self.guid, "uri": self._uri, "pubkey": self.pubkey, })) print msg def _storeValue(self, msg): self._dht._on_storeValue(msg) def _findNode(self, msg): self._dht.on_find_node(msg) def _findNodeResponse(self, msg): self._dht.on_findNodeResponse(self, msg) def _setup_settings(self): self.settings = self._db.settings.find_one({'id':"%s" % self._market_id}) if self.settings: self.nickname = self.settings['nickname'] if self.settings.has_key("nickname") else "" self.secret = self.settings['secret'] self.pubkey = self.settings['pubkey'] self.guid = self.settings['guid'] else: self.nickname = 'Default' self._generate_new_keypair() self.settings = self._db.settings.find_one({'id':"%s" % self._market_id}) self._log.debug('Retrieved Settings: %s', self.settings) def _generate_new_keypair(self): # Generate new keypair key = ec.ECC(curve='secp256k1') self.secret = key.get_privkey().encode('hex') pubkey = key.get_pubkey() signedPubkey = key.sign(pubkey) self.pubkey = pubkey.encode('hex') self._myself = key # Generate a node ID by ripemd160 hashing the signed pubkey guid = hashlib.new('ripemd160') guid.update(signedPubkey) self.guid = guid.digest().encode('hex') self._db.settings.update({"id":'%s' % self._market_id}, {"$set": {"secret":self.secret, "pubkey":self.pubkey, "guid":self.guid}}, True) def join_network(self, seed_uri): self.listen(self.pubkey) # Turn on zmq socket if seed_uri: self._log.info('Initializing Seed Peer(s): [%s]' % seed_uri) seed_peer = CryptoPeerConnection(self, seed_uri) self._dht.start(seed_peer) def get_crypto_peer(self, guid, uri, pubkey=None): if guid == self.guid: self._log.info('Trying to get cryptopeer for yourself') return peer = CryptoPeerConnection(self, uri, pubkey, guid=guid) return peer def addCryptoPeer(self, peer): peerExists = False for idx, aPeer in enumerate(self._activePeers): if aPeer._guid == peer._guid or aPeer._pub == peer._pub or aPeer._address == peer._address: self._log.info('guids or pubkey match') peerExists = True if peer._pub and aPeer._pub == '': self._log.info('no pubkey') aPeer._pub = peer._pub self._activePeers[idx] = aPeer if not peerExists and peer._guid != self._guid: self._log.info('Adding crypto peer %s' % peer._pub) self._routingTable.addContact(peer) print peer self._dht.add_active_peer(self, (peer._pub, peer._address, peer._guid)) # Return data array with details from the crypto file # TODO: This needs to be protected better; potentially encrypted file or DB @staticmethod def load_crypto_details(store_file): with open(store_file) as f: data = json.loads(f.read()) assert "nickname" in data assert "secret" in data assert "pubkey" in data assert len(data["secret"]) == 2 * 32 assert len(data["pubkey"]) == 2 * 33 return data["nickname"], data["secret"].decode("hex"), \ data["pubkey"].decode("hex") def get_profile(self): peers = {} self.settings = self._db.settings.find_one({'id':"%s" % self._market_id}) for uri, peer in self._peers.iteritems(): if peer._pub: peers[uri] = peer._pub.encode('hex') return {'uri': self._uri, 'pub': self._myself.get_pubkey().encode('hex'),'nickname': self.nickname, 'peers': peers} def respond_pubkey_if_mine(self, nickname, ident_pubkey): if ident_pubkey != self.pubkey: self._log.info("Public key does not match your identity") return # Return signed pubkey pubkey = self._myself.pubkey ec_key = obelisk.EllipticCurveKey() ec_key.set_secret(self.secret) digest = obelisk.Hash(pubkey) signature = ec_key.sign(digest) # Send array of nickname, pubkey, signature to transport layer self.send(proto_response_pubkey(nickname, pubkey, signature)) def pubkey_exists(self, pub): for uri, peer in self._peers.iteritems(): self._log.info('PEER: %s Pub: %s' % (peer._pub.encode('hex'), pub.encode('hex'))) if peer._pub.encode('hex') == pub.encode('hex'): return True return False def create_peer(self, uri, pub, node_guid): if pub: pub = pub.decode('hex') # Create the peer if public key is not already in the peer list # if not self.pubkey_exists(pub): self._peers[uri] = CryptoPeerConnection(self, uri, pub, node_guid) # Call 'peer' callbacks on listeners self.trigger_callbacks('peer', self._peers[uri]) # else: # print 'Pub Key is already in peer list' def send_enc(self, uri, msg): peer = self._peers[uri] pub = peer._pub # Now send a hello message to the peer if pub: self._log.info("Sending encrypted [%s] message to %s" % (msg['type'], uri)) peer.send(msg) else: # Will send clear profile on initial if no pub self._log.info("Sending unencrypted [%s] message to %s" % (msg['type'], uri)) self._peers[uri].send_raw(json.dumps(msg)) def init_peer(self, msg): uri = msg['uri'] pub = msg.get('pub') nickname = msg.get('nickname') msg_type = msg.get('type') guid = msg['guid'] if not self.valid_peer_uri(uri): self._log.error("Invalid Peer: %s " % uri) return if uri not in self._peers: # Unknown peer self._log.info('Add New Peer: %s' % uri) self.create_peer(uri, pub, guid) if not msg_type: self.send_enc(uri, hello_request(self.get_profile())) elif msg_type == 'hello_request': self.send_enc(uri, hello_response(self.get_profile())) else: # Known peer if pub: # test if we have to update the pubkey if not self._peers[uri]._pub: self._log.info("Setting public key for seed node") self._peers[uri]._pub = pub.decode('hex') self.trigger_callbacks('peer', self._peers[uri]) if self._peers[uri]._pub != pub.decode('hex'): self._log.info("Updating public key for node") self._peers[uri]._nickname = nickname self._peers[uri]._pub = pub.decode('hex') self.trigger_callbacks('peer', self._peers[uri]) if msg_type == 'hello_request': # reply only if necessary self.send_enc(uri, hello_response(self.get_profile())) def on_message(self, msg): # here goes the application callbacks # we get a "clean" msg which is a dict holding whatever self._log.info("[On Message] Data received: %s" % msg) pubkey = msg.get('pubkey') uri = msg.get('uri') ip = urlparse(uri).hostname port = urlparse(uri).port guid = msg.get('senderGUID') self._dht.add_active_peer(self, (pubkey, uri, guid)) self._dht.add_known_node((ip, port, guid)) self.trigger_callbacks(msg['type'], msg) def on_raw_message(self, serialized): try: # Try to deserialize cleartext message msg = json.loads(serialized) self._log.info("Message Received [%s]" % msg.get('type', 'unknown')) except ValueError: try: # Encrypted? try: msg = self._myself.decrypt(serialized) msg = json.loads(msg) self._log.info("Decrypted Message [%s]" % msg.get('type', 'unknown')) except: self._log.error("Could not decrypt message: %s" % msg) return except: self._log.info("Bad Message: %s..." % self._myself.decrypt(serialized)) traceback.print_exc() return if msg.get('type') != '': msg_type = msg.get('type') msg_uri = msg.get('uri') msg_guid = msg.get('guid') self._log.info(msg.get('type')) # # if msg_type.startswith('hello') and msg_uri: # self.init_peer(msg) # for uri, pub in msg.get('peers', {}).iteritems(): # # Do not add yourself as a peer # if uri != self._uri: # self.init_peer({'uri': uri, 'pub': pub}) # self._log.info("Update peer table [%s peers]" % len(self._peers)) # # elif msg_type == 'goodbye' and msg_uri: # self._log.info("Received goodbye from %s" % msg_uri) # self.remove_peer(msg_uri) # # else: self.on_message(msg) else: self._log.error('Received a message with no type')
class CryptoTransportLayer(TransportLayer): def __init__(self, my_ip, my_port, market_id): self._log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) # Connect to database MONGODB_URI = 'mongodb://localhost:27017' _dbclient = MongoClient() self._db = _dbclient.openbazaar self._market_id = market_id self.nick_mapping = {} self._uri = "tcp://%s:%s" % (my_ip, my_port) # Set up self._setup_settings() self._dht = DHT(market_id, self.settings) self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), privkey=self.secret.decode('hex'), curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid) # Set up callbacks self.add_callback('ping', self._dht._on_ping) self.add_callback('findNode', self._dht._on_findNode) self.add_callback('findNodeResponse', self._dht._on_findNodeResponse) def _setup_settings(self): self.settings = self._db.settings.find_one( {'id': "%s" % self._market_id}) if self.settings: self.nickname = self.settings['nickname'] if self.settings.has_key( "nickname") else "" self.secret = self.settings['secret'] self.pubkey = self.settings['pubkey'] self.guid = self.settings['guid'] else: self.nickname = 'Default' self._generate_new_keypair() self.settings = self._db.settings.find_one( {'id': "%s" % self._market_id}) self._log.debug('Retrieved Settings: %s', self.settings) def _generate_new_keypair(self): # Generate new keypair key = ec.ECC(curve='secp256k1') self.secret = key.get_privkey().encode('hex') pubkey = key.get_pubkey() signedPubkey = key.sign(pubkey) self.pubkey = pubkey.encode('hex') self._myself = key # Generate a node ID by ripemd160 hashing the signed pubkey guid = hashlib.new('ripemd160') guid.update(signedPubkey) self.guid = guid.digest().encode('hex') self._db.settings.update({"id": '%s' % self._market_id}, { "$set": { "secret": self.secret, "pubkey": self.pubkey, "guid": self.guid } }, True) def join_network(self, seed_uri): self.listen(self.pubkey) # Turn on zmq socket if seed_uri: self._log.info('Initializing Seed Peer(s): [%s]' % (seed_uri)) seed_peer = CryptoPeerConnection(self, seed_uri) self._dht.start(seed_peer) def _addCryptoPeer(self, uri, guid, pubkey): peer = CryptoPeerConnection(self, uri, pubkey) self.addCryptoPeer(peer) def addCryptoPeer(self, peer): peerExists = False for idx, aPeer in enumerate(self._activePeers): if aPeer._guid == peer._guid or aPeer._pub == peer._pub or aPeer._address == peer._address: self._log.info('guids or pubkey match') peerExists = True if peer._pub and aPeer._pub == '': self._log.info('no pubkey') aPeer._pub = peer._pub self._activePeers[idx] = aPeer if not peerExists: self._log.info('Adding crypto peer %s' % peer._pub) self._routingTable.addContact(peer) self._activePeers.append(peer) # Return data array with details from the crypto file # TODO: This needs to be protected better; potentially encrypted file or DB def load_crypto_details(self, store_file): with open(store_file) as f: data = json.loads(f.read()) assert "nickname" in data assert "secret" in data assert "pubkey" in data assert len(data["secret"]) == 2 * 32 assert len(data["pubkey"]) == 2 * 33 return data["nickname"], data["secret"].decode("hex"), \ data["pubkey"].decode("hex") def get_profile(self): peers = {} self.settings = self._db.settings.find_one( {'id': "%s" % self._market_id}) for uri, peer in self._peers.iteritems(): if peer._pub: peers[uri] = peer._pub.encode('hex') return { 'uri': self._uri, 'pub': self._myself.get_pubkey().encode('hex'), 'nickname': self.nickname, 'peers': peers } def respond_pubkey_if_mine(self, nickname, ident_pubkey): if ident_pubkey != self.pubkey: self._log.info("Public key does not match your identity") return # Return signed pubkey pubkey = self._myself.pubkey ec_key = obelisk.EllipticCurveKey() ec_key.set_secret(self.secret) digest = obelisk.Hash(pubkey) signature = ec_key.sign(digest) # Send array of nickname, pubkey, signature to transport layer self.send(proto_response_pubkey(nickname, pubkey, signature)) def pubkey_exists(self, pub): for uri, peer in self._peers.iteritems(): self._log.info('PEER: %s Pub: %s' % (peer._pub.encode('hex'), pub.encode('hex'))) if peer._pub.encode('hex') == pub.encode('hex'): return True return False def create_peer(self, uri, pub, node_guid): if pub: pub = pub.decode('hex') # Create the peer if public key is not already in the peer list # if not self.pubkey_exists(pub): self._peers[uri] = CryptoPeerConnection(self, uri, pub, node_guid) # Call 'peer' callbacks on listeners self.trigger_callbacks('peer', self._peers[uri]) # else: # print 'Pub Key is already in peer list' def send_enc(self, uri, msg): peer = self._peers[uri] pub = peer._pub # Now send a hello message to the peer if pub: self._log.info("Sending encrypted [%s] message to %s" % (msg['type'], uri)) peer.send(msg) else: # Will send clear profile on initial if no pub self._log.info("Sending unencrypted [%s] message to %s" % (msg['type'], uri)) self._peers[uri].send_raw(json.dumps(msg)) def init_peer(self, msg): uri = msg['uri'] pub = msg.get('pub') nickname = msg.get('nickname') msg_type = msg.get('type') guid = msg['guid'] if not self.valid_peer_uri(uri): self._log.error("Invalid Peer: %s " % uri) return if uri not in self._peers: # Unknown peer self._log.info('Add New Peer: %s' % uri) self.create_peer(uri, pub, guid) if not msg_type: self.send_enc(uri, hello_request(self.get_profile())) elif msg_type == 'hello_request': self.send_enc(uri, hello_response(self.get_profile())) else: # Known peer if pub: # test if we have to update the pubkey if not self._peers[uri]._pub: self._log.info("Setting public key for seed node") self._peers[uri]._pub = pub.decode('hex') self.trigger_callbacks('peer', self._peers[uri]) if (self._peers[uri]._pub != pub.decode('hex')): self._log.info("Updating public key for node") self._peers[uri]._nickname = nickname self._peers[uri]._pub = pub.decode('hex') self.trigger_callbacks('peer', self._peers[uri]) if msg_type == 'hello_request': # reply only if necessary self.send_enc(uri, hello_response(self.get_profile())) def on_message(self, msg): # here goes the application callbacks # we get a "clean" msg which is a dict holding whatever self._log.info("Data received: %s" % msg) pubkey = msg.get('pubkey') uri = msg.get('uri') ip = urlparse(uri).hostname port = urlparse(uri).port guid = msg.get('senderGUID') new_peer = CryptoPeerConnection(self, uri, pubkey, guid) self._dht.add_active_peer(new_peer) self._dht.add_known_node((ip, port, guid)) self.trigger_callbacks(msg['type'], msg) def on_raw_message(self, serialized): try: # Try to deserialize cleartext message msg = json.loads(serialized) self._log.info("Message Received [%s]" % msg.get('type', 'unknown')) except ValueError: try: # Encrypted? try: msg = self._myself.decrypt(serialized) msg = json.loads(msg) self._log.info("Decrypted Message [%s]" % msg.get('type', 'unknown')) except: self._log.error("Could not decrypt message: %s" % msg) return except: self._log.info("Bad Message: %s..." % self._myself.decrypt(serialized)) traceback.print_exc() return if msg.get('type') != '': msg_type = msg.get('type') msg_uri = msg.get('uri') msg_guid = msg.get('guid') # # if msg_type.startswith('hello') and msg_uri: # self.init_peer(msg) # for uri, pub in msg.get('peers', {}).iteritems(): # # Do not add yourself as a peer # if uri != self._uri: # self.init_peer({'uri': uri, 'pub': pub}) # self._log.info("Update peer table [%s peers]" % len(self._peers)) # # elif msg_type == 'goodbye' and msg_uri: # self._log.info("Received goodbye from %s" % msg_uri) # self.remove_peer(msg_uri) # # else: self.on_message(msg)
import pycom import time from machine import Pin from dht import DHT pycom.heartbeat(False) pycom.rgbled(0x000008) # blue th = DHT(Pin('P3', mode=Pin.OPEN_DRAIN),0) time.sleep(2) result = th.read() if result.is_valid(): pycom.rgbled(0x001000) # green print("Temperature: %d C" % result.temperature) print("Humidity: %d %%" % result.humidity)
class CryptoTransportLayer(TransportLayer): def __init__(self, ob_ctx, db): self.ob_ctx = ob_ctx self.log = logging.getLogger( '[%s] %s' % (ob_ctx.market_id, self.__class__.__name__)) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) self.db = db self.bitmessage_api = None if (ob_ctx.bm_user, ob_ctx.bm_pass, ob_ctx.bm_port) != (None, None, -1): if not self._connect_to_bitmessage(): self.log.info('Bitmessage not installed or started') self.market_id = ob_ctx.market_id self.nick_mapping = {} self.uri = network_util.get_peer_url(ob_ctx.server_ip, ob_ctx.server_port) self.ip = ob_ctx.server_ip self.nickname = "" self.dev_mode = ob_ctx.dev_mode self.all_messages = ('hello', 'findNode', 'findNodeResponse', 'store') self._setup_settings() ob_ctx.market_id = self.market_id self.dht = DHT(self, self.market_id, self.settings, self.db) TransportLayer.__init__(self, ob_ctx, self.guid, self.nickname) self.start_listener() if ob_ctx.enable_ip_checker and not ob_ctx.seed_mode and not ob_ctx.dev_mode: self.start_ip_address_checker() def start_listener(self): self.add_callbacks([(msg, { 'cb': getattr(self, 'on_%s' % msg), 'validator_cb': getattr(self, 'validate_on_%s' % msg) }) for msg in self.all_messages]) self.listener = connection.CryptoPeerListener(self.ip, self.port, self.pubkey, self.secret, self.ctx, self.guid, self._on_message) self.listener.set_ok_msg({ 'type': 'ok', 'senderGUID': self.guid, 'pubkey': self.pubkey, 'senderNick': self.nickname }) self.listener.listen() def start_ip_address_checker(self): '''Checks for possible public IP change''' if self.ob_ctx.enable_ip_checker: self.caller = PeriodicCallback(self._ip_updater_periodic_callback, 5000, ioloop.IOLoop.instance()) self.caller.start() self.log.info( "IP_CHECKER_ENABLED: Periodic IP Address Checker started.") def _ip_updater_periodic_callback(self): if self.ob_ctx.enable_ip_checker: new_ip = network_util.get_my_ip() if not new_ip or new_ip == self.ip: return self.ob_ctx.server_ip = new_ip self.ip = new_ip if self.listener is not None: self.listener.set_ip_address(new_ip) self.dht._iterativeFind(self.guid, [], 'findNode') def save_peer_to_db(self, peer_tuple): uri = peer_tuple[0] pubkey = peer_tuple[1] guid = peer_tuple[2] nickname = peer_tuple[3] # Update query self.db.deleteEntries("peers", {"uri": uri, "guid": guid}, "OR") if guid is not None: self.db.insertEntry( "peers", { "uri": uri, "pubkey": pubkey, "guid": guid, "nickname": nickname, "market_id": self.market_id }) def _connect_to_bitmessage(self): # Get bitmessage going # First, try to find a local instance result = False bm_user = self.ob_ctx.bm_user bm_pass = self.ob_ctx.bm_pass bm_port = self.ob_ctx.bm_port try: self.log.info( '[_connect_to_bitmessage] Connecting to Bitmessage on port %s', bm_port) self.bitmessage_api = xmlrpclib.ServerProxy( "http://{}:{}@localhost:{}/".format(bm_user, bm_pass, bm_port), verbose=0) result = self.bitmessage_api.add(2, 3) self.log.info( "[_connect_to_bitmessage] Bitmessage API is live: %s", result) # If we failed, fall back to starting our own except Exception as e: self.log.info("Failed to connect to bitmessage instance: %s", e) self.bitmessage_api = None return result def validate_on_hello(self, msg): self.log.debug('Validating ping message.') return True def on_hello(self, msg): self.log.info('Pinged %s', json.dumps(msg, ensure_ascii=False)) def validate_on_store(self, msg): self.log.debug('Validating store value message.') return True def on_store(self, msg): self.dht._on_storeValue(msg) def validate_on_findNode(self, msg): self.log.debug('Validating find node message.') return True def on_findNode(self, msg): self.dht.on_find_node(msg) def validate_on_findNodeResponse(self, msg): self.log.debug('Validating find node response message.') return True def on_findNodeResponse(self, msg): self.dht.on_findNodeResponse(self, msg) def _setup_settings(self): try: self.settings = self.db.selectEntries( "settings", {"market_id": self.market_id}) except (OperationalError, DatabaseError) as e: print e raise SystemExit( "database file %s corrupt or empty - cannot continue" % self.db.db_path) if len(self.settings) == 0: self.settings = {"market_id": self.market_id, "welcome": "enable"} self.db.insertEntry("settings", self.settings) else: self.settings = self.settings[0] # Generate PGP key during initial setup or if previous PGP gen failed if not self.settings.get('PGPPubKey'): try: self.log.info( 'Generating PGP keypair. This may take several minutes...') print 'Generating PGP keypair. This may take several minutes...' gpg = gnupg.GPG() input_data = gpg.gen_key_input( key_type="RSA", key_length=2048, name_email='*****@*****.**', name_comment="Autogenerated by Open Bazaar", passphrase="P@ssw0rd") assert input_data is not None key = gpg.gen_key(input_data) assert key is not None pubkey_text = gpg.export_keys(key.fingerprint) newsettings = { "PGPPubKey": pubkey_text, "PGPPubkeyFingerprint": key.fingerprint } self.db.updateEntries("settings", newsettings, {"market_id": self.market_id}) self.settings.update(newsettings) self.log.info('PGP keypair generated.') except Exception as e: sys.exit("Encountered a problem with GPG: %s" % e) if not self.settings.get('pubkey'): # Generate Bitcoin keypair self._generate_new_keypair() if not self.settings.get('nickname'): newsettings = {'nickname': 'Default'} self.db.updateEntries('settings', newsettings, {"market_id": self.market_id}) self.settings.update(newsettings) self.nickname = self.settings.get('nickname', '') self.secret = self.settings.get('secret', '') self.pubkey = self.settings.get('pubkey', '') self.privkey = self.settings.get('privkey') self.btc_pubkey = privkey_to_pubkey(self.privkey) self.guid = self.settings.get('guid', '') self.sin = self.settings.get('sin', '') self.bitmessage = self.settings.get('bitmessage', '') if not self.settings.get('bitmessage'): # Generate Bitmessage address if self.bitmessage_api is not None: self._generate_new_bitmessage_address() self.cryptor = Cryptor(pubkey_hex=self.pubkey, privkey_hex=self.secret) # In case user wants to override with command line passed bitmessage values if self.ob_ctx.bm_user is not None and \ self.ob_ctx.bm_pass is not None and \ self.ob_ctx.bm_port is not None: self._connect_to_bitmessage() def _generate_new_keypair(self): secret = str(random.randrange(2**256)) self.secret = hashlib.sha256(secret).hexdigest() self.pubkey = privkey_to_pubkey(self.secret) self.privkey = random_key() self.btc_pubkey = privkey_to_pubkey(self.privkey) print 'PUBLIC KEY: ', self.btc_pubkey # Generate SIN sha_hash = hashlib.sha256() sha_hash.update(self.pubkey) ripe_hash = hashlib.new('ripemd160') ripe_hash.update(sha_hash.digest()) self.guid = ripe_hash.hexdigest() self.sin = obelisk.EncodeBase58Check('\x0F\x02%s' % ripe_hash.digest()) newsettings = { "secret": self.secret, "pubkey": self.pubkey, "privkey": self.privkey, "guid": self.guid, "sin": self.sin } self.db.updateEntries("settings", newsettings, {"market_id": self.market_id}) self.settings.update(newsettings) def _generate_new_bitmessage_address(self): # Use the guid generated previously as the key self.bitmessage = self.bitmessage_api.createRandomAddress( self.guid.encode('base64'), False, 1.05, 1.1111) newsettings = {"bitmessage": self.bitmessage} self.db.updateEntries("settings", newsettings, {"market_id": self.market_id}) self.settings.update(newsettings) def join_network(self, seeds=None, callback=None): if seeds is None: seeds = [] self.log.info('Joining network') # Connect up through seed servers for idx, seed in enumerate(seeds): seeds[idx] = network_util.get_peer_url(seed, "12345") # Connect to persisted peers db_peers = self.get_past_peers() known_peers = list(set(seeds).union(db_peers)) for known_peer in known_peers: self.dht.add_peer(self, known_peer) # Populate routing table by searching for self if known_peers: # Check every one second if we are connected # We could use a PeriodicCallback but I think this is simpler # since this will be repeated in most cases less than 10 times def join_callback(): # If we are not connected to any node, reschedule a check if not self.dht.activePeers: ioloop.IOLoop.instance().call_later(1, join_callback) else: self.search_for_my_node() join_callback() if callback is not None: callback('Joined') def get_past_peers(self): result = self.db.selectEntries("peers", {"market_id": self.market_id}) return [peer['uri'] for peer in result] def search_for_my_node(self): self.log.info('Searching for myself') self.dht._iterativeFind(self.guid, self.dht.knownNodes, 'findNode') def get_crypto_peer(self, guid=None, uri=None, pubkey=None, nickname=None): if guid == self.guid: self.log.error('Cannot get CryptoPeerConnection for your own node') return self.log.debug( 'Getting CryptoPeerConnection' '\nGUID: %s' '\nURI: %s' '\nPubkey:%s' '\nNickname:%s', guid, uri, pubkey, nickname) return connection.CryptoPeerConnection(self, uri, pubkey, guid=guid, nickname=nickname) def respond_pubkey_if_mine(self, nickname, ident_pubkey): if ident_pubkey != self.pubkey: self.log.info("Public key does not match your identity") return # Return signed pubkey pubkey = self.cryptor.pubkey # XXX: A Cryptor does not have such a field. ec_key = obelisk.EllipticCurveKey() ec_key.set_secret(self.secret) digest = obelisk.Hash(pubkey) signature = ec_key.sign(digest) # Send array of nickname, pubkey, signature to transport layer self.send(proto_response_pubkey(nickname, pubkey, signature)) def send(self, data, send_to=None, callback=None): self.log.debug("Outgoing Data: %s %s", data, send_to) # Directed message if send_to is not None: peer = self.dht.routingTable.getContact(send_to) if peer is None: for activePeer in self.dht.activePeers: if activePeer.guid == send_to: peer = activePeer break if peer: self.log.debug('Directed Data (%s): %s', send_to, data) try: peer.send(data, callback=callback) except Exception as e: self.log.error('Not sending message directly to peer %s', e) else: self.log.error('No peer found') else: # FindKey and then send for peer in self.dht.activePeers: try: routing_peer = self.dht.routingTable.getContact(peer.guid) if routing_peer is None: self.dht.routingTable.addContact(peer) routing_peer = peer data['senderGUID'] = self.guid data['pubkey'] = self.pubkey def cb(msg): self.log.debug('Message Back: \n%s', pformat(msg)) routing_peer.send(data, cb) except Exception: self.log.info("Error sending over peer!") traceback.print_exc() def _on_message(self, msg): # here goes the application callbacks # we get a "clean" msg which is a dict holding whatever pubkey = msg.get('pubkey') uri = msg.get('uri') guid = msg.get('senderGUID') nickname = msg.get('senderNick')[:120] self.log.info('On Message: %s', json.dumps(msg, ensure_ascii=False)) self.dht.add_peer(self, uri, pubkey, guid, nickname) t = Thread(target=self.trigger_callbacks, args=( msg['type'], msg, )) t.start() def store(self, *args, **kwargs): """ Store or republish data. Refer to the dht module (iterativeStore()) for further details. """ self.dht.iterativeStore(*args, **kwargs) def shutdown(self): print "CryptoTransportLayer.shutdown()!" print "Notice: explicit DHT Shutdown not implemented." try: if self.bitmessage_api is not None: self.bitmessage_api.close() except Exception as e: # It might not even be open; we can't do much more on our # way out if exception is thrown here. self.log.error( "Could not shutdown bitmessage_api's ServerProxy: %s", e.message)
DHT_NUM = 8 RECEPTI_NUM = 5 state = random.getstate() random.seed(dht.config.TESTING_CATEGORY_SEED) recepti = [{ 'title': 'naziv' + str(i), 'type': dht.config.category_names[random.randint(0, len(dht.config.category_names) - 1)], 'description': 'Opis ' + str(i), 'ingredients': ['Sastojak_1_' + str(i), 'Sastojak_2_' + str(i), 'Sastojak_3_' + str(i)], 'picture': None } for i in range(RECEPTI_NUM)] random.setstate(state) dht = [DHT("localhost", 3001 + i, dht.config.regions[i % len(dht.config.regions)]) for i in range(DHT_NUM)] # Sacekaj dok se svi konektuju all_connected = False while not all_connected: all_connected = True for d in dht: if not d.connected: all_connected = False break print "KONEKCIJE" for d in dht: print d.peer.address() peer_sum = 0 for b_index, bucket in enumerate(d.buckets.buckets):
import pycom import time from machine import Pin from dht import DHT powerPin = Pin('G28', mode=Pin.OUT) powerPin(0) pycom.heartbeat(False) pycom.rgbled(0x000008) # blue powerPin(1) time.sleep(2) th0 = DHT('G24', 1) th1 = DHT('G11', 1) result0 = th0.read() result1 = th1.read() # powerPin(0) if result0.is_valid(): pycom.rgbled(0x001000) # green print('Temperature0: {:3.1f}'.format(result0.temperature / 1.0)) print('Humidity0: {:3.1f}'.format(result0.humidity / 1.0)) if result1.is_valid(): pycom.rgbled(0x001000) # green print('Temperature1: {:3.1f}'.format(result1.temperature / 1.0)) print('Humidity1: {:3.1f}'.format(result1.humidity / 1.0))
def __init__(self, port): self.dht = DHT(port) self.myPort = port self.fila = queue.Queue() self.t = threading.Thread(target=self.enviando) self.t.start()
import signal import time import datetime logging.basicConfig() logger = logging.getLogger(__name__) logger.setLevel(logging.WARNING) from sds import SDS from gps import GPS from dht import DHT quit_event = threading.Event() sds = SDS(quit_event=quit_event) gps = GPS(quit_event=quit_event) dht = DHT(quit_event=quit_event) def signal_handler(sig, frame): logger.warning("Ctrl-C pressed, quitting") quit_event.set() sys.exit(0) def mount_disk(): if not os.path.ismount(DISK): os.system("mount %s" % dist) if __name__ == "__main__": #Start all acquisition threads
class CryptoTransportLayer(TransportLayer): def __init__(self, my_ip, my_port, market_id, bm_user=None, bm_pass=None, bm_port=None, seed_mode=0, dev_mode=False): self._log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) # Connect to database MONGODB_URI = 'mongodb://*****:*****@localhost:{}/".format(bm_user, bm_pass, bm_port), verbose=0) result = self._bitmessage_api.add(2,3) self._log.info("Bitmessage test result: {}, API is live".format(result)) # If we failed, fall back to starting our own except Exception as e: self._log.info("Failed to connect to bitmessage instance: {}".format(e)) self._bitmessage_api = None # self._log.info("Spawning internal bitmessage instance") # # Add bitmessage submodule path # sys.path.insert(0, os.path.join( # os.path.dirname(__file__), '..', 'pybitmessage', 'src')) # import bitmessagemain as bitmessage # bitmessage.logger.setLevel(logging.WARNING) # bitmessage_instance = bitmessage.Main() # bitmessage_instance.start(daemon=True) # bminfo = bitmessage_instance.getApiAddress() # if bminfo is not None: # self._log.info("Started bitmessage daemon at %s:%s".format( # bminfo['address'], bminfo['port'])) # bitmessage_api = xmlrpclib.ServerProxy("http://{}:{}@{}:{}/".format( # bm_user, bm_pass, bminfo['address'], bminfo['port'])) # else: # self._log.info("Failed to start bitmessage dameon") # self._bitmessage_api = None return result def _checkok(self, msg): self._log.info('Check ok') def get_guid(self): return self._guid def getDHT(self): return self._dht def getBitmessageAPI(self): return self._bitmessage_api def getMarketID(self): return self._market_id def getMyself(self): return self._myself def _ping(self, msg): self._log.info('Pinged %s ' % msg) pinger = CryptoPeerConnection(self,msg['uri'], msg['pubkey'], msg['senderGUID']) pinger.send_raw(json.dumps( {"type": "hello_response", "senderGUID": self.guid, "uri": self._uri, "senderNick": self._nickname, "pubkey": self.pubkey, })) def _storeValue(self, msg): self._dht._on_storeValue(msg) def _findNode(self, msg): self._dht.on_find_node(msg) def _findNodeResponse(self, msg): self._dht.on_findNodeResponse(self, msg) def _setup_settings(self): self.settings = self._db.settings.find_one({'id':"%s" % self._market_id}) if self.settings: self._nickname = self.settings['nickname'] if self.settings.has_key("nickname") else "" self.secret = self.settings['secret'] if self.settings.has_key("secret") else "" self.pubkey = self.settings['pubkey'] if self.settings.has_key("pubkey") else "" self.guid = self.settings['guid'] if self.settings.has_key("guid") else "" self.sin = self.settings['sin'] if self.settings.has_key("sin") else "" self.bitmessage = self.settings['bitmessage'] if self.settings.has_key('bitmessage') else "" else: self._nickname = 'Default' # Generate Bitcoin keypair self._generate_new_keypair() # Generate Bitmessage address if self._bitmessage_api is not None: self._generate_new_bitmessage_address() # Generate PGP key gpg = gnupg.GPG() input_data = gpg.gen_key_input(key_type="RSA", key_length=2048, name_comment="Autogenerated by Open Bazaar", passphrase="P@ssw0rd") key = gpg.gen_key(input_data) pubkey_text = gpg.export_keys(key.fingerprint) self._db.settings.update({"id":'%s' % self._market_id}, {"$set": {"PGPPubKey":pubkey_text, "PGPPubkeyFingerprint":key.fingerprint}}, True) self.settings = self._db.settings.find_one({'id':"%s" % self._market_id}) self._log.debug('Retrieved Settings: %s', self.settings) def _generate_new_keypair(self): # Generate new keypair key = ec.ECC(curve='secp256k1') self.secret = key.get_privkey().encode('hex') pubkey = key.get_pubkey() signedPubkey = key.sign(pubkey) self.pubkey = pubkey.encode('hex') self._myself = key # Generate SIN sha_hash = hashlib.sha256() sha_hash.update(pubkey) ripe_hash = hashlib.new('ripemd160') ripe_hash.update(sha_hash.digest()) self.guid = ripe_hash.digest().encode('hex') self.sin = obelisk.EncodeBase58Check('\x0F\x02%s' + ripe_hash.digest()) self._db.settings.update({"id":'%s' % self._market_id}, {"$set": {"secret":self.secret, "pubkey":self.pubkey, "guid":self.guid, "sin":self.sin}}, True) def _generate_new_bitmessage_address(self): # Use the guid generated previously as the key self.bitmessage = self._bitmessage_api.createRandomAddress(self.guid.encode('base64'), False, 1.05, 1.1111) self._db.settings.update({"id":'%s' % self._market_id}, {"$set": {"bitmessage":self.bitmessage}}, True) def join_network(self, dev_mode=0, callback=lambda msg: None): if dev_mode: self._log.info('DEV MODE') seed_peers = {'127.0.0.1'} else: seed_peers = ('seed.openbazaar.org', 'seed2.openbazaar.org') for seed in seed_peers: self._log.info('Initializing Seed Peer(s): [%s]' % seed) def cb(msg): self._dht._iterativeFind(self._guid, self._dht._knownNodes, 'findNode') callback(msg) self.connect('tcp://%s:12345' % seed, callback=cb) # Try to connect to known peers known_peers = self._db.peers.find() for known_peer in known_peers: def cb(msg): #self._dht._iterativeFind(self._guid, self._dht._knownNodes, 'findNode') callback(msg) self.connect(known_peer['uri'], callback=cb) # self.listen(self.pubkey) # Turn on zmq socket # # if seed_uri: # self._log.info('Initializing Seed Peer(s): [%s]' % seed_uri) # seed_peer = CryptoPeerConnection(self, seed_uri) # self._dht.start(seed_peer) def connect(self, uri, callback): def cb(msg): ip = urlparse(uri).hostname port = urlparse(uri).port self._dht.add_known_node((ip, port, peer._guid)) # Turning off peers #self._init_peer({'uri': seed_uri, 'guid':seed_guid}) # Add to routing table #self.addCryptoPeer(peer) callback(msg) peer = CryptoPeerConnection(self, uri, callback=cb) return peer def get_crypto_peer(self, guid, uri, pubkey=None, nickname=None): if guid == self.guid: self._log.info('Trying to get crypto peer for yourself') return self._log.info('%s %s %s %s' % (guid, uri, pubkey, nickname)) peer = CryptoPeerConnection(self, uri, pubkey, guid=guid, nickname=nickname) return peer def addCryptoPeer(self, peer_to_add): foundOutdatedPeer = False for idx, peer in enumerate(self._dht._activePeers): if (peer._address, peer._guid, peer._pub) == (peer_to_add._address, peer_to_add._guid, peer_to_add._pub): self._log.info('Found existing peer, not adding.') return if peer._guid == peer_to_add._guid or peer._pub == peer_to_add._pub or peer._address == peer_to_add._address: foundOutdatedPeer = True self._log.info('Found an outdated peer') # Update existing peer self._activePeers[idx] = peer_to_add if not foundOutdatedPeer and peer_to_add._guid != self._guid: self._log.info('Adding crypto peer at %s' % peer_to_add._nickname) self._dht.add_active_peer(self, (peer_to_add._pub, peer_to_add._address, peer_to_add._guid, peer_to_add._nickname)) # Return data array with details from the crypto file # TODO: This needs to be protected better; potentially encrypted file or DB @staticmethod def load_crypto_details(store_file): with open(store_file) as f: data = json.loads(f.read()) assert "nickname" in data assert "secret" in data assert "pubkey" in data assert len(data["secret"]) == 2 * 32 assert len(data["pubkey"]) == 2 * 33 return data["nickname"], data["secret"].decode("hex"), \ data["pubkey"].decode("hex") def get_profile(self): peers = {} self.settings = self._db.settings.find_one({'id':"%s" % self._market_id}) for uri, peer in self._peers.iteritems(): if peer._pub: peers[uri] = peer._pub.encode('hex') return {'uri': self._uri, 'pub': self._myself.get_pubkey().encode('hex'),'nickname': self._nickname, 'peers': peers} def respond_pubkey_if_mine(self, nickname, ident_pubkey): if ident_pubkey != self.pubkey: self._log.info("Public key does not match your identity") return # Return signed pubkey pubkey = self._myself.pubkey ec_key = obelisk.EllipticCurveKey() ec_key.set_secret(self.secret) digest = obelisk.Hash(pubkey) signature = ec_key.sign(digest) # Send array of nickname, pubkey, signature to transport layer self.send(proto_response_pubkey(nickname, pubkey, signature)) def pubkey_exists(self, pub): for uri, peer in self._peers.iteritems(): self._log.info('PEER: %s Pub: %s' % (peer._pub.encode('hex'), pub.encode('hex'))) if peer._pub.encode('hex') == pub.encode('hex'): return True return False def create_peer(self, uri, pub, node_guid): if pub: pub = pub.decode('hex') # Create the peer if public key is not already in the peer list # if not self.pubkey_exists(pub): self._peers[uri] = CryptoPeerConnection(self, uri, pub, node_guid) # Call 'peer' callbacks on listeners self.trigger_callbacks('peer', self._peers[uri]) # else: # print 'Pub Key is already in peer list' def send(self, data, send_to=None, callback=lambda msg: None): self._log.debug("Outgoing Data: %s %s" % (data, send_to)) # Directed message if send_to is not None: peer = self._dht._routingTable.getContact(send_to) #peer = CryptoPeerConnection(msg['uri']) if peer: self._log.debug('Directed Data (%s): %s' % (send_to, data)) try: peer.send(data, callback=callback) except: self._log.error('Not sending messing directly to peer') else: self._log.error('No peer found') else: # FindKey and then send for peer in self._dht._activePeers: try: peer = self._dht._routingTable.getContact(peer._guid) data['senderGUID'] = self._guid data['pubkey'] = self.pubkey print data #if peer._pub: # peer.send(data, callback) #else: def cb(msg): print 'msg %s' % msg peer.send(data, cb) except: self._log.info("Error sending over peer!") traceback.print_exc() def send_enc(self, uri, msg): peer = self._peers[uri] pub = peer._pub # Now send a hello message to the peer if pub: self._log.info("Sending encrypted [%s] message to %s" % (msg['type'], uri)) peer.send(msg) else: # Will send clear profile on initial if no pub self._log.info("Sending unencrypted [%s] message to %s" % (msg['type'], uri)) self._peers[uri].send_raw(json.dumps(msg)) def _init_peer(self, msg): uri = msg['uri'] pub = msg.get('pub') nickname = msg.get('nickname') msg_type = msg.get('type') guid = msg['guid'] if not self.valid_peer_uri(uri): self._log.error("Invalid Peer: %s " % uri) return if uri not in self._peers: # Unknown peer self._log.info('Add New Peer: %s' % uri) self.create_peer(uri, pub, guid) if not msg_type: self.send_enc(uri, hello_request(self.get_profile())) elif msg_type == 'hello_request': self.send_enc(uri, hello_response(self.get_profile())) else: # Known peer if pub: # test if we have to update the pubkey if not self._peers[uri]._pub: self._log.info("Setting public key for seed node") self._peers[uri]._pub = pub.decode('hex') self.trigger_callbacks('peer', self._peers[uri]) if self._peers[uri]._pub != pub.decode('hex'): self._log.info("Updating public key for node") self._peers[uri]._nickname = nickname self._peers[uri]._pub = pub.decode('hex') self.trigger_callbacks('peer', self._peers[uri]) if msg_type == 'hello_request': # reply only if necessary self.send_enc(uri, hello_response(self.get_profile())) def _on_message(self, msg): # here goes the application callbacks # we get a "clean" msg which is a dict holding whatever #self._log.info("[On Message] Data received: %s" % msg) pubkey = msg.get('pubkey') uri = msg.get('uri') ip = urlparse(uri).hostname port = urlparse(uri).port guid = msg.get('senderGUID') nickname = msg.get('senderNick') self._log.info('on message %s' % nickname) self._dht.add_known_node((ip, port, guid, nickname)) self._dht.add_active_peer(self, (pubkey, uri, guid, nickname)) self.trigger_callbacks(msg['type'], msg) def _on_raw_message(self, serialized): try: # Try to de-serialize clear text message msg = json.loads(serialized) self._log.info("Message Received [%s]" % msg.get('type', 'unknown')) if msg.get('type') is None: data = msg.get('data').decode('hex') sig = msg.get('sig').decode('hex') try: data = self._myself.decrypt(data) self._log.debug('Signature: %s' % sig.encode('hex')) self._log.debug('Signed Data: %s' % data) guid = json.loads(data).get('guid') peer = self._dht._routingTable.getContact(guid) ecc = ec.ECC(curve='secp256k1',pubkey=json.loads(data).get('pubkey').decode('hex')) # Check signature if ecc.verify(sig, data): self._log.info('Verified') else: self._log.error('Message signature could not be verified %s' % msg) return msg = json.loads(data) self._log.debug('Message Data %s ' % msg) except: self._log.error('Could not decrypt message properly') except ValueError: try: # Encrypted? try: msg = self._myself.decrypt(serialized) msg = json.loads(msg) self._log.info("Decrypted Message [%s]" % msg.get('type', 'unknown')) except: self._log.error("Could not decrypt message: %s" % msg) return except: self._log.error('Message probably sent using incorrect pubkey') return if msg.get('type') is not None: msg_type = msg.get('type') msg_uri = msg.get('uri') msg_guid = msg.get('guid') self._on_message(msg) else: self._log.error('Received a message with no type')
'naziv' + str(i), 'type': dht.config.category_names[random.randint( 0, len(dht.config.category_names) - 1)], 'description': 'Opis ' + str(i), 'ingredients': ['Sastojak_1_' + str(i), 'Sastojak_2_' + str(i), 'Sastojak_3_' + str(i)], 'picture': None } for i in range(RECEPTI_NUM)] random.setstate(state) dht = [ DHT(dht.config.BOOTSTRAP_HOST, 3001 + i, dht.config.regions[i % len(dht.config.regions)]) for i in range(DHT_NUM) ] # Sacekaj dok se svi konektuju all_connected = False while not all_connected: all_connected = True for d in dht: if not d.connected: all_connected = False break print "KONEKCIJE" for d in dht: print d.peer.address()
'naziv' + str(i), 'type': dht.config.category_names[random.randint( 0, len(dht.config.category_names) - 1)], 'description': 'Opis ' + str(i), 'ingredients': ['Sastojak_1_' + str(i), 'Sastojak_2_' + str(i), 'Sastojak_3_' + str(i)], 'picture': None } for i in range(RECEPTI_NUM)] random.setstate(state) dht = [ DHT("localhost", 3001 + i, dht.config.regions[i % len(dht.config.regions)]) for i in range(DHT_NUM) ] # Sacekaj dok se svi konektuju all_connected = False while not all_connected: all_connected = True for d in dht: if not d.connected: all_connected = False break print "KONEKCIJE" for d in dht: print d.peer.address()
def salvando_dados_local(umidade,temperatura): print 'Salvando dados localmente' DHT.saveToDatabase(temperatura,umidade) print "Dados salvos com sucesso!"
class RATPWithExtras: def __init__(self, lcd_rs_pin, lcd_e_pin, lcd_db_pins, button_pin, dht_pin): # LCD self.lcd_rs_pin = lcd_rs_pin self.lcd_e_pin = lcd_e_pin self.lcd_db_pins = lcd_db_pins # Button self.button_pin = button_pin # DHT self.dht_type = Adafruit_DHT.DHT22 self.dht_pin = dht_pin self.dht = DHT(self.dht_pin, self.dht_type) self.lcd = HD44780(self.lcd_e_pin, self.lcd_rs_pin, self.lcd_db_pins) self.cur_transport = 0 self.transports = TRANSPORTS_TO_SHOW[self.cur_transport] def set_temp_if_there(self, temp, col, sign, length): temp_string = str(temp) if temp_string != "None": temp_string = str(round(temp, 1)) self.lcd.message_at(METADATA_LINE, col, temp_string + sign, length) def set_humidity(self, temp, col, sign, length): temp_string = str(temp) if temp_string != "None": temp_string = str(round(temp, 1)) self.lcd.message_at(METADATA_LINE, col, temp_string + sign, length) def set_trans(self, time, row): timings = time_converter.get_timings(time) if isinstance(timings, time_converter.RegularTimings): self.lcd.message_at(row, 4, timings.first_destination, LEN_DESTINATION) self.lcd.message_at(row, 12, " ", LEN_SPACE) self.lcd.message_at(row, 13, timings.first_timing, LEN_TIME) self.lcd.message_at(row, 16, "/", LEN_SEPARATOR) self.lcd.message_at(row, 17, timings.second_timing, LEN_TIME) elif isinstance(timings, time_converter.TimingIssue): self.lcd.message_at( row, 4, timings.message, LEN_DESTINATION + LEN_SPACE + LEN_TIME + LEN_SEPARATOR + LEN_TIME) def update_destinations_temperature(self): next_first = get_page(BUS_TIMES[self.transports[0]]) self.set_trans(next_first, BUS_LINE_1) next_second = get_page(BUS_TIMES[self.transports[1]]) self.set_trans(next_second, BUS_LINE_2) self.lcd.message_at(METADATA_LINE, 0, strftime("%H:%M"), LEN_CLOCK) humidity, temp = self.dht.get_temp_humidity() temp_string = str(temp) if temp_string != "None": temp_string = str(round(temp, 1)) self.lcd.message_at(METADATA_LINE, 7, temp_string + chr(223) + "C", LEN_TEMP) humidity_string = str(humidity) if humidity_string != "None": humidity_string = str(round(humidity, 1)) self.lcd.message_at(METADATA_LINE, 15, humidity_string + "%", LEN_HUMIDITY) def init_gpio(self): GPIO.setmode(GPIO.BCM) GPIO.setup(self.button_pin, GPIO.IN) GPIO.add_event_detect(self.button_pin, GPIO.FALLING, callback=self.cycle) self.dht.init_gpio() self.lcd.init_gpio() # noinspection PyUnusedLocal def cycle(self, channel): self.cur_transport = (self.cur_transport + 1) % len(TRANSPORTS_TO_SHOW) self.transports = TRANSPORTS_TO_SHOW[self.cur_transport] self.set_destinations() self.update_destinations_temperature() def set_destinations(self): self.lcd.message_at(BUS_LINE_1, 0, self.transports[0][:-1], LEN_DESTINATION_NUMBER) self.lcd.message_at(BUS_LINE_2, 0, self.transports[1][:-1], LEN_DESTINATION_NUMBER) self.lcd.message_at(INTERMEDIATE_LINE, 0, "--------------------", LEN_FULLLINE) def clean(self): self.lcd.clear() GPIO.remove_event_detect(self.button_pin) GPIO.cleanup()
from network import WLAN import urequests as requests import machine import time from dht import DHT from machine import Pin TOKEN = "Token here" #Put here your TOKEN DELAY = 60 # Delay in seconds th = DHT(Pin('P23', mode=Pin.OPEN_DRAIN), 0) # DHT sensor is connected to port 23 time.sleep(2) # wait 2 seconds wlan = WLAN(mode=WLAN.STA) wlan.antenna(WLAN.INT_ANT) # Assign your Wi-Fi credentials wlan.connect("wifi-name", auth=(WLAN.WPA2, "wifi-password"), timeout=5000) while not wlan.isconnected(): machine.idle() print("Connected to Wifi\n") # Builds the json to send the request def build_json(variable1, value1, variable2, value2): try: data = {variable1: {"value": value1}, variable2: {"value": value2}} return data except:
class CryptoTransportLayer(TransportLayer): def __init__(self, my_ip, my_port, market_id, db, bm_user=None, bm_pass=None, bm_port=None, seed_mode=0, dev_mode=False, disable_ip_update=False): self.log = logging.getLogger( '[%s] %s' % (market_id, self.__class__.__name__) ) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) # Connect to database self.db = db self.bitmessage_api = None if (bm_user, bm_pass, bm_port) != (None, None, None): if not self._connect_to_bitmessage(bm_user, bm_pass, bm_port): self.log.info('Bitmessage not installed or started') try: socket.inet_pton(socket.AF_INET6, my_ip) my_uri = "tcp://[%s]:%s" % (my_ip, my_port) except (socket.error, ValueError): my_uri = "tcp://%s:%s" % (my_ip, my_port) self.market_id = market_id self.nick_mapping = {} self.uri = my_uri self.ip = my_ip self.nickname = "" self._dev_mode = dev_mode # Set up self._setup_settings() self.dht = DHT(self, self.market_id, self.settings, self.db) # self._myself = ec.ECC(pubkey=self.pubkey.decode('hex'), # privkey=self.secret.decode('hex'), # curve='secp256k1') TransportLayer.__init__(self, market_id, my_ip, my_port, self.guid, self.nickname) self.setup_callbacks() self.listen(self.pubkey) if seed_mode == 0 and not dev_mode and not disable_ip_update: self.start_ip_address_checker() def setup_callbacks(self): self.add_callbacks([('hello', self._ping), ('findNode', self._find_node), ('findNodeResponse', self._find_node_response), ('store', self._store_value)]) def start_ip_address_checker(self): '''Checks for possible public IP change''' self.caller = PeriodicCallback(self._ip_updater_periodic_callback, 5000, ioloop.IOLoop.instance()) self.caller.start() def _ip_updater_periodic_callback(self): try: r = requests.get('http://ipv4.icanhazip.com') if r and hasattr(r, 'text'): ip = r.text ip = ip.strip(' \t\n\r') if ip != self.ip: self.ip = ip try: socket.inet_pton(socket.AF_INET6, self.ip) my_uri = 'tcp://[%s]:%s' % (self.ip, self.port) except (socket.error, ValueError): my_uri = 'tcp://%s:%s' % (self.ip, self.port) self.uri = my_uri self.stream.close() self.listen(self.pubkey) self.dht._iterativeFind(self.guid, [], 'findNode') else: self.log.error('Could not get IP') except Exception as e: self.log.error('[Requests] error: %s' % e) def save_peer_to_db(self, peer_tuple): uri = peer_tuple[0] pubkey = peer_tuple[1] guid = peer_tuple[2] nickname = peer_tuple[3] # Update query self.db.deleteEntries("peers", {"uri": uri, "guid": guid}, "OR") # if len(results) > 0: # self.db.updateEntries("peers", {"id": results[0]['id']}, {"market_id": self.market_id, "uri": uri, "pubkey": pubkey, "guid": guid, "nickname": nickname}) # else: if guid is not None: self.db.insertEntry("peers", { "uri": uri, "pubkey": pubkey, "guid": guid, "nickname": nickname, "market_id": self.market_id }) def _connect_to_bitmessage(self, bm_user, bm_pass, bm_port): # Get bitmessage going # First, try to find a local instance result = False try: self.log.info('[_connect_to_bitmessage] Connecting to Bitmessage on port %s' % bm_port) self.bitmessage_api = xmlrpclib.ServerProxy("http://{}:{}@localhost:{}/".format(bm_user, bm_pass, bm_port), verbose=0) result = self.bitmessage_api.add(2, 3) self.log.info("[_connect_to_bitmessage] Bitmessage API is live: %s", result) # If we failed, fall back to starting our own except Exception as e: self.log.info("Failed to connect to bitmessage instance: {}".format(e)) self.bitmessage_api = None # self._log.info("Spawning internal bitmessage instance") # # Add bitmessage submodule path # sys.path.insert(0, os.path.join( # os.path.dirname(__file__), '..', 'pybitmessage', 'src')) # import bitmessagemain as bitmessage # bitmessage.logger.setLevel(logging.WARNING) # bitmessage_instance = bitmessage.Main() # bitmessage_instance.start(daemon=True) # bminfo = bitmessage_instance.getApiAddress() # if bminfo is not None: # self._log.info("Started bitmessage daemon at %s:%s".format( # bminfo['address'], bminfo['port'])) # bitmessage_api = xmlrpclib.ServerProxy("http://{}:{}@{}:{}/".format( # bm_user, bm_pass, bminfo['address'], bminfo['port'])) # else: # self._log.info("Failed to start bitmessage dameon") # self._bitmessage_api = None return result def _checkok(self, msg): self.log.info('Check ok') def get_guid(self): return self.guid def get_dht(self): return self.dht def get_bitmessage_api(self): return self.bitmessage_api def get_market_id(self): return self.market_id # def get_myself(self): # return self._myself def _ping(self, msg): self.log.info('Pinged %s ' % json.dumps(msg, ensure_ascii=False)) # # pinger = CryptoPeerConnection(self, msg['uri'], msg['pubkey'], msg['senderGUID']) # pinger.send_raw(json.dumps( # {"type": "hello_response", # "senderGUID": self.guid, # "uri": self.uri, # "senderNick": self.nickname, # "pubkey": self.pubkey, # })) def _store_value(self, msg): self.dht._on_storeValue(msg) def _find_node(self, msg): self.dht.on_find_node(msg) def _find_node_response(self, msg): self.dht.on_findNodeResponse(self, msg) def _setup_settings(self): try: self.settings = self.db.selectEntries("settings", {"market_id": self.market_id}) except (OperationalError, DatabaseError) as e: print e raise SystemExit("database file %s corrupt or empty - cannot continue" % self.db.db_path) if len(self.settings) == 0: self.settings = {"market_id": self.market_id, "welcome": "enable"} self.db.insertEntry("settings", self.settings) else: self.settings = self.settings[0] # Generate PGP key during initial setup or if previous PGP gen failed if not ('PGPPubKey' in self.settings and self.settings["PGPPubKey"]): try: self.log.info('Generating PGP keypair. This may take several minutes...') print 'Generating PGP keypair. This may take several minutes...' gpg = gnupg.GPG() input_data = gpg.gen_key_input(key_type="RSA", key_length=2048, name_email='*****@*****.**', name_comment="Autogenerated by Open Bazaar", passphrase="P@ssw0rd") assert input_data is not None key = gpg.gen_key(input_data) assert key is not None pubkey_text = gpg.export_keys(key.fingerprint) newsettings = {"PGPPubKey": pubkey_text, "PGPPubkeyFingerprint": key.fingerprint} self.db.updateEntries("settings", {"market_id": self.market_id}, newsettings) self.settings.update(newsettings) self.log.info('PGP keypair generated.') except Exception as e: self.log.error("Encountered a problem with GPG: %s" % e) raise SystemExit("Encountered a problem with GPG: %s" % e) if not ('pubkey' in self.settings and self.settings['pubkey']): # Generate Bitcoin keypair self._generate_new_keypair() if not ('nickname' in self.settings and self.settings['nickname']): newsettings = {'nickname': 'Default'} self.db.updateEntries('settings', {"market_id": self.market_id}, newsettings) self.settings.update(newsettings) self.nickname = self.settings['nickname'] if 'nickname' in self.settings else "" self.secret = self.settings['secret'] if 'secret' in self.settings else "" self.pubkey = self.settings['pubkey'] if 'pubkey' in self.settings else "" self.privkey = self.settings.get('privkey') self.btc_pubkey = privkey_to_pubkey(self.privkey) self.guid = self.settings['guid'] if 'guid' in self.settings else "" self.sin = self.settings['sin'] if 'sin' in self.settings else "" self.bitmessage = self.settings['bitmessage'] if 'bitmessage' in self.settings else "" if not ('bitmessage' in self.settings and self.settings['bitmessage']): # Generate Bitmessage address if self.bitmessage_api is not None: self._generate_new_bitmessage_address() self._myself = ec.ECC( pubkey=pubkey_to_pyelliptic(self.pubkey).decode('hex'), raw_privkey=self.secret.decode('hex'), curve='secp256k1' ) self.log.debug('Retrieved Settings: \n%s', pformat(self.settings)) def _generate_new_keypair(self): secret = str(random.randrange(2 ** 256)) self.secret = hashlib.sha256(secret).hexdigest() self.pubkey = privtopub(self.secret) self.privkey = random_key() print 'PRIVATE KEY: ', self.privkey self.btc_pubkey = privtopub(self.privkey) print 'PUBLIC KEY: ', self.btc_pubkey # Generate SIN sha_hash = hashlib.sha256() sha_hash.update(self.pubkey) ripe_hash = hashlib.new('ripemd160') ripe_hash.update(sha_hash.digest()) self.guid = ripe_hash.digest().encode('hex') self.sin = obelisk.EncodeBase58Check('\x0F\x02%s' + ripe_hash.digest()) newsettings = { "secret": self.secret, "pubkey": self.pubkey, "privkey": self.privkey, "guid": self.guid, "sin": self.sin } self.db.updateEntries("settings", {"market_id": self.market_id}, newsettings) self.settings.update(newsettings) def _generate_new_bitmessage_address(self): # Use the guid generated previously as the key self.bitmessage = self.bitmessage_api.createRandomAddress( self.guid.encode('base64'), False, 1.05, 1.1111 ) newsettings = {"bitmessage": self.bitmessage} self.db.updateEntries("settings", {"market_id": self.market_id}, newsettings) self.settings.update(newsettings) def join_network(self, seed_peers=None, callback=lambda msg: None): if seed_peers is None: seed_peers = [] self.log.info('Joining network') known_peers = [] # Connect up through seed servers for idx, seed in enumerate(seed_peers): try: socket.inet_pton(socket.AF_INET6, seed) seed_peers[idx] = "tcp://[%s]:12345" % seed except (socket.error, ValueError): seed_peers[idx] = "tcp://%s:12345" % seed # Connect to persisted peers db_peers = self.get_past_peers() known_peers = list(set(seed_peers)) + list(set(db_peers)) self.connect_to_peers(known_peers) # TODO: This needs rethinking. Normally we can search for ourselves # but because we are not connected to them quick enough this # will always fail. Need @gubatron to review # Populate routing table by searching for self # if len(known_peers) > 0: # self.search_for_my_node() if callback is not None: callback('Joined') def get_past_peers(self): peers = [] result = self.db.selectEntries("peers", {"market_id": self.market_id}) for peer in result: peers.append(peer['uri']) return peers def search_for_my_node(self): print 'Searching for myself' self.dht._iterativeFind(self.guid, self.dht.knownNodes, 'findNode') def connect_to_peers(self, known_peers): for known_peer in known_peers: t = Thread(target=self.dht.add_peer, args=(self, known_peer,)) t.start() def get_crypto_peer(self, guid=None, uri=None, pubkey=None, nickname=None, callback=None): if guid == self.guid: self.log.error('Cannot get CryptoPeerConnection for your own node') return self.log.debug('Getting CryptoPeerConnection' + '\nGUID:%s\nURI:%s\nPubkey:%s\nNickname:%s' % (guid, uri, pubkey, nickname)) return connection.CryptoPeerConnection(self, uri, pubkey, guid=guid, nickname=nickname) def addCryptoPeer(self, peer_to_add): foundOutdatedPeer = False for idx, peer in enumerate(self.dht.activePeers): if (peer.address, peer.guid, peer.pub) == \ (peer_to_add.address, peer_to_add.guid, peer_to_add.pub): self.log.info('Found existing peer, not adding.') return if peer.guid == peer_to_add.guid or \ peer.pub == peer_to_add.pub or \ peer.address == peer_to_add.address: foundOutdatedPeer = True self.log.info('Found an outdated peer') # Update existing peer self.activePeers[idx] = peer_to_add self.dht.add_peer(self, peer_to_add.address, peer_to_add.pub, peer_to_add.guid, peer_to_add.nickname) if not foundOutdatedPeer and peer_to_add.guid != self.guid: self.log.info('Adding crypto peer at %s' % peer_to_add.nickname) self.dht.add_peer(self, peer_to_add.address, peer_to_add.pub, peer_to_add.guid, peer_to_add.nickname) def get_profile(self): peers = {} self.settings = self.db.selectEntries("settings", {"market_id": self.market_id})[0] for uri, peer in self.peers.iteritems(): if peer.pub: peers[uri] = peer.pub.encode('hex') return {'uri': self.uri, 'pub': self._myself.get_pubkey().encode('hex'), 'nickname': self.nickname, 'peers': peers} def respond_pubkey_if_mine(self, nickname, ident_pubkey): if ident_pubkey != self.pubkey: self.log.info("Public key does not match your identity") return # Return signed pubkey pubkey = self._myself.pubkey ec_key = obelisk.EllipticCurveKey() ec_key.set_secret(self.secret) digest = obelisk.Hash(pubkey) signature = ec_key.sign(digest) # Send array of nickname, pubkey, signature to transport layer self.send(proto_response_pubkey(nickname, pubkey, signature)) def pubkey_exists(self, pub): for peer in self.peers.itervalues(): self.log.info( 'PEER: %s Pub: %s' % ( peer.pub.encode('hex'), pub.encode('hex') ) ) if peer.pub.encode('hex') == pub.encode('hex'): return True return False def create_peer(self, uri, pub, node_guid): if pub: pub = pub.decode('hex') # Create the peer if public key is not already in the peer list # if not self.pubkey_exists(pub): self.peers[uri] = connection.CryptoPeerConnection(self, uri, pub, node_guid) # Call 'peer' callbacks on listeners self.trigger_callbacks('peer', self.peers[uri]) # else: # print 'Pub Key is already in peer list' def send(self, data, send_to=None, callback=lambda msg: None): self.log.debug("Outgoing Data: %s %s" % (data, send_to)) # Directed message if send_to is not None: peer = self.dht.routingTable.getContact(send_to) if not peer: for activePeer in self.dht.activePeers: if activePeer.guid == send_to: peer = activePeer break # peer = CryptoPeerConnection(msg['uri']) if peer: self.log.debug('Directed Data (%s): %s' % (send_to, data)) try: peer.send(data, callback=callback) except Exception as e: self.log.error('Not sending message directly to peer %s' % e) else: self.log.error('No peer found') else: # FindKey and then send for peer in self.dht.activePeers: try: peer = self.dht.routingTable.getContact(peer.guid) data['senderGUID'] = self.guid data['pubkey'] = self.pubkey def cb(msg): self.log.debug('Message Back: \n%s' % pformat(msg)) peer.send(data, cb) except: self.log.info("Error sending over peer!") traceback.print_exc() def send_enc(self, uri, msg): peer = self.peers[uri] pub = peer.pub # Now send a hello message to the peer if pub: self.log.info( "Sending encrypted [%s] message to %s" % ( msg['type'], uri ) ) peer.send(msg) else: # Will send clear profile on initial if no pub self.log.info( "Sending unencrypted [%s] message to %s" % ( msg['type'], uri ) ) self.peers[uri].send_raw(json.dumps(msg)) def _init_peer(self, msg): uri = msg['uri'] pub = msg.get('pub') nickname = msg.get('nickname') msg_type = msg.get('type') guid = msg['guid'] if not self.valid_peer_uri(uri): self.log.error("Invalid Peer: %s " % uri) return if uri not in self.peers: # Unknown peer self.log.info('Add New Peer: %s' % uri) self.create_peer(uri, pub, guid) if not msg_type: self.send_enc(uri, hello_request(self.get_profile())) elif msg_type == 'hello_request': self.send_enc(uri, hello_response(self.get_profile())) else: # Known peer if pub: # test if we have to update the pubkey if not self.peers[uri].pub: self.log.info("Setting public key for seed node") self.peers[uri].pub = pub.decode('hex') self.trigger_callbacks('peer', self.peers[uri]) if self.peers[uri].pub != pub.decode('hex'): self.log.info("Updating public key for node") self.peers[uri].nickname = nickname self.peers[uri].pub = pub.decode('hex') self.trigger_callbacks('peer', self.peers[uri]) if msg_type == 'hello_request': # reply only if necessary self.send_enc(uri, hello_response(self.get_profile())) def _on_message(self, msg): # here goes the application callbacks # we get a "clean" msg which is a dict holding whatever # self.log.info("[On Message] Data received: %s" % msg) pubkey = msg.get('pubkey') uri = msg.get('uri') ip = urlparse(uri).hostname port = urlparse(uri).port guid = msg.get('senderGUID') nickname = msg.get('senderNick')[:120] self.dht.add_known_node((ip, port, guid, nickname)) self.log.info('On Message: %s' % json.dumps(msg, ensure_ascii=False)) self.dht.add_peer(self, uri, pubkey, guid, nickname) t = Thread(target=self.trigger_callbacks, args=(msg['type'], msg,)) t.start() def _on_raw_message(self, serialized): try: msg = json.loads(serialized) self.log.info("Message Received [%s]" % msg.get('type', 'unknown')) if msg.get('type') is None: data = msg.get('data').decode('hex') sig = msg.get('sig').decode('hex') try: cryptor = makePrivCryptor(self.secret) try: data = cryptor.decrypt(data) except Exception as e: self.log.info('Exception: %s' % e) self.log.debug('Signature: %s' % sig.encode('hex')) self.log.debug('Signed Data: %s' % data) # Check signature data_json = json.loads(data) sigCryptor = makePubCryptor(data_json['pubkey']) if sigCryptor.verify(sig, data): self.log.info('Verified') else: self.log.error('Message signature could not be verified %s' % msg) # return msg = json.loads(data) self.log.debug('Message Data %s ' % msg) except Exception as e: self.log.error('Could not decrypt message properly %s' % e) except ValueError: try: # Encrypted? try: msg = self._myself.decrypt(serialized) msg = json.loads(msg) self.log.info( "Decrypted Message [%s]" % msg.get('type', 'unknown') ) except: self.log.error("Could not decrypt message: %s" % msg) return except: self.log.error('Message probably sent using incorrect pubkey') return if msg.get('type') is not None: self._on_message(msg) else: self.log.error('Received a message with no type') def shutdown(self): print "CryptoTransportLayer.shutdown()!" try: TransportLayer.shutdown(self) print "CryptoTransportLayer.shutdown(): ZMQ sockets destroyed." except Exception as e: self.log.error("Transport shutdown error: " + e.message) print "Notice: explicit DHT Shutdown not implemented." try: self.bitmessage_api.close() except Exception as e: # might not even be open, not much more we can do on our way out if exception thrown here. self.log.error("Could not shutdown bitmessage_api's ServerProxy. " + e.message)
class CryptoTransportLayer(TransportLayer): def __init__(self, my_ip, my_port, market_id, bm_user=None, bm_pass=None, bm_port=None): self._log = logging.getLogger('[%s] %s' % (market_id, self.__class__.__name__)) # Connect to database MONGODB_URI = 'mongodb://*****:*****@localhost:{}/".format(bm_user, bm_pass, bm_port), verbose=1) result = self._bitmessage_api.add(2,3) self._log.info("Bitmessage test result: {}, API is live".format(result)) # If we failed, fall back to starting our own except Exception as e: self._log.info("Failed to connect to bitmessage instance: {}".format(e)) # self._log.info("Spawning internal bitmessage instance") # # Add bitmessage submodule path # sys.path.insert(0, os.path.join( # os.path.dirname(__file__), '..', 'pybitmessage', 'src')) # import bitmessagemain as bitmessage # bitmessage.logger.setLevel(logging.WARNING) # bitmessage_instance = bitmessage.Main() # bitmessage_instance.start(daemon=True) # bminfo = bitmessage_instance.getApiAddress() # if bminfo is not None: # self._log.info("Started bitmessage daemon at %s:%s".format( # bminfo['address'], bminfo['port'])) # bitmessage_api = xmlrpclib.ServerProxy("http://{}:{}@{}:{}/".format( # bm_user, bm_pass, bminfo['address'], bminfo['port'])) # else: # self._log.info("Failed to start bitmessage dameon") # self._bitmessage_api = None return result def _checkok(self, msg): self._log.info('Check ok') def get_guid(self): return self._guid def getDHT(self): return self._dht def getBitmessageAPI(self): return self._bitmessage_api def getMarketID(self): return self._market_id def getMyself(self): return self._myself def _ping(self, msg): self._log.info('Pinged %s ' % msg) pinger = CryptoPeerConnection(self,msg['uri'], msg['pubkey'], msg['senderGUID']) pinger.send_raw(json.dumps( {"type": "hello_response", "senderGUID": self.guid, "uri": self._uri, "pubkey": self.pubkey, })) def _storeValue(self, msg): self._dht._on_storeValue(msg) def _findNode(self, msg): self._dht.on_find_node(msg) def _findNodeResponse(self, msg): self._dht.on_findNodeResponse(self, msg) def _setup_settings(self): self.settings = self._db.settings.find_one({'id':"%s" % self._market_id}) if self.settings: self.nickname = self.settings['nickname'] if self.settings.has_key("nickname") else "" self.secret = self.settings['secret'] if self.settings.has_key("secret") else "" self.pubkey = self.settings['pubkey'] if self.settings.has_key("pubkey") else "" self.guid = self.settings['guid'] if self.settings.has_key("guid") else "" self.bitmessage = self.settings['bitmessage'] if self.settings.has_key('bitmessage') else "" else: self.nickname = 'Default' self._generate_new_keypair() if self._bitmessage_api is not None: self._generate_new_bitmessage_address() self.settings = self._db.settings.find_one({'id':"%s" % self._market_id}) self._log.debug('Retrieved Settings: %s', self.settings) def _generate_new_keypair(self): # Generate new keypair key = ec.ECC(curve='secp256k1') self.secret = key.get_privkey().encode('hex') pubkey = key.get_pubkey() signedPubkey = key.sign(pubkey) self.pubkey = pubkey.encode('hex') self._myself = key # Generate a node ID by ripemd160 hashing the signed pubkey guid = hashlib.new('ripemd160') guid.update(signedPubkey) self.guid = guid.digest().encode('hex') self._db.settings.update({"id":'%s' % self._market_id}, {"$set": {"secret":self.secret, "pubkey":self.pubkey, "guid":self.guid}}, True) def _generate_new_bitmessage_address(self): # Use the guid generated previously as the key self.bitmessage = self._bitmessage_api.createRandomAddress(self.guid.encode('base64'), False, 1.05, 1.1111) self._db.settings.update({"id":'%s' % self._market_id}, {"$set": {"bitmessage":self.bitmessage}}, True) def join_network(self, seed_uri, callback=lambda msg: None): if seed_uri: self._log.info('Initializing Seed Peer(s): [%s]' % (seed_uri)) def cb(msg): self._dht._iterativeFind(self._guid, self._dht._knownNodes, 'findNode') callback(msg) self.connect(seed_uri, callback=cb) # self.listen(self.pubkey) # Turn on zmq socket # # if seed_uri: # self._log.info('Initializing Seed Peer(s): [%s]' % seed_uri) # seed_peer = CryptoPeerConnection(self, seed_uri) # self._dht.start(seed_peer) def connect(self, uri, callback): def cb(msg): ip = urlparse(uri).hostname port = urlparse(uri).port self._dht.add_known_node((ip, port, peer._guid)) # Turning off peers #self.init_peer({'uri': seed_uri, 'guid':seed_guid}) # Add to routing table self.addCryptoPeer(peer) callback(msg) peer = CryptoPeerConnection(self, uri, callback=cb) return peer def get_crypto_peer(self, guid, uri, pubkey=None): if guid == self.guid: self._log.info('Trying to get cryptopeer for yourself') return peer = CryptoPeerConnection(self, uri, pubkey, guid=guid) return peer def addCryptoPeer(self, peer_to_add): foundOutdatedPeer = False for idx, peer in enumerate(self._dht._activePeers): if (peer._address, peer._guid, peer._pub) == (peer_to_add._address, peer_to_add._guid, peer_to_add._pub): self._log.info('Found existing peer, not adding.') return if peer._guid == peer_to_add._guid or peer._pub == peer_to_add._pub or peer._address == peer_to_add._address: foundOutdatedPeer = True self._log.info('Found an outdated peer') # Update existing peer self._activePeers[idx] = peer_to_add if not foundOutdatedPeer and peer_to_add._guid != self._guid: self._log.info('Adding crypto peer at %s' % peer_to_add._address) self._dht.add_active_peer(self, (peer_to_add._pub, peer_to_add._address, peer_to_add._guid)) # Return data array with details from the crypto file # TODO: This needs to be protected better; potentially encrypted file or DB @staticmethod def load_crypto_details(store_file): with open(store_file) as f: data = json.loads(f.read()) assert "nickname" in data assert "secret" in data assert "pubkey" in data assert len(data["secret"]) == 2 * 32 assert len(data["pubkey"]) == 2 * 33 return data["nickname"], data["secret"].decode("hex"), \ data["pubkey"].decode("hex") def get_profile(self): peers = {} self.settings = self._db.settings.find_one({'id':"%s" % self._market_id}) for uri, peer in self._peers.iteritems(): if peer._pub: peers[uri] = peer._pub.encode('hex') return {'uri': self._uri, 'pub': self._myself.get_pubkey().encode('hex'),'nickname': self.nickname, 'peers': peers} def respond_pubkey_if_mine(self, nickname, ident_pubkey): if ident_pubkey != self.pubkey: self._log.info("Public key does not match your identity") return # Return signed pubkey pubkey = self._myself.pubkey ec_key = obelisk.EllipticCurveKey() ec_key.set_secret(self.secret) digest = obelisk.Hash(pubkey) signature = ec_key.sign(digest) # Send array of nickname, pubkey, signature to transport layer self.send(proto_response_pubkey(nickname, pubkey, signature)) def pubkey_exists(self, pub): for uri, peer in self._peers.iteritems(): self._log.info('PEER: %s Pub: %s' % (peer._pub.encode('hex'), pub.encode('hex'))) if peer._pub.encode('hex') == pub.encode('hex'): return True return False def create_peer(self, uri, pub, node_guid): if pub: pub = pub.decode('hex') # Create the peer if public key is not already in the peer list # if not self.pubkey_exists(pub): self._peers[uri] = CryptoPeerConnection(self, uri, pub, node_guid) # Call 'peer' callbacks on listeners self.trigger_callbacks('peer', self._peers[uri]) # else: # print 'Pub Key is already in peer list' def send_enc(self, uri, msg): peer = self._peers[uri] pub = peer._pub # Now send a hello message to the peer if pub: self._log.info("Sending encrypted [%s] message to %s" % (msg['type'], uri)) peer.send(msg) else: # Will send clear profile on initial if no pub self._log.info("Sending unencrypted [%s] message to %s" % (msg['type'], uri)) self._peers[uri].send_raw(json.dumps(msg)) def init_peer(self, msg): uri = msg['uri'] pub = msg.get('pub') nickname = msg.get('nickname') msg_type = msg.get('type') guid = msg['guid'] if not self.valid_peer_uri(uri): self._log.error("Invalid Peer: %s " % uri) return if uri not in self._peers: # Unknown peer self._log.info('Add New Peer: %s' % uri) self.create_peer(uri, pub, guid) if not msg_type: self.send_enc(uri, hello_request(self.get_profile())) elif msg_type == 'hello_request': self.send_enc(uri, hello_response(self.get_profile())) else: # Known peer if pub: # test if we have to update the pubkey if not self._peers[uri]._pub: self._log.info("Setting public key for seed node") self._peers[uri]._pub = pub.decode('hex') self.trigger_callbacks('peer', self._peers[uri]) if self._peers[uri]._pub != pub.decode('hex'): self._log.info("Updating public key for node") self._peers[uri]._nickname = nickname self._peers[uri]._pub = pub.decode('hex') self.trigger_callbacks('peer', self._peers[uri]) if msg_type == 'hello_request': # reply only if necessary self.send_enc(uri, hello_response(self.get_profile())) def on_message(self, msg): # here goes the application callbacks # we get a "clean" msg which is a dict holding whatever #self._log.info("[On Message] Data received: %s" % msg) pubkey = msg.get('pubkey') uri = msg.get('uri') ip = urlparse(uri).hostname port = urlparse(uri).port guid = msg.get('senderGUID') self._dht.add_known_node((ip, port, guid)) self._dht.add_active_peer(self, (pubkey, uri, guid)) self.trigger_callbacks(msg['type'], msg) def on_raw_message(self, serialized): try: # Try to deserialize cleartext message msg = json.loads(serialized) self._log.info("Message Received [%s]" % msg.get('type', 'unknown')) except ValueError: try: # Encrypted? try: msg = self._myself.decrypt(serialized) msg = json.loads(msg) self._log.info("Decrypted Message [%s]" % msg.get('type', 'unknown')) except: self._log.error("Could not decrypt message: %s" % msg) return except: self._log.error('Message probably sent using incorrect pubkey') return if msg.get('type') is not None: msg_type = msg.get('type') msg_uri = msg.get('uri') msg_guid = msg.get('guid') self._log.info('Type: %s' % msg.get('type')) self.on_message(msg) else: self._log.error('Received a message with no type')