예제 #1
0
def makeDefaultIdentity(name='', ip=''):
    """
    Use some local settings and config files to create some new identity.
    Nice to provide a user name or it will have a form like: [ip address]_[date].     
    """
    dhnio.Dprint(4, 'identity.makeDefaultIdentity: %s %s' % (name, ip))
    if ip == '':
        ip = dhnio.ReadTextFile(settings.ExternalIPFilename())
    if name == '':
        name = ip.replace('.', '-') + '_' + time.strftime('%M%S')
    servername = settings.IdentityServerName()
    url = 'http://'+servername+'/'+name.lower()+'.xml'

    ident = identity(xmlsrc=default_identity_src)
    ident.sources.append(url.encode("ascii").strip())
    ident.certificates=[]
    cdict = {}
    if settings.enableTCP() and settings.enableTCPreceiving():
        cdict['tcp'] = 'tcp://'+ip+':'+settings.getTCPPort()
    if settings.enableUDP() and settings.enableUDPreceiving():
        cdict['udp'] = 'udp://'+ip+':'+settings.getUDPPort()
    # if settings.enableSSH():
    #     cdict['ssh'] = 'ssh://'+ip+':'+settings.getSSHPort()
    # if settings.enableHTTP() or settings.enableHTTPServer():
    #     cdict['http'] = 'http://'+ip+':'+settings.getHTTPPort()
    # if settings.enableQ2Q():
    #     if settings.getQ2Qusername().strip() != '' and settings.getQ2Qhost().strip() != '':
    #         cdict['q2q'] = 'q2q://'+settings.getQ2Quserathost()
    #     else:
    #         cdict['q2q'] = 'q2q://default@'+settings.getQ2Qhost()
    # if settings.enableEMAIL():
    #     if settings.getEmailAddress().strip() != '':
    #         cdict['email'] = 'email://'+settings.getEmailAddress()
    #     else:
    #         cdict['email'] = 'email://'+name+'@datahaven.net'
    if settings.enableCSpace():
        if settings.getCSpaceKeyID() != '':
            cdict['cspace'] = 'cspace://'+settings.getCSpaceKeyID()
        else:
            cdict['cspace'] = 'cspace://not-registered'
        
    for c in misc.validTransports:
        if cdict.has_key(c):
            ident.contacts.append(cdict[c].encode("ascii").strip())

    ident.publickey = dhncrypto.MyPublicKey()
    ident.date = time.strftime('%b %d, %Y')
    ident.postage = "1"

    revnum = dhnio.ReadTextFile(settings.RevisionNumberFile())
    repo, location = misc.ReadRepoLocation()
    ident.version = (revnum.strip() + ' ' + repo.strip() + ' ' + dhnio.osinfo().strip()).strip()

    ident.sign()

    return ident
예제 #2
0
def main():
    sys.path.append('..')

    def _go_stun(port):
        print '+++++ LISTEN UDP ON PORT', port, 'AND RUN STUN DISCOVERY'
        stun.stunExternalIP(close_listener=False, internal_port=port, verbose=False).addBoth(_stuned)

    def _stuned(ip):
        if stun.getUDPClient() is None:
            print 'UDP CLIENT IS NONE - EXIT'
            reactor.stop()
            return

        print '+++++ EXTERNAL UDP ADDRESS IS', stun.getUDPClient().externalAddress
        
        if sys.argv[1] == 'listen':
            print '+++++ START LISTENING'
            return
        
        if sys.argv[1] == 'connect':
            print '+++++ CONNECTING TO REMOTE MACHINE'
            _try2connect()
            return

        lid = misc.getLocalIdentity()
        udp_contact = 'udp://'+stun.getUDPClient().externalAddress[0]+':'+str(stun.getUDPClient().externalAddress[1])
        lid.setProtoContact('udp', udp_contact)
        lid.sign()
        misc.setLocalIdentity(lid)
        misc.saveLocalIdentity()
        
        print '+++++ UPDATE IDENTITY', str(lid.contacts)
        _send_servers().addBoth(_id_sent)

    def _start_sending_ip():
        init(stun.getUDPClient())
        A().debug = True
        reactor.callLater(1, Start)
        def _start_session():
            # transport_udp_session.SetStateChangedCallbackFunc(_state_changed)
            address = (sys.argv[2], int(sys.argv[3]))
            sess = transport_udp_session.open_session(address)
            filename = sys.argv[4]
            loop_delay = None if len(sys.argv)<6 else int(sys.argv[5])
            transport_udp_session._StateChangedCallbackFunc = lambda index, old, new: _state_changed(index, address[0], new, filename, loop_delay)
            sess.automat('init', None)
        reactor.callLater(2, _start_session)        

    def _state_changed(index, ip, newstate, filename, loop_delay):
        print '+++++ STATE CHANGED     [%s]' % newstate
        sess = automat.objects().get(index)
        if newstate == 'CONNECTED':
            transport_udp_session.SetStateChangedCallbackFunc(None)
            if loop_delay:
                reactor.callLater(2, LoopingCall(send, filename, sess.remote_address[0], sess.remote_address[1]).start, loop_delay, True)
            else:
                reactor.callLater(2, send, filename, sess.remote_address[0], sess.remote_address[1])

    def _send_servers():
        import tmpfile, misc, nameurl, settings, transport_tcp
        sendfile, sendfilename = tmpfile.make("propagate")
        os.close(sendfile)
        LocalIdentity = misc.getLocalIdentity()
        dhnio.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)
            port = settings.IdentityServerPort()
            d = Deferred()
            transport_tcp.sendsingle(sendfilename, host, port, do_status_report=False, result_defer=d, description='Identity')
            dlist.append(d) 
        dl = DeferredList(dlist, consumeErrors=True)
        print '+++++ IDENTITY SENT TO %s:%s' % (host, port)
        return dl

    def _try2connect():
        remote_addr = dhnio.ReadTextFile(sys.argv[3]).split(' ')
        remote_addr = (remote_addr[0], int(remote_addr[1]))
        t = int(str(int(time.time()))[-1]) + 1
        data = '0' * t
        stun.getUDPClient().transport.write(data, remote_addr)
        print 'sent %d bytes to %s' % (len(data), str(remote_addr))
        reactor.callLater(1, _try2connect)

    def _id_sent(x):
        print '+++++ ID UPDATED ON THE SERVER', x
        if sys.argv[1] == 'send':
            _start_sending()
        elif sys.argv[1] == 'sendip':
            _start_sending_ip()
        elif sys.argv[1] == 'receive':
            _start_receiving()

    def _start_receiving():
        idurl = sys.argv[2]
        if not idurl.startswith('http://'):
            idurl = 'http://'+settings.IdentityServerName()+'/'+idurl+'.xml'
        print '+++++ START RECEIVING FROM', idurl
        _request_remote_id(idurl).addBoth(_receive_from_remote_peer, idurl)
        
    def _receive_from_remote_peer(x, idurl):
        init(stun.getUDPClient())
        A().debug = True
        contacts.addCorrespondent(idurl)
        reactor.callLater(1, Start)

    def _start_sending():
        idurl = sys.argv[2]
        if not idurl.startswith('http://'):
            idurl = 'http://'+settings.IdentityServerName()+'/'+idurl+'.xml'
        print '+++++ START SENDING TO', idurl
#        if len(sys.argv) == 6:
#            send(sys.argv[5], sys.argv[3], int(sys.argv[4]))
#        elif len(sys.argv) == 4:
        _request_remote_id(idurl).addBoth(_send_to_remote_peer, idurl, sys.argv[3], None if len(sys.argv)<5 else int(sys.argv[4]))

    def _request_remote_id(idurl):
        print '+++++ REQUEST ID FROM SERVER', idurl
        return identitycache.immediatelyCaching(idurl)
    
    def _send_to_remote_peer(x, idurl, filename, loop_delay):
        print '+++++ PREPARE SENDING TO', idurl
        init(stun.getUDPClient())
        A().debug = True
        contacts.addCorrespondent(idurl)
        reactor.callLater(1, Start)
        ident = identitycache.FromCache(idurl)
        if ident is None:
            print '+++++ REMOTE IDENTITY IS NONE'
            reactor.stop()
            return
        x, udphost, udpport, x = ident.getProtoParts('udp')
        transport_udp_session.SetStateChangedCallbackFunc(lambda index, old, new: _state_changed(index, udphost, new, filename, loop_delay))
    
    def _send_file(idurl, filename):
        ident = identitycache.FromCache(idurl)
        if ident is None:
            print '+++++ REMOTE IDENTITY IS NONE'
            reactor.stop()
        x, udphost, udpport, x = ident.getProtoParts('udp')
        print '+++++ SENDING TO', udphost, udpport
        send(filename, udphost, udpport)

    def _test_cancel():
        import transport_control as tc
        for t in tc.current_transfers():
            cancel(t.transfer_id)
        reactor.callLater(11, _test_cancel)

    # reactor.callLater(10, _test_cancel)
    
    dhnio.SetDebug(14)
    dhnio.LifeBegins()
    settings.init()
    misc.loadLocalIdentity()
    # contacts.init()
    # contacts.addCorrespondent(idurl)
    identitycache.init()
    identitycache.SetLocalIPs({'http://identity.datahaven.net/veselin.xml': '192.168.1.3',
                               'http://identity.datahaven.net/veselin-ubuntu-1024.xml': '192.168.1.100'})
    port = int(settings.getUDPPort())
    if sys.argv[1] in ['listen', 'connect']:
        port = int(sys.argv[2])
    _go_stun(port)