diff --git a/None/M2ZiNGU4MzcwZmRjNzg2NTdmMmYwMDExMTFjY2IxNTc1ODY1ZjVhMzE4NDk0OTRkMzEwMzM4ZDQ1OGNlZWNlYQ== b/None/M2ZiNGU4MzcwZmRjNzg2NTdmMmYwMDExMTFjY2IxNTc1ODY1ZjVhMzE4NDk0OTRkMzEwMzM4ZDQ1OGNlZWNlYQ== new file mode 100644 index 0000000..9ef09be Binary files /dev/null and b/None/M2ZiNGU4MzcwZmRjNzg2NTdmMmYwMDExMTFjY2IxNTc1ODY1ZjVhMzE4NDk0OTRkMzEwMzM4ZDQ1OGNlZWNlYQ== differ diff --git a/None/MjZkODU4ZTYyZGEwNzYyZDdlNDY3ODA4ODNmZWI0M2NmOGE1MzkyMGMyYzY5MDcyN2YyNTEwMTUxOWY1NzIyMw== b/None/MjZkODU4ZTYyZGEwNzYyZDdlNDY3ODA4ODNmZWI0M2NmOGE1MzkyMGMyYzY5MDcyN2YyNTEwMTUxOWY1NzIyMw== new file mode 100644 index 0000000..71806f0 Binary files /dev/null and b/None/MjZkODU4ZTYyZGEwNzYyZDdlNDY3ODA4ODNmZWI0M2NmOGE1MzkyMGMyYzY5MDcyN2YyNTEwMTUxOWY1NzIyMw== differ diff --git a/komrade/backend/crypt.py b/komrade/backend/crypt.py index 5d96865..ea0936d 100644 --- a/komrade/backend/crypt.py +++ b/komrade/backend/crypt.py @@ -15,6 +15,8 @@ LOG_GET_SET = 0 + + class Crypt(Logger): def __init__(self,name=None,fn=None,cell=None,init_d=None,use_secret=CRYPT_USE_SECRET,path_secret=PATH_CRYPT_SECRET,encrypt_values=True,path_encrypt_key=PATH_CRYPT_SECRET_KEY): if not name and fn: name=os.path.basename(fn).replace('.','_') @@ -174,24 +176,93 @@ class DataCrypt(Crypt): return super().__init__(name=PATH_CRYPT_CA_DATA.replace('.','_')) -from collections import defaultdict -class CryptMemory(Crypt): - def __init__(self): - self.data = defaultdict(None) - self.crypt = defaultdict(None) - self.cell = None + +class CryptList(Crypt): # like inbox + def __init__(self, + crypt, + keyname, + prefix='', + encryptor_func=lambda x: x, + decryptor_func=lambda x: x): + + self.crypt=crypt + self.keyname=keyname + self.prefix=prefix + self.encryptor_func=encryptor_func + self.decryptor_func=decryptor_func - def set(self,k,v,prefix=''): - k_b=self.package_key(k,prefix=prefix) - v_b=self.package_val(v) - self.data[k]=v_b - self.crypt[k_b]=v_b + @property + def val_b_encr(self): + return self.crypt.get( + self.keyname, + prefix=self.prefix + ) + @property + def val_b(self): + val_b_encr=self.val_b_encr + if not val_b_encr: return None + return self.decryptor_func(val_b_encr) + + @property + def values(self): + val_b=self.val_b + if not val_b: return [] + return pickle.loads(val_b) + + def prepend(self,x): + return self.append(x,insert=0) + + def append(self,x,insert=None): + val_l = self.values + # print('val_l =',val_l) + if insert is not None: + val_l.insert(insert,x) + else: + val_l.append(x) + # print('val_l2 =',val_l) + + return self.set(val_l) + + def set(self,val_l): + val_b = pickle.dumps(val_l) + val_b_encr = self.encryptor_func(val_b) + return self.crypt.set( + self.keyname, + val_b_encr, + prefix=self.prefix, + override=True + ) + + def remove(self,l): + if type(l)!=list: l=[l] + lset=set(l) + values = [x for x in self.values if x not in lset] + return self.set(values) + if __name__=='__main__': crypt = Crypt('testt') - print(crypt.set('hellothere',b'ryan')) + from komrade import KomradeSymmetricKeyWithPassphrase + key = KomradeSymmetricKeyWithPassphrase() + + + crypt_list = CryptList( + crypt=crypt, + keyname='MyInbox2', + prefix='inbox', + encryptor_func=key.encrypt, + decryptor_func=key.decrypt + ) + + print(crypt_list.values) + + print(crypt_list.remove('cool thing 0')) + + # print(crypt_list.append('cool thing 1')) + + print(crypt_list.prepend('cool thing 0')) - # print(crypt.get(b'hello there')) \ No newline at end of file + print(crypt_list.values) \ No newline at end of file diff --git a/komrade/backend/keymaker.py b/komrade/backend/keymaker.py index bc2fa75..3e5e0c1 100644 --- a/komrade/backend/keymaker.py +++ b/komrade/backend/keymaker.py @@ -280,7 +280,7 @@ class Keymaker(Logger): # return res def find_name(self,pubkey_b64): - res = self.crypt_keys.get(b64enc(q), prefix='/name/') + res = self.crypt_keys.get(b64enc(pubkey_b64), prefix='/name/') return res @property diff --git a/komrade/backend/komrades.py b/komrade/backend/komrades.py index d957100..4b9bbd7 100644 --- a/komrade/backend/komrades.py +++ b/komrade/backend/komrades.py @@ -421,11 +421,14 @@ class KomradeX(Caller): # enclosing msg_to_op = { - 'deliver_from':self.pubkey.data_b64, - 'deliver_from_name':self.name, - 'deliver_to':someone.pubkey.data_b64, - 'deliver_to_name':someone.name, - 'deliver_msg':direct_msg_data, + 'deliver_msg': { + 'from':self.pubkey.data_b64, + 'from_name':self.name, + 'to':someone.pubkey.data_b64, + 'to_name':someone.name, + 'msg':direct_msg_data, + } + } self.log('going to send msg to op?',msg_to_op) @@ -435,6 +438,9 @@ class KomradeX(Caller): route='deliver_msg' ) + + + def check_msgs(self,inbox=None): if not self.pubkey and self.privkey: return {'success':False,'status':'Need to be logged in'} @@ -534,7 +540,7 @@ class KomradeX(Caller): deleted=[] for post_id in post_ids: #print('deleting post:',post_id) - self.crypt_keys.delete( + self.crypt_data.delete( post_id, prefix='/post/', ) @@ -627,7 +633,7 @@ class KomradeX(Caller): unread = [] for post_id in inbox: if not post_id: continue - if not self.crypt_keys.get(post_id,prefix='/post/'): + if not self.crypt_data.get(post_id,prefix='/post/'): unread.append(post_id) self.log(f'I {self} have {len(unread)} new messages') @@ -643,11 +649,11 @@ class KomradeX(Caller): def read_msg(self,post_id): # get post - post_encr = self.crypt_keys.get(post_id,prefix='/post/') + post_encr = self.crypt_data.get(post_id,prefix='/post/') # print(post_id,'????') if not post_encr: self.download_msgs([post_id]) - post_encr = self.crypt_keys.get(post_id,prefix='/post/') + post_encr = self.crypt_data.get(post_id,prefix='/post/') # print(post_id,'????') return { @@ -722,7 +728,7 @@ class KomradeX(Caller): posts_downloaded = [] for post_id,post_encr in res['data_encr'].items(): # print('storing...',post_id) - self.crypt_keys.set( + self.crypt_data.set( post_id, post_encr, prefix='/post/' diff --git a/komrade/backend/operators.py b/komrade/backend/operators.py index f50b6d9..3a06b3d 100644 --- a/komrade/backend/operators.py +++ b/komrade/backend/operators.py @@ -87,6 +87,7 @@ class Operator(Keymaker): # add to phonebook if name: PHONEBOOK[name]=self if self.pubkey: PHONEBOOK[self.pubkey.data_b64]=self + self._inbox_crypt=None @property @@ -275,10 +276,6 @@ class Operator(Keymaker): # print('new_msg',new_msg) return new_msg - - - - def pronto_pronto(self, msg_obj): self.log(f'''*ring *ring* ... @@ -288,28 +285,44 @@ class Operator(Keymaker): return self.route_msg(msg_obj,reencrypt=True) - # route_response = self.route_msg(msg_obj) - # self.log('route_response',route_response) - # # set this to be the new msg - # #msg_obj.msg = msg_obj.msg_d['msg'] = response - # #self.log('what msg_obj looks like now:',msg_obj) - - # # send new content back - # # from komrade.backend.messages import Message - # # if type(route_response)==Message: - # # resp_msg_obj = route_response - # # else: - # resp_msg_obj = msg_obj.to_whom.compose_msg_to( - # route_response, - # msg_obj.from_whom - # ) - # self.log('resp_msg_obj',resp_msg_obj) - - # # re-encrypt - # if not resp_msg_obj.is_encrypted: - # resp_msg_obj.encrypt() - # self.log(f're-encrypted: {resp_msg_obj}') + + + + + ## inboxes? + def inbox_crypt(self, + crypt=None, + uri=None, + prefix='/inbox/', + privkey=None, + pubkey=None, + encryptor_func=None, + decryptor_func=None): + + # already + # if self._inbox_crypt is None: + # defaults + if not crypt: crypt=self.crypt_data + if not uri: uri=self.uri - # # pass msg back the chain - # return resp_msg_obj - \ No newline at end of file + if not encryptor_func or not decryptor_func: + if not privkey: privkey=self.privkey + if not pubkey: pubkey=self.pubkey + + smsg=SMessage( + privkey.data, + pubkey.data + ) + encryptor_func=smsg.wrap + decryptor_func=smsg.unwrap + + inbox_crypt = CryptList( + crypt=self.crypt_data, + keyname=self.uri, + prefix=prefix, + encryptor_func=encryptor_func, + decryptor_func=decryptor_func + ) + self.log('-->',inbox_crypt) + + return inbox_crypt \ No newline at end of file diff --git a/komrade/backend/the_operator.py b/komrade/backend/the_operator.py index a36c052..92db49d 100644 --- a/komrade/backend/the_operator.py +++ b/komrade/backend/the_operator.py @@ -424,61 +424,76 @@ class TheOperator(Operator): } + def validate_msg(self,msg_d): + if not is_valid_msg_d(msg_d): return False + + # alleged + ( + alleged_to_name, + alleged_to_pub, + alleged_from_name, + alleged_from_pub + ) = ( + msg_d.get('to_name'), + msg_d.get('to'), + msg_d.get('from_name'), + msg_d.get('from') + ) + + # recorded + ( + real_to_name, + real_to_pub, + real_from_name, + real_from_pub + ) = ( + self.find_name(alleged_to_pub), + self.find_pubkey(alleged_to_name), + self.find_name(alleged_from_pub), + self.find_pubkey(alleged_from_name) + ) + try: + assert alleged_to_name == real_to_name + assert alleged_to_pub == real_to_pub + assert alleged_from_name == real_from_name + assert alleged_from_pub == real_from_pub + except AssertionError: + return False + return True def deliver_msg(self,msg_to_op): data = msg_to_op.data - deliver_to = data.get('deliver_to') - deliver_from = data.get('deliver_from') - deliver_msg = data.get('deliver_msg') - - if not deliver_to or not deliver_from or not deliver_msg: - return {'success':False, 'status':'Invalid input.'} - - if b64enc(deliver_from) != b64enc(data['from']): - return {'success':False, 'status':'Sender to me is not the sender of the message I am to forward'} - - to_komrade = Komrade(pubkey=deliver_to) - from_komrade = Komrade(pubkey=deliver_from) - deliver_to_b = b64dec(deliver_to) + deliver_msg_d = data.get('deliver_msg') - self.log(f'''Got: -data = {data} -deliver_to = {deliver_to} -deliver_from = {deliver_from} -deliver_msg = {deliver_msg} + # is valid? + if not self.validate_msg(deliver_msg_d): + return { + 'status':'Message was not valid. Records between Komrade and Operator do not match.', + 'success':False + } -to_komrade = {to_komrade} -from_komrade = {from_komrade} -''') + # add type + deliver_msg_d['type']='DM' - ## just deliver? - + # package from komrade.backend.messages import Message msg_from_op = Message( from_whom=self, msg_d = { - 'to':data.get('deliver_to'), - 'to_name':data.get('deliver_to_name'), - + 'to':deliver_msg_d.get('to'), + 'to_name':deliver_msg_d.get('to_name'), 'msg':{ - - 'to':data.get('deliver_to'), - 'to_name':data.get('deliver_to_name'), - 'from':data.get('deliver_from'), - 'from_name':data.get('deliver_from_name'), - 'msg':data.get('deliver_msg'), + deliver_msg_d }, - - 'note':'Someone (marked "from") would like to send you (marked "to") this message (marked "msg").' } ) - self.log(f'{self}: Prepared this msg for delivery:\n{msg_from_op}') # encrypt msg_from_op.encrypt() + # deliver return self.actually_deliver_msg(msg_from_op) def actually_deliver_msg(self,msg_from_op): @@ -489,7 +504,7 @@ from_komrade = {from_komrade} # save new post post_id = get_random_binary_id() - self.crypt_keys.set( + self.crypt_data.set( post_id, msg_from_op_b_encr, prefix='/post/' @@ -602,7 +617,7 @@ from_komrade = {from_komrade} posts = {} for post_id in post_ids: - post = self.crypt_keys.get(b64enc(post_id),prefix='/post/') + post = self.crypt_data.get(b64enc(post_id),prefix='/post/') if post: posts[post_id] = post self.log('looking for:',post_id,post) @@ -633,7 +648,7 @@ from_komrade = {from_komrade} def delete_msgs(self,post_ids,inbox_uri=None): # @hack: this a bit dangerous? for post_id in post_ids: - self.crypt_keys.delete( + self.crypt_data.delete( post_id, prefix='/post/' )