Example #1
0
    def encrypt(self, object):
        self.lock.acquire()
        try:
            key = utility.random_bytes(16)

            pub_key   = crypto.RSA.construct(self.info['key'])
            encryptor = crypto.rijndael.rijndael(key, 16)
            
            encrypted_key  = pub_key.encrypt(key,'')[0]
            encrypted_text = encryptor.encrypt_cbc(safe_pickle.dumps(object))
            
            return (encrypted_key, encrypted_text)
        finally:
            self.lock.release()
Example #2
0
    def post_wodge(self, topics,subject,text,distance,anonymous,in_reply_to=None):
        if topics == [ ]:
            raise error.Error(_('Please specify some topics.'))
        if self.app.config['human-name'] == '' and not anonymous:
            raise error.Error(_('Please specify your name using the "Network/Configure..." menu item.'))
        if subject == '':
            raise error.Error(_('Please give a subject for your item.'))
        if text == '':
            raise error.Error(_('Please write some text for your item.'))
    
        wodge_info = {
            'topics'         : topics,
            'subject'        : subject,
            'text'           : text,
            'post-time'      : long(time.time())
        }

        if anonymous:
            wodge_info['name'] = ''
            wodge_info['human-name'] = ''
        else:
            wodge_info['name'] = self.app.name_server.public_key_name
            wodge_info['human-name'] = self.app.config['human-name']

        if in_reply_to:
            wodge_info['in-reply-to'] = in_reply_to.signature

        wodge_str = safe_pickle.dumps(wodge_info)
        if anonymous:
            wodge_sig = hash.hash_of(wodge_str)
        else:
            wodge_sig = self.app.name_server.sign(wodge_str)

        wodge = Wodge({
            'wodge': wodge_info,
            'string': wodge_str,
            'signature': wodge_sig,
            'initial_time': time.time(),
            'initial_distance': distance,
            #Fixme: make unit_decay_time an option
            'unit_decay_time': 60*60*24*7,
            'opinions': { },
            'collapsed': 0})
        # distance = post_distance + (time - post_time)/unit_decay_time

        self.insert_wodge(wodge)
        self.save()
Example #3
0
    def publish_auction(self, title, category, description, initial_price=0):

        info = {
            'type'       : 'auction',
            'category'   : category,
            'title'      : title,
            'seller'     : self.app.node.name,
            'description': description
            }        
        name = hash.hash_of(safe_pickle.dumps(info))
        self.auctions[name] = info
        self.auctions_prices[name] = initial_price
                
        keywords = string.split(string.lower(title))
        for item in keywords:
            self.node.publish(hash.hash_of('auction-name '+ item),
                              info, settings.identity_redundancy)

        self.node.publish(hash.hash_of('auction-category '+ category),
                          info, settings.identity_redundancy)
Example #4
0
def chat_tell_thread(chat, dests, message, attachment=None, augmentation=None):
    """Messages are sent in parallel, one thread per recipient. The
       information displayed in field ends with '...' until the last
       message has been sent, then with '..' until all recipients
       have answered, and finally with '.' The field is closed by
       the last thread to finish """
    
    check.check_matches(dests, ['text'])
    check.check_is_text(message)
    std_timestamp = host2standard_timestamp(time.time())
    if augmentation and len(augmentation) != len(message):
        sys.stderr.write("Augmentation %d bytes, should be %d bytes.\n"
                         % (len(augmentation), len(message)))
        augmentation = None
    
    message_id = chat.create_message_id()
    try:
        result = ['','','','','...\n']
        dest_list = [ ]
        dest_address  = [ ]
        checked_address = [ ]
        dest_names = [ ]
        received_names = [ ]
        offline_list  = [ ]
        offline_names = [ ]
        recipient_list = [ ]
        channel_pipes = { }
        chan_cnt=[0]

        for dest in dests:
            if dest[0]=='#':
                channel_pipes[dest] = chat.channels.sub_list_pipe(dest)
                recipient_list.append((None,None,dest))
                continue
            acq = chat.app.name_server.locate(dest)
            acq.start_watching(chat.node)
            while not acq.watched:
                yield 'sleep',0.1

            acq.lock.acquire()
            online = acq.online
            address = acq.address
            name = acq.name
            username = acq.info['name']
            acq.lock.release()

            if not online:
                offline_list.append(acq)
                offline_names.append(dest)
                recipient_list.append((name,None,username))
            else:
                dest_list.append(acq)
                dest_address.append(address)
                dest_names.append(dest)
                recipient_list.append((name,address,username))

        my_details = (
            chat.app.name_server.public_key_name,
            chat.app.name_server.name
        )

        package = {
            'from': my_details,
            'to': recipient_list,
            'text': message
        }
        if augmentation:
            package['aug'] = augmentation
        if attachment:
            package['attach'] = attachment

        package_pickle = safe_pickle.dumps(package)
        signature = chat.app.name_server.sign(package_pickle)
        message = ('chat message 2',package_pickle,signature)

        def recipient_thread(chat,address,name,channel,received_names,dest_address,
                             checked_address,chan_cnt,message_id,result, message=message):

            succ = 1
            try:
                ticket, template, wait = chat.node.call(address,message)
                if wait: yield ('call',(chat.node,ticket))
                ret_value = chat.node.get_reply(ticket,template)

                #Type checking
                if type(ret_value) != types.TupleType:
                    succ = 0
                    if not channel:
                        result[2] = result[2] + name + _(' sent bad reply.\n')
                        chat.update_message_status(message_id, result[0]+result[4]+result[2])
            except error.Error,err:
                succ = 0
                if not channel:
                    result[2] = result[2] + name + _(' could not be contacted: ')+err.message+'\n'
                    chat.update_message_status(message_id, result[0]+result[4]+result[2])
                    chat.app.name_server.bad_address(address)
                    
            if succ:
                if channel:
                    chan_cnt[0] += 1
                else:
                    received_names.append(name)
                    if ret_value[0]:
                        pass
                        #if ret_value[1] != '':
                        #    result[2] = result[2] + name + ' ' + ret_value[1] + '\n'
                    else:
                        if ret_value[1] == '':
                            result[2] = result[2] + name + _(' is quiet.\n')
                        else:
                            result[2] = result[2] + name + _(' is quiet: ') + ret_value[1] + '\n'
                            
                if chan_cnt[0] == 0:
                    result[0] = _('Message received by ') + utility.english_list(received_names) 
                elif chan_cnt[0] == 1:
                    result[0] = _('Message received by ')\
                                +utility.english_list(received_names+[ _('1 person')])+result[1]
                else:                            
                    result[0] = _('Message received by ')\
                                +utility.english_list(received_names+[ _('%d people') % chan_cnt[0] ])+result[1]
                chat.update_message_status(message_id,result[0]+result[4]+result[2])

            checked_address.append(address)
            checked_address.sort()
            if result[4]=='..\n' and checked_address == dest_address:
                if chan_cnt[0]==0 and received_names == []:
                    result[0] = _('Nobody received your message')
                result[4] = '.\n'
                chat.update_message_status(message_id, result[0]+result[4]+result[2])

        for i in range(len(dest_list)):
            utility.start_thread(recipient_thread(chat,dest_address[i],dest_names[i],0,\
                       received_names,dest_address,checked_address,chan_cnt,message_id,result))
         
        if channel_pipes:
            if channel_pipes.__len__()>1:
                result[1] = (_(' on channels %s') % utility.english_list(channel_pipes.keys()))
            else:
                result[1] = (_(' on channel %s') % channel_pipes.keys()[0])

        if channel_pipes:
            for chan_name in channel_pipes.keys():
                if not chat.channels.cache.has_key(chan_name):
                    chat.channels.cache[chan_name]=[]
                else:                    
                    for address in chat.channels.cache[chan_name]:
                        if address in dest_address:
                            continue                    
                        dest_address.append(address)
                        utility.start_thread(
                            recipient_thread(chat,address,'',1,received_names,
                                             dest_address,checked_address,chan_cnt,message_id,result))
                #reset the cache:
                chat.channels.cache[chan_name]=[]
                    
                    
        while channel_pipes:
            for chan_name,chan_pipe in channel_pipes.items():
                if chan_pipe.finished():
                    chan_pipe.stop()
                    del channel_pipes[chan_name]
                    continue
                
                for address in chan_pipe.read_all():
                    #update the cache
                    if address not in chat.channels.cache[chan_name]:
                        chat.channels.cache[chan_name].append(address)
                    if address in dest_address:
                        continue
                    dest_address.append(address)
                    utility.start_thread(recipient_thread(chat,address,'',1,received_names,
                               dest_address,checked_address,chan_cnt,message_id,result))
                    
            yield 'sleep',0.1

        #we now have launched all the tasks
        dest_address.sort()
        result[4]='..\n'
        if checked_address == dest_address:
            if chan_cnt[0]==0 and received_names == []:
                result[0] = _('Nobody received your message')
            result[4] = '.\n'
            chat.update_message_status(message_id, result[0]+result[4]+result[2])

        recall_list = [ ]
        if offline_list:
            chat.update_message_status(message_id,'Caching message...\n',1)
        for i in range(len(offline_list)):
            key   = utility.random_bytes(settings.name_bytes)
            lock  = hash.hash_of(key)
            crypt = offline_list[i].encrypt((key, message, std_timestamp))
            data  = {
                'type' : 'offline message',
                'crypt': crypt
            }
            name  = hash.hash_of('offline message '+offline_list[i].name)
            # Loose proof of @R50: @I21, @E22.

            recall_list.append((offline_list[i].nickname,name,data,key))

            publish_result, subthread = chat.app.cache.publish([name],data,lock)
            yield 'wait',subthread
            if publish_result:
                redundancy = publish_result[0]
            else: redundancy = 0
            if redundancy == settings.cache_redundancy:
                str = offline_names[i] + _(' will get your message when next logged on.\n')
            elif redundancy == 0:
                str = _('Could not store message for ') + offline_names[i] + '!\n'
            else:
                str = (offline_names[i]
                       + _(' will probably get your message when next logged on:\n' +\
                           '  Message only stored with redundancy %d.\n') % redundancy)

            result[3] = result[3] + str
            chat.update_message_status(message_id,result[3]+'\n',1)
            
        chat.recall_list = recall_list
Example #5
0
        def startup_thread(self, status_monitor=status_monitor):
            
            list = self.acquaintances.values()
            list.sort(lambda x,y: cmp(x.sort_value(),y.sort_value()))
            for item in list:
                item.start_watching(self.node)

                #start watching tends to breed, try to make sure we don't get
                #too many threads.
                #yes, this is hacky
                #print item.nickname, threading.activeCount()
                #time.sleep(0.25)

                while 1:
                    yield 'sleep',0.25
                    if threading.activeCount() < 40:
                        break
                 
            self.me.start_watching(self.node)
            while not self.me.watched:
                yield 'sleep',0.1
            
            online = self.me.online
            address = self.me.address
            if online:
                if status_monitor:
                    status_monitor(_('Shutting down your other peer.'))
                while 1:
                    ticket,template,wait = self.node.call(address, ('identity abort',))
                    if wait: yield 'call',(self.node,ticket)
                    try:
                        dummy_result = self.node.get_reply(ticket, template)
                    except error.Error:
                        break
                    yield 'sleep',4
            
            self.me.online  = 1
            self.me.address = self.node.address
            self.me.connect_time = time.time()
            # Task to retrieve existing watchers
            # Task to poll existing watchers
            utility.start_thread(name_server_watch_poller_thread(self))
            # now refresh my own offline presence
            pipe = self.node.retrieve(self.public_key_name_offline, settings.cache_redundancy)
            list = [ ]

            while not pipe.finished():
                for item in pipe.read_all():
                    if type(item[1]) == types.DictType and \
                           item[1].get('type') == 'identity offline' and \
                           item[1].get('salt'):
                        list.append(item)
                yield 'sleep',2
                if not self.running:
                    return
            pipe.stop()

            #if len(list) != 4:
            #    print _("%d peers holding your offline presence.") % len(list)

            for item in list:
                address, value = item
                key = hash.hash_of(safe_pickle.dumps(self.sign(value['salt'])))
                ticket, template, wait = self.node.call(address, ('data cache remove',key))
                if wait: yield 'call',(self.node,ticket)
                try:
                    dummy_result = self.node.get_reply(ticket,template)
                except error.Error:
                    pass

            self.lock.acquire()
            try:
                package = {
                    'name'       : self.info['name'],
                    'human-name' : self.info['human-name'],
                    'description': self.info['description'],
                    'timezone'   : self.info['timezone'],
                    'key'        : self.public_key,
                    'keywords'   : self.info['keywords'],
                }
            finally:
                self.lock.release()

            package_dumped = safe_pickle.dumps(package)
            signature = self.sign(package_dumped)


            # now publish and cache offline identity
            value = {
                'type' : 'identity offline',
                'package' : package_dumped,
                'signature' : signature,
                'salt' : utility.random_bytes(settings.name_bytes)
            }
            lock = hash.hash_of(hash.hash_of(safe_pickle.dumps(self.sign(value['salt']))))
            publications = [ self.public_key_name_offline, self.service_name ]
            for item in package['keywords']:
                publications.append(hash.hash_of('identity-name '+item))
            # thomasV
            # redundancy 4: this is the meta-publish
            result, publish_thread = self.app.cache.publish(publications,value,lock, 4)
            yield 'wait',publish_thread
Example #6
0
def key_name(key):
    ret = hash.hash_of(safe_pickle.dumps(key))
    check.check_is_name(ret)  #=@E25
    # Proof: @E24.
    return ret
Example #7
0
def find_task(daemon, query, input, output, connection):

    import safe_pickle

    for char in "+-_.,?()![]":
        query = query.replace(char, " ")
    query = query.lower()
    list = query.split()
    if list:
        key = list[0]
        pipe = daemon.node.retrieve(hash.hash_of("identity-name " + key), settings.identity_redundancy)
    else:
        pipe = daemon.node.retrieve(hash.hash_of("service identity"), settings.identity_redundancy)

    results = []
    while not pipe.finished():

        list = pipe.read_all()
        prev_pair = None
        for pair in list:
            if pair == prev_pair:
                continue
            link, item = prev_pair = pair

            try:
                item = utility.check_and_demangle_item(item)
            except:
                continue

            if item["key"] not in results:
                results.append(item["key"])
                name = hash.hash_of(safe_pickle.dumps(item["key"]))
                check.check_is_name(name)
                str = hash.hash_to_person(name)
                output.write(str + "   " + item["name"] + " (" + utility.force_string(item["human-name"]) + ")\n")

        time.sleep(0.5)
        try:
            output.flush()
        except:
            return

    if not results:
        try:
            output.write('No user matching "' + key + '"')
        except:
            pass
    else:
        if results.__len__() == 1:
            msg = "1 user found."
        else:
            msg = "%d users found." % results.__len__()
        output.write(msg)

    pipe.stop()
    try:
        input.close()
        output.close()
        connection.close()
    except:
        # connection reset by peer...
        pass