def _do_send_my_identity(self): """ Send my updated identity to the identity servers to register it. """ my_sources = my_id.getLocalIdentity().getSources(as_originals=True) payload = my_id.getLocalIdentity().serialize(as_text=False) dlist = [] if _Debug: lg.out(_DebugLevel, 'id_rotator._do_send_my_identity my_sources=%r' % my_sources) for idurl_bin in my_sources: _, host, _webport, filename = nameurl.UrlParse(idurl_bin) webport = None if host in self.preferred_servers: webport = int(self.preferred_servers[host][0]) if not webport and host in self.known_servers: webport = int(self.known_servers[host][0]) if not webport: webport = _webport url = net_misc.pack_address((host, webport, ), proto='http') dlist.append(net_misc.http_post_data( url=url, data=payload, connectTimeout=15, )) if _Debug: lg.args(_DebugLevel, url=url, filename=filename, size=len(payload)) return DeferredList(dlist, fireOnOneCallback=True)
def _update_my_identity(self): contacts_changed = False old_contacts = list(my_id.getLocalIdentity().getContacts()) identity_changed = my_id.rebuildLocalIdentity() if not identity_changed and len(active_protos()) > 0: self.automat('my-id-updated', (False, False)) return new_contacts = my_id.getLocalIdentity().getContacts() if len(old_contacts) != len(new_contacts): contacts_changed = True if not contacts_changed: for pos in range(len(old_contacts)): if old_contacts[pos] != new_contacts[pos]: contacts_changed = True break if contacts_changed: # erase all stats about received packets # if some contacts in my identity has been changed if _Debug: lg.out( 4, ' my contacts were changed, erase active_protos() flags' ) active_protos().clear() if _Debug: lg.out( 4, ' identity HAS %sBEEN CHANGED' % ('' if identity_changed else 'NOT ')) self.automat('my-id-updated', (contacts_changed, identity_changed))
def _new_idurl_exist(idsrc, new_idurl, pos): if _Debug: lg.out(_DebugLevel, 'id_rotator.doSelectNewIDServer._new_idurl_exist %r already with same name' % new_idurl) latest_revision = my_id.getLocalIdentity().getRevisionValue() try: existing_identity_with_same_name = identity.identity(xmlsrc=idsrc) if not existing_identity_with_same_name.isCorrect(): raise Exception('remote identity not correct at position %r' % pos) if not existing_identity_with_same_name.Valid(): raise Exception('remote identity not valid at position %r' % pos) except: lg.exc() if pos + 1 >= len(target_hosts): self.automat('no-id-servers-found') else: _ping_one_server(pos + 1) return if existing_identity_with_same_name.getPublicKey() == my_id.getLocalIdentity().getPublicKey(): if latest_revision <= existing_identity_with_same_name.getRevisionValue(): self.new_revision = max(self.new_revision or -1, existing_identity_with_same_name.getRevisionValue() + 1) lg.info('found my own identity on "old" ID server and will re-use that source again: %r' % new_idurl) if new_idurl not in self.possible_sources: self.possible_sources.append(new_idurl) self.automat('found-new-id-source', new_idurl) return if pos + 1 >= len(target_hosts): self.automat('no-id-servers-found') else: _ping_one_server(pos + 1)
def update(): """ A good way to check all things - load and sign again. """ from userid import my_id bpio.init() settings.init() src = bpio.ReadTextFile(settings.LocalIdentityFilename()) my_id.setLocalIdentity(identity(xmlsrc=src)) my_id.getLocalIdentity().sign() my_id.saveLocalIdentity() print my_id.getLocalIdentity().serialize()
def update(): """ A good way to check all things - load and sign again. Also will test rebuilding of the identity """ from userid import my_id bpio.init() settings.init() src = bpio.ReadTextFile(settings.LocalIdentityFilename()) print(src) my_id.setLocalIdentity(identity(xmlsrc=src)) my_id.getLocalIdentity().sign() my_id.saveLocalIdentity() print(my_id.getLocalIdentity().serialize()) print(my_id.rebuildLocalIdentity(revision_up=True))
def _do_check_ping_results(self, ping_results): """ """ self.alive_idurls = [] my_sources = my_id.getLocalIdentity().getSources(as_originals=True) local_revision = my_id.getLocalIdentity().getRevisionValue() latest_revision = -1 pos = -1 for result, remote_identity_src in ping_results: pos += 1 idurl_bin = my_sources[pos] if not result: self.alive_idurls.append(None) continue try: remote_ident = identity.identity(xmlsrc=remote_identity_src) if not remote_ident.isCorrect(): raise Exception( 'remote identity not correct at position %r' % pos) if not remote_ident.Valid(): raise Exception( 'remote identity not valid at position %r' % pos) if latest_revision == -1: latest_revision = remote_ident.getRevisionValue() if latest_revision <= remote_ident.getRevisionValue(): latest_revision = remote_ident.getRevisionValue() except: lg.exc() self.alive_idurls.append(None) continue self.alive_idurls.append(idurl_bin) if not self.new_revision: self.new_revision = max(local_revision, latest_revision) + 1 if _Debug: lg.args(_DebugLevel, new_revision=self.new_revision, alive_idurls=self.alive_idurls) if not self.alive_idurls or not list(filter(None, self.alive_idurls)): # so all my id sources are down # if no alive sources found then probably network is down # and we should not do anything at the moment # but we must also check in that case if any of my ID servers are still alive, but only my identity was removed # otherwise we can get situation when all my id servers are UP, but my identity just expired and id_rotator do nothing to fix that self._fallback_and_ping_my_servers() return self.automat('ping-done', self.alive_idurls)
def doRequestMyIdentity(self, *args, **kwargs): """ Action method. """ if _Debug: lg.out(_DebugLevel, 'id_rotator.doRequestMyIdentity') def _cb(results): if _Debug: lg.args(_DebugLevel, results=results) # TODO: validate my identity in all responses self.automat('my-id-exist', results) return results def _eb(err): lg.err(err) self.automat('my-id-not-exist', err) return None dl = [] for idurl in my_id.getLocalIdentity().getSources(as_originals=True): dl.append(net_misc.getPageTwisted(idurl, timeout=10)) d = DeferredList(dl) d.addCallback(_cb) d.addErrback(_eb)
def SendIdentity(remote_idurl, wide=False, timeout=10, callbacks={}): """ """ packet_id = 'identity:%s' % packetid.UniqueID() if _Debug: lg.out( _DebugLevel, "p2p_service.SendIdentity to %s wide=%s packet_id=%r" % ( nameurl.GetName(remote_idurl), wide, packet_id, )) result = signed.Packet( Command=commands.Identity(), OwnerID=my_id.getLocalID(), CreatorID=my_id.getLocalID(), PacketID=packet_id, Payload=my_id.getLocalIdentity().serialize(), RemoteID=remote_idurl, ) gateway.outbox(result, wide=wide, callbacks=callbacks, response_timeout=timeout) return result
def get_contact_identity(idurl): """ The Main Method Here - return identity object for given ID or None if not found. Only valid contacts for packets will be signed by local identity, suppliers, customers. """ if idurl is None: return None idurl = id_url.field(idurl) if idurl.to_bin() == my_id.getLocalID().to_bin(): return my_id.getLocalIdentity() # if is_supplier(idurl): # return identitycache.FromCache(idurl) # if is_customer(idurl): # return identitycache.FromCache(idurl) # if is_correspondent(idurl): # return identitycache.FromCache(idurl) if identitycache.HasKey(idurl): # lg.warn("who is %s ?" % nameurl.GetName(idurl)) return identitycache.FromCache(idurl) lg.warn("%s is NOT FOUND IN CACHE" % idurl) # TODO: # this is not correct: # need to check if other contacts is fine - if internet is turned off we can get lots of fails ... return None
def doSendRequestService(self, arg): """ Action method. """ if len(self.request_service_packet_id) >= 3: if _Debug: lg.warn('too many service requests to %s' % self.router_idurl) self.automat('service-refused', arg) return service_info = 'service_proxy_server \n' orig_identity = config.conf().getData( 'services/proxy-transport/my-original-identity').strip() if not orig_identity: orig_identity = my_id.getLocalIdentity().serialize() service_info += orig_identity # for t in gateway.transports().values(): # service_info += '%s://%s' % (t.proto, t.host) # service_info += ' ' newpacket = signed.Packet( commands.RequestService(), my_id.getLocalID(), my_id.getLocalID(), packetid.UniqueID(), service_info, self.router_idurl, ) packet_out.create( newpacket, wide=False, callbacks={ commands.Ack(): self._on_request_service_ack, commands.Fail(): self._on_request_service_fail }, ) self.request_service_packet_id.append(newpacket.PacketID)
def SendServers(): """ My identity file can be stored in different locations, see the "sources" field. So I can use different identity servers to store more secure and reliable. This method will send my identity file to all my identity servers via transport_tcp. """ from transport.tcp import tcp_node sendfile, sendfilename = tmpfile.make("propagate") os.close(sendfile) LocalIdentity = my_id.getLocalIdentity() bpio.WriteTextFile(sendfilename, LocalIdentity.serialize(as_text=True)) dlist = [] for idurl in LocalIdentity.getSources(as_originals=True): # sources for out identity are servers we need to send to protocol, host, port, filename = nameurl.UrlParse(idurl) # TODO: rebuild identity-server logic to be able to send my identity via HTTP POST instead of TCP and # get rid of second TCP port at all webport, tcpport = known_servers.by_host().get(host, ( # by default use "expected" port numbers settings.IdentityWebPort(), settings.IdentityServerPort())) normalized_address = net_misc.normalize_address((host, int(tcpport), )) dlist.append(tcp_node.send( sendfilename, normalized_address, 'Identity', keep_alive=False, )) if _Debug: lg.args(_DebugLevel, normalized_address=normalized_address, filename=filename) dl = DeferredList(dlist, consumeErrors=True) return dl
def _do_send_my_identity(self): """ Send my updated identity to the identity servers to register it. """ from transport.tcp import tcp_node sendfilename = settings.LocalIdentityFilename() my_sources = my_id.getLocalIdentity().getSources(as_originals=True) dlist = [] if _Debug: lg.out( _DebugLevel, 'id_rotator._do_send_my_identity my_sources=%r' % my_sources) for idurl_bin in my_sources: _, host, _, _ = nameurl.UrlParse(idurl_bin) tcpport = None if host in self.preferred_servers: tcpport = int(self.preferred_servers[host][1]) if not tcpport and host in self.known_servers: tcpport = int(self.known_servers[host][1]) if not tcpport: tcpport = settings.IdentityServerPort() srvhost = net_misc.pack_address(( host, tcpport, )) if _Debug: lg.out(_DebugLevel, ' sending to %r via TCP' % srvhost) dlist.append( tcp_node.send( sendfilename, srvhost, 'Identity', keep_alive=False, )) return DeferredList(dlist, fireOnOneCallback=True)
def doStart(self, arg): """ Action method. """ options = {'idurl': my_id.getLocalID(), } id_contact = '' default_host = '' ident = my_id.getLocalIdentity() if ident: id_contact = ident.getContactsByProto().get(self.proto, '') if id_contact: assert id_contact.startswith(self.proto + '://') id_contact = id_contact.strip(self.proto + '://') if self.proto == 'tcp': if not id_contact: default_host = misc.readExternalIP() + ':' + str(settings.getTCPPort()) options['host'] = id_contact or default_host options['tcp_port'] = settings.getTCPPort() elif self.proto == 'udp': if not id_contact: default_host = nameurl.GetName(my_id.getLocalID()) + '@' + platform.node() options['host'] = id_contact or default_host options['dht_port'] = settings.getDHTPort() options['udp_port'] = settings.getUDPPort() elif self.proto == 'proxy': pass if _Debug: lg.out(8, 'network_transport.doStart connecting %s transport : %s' % (self.proto.upper(), options)) self.interface.connect(options)
def _do_id_server_health_check(self): my_idurl = my_id.getLocalIdentity().getIDURL(as_original=True) if _Debug: lg.args(_DebugLevel, my_idurl=my_idurl) def _verify(xmlsrc=None): if not xmlsrc: lg.err('my current identity server not healthy') self.NeedPropagate = True self.automat('check-synchronize') return remote_ident = identity.identity(xmlsrc=xmlsrc) if not remote_ident.isCorrect() or not remote_ident.Valid(): lg.warn('my current identity server responded with bad identity file') self.NeedPropagate = True self.automat('check-synchronize') return if remote_ident.getIDURL(as_original=True) != my_idurl: lg.warn('my current identity server responded with unknown identity') self.NeedPropagate = True self.automat('check-synchronize') return if _Debug: lg.dbg(_DebugLevel, 'my current identity server is healthy') last_time = identitycache.last_time_cached(my_idurl) if last_time and time.time() - last_time < config.conf().getInt('services/identity-propagate/health-check-interval-seconds'): if _Debug: lg.dbg(_DebugLevel, 'skip health check of my current identity server, last time cached %f seconds ago' % (time.time() - last_time)) return d = identitycache.immediatelyCaching(my_idurl, try_other_sources=False) d.addCallback(_verify) d.addErrback(lambda _: _verify() and None)
def doSetNickname(self, *args, **kwargs): """ Action method. """ self.nickname = args[0] if (args and args[0]) else ( settings.getNickName() or my_id.getLocalIdentity().getIDName()) settings.setNickName(self.nickname)
def doSendRequestService(self, arg): """ Action method. """ if len(self.request_service_packet_id) >= 3: if _Debug: lg.warn('too many service requests to %s' % self.router_idurl) self.automat('service-refused', arg) return service_info = 'service_proxy_server \n' orig_identity = config.conf().getData('services/proxy-transport/my-original-identity').strip() if not orig_identity: orig_identity = my_id.getLocalIdentity().serialize() service_info += orig_identity # for t in gateway.transports().values(): # service_info += '%s://%s' % (t.proto, t.host) # service_info += ' ' newpacket = signed.Packet( commands.RequestService(), my_id.getLocalID(), my_id.getLocalID(), packetid.UniqueID(), service_info, self.router_idurl,) packet_out.create(newpacket, wide=False, callbacks={ commands.Ack(): self._on_request_service_ack, commands.Fail(): self._on_request_service_fail},) self.request_service_packet_id.append(newpacket.PacketID)
def SlowSendCustomers(delay=1): """ Same, "slowly" send my identity file to all my customers. """ global _SlowSendIsWorking if _SlowSendIsWorking: lg.out( 8, "propagate.SlowSendCustomers slow send is working at the moment. skip." ) return lg.out(8, "propagate.SlowSendCustomers delay=%s" % str(delay)) def _send(index, payload, delay): global _SlowSendIsWorking idurl = contactsdb.customer(index) if not idurl: _SlowSendIsWorking = False return # transport_control.ClearAliveTime(idurl) SendToID(idurl, Payload=payload, wide=True) reactor.callLater(delay, _send, index + 1, payload, delay) _SlowSendIsWorking = True payload = strng.to_bin(my_id.getLocalIdentity().serialize()) _send(0, payload, delay)
def SlowSendSuppliers(delay=1, customer_idurl=None): """ Doing same thing, but puts delays before sending to every next supplier. This is used when need to "ping" suppliers. """ global _SlowSendIsWorking if _SlowSendIsWorking: lg.out(8, "propagate.SlowSendSuppliers is working at the moment. skip.") return lg.out(8, "propagate.SlowSendSuppliers delay=%s" % str(delay)) def _send(index, payload, delay): global _SlowSendIsWorking idurl = contactsdb.supplier(index, customer_idurl=customer_idurl) if not idurl: _SlowSendIsWorking = False return # transport_control.ClearAliveTime(idurl) SendToID(idurl, Payload=payload, wide=True) reactor.callLater(delay, _send, index + 1, payload, delay) _SlowSendIsWorking = True payload = strng.to_bin(my_id.getLocalIdentity().serialize()) _send(0, payload, delay)
def _do_send_request_service(self, *args, **kwargs): if len(self.request_service_packet_id) >= 10: if _Debug: lg.warn('too many service requests to %r' % self.router_idurl) self.automat('service-refused', *args, **kwargs) return orig_identity = config.conf().getData('services/proxy-transport/my-original-identity').strip() if not orig_identity: orig_identity = my_id.getLocalIdentity().serialize(as_text=True) service_info = { 'name': 'service_proxy_server', 'payload': { 'identity': orig_identity, }, } newpacket = signed.Packet( commands.RequestService(), my_id.getIDURL(), my_id.getIDURL(), packetid.UniqueID(), serialization.DictToBytes(service_info, values_to_text=True), self.router_idurl, ) packet_out.create( newpacket, wide=False, callbacks={ commands.Ack(): self._on_request_service_ack, commands.Fail(): self._on_request_service_fail, None: lambda pkt_out: self.automat('request-timeout', pkt_out), }, response_timeout=30, ) self.request_service_packet_id.append(newpacket.PacketID)
def _recover(): from system import bpio from lib import nameurl if len(args) < 3: return 2 src = bpio.ReadBinaryFile(args[2]) if len(src) > 1024 * 10: print_text('file is too big for private key') return 0 try: lines = src.split('\n') idurl = lines[0] txt = '\n'.join(lines[1:]) if idurl != nameurl.FilenameUrl(nameurl.UrlFilename(idurl)): idurl = '' txt = src except: idurl = '' txt = src if idurl == '' and len(args) > 3: idurl = args[3] if idurl == '': print_text('BitDust need to know your IDURL to recover your account\n') return 2 from automats import automat from main import initializer initializer.A('run-cmd-line-recover', {'idurl': idurl, 'keysrc': txt}) reactor.run() automat.objects().clear() if my_id.isLocalIdentityReady(): print_text('your identity were restored:') print_text(my_id.getLocalIdentity().serialize()) else: print_text('identity recovery FAILED') return 0
def _do_send_request_service(self, *args, **kwargs): if len(self.request_service_packet_id) >= 3: if _Debug: lg.warn('too many service requests to %r' % self.router_idurl) self.automat('service-refused', *args, **kwargs) return orig_identity = config.conf().getData('services/proxy-transport/my-original-identity').strip() if not orig_identity: orig_identity = my_id.getLocalIdentity().serialize() service_info = { 'name': 'service_proxy_server', 'payload': { 'identity': strng.to_text(orig_identity), }, } service_info_raw = json.dumps(service_info) newpacket = signed.Packet( commands.RequestService(), my_id.getLocalID(), my_id.getLocalID(), packetid.UniqueID(), service_info_raw, self.router_idurl, ) packet_out.create(newpacket, wide=False, callbacks={ commands.Ack(): self._on_request_service_ack, commands.Fail(): self._on_request_service_fail, },) self.request_service_packet_id.append(newpacket.PacketID)
def SendToID(idurl, Payload=None, wide=False, ack_handler=None, timeout_handler=None, response_timeout=20, ): """ Create ``packet`` with my Identity file and calls ``transport.gateway.outbox()`` to send it. """ global _PropagateCounter if _Debug: lg.out(_DebugLevel, "propagate.SendToID [%s] wide=%s" % (nameurl.GetName(idurl), str(wide))) if ack_handler is None: ack_handler = HandleAck if timeout_handler is None: timeout_handler = HandleTimeOut thePayload = Payload if thePayload is None: thePayload = strng.to_bin(my_id.getLocalIdentity().serialize()) p = signed.Packet( Command=commands.Identity(), OwnerID=my_id.getIDURL(), CreatorID=my_id.getIDURL(), PacketID=('propagate:%d:%s' % (_PropagateCounter, packetid.UniqueID())), Payload=thePayload, RemoteID=idurl, ) _PropagateCounter += 1 result = gateway.outbox(p, wide, response_timeout=response_timeout, callbacks={ commands.Ack(): ack_handler, commands.Fail(): ack_handler, None: timeout_handler, }) if wide: # this is a ping packet - need to clear old info p2p_stats.ErasePeerProtosStates(idurl) p2p_stats.EraseMyProtosStates(idurl) return result
def test1(): """ Some tests. """ from userid import my_id myidentity = my_id.getLocalIdentity() print 'getIP =', myidentity.getIP() if myidentity.Valid(): print "myidentity is Valid!!!!" else: print "myidentity is not Valid" my_id.saveLocalIdentity() # sign and save raise Exception("myidentity is not Valid") print "myidentity.contacts" print myidentity.contacts print "len myidentity.contacts " print len(myidentity.contacts) print "len myidentity.contacts[0] " print myidentity.contacts[0] con = myidentity.getContact() print "con:", con, type(con) protocol, machine, port, filename = nameurl.UrlParse(con) print protocol, machine, port, filename print "identity.main serialize:\n", myidentity.serialize() for index in range(myidentity.getContactsNumber()): proto, host, port, filename = myidentity.getContactParts(index) print '[%s] [%s] [%s] [%s]' % (proto, host, port, filename)
def doCheckPingRouter(self, *args, **kwargs): """ Action method. """ if self.router_connection_info: gateway.send_keep_alive(self.router_connection_info['proto'], self.router_connection_info['host']) live_time = time.time() - self.latest_packet_received if live_time < 60.0: if _Debug: lg.out( _DebugLevel, 'proxy_receiver.doCheckPingRouter OK, latest packet received %f sec ago' % live_time) return if _Debug: lg.out( _DebugLevel, 'proxy_receiver.doCheckPingRouter to %s' % self.router_idurl) identity_source = config.conf().getData( 'services/proxy-transport/my-original-identity').strip() if identity_source: if _Debug: lg.out(_DebugLevel, ' "my-original-identity" prepared for sending') else: identity_source = my_id.getLocalIdentity().serialize() if _Debug: lg.out(_DebugLevel, ' local identity prepared for sending') self._do_send_identity_to_router(identity_source, failed_event='router-disconnected')
def doStartListening(self, arg): """ Action method. """ try: _, info = arg self.router_proto_host = (info.proto, info.host) except: try: s = config.conf().getString('services/proxy-transport/current-router').strip() _, router_proto, router_host = s.split(' ') self.router_proto_host = (router_proto, router_host) except: lg.exc() self.router_identity = identitycache.FromCache(self.router_idurl) config.conf().setString('services/proxy-transport/current-router', '%s %s %s' % ( self.router_idurl, self.router_proto_host[0], self.router_proto_host[1])) if ReadMyOriginalIdentitySource(): lg.warn('my original identity is not empty') else: config.conf().setData('services/proxy-transport/my-original-identity', my_id.getLocalIdentity().serialize()) self.request_service_packet_id = [] callback.insert_inbox_callback(0, self._on_inbox_packet_received) if _Debug: lg.out(2, 'proxy_receiver.doStartListening !!!!!!! router: %s at %s://%s' % ( self.router_idurl, self.router_proto_host[0], self.router_proto_host[1]))
def SendToID(idurl, ack_handler=None, Payload=None, NeedAck=False, wide=False): """ Create ``packet`` with my Identity file and calls ``transport.gateway.outbox()`` to send it. """ lg.out( 8, "propagate.SendToID [%s] wide=%s" % (nameurl.GetName(idurl), str(wide))) if ack_handler is None: ack_handler = HandleAck thePayload = Payload if thePayload is None: thePayload = my_id.getLocalIdentity().serialize() p = signed.Packet( commands.Identity(), my_id.getLocalID(), # MyID, my_id.getLocalID(), # MyID, 'Identity', # my_id.getLocalID(), #PacketID, thePayload, idurl) # callback.register_interest(AckHandler, p.RemoteID, p.PacketID) gateway.outbox(p, wide, callbacks={ commands.Ack(): ack_handler, commands.Fail(): ack_handler, }) if wide: # this is a ping packet - need to clear old info stats.ErasePeerProtosStates(idurl) stats.EraseMyProtosStates(idurl)
def SendServers(): """ My identity file can be stored in different locations, see the "sources" field. So I can use different identity servers to store more secure. This method will send my identity file to all my identity servers via transport_tcp. """ from transport.tcp import tcp_node sendfile, sendfilename = tmpfile.make("propagate") os.close(sendfile) LocalIdentity = my_id.getLocalIdentity() bpio.WriteFile(sendfilename, LocalIdentity.serialize()) dlist = [] for idurl in LocalIdentity.sources: # sources for out identity are servers we need to send to protocol, host, port, filename = nameurl.UrlParse(idurl) # if host == settings.IdentityServerName(): # host = '67.207.147.183' webport, tcpport = known_servers.by_host().get( host, (settings.IdentityWebPort(), settings.IdentityServerPort())) # srvhost = '%s:%d' % (host, int(tcpport)) dlist.append( tcp_node.send(sendfilename, (host, int(tcpport)), 'Identity', True)) # dlist.append(gateway.send_file_single('tcp', srvhost, sendfilename, 'Identity')) dl = DeferredList(dlist, consumeErrors=True) return dl
def SendToIDs(idlist, wide=False, ack_handler=None, timeout_handler=None, response_timeout=20): """ Same, but send to many IDs and also check previous packets to not re-send. """ global _PropagateCounter if _Debug: lg.out(_DebugLevel, "propagate.SendToIDs to %d users, wide=%s" % (len(idlist), wide)) if ack_handler is None: ack_handler = HandleAck if timeout_handler is None: timeout_handler = HandleTimeOut LocalIdentity = my_id.getLocalIdentity() Payload = strng.to_bin(LocalIdentity.serialize()) alreadysent = set() totalsent = 0 inqueue = {} found_previous_packets = 0 for pkt_out in packet_out.queue(): if id_url.is_in(pkt_out.remote_idurl, idlist, as_field=False): if pkt_out.description.count('Identity'): if pkt_out.remote_idurl not in inqueue: inqueue[pkt_out.remote_idurl] = 0 inqueue[pkt_out.remote_idurl] += 1 found_previous_packets += 1 for contact in idlist: if not contact: continue if contact in alreadysent: # just want to send once even if both customer and supplier continue if contact in inqueue and inqueue[contact] > 2: # now only 2 protocols is working: tcp and udp if _Debug: lg.out(_DebugLevel, ' skip sending [Identity] to %s, packet already in the queue' % contact) continue p = signed.Packet( Command=commands.Identity(), OwnerID=my_id.getLocalID(), CreatorID=my_id.getLocalID(), PacketID=('propagate:%d:%s' % (_PropagateCounter, packetid.UniqueID())), Payload=Payload, RemoteID=contact, ) _PropagateCounter += 1 if _Debug: lg.out(_DebugLevel, " sending [Identity] to %s" % nameurl.GetName(contact)) gateway.outbox(p, wide, response_timeout=response_timeout, callbacks={ commands.Ack(): ack_handler, commands.Fail(): ack_handler, None: timeout_handler, }) if wide: # this is a ping packet - need to clear old info p2p_stats.ErasePeerProtosStates(contact) p2p_stats.EraseMyProtosStates(contact) alreadysent.add(contact) totalsent += 1 del alreadysent return totalsent
def doSetNickname(self, arg): """ Action method. """ self.nickname = arg or \ settings.getNickName() or \ my_id.getLocalIdentity().getIDName() settings.setNickName(self.nickname)
def _is_my_contacts_present_in_identity(self, ident): for my_contact in my_id.getLocalIdentity().getContacts(): if ident.getContactIndex(contact=my_contact) >= 0: if _Debug: lg.out(_DebugLevel, ' found %s in identity : %s' % ( my_contact, ident.getIDURL())) return True return False
def doModifyMyIdentity(self, arg): """ Action method. """ config.conf().setData('services/proxy-transport/my-original-identity', my_id.getLocalIdentity().serialize()) modified = my_id.rebuildLocalIdentity() if not modified: lg.warn('my identity was not modified')
def doStartListening(self, *args, **kwargs): """ Action method. """ try: _, info = args[0] self.router_proto_host = (info.proto, info.host) except: try: s = config.conf().getString('services/proxy-transport/current-router').strip() _, router_proto, router_host = s.split(' ') self.router_proto_host = (router_proto, strng.to_bin(router_host), ) except: lg.exc() self.router_identity = identitycache.FromCache(self.router_idurl) config.conf().setString('services/proxy-transport/current-router', '%s %s %s' % ( strng.to_text(self.router_idurl), strng.to_text(self.router_proto_host[0]), strng.to_text(self.router_proto_host[1]), )) current_identity = my_id.getLocalIdentity().serialize() previous_identity = ReadMyOriginalIdentitySource() if previous_identity: lg.warn('my original identity is not empty, SKIP overwriting') lg.out(2, '\nPREVIOUS ORIGINAL IDENTITY:\n%s\n' % current_identity) else: WriteMyOriginalIdentitySource(current_identity) lg.warn('current identity was stored as my-original-identity') self.request_service_packet_id = [] callback.insert_inbox_callback(0, self._on_inbox_packet_received) if contact_status.isKnown(self.router_idurl): contact_status.A(self.router_idurl).addStateChangedCallback( self._on_router_contact_status_connected, newstate='CONNECTED') contact_status.A(self.router_idurl).addStateChangedCallback( self._on_router_contact_status_offline, newstate='OFFLINE') active_router_sessions = gateway.find_active_session(info.proto, info.host) if active_router_sessions: self.router_connection_info = { 'id': active_router_sessions[0].id, 'index': active_router_sessions[0].index, 'proto': info.proto, 'host': info.host, 'idurl': self.router_idurl, 'global_id': global_id.UrlToGlobalID(self.router_idurl), } active_router_session_machine = automat.objects().get(self.router_connection_info['index'], None) if active_router_session_machine: active_router_session_machine.addStateChangedCallback( self._on_router_session_disconnected, oldstate='CONNECTED') lg.info('connected to proxy router and set active session: %s' % self.router_connection_info) else: lg.err('not found proxy router session state machine: %s' % self.router_connection_info['index']) else: lg.err('active connection with proxy router at %s:%s was not found' % (info.proto, info.host, )) if _Debug: lg.out(2, 'proxy_receiver.doStartListening !!!!!!! router: %s at %s://%s' % ( self.router_idurl, self.router_proto_host[0], self.router_proto_host[1]))
def _do_verify_my_sources(self): my_sources = my_id.getLocalIdentity().getSources(as_originals=True) dl = [] for idurl_bin in my_sources: d = net_misc.getPageTwisted(idurl_bin, timeout=5) dl.append(d) d = DeferredList(dl, consumeErrors=True) d.addCallback(self._do_check_ping_results) d.addErrback(lambda err: self.automat('ping-failed', err))
def _is_my_contacts_present_in_identity(self, ident): for my_contact in my_id.getLocalIdentity().getContacts(): if ident.getContactIndex(contact=my_contact) >= 0: if _Debug: lg.out( _DebugLevel, ' found %s in identity : %s' % (my_contact, ident.getIDURL())) return True return False
def doInit(self, event, *args, **kwargs): """ Action method. """ self.result_defer = kwargs.get('result_defer') self.check_only = False if event == 'check': self.check_only = True self.alive_idurls = [] self.old_sources = my_id.getLocalIdentity().getSources( as_originals=True) self.known_servers = known_servers.by_host() self.preferred_servers = kwargs.get('preferred_servers', {}) self.possible_sources = [] if _Debug: lg.args(_DebugLevel, preferred_servers=self.preferred_servers) self.force = kwargs.get('force', False) self.new_revision = kwargs.get('new_revision') self.rotated = False if not self.preferred_servers: try: for srv in strng.to_text(config.conf().getData( 'services/identity-propagate/known-servers')).split( ','): if srv.strip(): host, web_port, tcp_port = srv.strip().split(':') self.preferred_servers[host] = ( int(web_port), int(tcp_port), ) except: lg.exc() self.preferred_servers = { strng.to_bin(k): v for k, v in self.preferred_servers.items() } self.current_servers = [] for idurl in my_id.getLocalIdentity().getSources(as_originals=True): self.current_servers.append(strng.to_bin(nameurl.GetHost(idurl))) if _Debug: lg.args(_DebugLevel, known_servers=self.known_servers, preferred_servers=self.preferred_servers, current_servers=self.current_servers)
def _check_reset_original_identity(self): from logs import lg from lib import misc from lib import strng from main.config import conf from userid import identity from userid import my_id from userid import id_url orig_ident_xmlsrc = conf().getData( 'services/proxy-transport/my-original-identity', '').strip() current_router_idurl = conf().getString( 'services/proxy-transport/current-router', '').strip() if current_router_idurl: current_router_idurl = id_url.field( current_router_idurl.split(' ')[0]) if not orig_ident_xmlsrc: if current_router_idurl: lg.warn( '"current-router" is %s, but "my-original-identity" is empty' % current_router_idurl) else: lg.warn('"current-router" and "my-original-identity" is empty') self._reset_my_original_identity() return orig_ident = identity.identity(xmlsrc=orig_ident_xmlsrc) if not orig_ident.isCorrect() or not orig_ident.Valid(): lg.warn('"my-original-identity" config has not valid value') self._reset_my_original_identity() return if orig_ident.getIDURL() != my_id.getIDURL(): lg.warn( '"my-original-identity" source is not equal to local identity source' ) self._reset_my_original_identity() return externalIP = strng.to_bin(misc.readExternalIP()) if externalIP and strng.to_bin(orig_ident.getIP()) != externalIP: lg.warn( 'external IP was changed : reset "my-original-identity" config' ) self._reset_my_original_identity() return if not current_router_idurl: lg.warn( '"my-original-identity" config is correct, but current router is empty' ) self._reset_my_original_identity() all_orig_contacts_present_in_local_identity = True for orig_contact in orig_ident.getContacts(): if orig_contact not in my_id.getLocalIdentity().getContacts(): all_orig_contacts_present_in_local_identity = False if all_orig_contacts_present_in_local_identity: lg.warn( 'all of "my-original-identity" contacts is found in local identity: need to RESET!' ) self._reset_my_original_identity()
def verify(): """ """ ordered_list = transports().keys() ordered_list.sort(key=settings.getTransportPriority, reverse=True) if _Debug: lg.out(4, "gateway.verify sorted list : %r" % ordered_list) my_id_obj = my_id.getLocalIdentity() resulted = Deferred() all_results = {} def _verify_transport(proto): if _Debug: lg.out(_DebugLevel - 8, " verifying %s_transport" % proto) if not settings.transportIsEnabled(proto): if _Debug: lg.out(_DebugLevel - 8, " %s_transport is disabled" % proto) return succeed(True) transp = transport(proto) if transp.state == "OFFLINE": if _Debug: lg.out(_DebugLevel - 8, " %s_transport state is OFFLINE" % proto) return succeed(True) if transp.state != "LISTENING": if _Debug: lg.out(_DebugLevel - 8, " %s_transport state is not LISTENING" % proto) return succeed(True) transp_result = transp.interface.verify_contacts(my_id_obj) if _Debug: lg.out(_DebugLevel - 8, " %s result is %r" % (proto, transp_result)) if isinstance(transp_result, bool) and transp_result: return succeed(True) if isinstance(transp_result, bool) and transp_result == False: return succeed(False) if isinstance(transp_result, Deferred): ret = Deferred() transp_result.addCallback(lambda result_value: ret.callback(result_value)) return ret lg.warn("incorrect result returned from %s_interface.verify_contacts(): %r" % (proto, transp_result)) return succeed(False) def _on_verified_one(t_result, proto): all_results[proto] = t_result if _Debug: lg.out(_DebugLevel - 8, " verified %s transport, result=%r" % (proto, t_result)) if len(all_results) == len(ordered_list): resulted.callback((ordered_list, all_results)) for proto in ordered_list: d = _verify_transport(proto) d.addCallback(_on_verified_one, proto) return resulted
def _on_nodes_lookup_finished(self, idurls): if _Debug: lg.out(_DebugLevel, 'proxy_receiver._on_nodes_lookup_finished : %r' % idurls) for idurl in idurls: ident = identitycache.FromCache(idurl) remoteprotos = set(ident.getProtoOrder()) myprotos = set(my_id.getLocalIdentity().getProtoOrder()) if len(myprotos.intersection(remoteprotos)) > 0: self.automat('found-one-user', idurl) return self.automat('users-not-found')
def doSetNickname(self, arg): """ Action method. """ if arg is None: a, c = None, None else: a, c = arg self.nickname = a or \ settings.getNickName() or \ my_id.getLocalIdentity().getIDName() self.result_callback = c
def _nodes_lookup_finished(self, idurls): # TODO: this is still under construction - so I am using this node for tests idurls = ['http://veselin-p2p.ru/bitdust_vps1000_k.xml', ] if _Debug: lg.out(_DebugLevel, 'accountants_finder._nodes_lookup_finished : %r' % idurls) for idurl in idurls: ident = identitycache.FromCache(idurl) remoteprotos = set(ident.getProtoOrder()) myprotos = set(my_id.getLocalIdentity().getProtoOrder()) if len(myprotos.intersection(remoteprotos)) > 0: self.automat('found-one-user', idurl) return self.automat('users-not-found')
def doSendMyIdentity(self, arg): """ Action method. """ identity_source = config.conf().getData('services/proxy-transport/my-original-identity').strip() if identity_source: if _Debug: lg.out(_DebugLevel, 'proxy_receiver.doSendMyIdentity use my previously stored identity') else: identity_source = my_id.getLocalIdentity().serialize() cur_contacts = my_id.getLocalIdentity().getContacts() if _Debug: lg.out(_DebugLevel, 'proxy_receiver.doSendMyIdentity using my current identity, contacts=%s' % cur_contacts) newpacket = signed.Packet( commands.Identity(), my_id.getLocalID(), my_id.getLocalID(), 'identity', identity_source, self.router_idurl, ) packet_out.create(newpacket, wide=True, callbacks={ commands.Ack(): lambda response, info: self.automat('ack-received', (response, info)), commands.Fail(): lambda x: self.automat('nodes-not-found') })
def main(): """ This should print a current identity or create a new one. """ from userid import my_id my_id.loadLocalIdentity() if my_id.isLocalIdentityReady(): my_id.getLocalIdentity().sign() print my_id.getLocalIdentity().serialize() print 'Valid is: ', my_id.getLocalIdentity().Valid() else: my_id.setLocalIdentity(my_id.buildDefaultIdentity(sys.argv[1])) my_id.saveLocalIdentity() print my_id.getLocalIdentity().serialize() print 'Valid is: ', my_id.getLocalIdentity().Valid() my_id._LocalIdentity = None my_id.loadLocalIdentity()
def RequestIdentity(request): """ Someone is requesting a copy of our current identity. Already verified that they are a contact. Can also be used as a sort of "ping" test to make sure we are alive. """ if _Debug: lg.out(_DebugLevel, "p2p_service.RequestIdentity from %s" % request.OwnerID) MyID = my_id.getLocalID() RemoteID = request.OwnerID PacketID = request.PacketID identitystr = my_id.getLocalIdentity().serialize() result = signed.Packet(commands.Identity(), MyID, MyID, PacketID, identitystr, RemoteID) gateway.outbox(result, False)
def SendIdentity(remote_idurl, wide=False, callbacks={}): """ """ if _Debug: lg.out(_DebugLevel, "p2p_service.SendIdentity to %s" % nameurl.GetName(remote_idurl)) result = signed.Packet( commands.Identity(), my_id.getLocalID(), my_id.getLocalID(), "identity", my_id.getLocalIdentity().serialize(), remote_idurl, ) gateway.outbox(result, wide=wide, callbacks=callbacks) return result
def doSendMyIdentity(self, arg): """ Action method. """ # TODO: just to debug - skip sending to ID servers and go further # self.state = 'REQUEST_ID' # self.event('my-id-exist', self.new_identity.serialize()) # return mycurrentidentity = None if my_id.isLocalIdentityReady(): mycurrentidentity = my_id.getLocalIdentity() my_id.setLocalIdentity(self.new_identity) def _cb(x): my_id.setLocalIdentity(mycurrentidentity) self.automat('my-id-sent') def _eb(x): my_id.setLocalIdentity(mycurrentidentity) self.automat('my-id-failed') dl = self._send_new_identity() dl.addCallback(_cb) dl.addErrback(_eb)
def get_contact_identity(idurl): """ The Main Method Here - return identity object for given ID or None if not found. Only valid contacts for packets will be signed by local identity, suppliers, customers. """ if idurl is None: return None if idurl == my_id.getLocalID(): return my_id.getLocalIdentity() if is_supplier(idurl): return identitycache.FromCache(idurl) if is_customer(idurl): return identitycache.FromCache(idurl) if is_correspondent(idurl): return identitycache.FromCache(idurl) if identitycache.HasKey(idurl): # lg.warn("who is %s ?" % nameurl.GetName(idurl)) return identitycache.FromCache(idurl) lg.out(6, "contactsdb.getContact %s is not found" % nameurl.GetName(idurl)) # TODO: # this is not correct: # need to check if other contacts is fine - if internet is turned off we can get lots fails ... return None
def doSendRequestService(self, arg): """ Action method. """ if len(self.request_service_packet_id) >= 3: if _Debug: lg.warn('too many service requests to %s' % self.router_idurl) self.automat('service-refused', arg) return from transport import gateway service_info = 'service_proxy_server \n' orig_identity = config.conf().getData('services/proxy-transport/my-original-identity').strip() if not orig_identity: orig_identity = my_id.getLocalIdentity().serialize() service_info += orig_identity # for t in gateway.transports().values(): # service_info += '%s://%s' % (t.proto, t.host) # service_info += ' ' request = p2p_service.SendRequestService( self.router_idurl, service_info, callbacks={ commands.Ack(): self._request_service_ack, commands.Fail(): self._request_service_fail}) self.request_service_packet_id.append(request.PacketID)
def _register(): if len(args) <= 2: return 2 pksize = settings.getPrivateKeySize() if len(args) > 3: try: pksize = int(args[3]) except: print_text('incorrect private key size\n') return 0 from automats import automat from main import initializer from lib import misc if not misc.ValidUserName(args[2]): return 0 initializer.A('run-cmd-line-register', {'username': args[2], 'pksize': pksize}) reactor.run() automat.objects().clear() if my_id.isLocalIdentityReady(): print_text('new identity created:') print_text(my_id.getLocalIdentity().serialize()) else: print_text('identity creation FAILED') return 0
def cmd_identity(opts, args, overDict, running): from userid import my_id from main import settings settings.init() my_id.init() if args[0] == 'idurl': if my_id.isLocalIdentityReady(): print_text(my_id.getLocalID()) else: print_text('local identity is not exist') return 0 if len(args) == 1 or args[1].lower() in ['info', '?', 'show', 'print']: if my_id.isLocalIdentityReady(): print_text(my_id.getLocalIdentity().serialize()) else: print_text('local identity is not exist') return 0 def _register(): if len(args) <= 2: return 2 pksize = settings.getPrivateKeySize() if len(args) > 3: try: pksize = int(args[3]) except: print_text('incorrect private key size\n') return 0 from automats import automat from main import initializer from lib import misc if not misc.ValidUserName(args[2]): return 0 initializer.A('run-cmd-line-register', {'username': args[2], 'pksize': pksize}) reactor.run() automat.objects().clear() if my_id.isLocalIdentityReady(): print_text('new identity created:') print_text(my_id.getLocalIdentity().serialize()) else: print_text('identity creation FAILED') return 0 def _recover(): from system import bpio from lib import nameurl if len(args) < 3: return 2 src = bpio.ReadBinaryFile(args[2]) if len(src) > 1024 * 10: print_text('file is too big for private key') return 0 try: lines = src.split('\n') idurl = lines[0] txt = '\n'.join(lines[1:]) if idurl != nameurl.FilenameUrl(nameurl.UrlFilename(idurl)): idurl = '' txt = src except: idurl = '' txt = src if idurl == '' and len(args) > 3: idurl = args[3] if idurl == '': print_text('BitDust need to know your IDURL to recover your account\n') return 2 from automats import automat from main import initializer initializer.A('run-cmd-line-recover', {'idurl': idurl, 'keysrc': txt}) reactor.run() automat.objects().clear() if my_id.isLocalIdentityReady(): print_text('your identity were restored:') print_text(my_id.getLocalIdentity().serialize()) else: print_text('identity recovery FAILED') return 0 if args[1].lower() in ['create', 'new', 'register', 'generate', ]: if my_id.isLocalIdentityReady(): print_text('local identity [%s] already exist\n' % my_id.getIDName()) return 1 if running: print_text('BitDust is running at the moment, need to stop the software at first\n') return 0 return _register() if args[1].lower() in ['restore', 'recover', 'read', 'load', ]: if running: print_text('BitDust is running at the moment, need to stop the software at first\n') return 0 return _recover() if args[1].lower() in ['delete', 'remove', 'erase', 'del', 'rm', 'kill']: if running: print_text('BitDust is running at the moment, need to stop the software at first\n') return 0 oldname = my_id.getIDName() my_id.forgetLocalIdentity() my_id.eraseLocalIdentity() print_text('local identity [%s] is no longer exist\n' % oldname) return 0 return 2