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)
def parse_user_dentry(dentry): if not dentry.startswith('u_'): return None uid = dentry[2:] if not valid_uid(uid): uid = None return uid
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
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
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)
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
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'])
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)
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}
# 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()
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=[])