Beispiel #1
0
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()
Beispiel #2
0
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})
Beispiel #3
0
    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)
Beispiel #4
0
    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()
Beispiel #5
0
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']
Beispiel #6
0
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()
Beispiel #7
0
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
    })
Beispiel #8
0
    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()
Beispiel #9
0
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)
Beispiel #10
0
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()
Beispiel #11
0
    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]
Beispiel #14
0
    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()
Beispiel #15
0
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
Beispiel #16
0
    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()
Beispiel #17
0
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
Beispiel #18
0
 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"
Beispiel #19
0
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)
Beispiel #20
0
    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()
Beispiel #21
0
    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()
Beispiel #22
0
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"
Beispiel #23
0
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)
Beispiel #24
0
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)
Beispiel #25
0
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)
Beispiel #26
0
# 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)
Beispiel #27
0
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')
Beispiel #29
0
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)
Beispiel #30
0
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)
Beispiel #31
0
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)
Beispiel #32
0
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):
Beispiel #33
0
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))
Beispiel #34
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()
Beispiel #35
0
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
Beispiel #36
0
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')
Beispiel #37
0
    '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()
Beispiel #38
0
    '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()
Beispiel #39
0
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()
Beispiel #41
0
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:
Beispiel #42
0
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)
Beispiel #43
0
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')