Esempio n. 1
0
def serve_https(port):
    global _APIListener
    from crypt import certificate

    # server private key
    if os.path.exists(settings.APIServerCertificateKeyFile()):
        server_key_pem = local_fs.ReadBinaryFile(settings.APIServerCertificateKeyFile())
        server_key = certificate.load_private_key(server_key_pem)
    else:
        server_key, server_key_pem = certificate.generate_private_key()
        local_fs.WriteBinaryFile(settings.APIServerCertificateKeyFile(), server_key_pem)
    # server certificate
    if os.path.exists(settings.APIServerCertificateFile()):
        server_cert_pem = local_fs.ReadBinaryFile(settings.APIServerCertificateFile())
    else:
        server_cert_pem = certificate.generate_self_signed_cert(
            hostname=u'localhost',
            ip_addresses=[u'127.0.0.1', ],
            server_key=server_key,
        )
        local_fs.WriteBinaryFile(settings.APIServerCertificateFile(), server_cert_pem)
    # client private key
    if os.path.exists(settings.APIClientCertificateKeyFile()):
        client_key_pem = local_fs.ReadBinaryFile(settings.APIClientCertificateKeyFile())
        client_key = certificate.load_private_key(client_key_pem)
    else:
        client_key, client_key_pem = certificate.generate_private_key()
        local_fs.WriteBinaryFile(settings.APIClientCertificateKeyFile(), client_key_pem)
    # client certificate
    if os.path.exists(settings.APIClientCertificateFile()):
        client_cert_pem = local_fs.ReadBinaryFile(settings.APIClientCertificateFile())
        ca_cert_pem = local_fs.ReadBinaryFile(settings.APIServerCertificateFile())
    else:
        ca_cert_pem = local_fs.ReadBinaryFile(settings.APIServerCertificateFile())
        ca_cert = certificate.load_certificate(ca_cert_pem)
        client_cert_pem = certificate.generate_csr_client_cert(
            hostname=u'localhost',
            server_ca_cert=ca_cert,
            server_key=server_key,
            client_key=client_key,
        )
        local_fs.WriteBinaryFile(settings.APIClientCertificateFile(), client_cert_pem)

    try:
        from twisted.internet import ssl
        api_resource = BitDustRESTHTTPServer()
        site = BitDustAPISite(api_resource, timeout=None)
        auth = ssl.Certificate.loadPEM(server_cert_pem)
        cert = ssl.PrivateCertificate.loadPEM(server_cert_pem + server_key_pem)
        _APIListener = reactor.listenSSL(port, site, cert.options(auth), interface='127.0.0.1')  # @UndefinedVariable
    except:
        lg.exc()
        os._exit(1)
Esempio n. 2
0
def identity_cached(new_id_obj):
    """
    After receiving identity file of another user we need to check his identity sources.
    I can be file from identity server or Identity() packet received directly from remote peer.
    Also it can be my own identity that was changed locally.
    In any case we need to take certain actions if those identity sources changed.
    First identity source forms IDURL of that identity and act as unique global ID of that BitDust node.
    When first identity source changed (because identity server went down) identity is "rotated":
    second identity source will be placed on the first position and IDURL will change.
    In that case we need to remember new IDURL and keep track of old IDURL of that user - this way we can
    match and merge different IDURL's for one owner.
    """
    global _IdentityHistoryDir
    global _KnownUsers
    global _KnownIDURLs
    global _MergedIDURLs
    from userid import identity
    pub_key = new_id_obj.getPublicKey()
    user_name = new_id_obj.getIDName()
    if _Debug:
        lg.args(_DebugLevel, user_name=user_name)
    is_identity_rotated = False
    latest_id_obj = None
    latest_sources = []
    if pub_key not in _KnownUsers:
        user_path = tempfile.mkdtemp(prefix=user_name+'@', dir=_IdentityHistoryDir)
        _KnownUsers[pub_key] = user_path
        first_identity_file_path = os.path.join(user_path, '0')
        local_fs.WriteBinaryFile(first_identity_file_path, new_id_obj.serialize())
        if _Debug:
            lg.out(_DebugLevel, 'id_url.identity_cached wrote first item for user %r in identity history: %r' % (
                user_name, first_identity_file_path))
    else:
        user_path = _KnownUsers[pub_key]
        user_identity_files = sorted(map(int, os.listdir(user_path)))
        if len(user_identity_files) == 0:
            raise Exception('identity history for user %r is broken, public key is known, but no identity files found' % user_name)
        latest_identity_file_path = ''
        latest_pub_key = None
        latest_revision = -1
        known_revisions = set()
        for id_file in user_identity_files:
            identity_file_path = os.path.join(user_path, strng.to_text(id_file))
            xmlsrc = local_fs.ReadBinaryFile(identity_file_path)
            one_id_obj = identity.identity(xmlsrc=xmlsrc)
            if not one_id_obj.isCorrect():
                lg.err('identity history for user %r is broken, identity in the file %r is not correct' % (user_name, identity_file_path))
                continue
            if not one_id_obj.Valid():
                lg.err('identity history for user %r is broken, identity in the file %r is not valid' % (user_name, identity_file_path))
                continue
            if not latest_pub_key:
                latest_pub_key = one_id_obj.getPublicKey()
            if latest_pub_key != one_id_obj.getPublicKey():
                lg.err('identity history for user %r is broken, public key not matching in the file %r' % (user_name, identity_file_path))
                continue
            known_revisions.add(one_id_obj.getRevisionValue())
            if one_id_obj.getRevisionValue() > latest_revision:
                latest_revision = one_id_obj.getRevisionValue()
                latest_identity_file_path = identity_file_path
        xmlsrc = local_fs.ReadBinaryFile(latest_identity_file_path)
        latest_id_obj = identity.identity(xmlsrc=xmlsrc)
        if latest_id_obj.getPublicKey() != new_id_obj.getPublicKey():
            raise Exception('identity history for user %r is broken, public key not matching' % user_name)
        if latest_id_obj.getIDName() != new_id_obj.getIDName():
            lg.warn('found another user name in identity history for user %r : %r' % (user_name, latest_id_obj.getIDName()))
        if new_id_obj.getRevisionValue() in known_revisions:
            if _Debug:
                lg.out(_DebugLevel, 'id_url.identity_cached revision %d already known for user %r' % (new_id_obj.getRevisionValue(), user_name))
        else:
            latest_sources = latest_id_obj.getSources(as_originals=True)
            new_sources = new_id_obj.getSources(as_originals=True)
            if latest_sources == new_sources:
                local_fs.WriteBinaryFile(latest_identity_file_path, new_id_obj.serialize())
                if _Debug:
                    lg.out(_DebugLevel, 'id_url.identity_cached latest identity sources for user %r did not changed, updated file %r' % (
                        user_name, latest_identity_file_path))
            else:
                next_identity_file = user_identity_files[-1] + 1
                next_identity_file_path = os.path.join(user_path, strng.to_text(next_identity_file))
                local_fs.WriteBinaryFile(next_identity_file_path, new_id_obj.serialize())
                is_identity_rotated = True
                if _Debug:
                    lg.out(_DebugLevel, 'id_url.identity_cached identity sources for user %r changed, wrote new item in the history: %r' % (
                        user_name, next_identity_file_path))
    new_revision = new_id_obj.getRevisionValue()
    new_sources = new_id_obj.getSources(as_originals=True)
    for new_idurl in reversed(new_sources):
        if new_idurl not in _KnownIDURLs:
            _KnownIDURLs[new_idurl] = new_id_obj.getPublicKey()
            if _Debug:
                lg.out(_DebugLevel, 'id_url.identity_cached new IDURL added: %r' % new_idurl)
        else:
            if _KnownIDURLs[new_idurl] != new_id_obj.getPublicKey():
                lg.warn('another user had same identity source: %r' % new_idurl)
                _KnownIDURLs[new_idurl] = new_id_obj.getPublicKey()
        if pub_key not in _MergedIDURLs:
            _MergedIDURLs[pub_key] = {}
            if _Debug:
                lg.out(_DebugLevel, 'id_url.identity_cached new Public Key added: %s...' % pub_key[-10:])
        prev_idurl = _MergedIDURLs[pub_key].get(new_revision, None)
        if new_revision in _MergedIDURLs[pub_key]:
            if _MergedIDURLs[pub_key][new_revision] != new_idurl:
                if nameurl.GetName(_MergedIDURLs[pub_key][new_revision]) == nameurl.GetName(new_idurl):
                    if _MergedIDURLs[pub_key][new_revision] not in new_sources:
                        lg.warn('rewriting existing identity revision %d : %r -> %r' % (
                        new_revision, _MergedIDURLs[pub_key][new_revision], new_idurl))
            _MergedIDURLs[pub_key][new_revision] = new_idurl
        else:
            _MergedIDURLs[pub_key][new_revision] = new_idurl
            if _Debug:
                lg.out(_DebugLevel, 'id_url.identity_cached added new revision %d for user %r, total revisions %d: %r -> %r' % (
                    new_revision, user_name, len(_MergedIDURLs[pub_key]), prev_idurl, new_idurl))
    if _Debug:
        lg.args(_DebugLevel, is_identity_rotated=is_identity_rotated, latest_id_obj=bool(latest_id_obj))
    if is_identity_rotated and latest_id_obj is not None:
        latest_revision = latest_id_obj.getRevisionValue()
        if _Debug:
            lg.args(_DebugLevel, new_revision=new_revision, latest_revision=latest_revision)
        if new_revision > latest_revision:
            lg.info('found rotated identity after caching %r -> %r' % (
                latest_id_obj.getSources(as_originals=True)[0], new_sources[0]))
            from main import events
            events.send('identity-rotated', data=dict(
                old_idurls=latest_id_obj.getSources(as_originals=True),
                new_idurls=new_id_obj.getSources(as_originals=True),
                old_revision=latest_id_obj.getRevisionValue(),
                new_revision=new_revision,
            ))
            if latest_id_obj.getIDURL(as_original=True) != new_id_obj.getIDURL(as_original=True):
                events.send('identity-url-changed', data=dict(
                    old_idurl=latest_id_obj.getIDURL(as_original=True),
                    new_idurl=new_id_obj.getIDURL(as_original=True),
                    old_revision=latest_id_obj.getRevisionValue(),
                    new_revision=new_revision,
                ))
            from userid import my_id
            if my_id.isLocalIdentityReady():
                if my_id.getLocalID() == new_id_obj.getIDURL():
                    events.send('my-identity-rotated', data=dict(
                        old_idurls=latest_id_obj.getSources(as_originals=True),
                        new_idurls=new_id_obj.getSources(as_originals=True),
                        old_revision=latest_id_obj.getRevisionValue(),
                        new_revision=new_revision,
                    ))
                    if latest_id_obj.getIDURL(as_original=True) != new_id_obj.getIDURL(as_original=True):
                        events.send('my-identity-url-changed', data=dict(
                            old_idurl=latest_id_obj.getIDURL(as_original=True),
                            new_idurl=new_id_obj.getIDURL(as_original=True),
                            old_revision=latest_id_obj.getRevisionValue(),
                            new_revision=new_revision,
                        ))
        else:
            lg.warn('cached out-dated revision %d for %r' % (new_revision, new_sources[0]))
    else:
        if _Debug:
            lg.out(_DebugLevel, 'id_url.identity_cached revision %d for %r' % (new_revision, new_sources[0]))
    return True
Esempio n. 3
0
def WriteBinaryFile(filename, data):
    return local_fs.WriteBinaryFile(filename=filename, data=data)