Beispiel #1
0
    def got_user_profile(self, user, reply, ctx):
        """ This is called when other person's profile has been received """

        user.inprogress = False
        if reply == None:
            return
        profile = reply.get('uprofile')
        if profile == None:
            warning('Invalid user profile: %s\n' % str(reply))
            return
        uid = profile.get('uid')
        if not valid_uid(uid):
            warning('Invalid uid: %s\n' % str(uid))
            return
        if uid == self.myuid or uid != user.get('uid'):
            warning('uid treason detected. Message from %s: %s\n' % (user.get('uid'), str(profile)))
            return
        oldstatus = (user.get('status'), user.get('status_icon'))
        if not user.unserialize(profile):
            warning('Invalid user profile: %s\n' % str(profile))
            return

        # Now we know the profile is valid
        create_user_communities(user)
        self.announce_user_change(user)
        self.save_user(user)

        if oldstatus != (user.get('status'), user.get('status_icon')):
            self.show_status_change(user)

        # The user profile is now up-to-date. Now we can fetch everything else.
        self.request_user_icon(user)
        self.fetch_community_profiles(user)
Beispiel #2
0
def parse_user_dentry(dentry):
    if not dentry.startswith('u_'):
        return None
    uid = dentry[2:]
    if not valid_uid(uid):
        uid = None
    return uid
Beispiel #3
0
def valid_addr(addr):
    l = addr.split(':')
    if not ((len(l) == 2 and l[0] == 'u') or (len(l) == 3 and l[0] == 'c')):
        return False
    if l[0] == 'u' and not valid_uid(l[1]):
        return False
    if l[0] == 'c' and not valid_community(l[2]):
        return False
    return True
Beispiel #4
0
 def safe_get_user(self, uid, ip):
     if valid_uid(uid) == False or uid == self.myuid:
         return None
     user = self.get_user(uid)
     if user == None:
         # Create a minimal user object for the peer so that we can reply
         return create_user(uid)
     oldip = user.get('ip')
     if ip != None and oldip != None and ip != oldip:
         return None
     if self.is_blacklisted(user):
         return None
     return user
Beispiel #5
0
    def got_bye(self, d, address):
        """ User quit, denounce """

        validator = {
            'uid': lambda s: valid_uid(s) and s != self.myuid,
           }
        if not validate(validator, d):
            return

        user = self.safe_get_user(d.get('uid'), address[0])
        if user == None:
            info('Rejecting quit message from uid %s\n' % d.get('uid'))
        else:
            self.denounce_user(user)
Beispiel #6
0
    def validate(self):
        if not self.fields or len(self.fields) < 6:
            return False

        # 0. Check field lengths
        if len(self.fields[0]) != 20:
            return False

        if not (len(self.fields[1]) == 0 or len(self.fields[1]) == 20):
            return False

        if len(self.fields[2]) > MAX_CTIME_STR_LENGTH:
            return False

        if len(self.fields[5]) > MAX_MSG_STR_LENGTH:
            return False

        # 1. Check SHA1 sum
        m = hashlib.sha1()
        for f in self.fields[1:]:
            m.update(f)

        if m.digest() != self.fields[0]:
            return False

        # 2. Check addresses
        l = self.get_sender_addr().split(':')
        if len(l) != 2 or l[0] != 'u' or not valid_uid(l[1]):
            return False

        if not valid_addr(self.get_target_addr()):
            return False

        # 3. Check ctime
        l = self.get_ctime()
        if len(l) < 2:
            return False
        timet = str_to_int(l[0], -1)
        seqnumber = str_to_int(l[1], -1)
        return timet >= 0 and seqnumber >= 0
Beispiel #7
0
    def got_hello(self, d, address):
        """ Check validity of Proximate hello, and register the other party. """

        validator = {
            'v': valid_protocol_version,
            'pv': lambda x: type(x) == int and x >= 0,
            'port': valid_port,
            'nick': valid_nick,
            'uid': lambda s: valid_uid(s) and s != self.myuid,
           }
        if not validate(validator, d):
            if type(d) != dict or d.get('uid') != self.myuid:
                info('Rejecting signature: %s\n' % str(d))
            return

        updatelist = [('nick', d['nick']), ('protocolversion', d['v'])]

        if address != None:
            ip = address[0]
        else:
            ip = None
        self.add_or_update_user(d['uid'], updatelist, d['pv'], ip, d['port'])
Beispiel #8
0
    def request_cb(self, target_user, request, ctx):
        """ Handles answers from fetcher """

        if request == None:
            return

        if not validate({'r': str,
                         'uid': lambda s: type(s) == str and valid_uid(s) and s != self.my_uid,
                         'param': str}, request):
            debug('Key management: Broken payload: %s\n' %(' '.join(payload)))
            return

        cmd = request['r']
        uid = request['uid']
        param = request['param']

        if uid == self.my_uid:
            return

        debug('Key management: got answer %s from %s\n' %(cmd, uid))
        user = self.community.get_user(uid)

        if self.current['user'] and user != self.current['user']:
            warning('keymanagement: Protocol violation from %s: Current uid is %s\n' %(nick, self.current['uid'].get('uid')))
            return {'r': self.KM_PROTOCOL_VIOLATION, 'uid': self.my_uid}

        if not self.check_answer(cmd):
            warning('keymanagement: Protocol violation from %s: request was %s but answer was %s' %(uid, self.current['state'], cmd))
            self.send_request(user, self.KM_PROTOCOL_VIOLATION, '')
            return

        self.key_exchange_gui.plugin_to_gui(user, cmd, False)

        payload = ''
        if cmd == self.KM_REQUEST_ACK:
            self.temp_key_watcher = self.gen_temp_key()
            self.temp_passphrase = self.gen_passphrase()
            debug('Key management: passphrase is %s\n' %(self.temp_passphrase))
            return
        if cmd == self.KM_REQUEST_ANSWER_ACK:
            self.gen_temp_key()
            return
        elif cmd == self.KM_TEMP_KEY1:
            # Received temporery key: save it and send our temporary key
            # encrypted with the symmetric cipher
            temp_key = self.sym_dec(param, self.temp_passphrase)
            if temp_key and self.save_key(user, pub=temp_key, temp=True):
                send_cmd = self.KM_TEMP_KEY2
                payload = self.sym_enc(self.load_pub_key(self.myself, temp=True),
                    self.temp_passphrase)
                if not payload:
                    send_cmd = self.KM_ERROR
                    payload = ''
            else:
                send_cmd = self.KM_ERROR
                payload = ''
        elif cmd == self.KM_PERM_KEY1:
            # Received counterpartys permanent key, so let's save it and send ours
            perm_key = self.asym_dec(param, self.key_path(self.myself, temp=True))
            if perm_key and self.save_key(user, pub=perm_key):
                send_cmd = self.KM_PERM_KEY2
                payload = self.asym_enc(self.load_pub_key(self.myself),
                                        self.key_path(user, temp=True))
                if not payload:
                    send_cmd = KM.ERROR
                    payload = ''
            else:
                send_cmd = KM_ERROR
                payload = ''
        elif cmd == self.KM_PERM_KEY_ACK:
            send_cmd = self.KM_FINISHED
        elif cmd == self.KM_FINISHED:
            # Successful key exchange
            self.current = {'user': None, 'state': None}
            self.community.announce_user_change(user) # update user state
            return
        elif cmd == self.KM_CANCEL:
            self.current = {'user': None, 'state': None}
            return
        elif cmd == self.KM_ERROR:
            self.current = {'user': None, 'state': None}
            return
        elif cmd == self.KM_PROTOCOL_VIOLATION:
            self.current = {'user': None, 'state': None}
            return
        elif cmd == self.KM_REQUEST_NACK:
            self.current = {'user': None, 'state': None}
            return

        self.current['state'] = send_cmd
        self.send_request(user, send_cmd, payload)
Beispiel #9
0
    def handle_requests(self, from_user, request):
        """ Handles requests from fetcher """
        if request == None:
            return
        if not validate({'t': str,
                         'uid': lambda s: type(s) == str and valid_uid(s) and s != self.my_uid,
                         'param': str}, request):
            debug('Key management: Broken request: %s\n' %(request))
            return {'r': self.KM_PROTOCOL_VIOLATION, uid: self.my_uid}
        cmd = request['t']
        uid = request['uid']
        param = request['param']

        debug('Key management: handling request %s from %s\n' %(cmd, uid))

        user = self.community.get_user(uid)
        if user != from_user:
            warning("keymanagement: Invalid uid from fetcher: %s\n" %(uid))
            return {'r': self.KM_PROTOCOL_VIOLATION, 'uid': self.my_uid}
        nick = user.get('nick')

        if self.current['user'] and user != self.current['user']:
            warning('keymanagement: Paraller request from %s: Current uid is %s\n' %(nick, self.current['user'].get('uid')))
            return {'r': self.KM_REQUEST_NACK, 'uid': self.my_uid}

        if not self.check_request(cmd):
            warning('keymanagement: Protocol violation from %s: Current state is %s but received request %s\n' %(nick, self.current['state'], cmd))
            return {'r': self.KM_PROTOCOL_VIOLATION, 'uid': self.my_uid}

        self.current['state'] = cmd

        self.key_exchange_gui.plugin_to_gui(user, cmd, True)

        payload = ''
        if cmd == self.KM_REQUEST_KEY:
            self.current['user'] = user
            result = self.KM_REQUEST_ACK
        elif cmd == self.KM_REQUEST_DENIED:
            debug('keymanagement: %s denied request for key exchange\n' %(nick))
            self.current = {'user': None, 'state': None}
            result = self.KM_CANCEL
        elif cmd == self.KM_REQUEST_OK:
            debug('keymanagement: started key exchange with %s\n' %(nick))
            result = self.KM_REQUEST_ANSWER_ACK
        elif cmd == self.KM_TEMP_KEY_ACK:
            # Other user has typed in the passphrase. We can now send the
            # temporary key encrypted with it.
            result = self.KM_TEMP_KEY1
            payload = self.sym_enc(self.load_pub_key(self.myself, temp=True),
                self.temp_passphrase)
            if not payload:
                result = self.KM_ERROR
                payload = ''
        elif cmd == self.KM_TEMP_KEY2:
            # Received other party's temporary key. Let's send our
            # permanent key encrypted with this temporary key.
            temp_key = self.sym_dec(param, self.temp_passphrase)
            if temp_key and self.save_key(user, pub=temp_key, temp=True):
                result = self.KM_PERM_KEY1
                payload = self.asym_enc(self.load_pub_key(self.myself),
                                        self.key_path(user, temp=True))
                if not payload:
                    result = self.KM_ERROR
                    payload = ''
            else:
                result = self.KM_ERROR
                payload = ''
        elif cmd == self.KM_PERM_KEY2:
            # Received permanent key. Save it and send "finished".
            perm_key = self.asym_dec(param, self.key_path(self.myself, temp=True))
            if perm_key and self.save_key(user, pub=perm_key):
                result = self.KM_PERM_KEY_ACK
            else:
                result = self.KM_ERROR
        elif cmd == self.KM_CANCEL:
            self.current = {'user': None, 'state': None}
            # Key exchange canceled
            result = self.KM_CANCEL
        elif cmd == self.KM_FINISHED:
            self.community.announce_user_change(user) # update user state
            self.current = {'user': None, 'state': None}
            # Successful key exchange
            result = self.KM_FINISHED
        elif cmd == self.KM_ERROR:
            self.current = {'user': None, 'state': None}
            result = self.KM_ERROR
        elif cmd == self.KM_PROTOCOL_VIOLATION:
            self.current = {'user': None, 'state': None}
            result = self.KM_PROTOCOL_VIOLATION

        debug('Key management: sending answer %s to %s\n' %(result, nick))
        return {'r': result, 'uid': self.my_uid, 'param': payload}
Beispiel #10
0
# See the LICENSE file for more details.
#
from time import time

from meta import Meta, Meta_Attribute, validate_list, privatebool, \
     publicstring, publicunsignedint, privateunsignedint, privatestringlist, \
     is_unsigned_int
from proximateprotocol import valid_community, valid_uid

comattrs = {}

# Public attributes
for pubkey in ['creator', 'description', 'keywords', 'timestart', 'timeend', 'location', 'www']:
    comattrs[pubkey] = publicstring()

comattrs['creatoruid'] = Meta_Attribute(str, public=True, is_valid=lambda n, v: valid_uid(v))

comattrs['iconversion'] = Meta_Attribute(int, public=True, is_valid=is_unsigned_int, default=0)

comattrs['name'] = Meta_Attribute(str, public=True, is_valid=lambda n, v: valid_community(v))
comattrs['name'].is_required()

# Private attributes
comattrs['cid'] = privateunsignedint()
comattrs['invisible'] = privatebool(default=False)
comattrs['members'] = Meta_Attribute(list, public=False, is_valid=lambda n, v: validate_list(v, valid_uid), default=[])
comattrs['keys'] = privatestringlist()
comattrs['peer'] = Meta_Attribute(bool, public=False, default=True)
comattrs['public'] = Meta_Attribute(bool, public=False, default=True)
comattrs['iconlocked'] = Meta_Attribute(bool, public=False, default=False)
comattrs['myiconversion'] = privateunsignedint()
Beispiel #11
0
        if name not in tempcommunities:
            communities.append(name)
    return communities

userattributes['communities'] = Meta_Attribute(list, public=True, is_valid=lambda n, v: validate_list(v, valid_community), default=[DEFAULT_COMMUNITY_NAME])
userattributes['communities'].is_required()
userattributes['communities'].process_before_save(community_filter)

userattributes['faceversion'] = Meta_Attribute(int, public=True, is_valid=is_unsigned_int, default=0)
userattributes['fscounter'] = Meta_Attribute(int, public=True, is_valid=is_unsigned_int, default=0)
userattributes['fscounter'].is_required()

userattributes['nick'] = Meta_Attribute(str, public=True, is_valid=lambda n, v: valid_nick(v), default=TP_NICK_DEFAULT)
userattributes['nick'].is_required()
userattributes['status_icon'] = Meta_Attribute(str, public=True, is_valid=lambda n, v: valid_status(v))
userattributes['uid'] = Meta_Attribute(str, public=True, is_valid=lambda n, v: valid_uid(v))
userattributes['uid'].is_required()

# Private attributes
userattributes['key_fname'] = privatestring()
userattributes['privcommunities'] = Meta_Attribute(list, public=False, is_valid=lambda n, v: type(v) == list and validate_list(v, valid_cid), default=[])
userattributes['remotes'] = Meta_Attribute(list, public=False)
userattributes['friend'] = Meta_Attribute(bool, public=False, save=True, default=False)
userattributes['myfaceversion'] = privateunsignedint()

# Private non-saved attributes
userattributes['ip'] = Meta_Attribute(str, public=False, save=False, is_valid=lambda n, v: valid_ip(v))
userattributes['port'] = Meta_Attribute(int, public=False, save=False, is_valid=lambda n, v: valid_port(v))
userattributes['protocolversion'] = Meta_Attribute(int, public=False, save=False, is_valid=lambda n, v: valid_protocol_version(v), default=PROXIMATE_PROTOCOL_VERSION)

userattributes['tempcommunities'] = Meta_Attribute(list, public=False, save=False, is_valid=lambda n, v: validate_list(v, valid_community), default=[])