diff --git a/komrade/backend/callers.py b/komrade/backend/callers.py index d56ade3..9f6a5d9 100644 --- a/komrade/backend/callers.py +++ b/komrade/backend/callers.py @@ -11,80 +11,86 @@ class Caller(Operator): Variant of an Operator which handles local keys and keymaking. """ + def ring_ring(self,msg): + return super().ring_ring( + msg, + to_whom=self.op, + get_resp_from=self.phone.ring_ring + ) - def ring_ring(self,with_msg,to_phone=None): - + # def ring_ring(self,msg): + # if not to_phone: to_phone=self.phone + # return super().ring_ring(msg,to_phone) - # message should be encrypted caller2caller (by Person.ring) - msg_encr_caller2caller = with_msg + # # message should be encrypted caller2caller (by Person.ring) + # msg_encr_caller2caller = with_msg - # Caller can only encrypt for Operator (end phone) - if not to_phone: to_phone=self.op - to_whom = to_phone + # # Caller can only encrypt for Operator (end phone) + # if not to_phone: to_phone=self.op + # to_whom = to_phone - # ring 1: encrypt caller2phone - msg_encr_caller2caller_caller2phone = self.package_msg_to( - msg_encr_caller2caller, - to_whom - ) - self.log('msg_encr_caller2caller_caller2phone',msg_encr_caller2caller_caller2phone) + # # ring 1: encrypt caller2phone + # msg_encr_caller2caller_caller2phone = self.package_msg_to( + # msg_encr_caller2caller, + # to_whom + # ) + # self.log('msg_encr_caller2caller_caller2phone',msg_encr_caller2caller_caller2phone) - # ring 2: dial and get response - resp_msg_encr_caller2caller_caller2phone = self.phone.ring_ring( - msg_encr_caller2caller_caller2phone - ) - self.log('resp_msg_encr_caller2caller_caller2phone',resp_msg_encr_caller2caller_caller2phone) + # # ring 2: dial and get response + # resp_msg_encr_caller2caller_caller2phone = self.phone.ring_ring( + # msg_encr_caller2caller_caller2phone + # ) + # self.log('resp_msg_encr_caller2caller_caller2phone',resp_msg_encr_caller2caller_caller2phone) - # ring 3: decrypt and send back - resp_msg_encr_caller2caller = self.unpackage_msg_from( - resp_msg_encr_caller2caller_caller2phone, - to_whom - ) - self.log('resp_msg_encr_caller2caller',resp_msg_encr_caller2caller) + # # ring 3: decrypt and send back + # resp_msg_encr_caller2caller = self.unpackage_msg_from( + # resp_msg_encr_caller2caller_caller2phone + # ) + # self.log('resp_msg_encr_caller2caller',resp_msg_encr_caller2caller) - return resp_msg_encr_caller2caller + # return resp_msg_encr_caller2caller - def get_new_keys(self, name = None, passphrase = DEBUG_DEFAULT_PASSPHRASE, is_group=None): - # get needed metadata - if not name: name=self.name - if name is None: - name = input('\nWhat is the name for this account? ') - if passphrase is None: - passphrase = getpass.getpass('\nEnter a memborable password: ') - # if is_group is None: - # is_group = input('\nIs this a group account? [y/N]').strip().lower() == 'y' + # def get_new_keys(self, name = None, passphrase = DEBUG_DEFAULT_PASSPHRASE, is_group=None): + # # get needed metadata + # if not name: name=self.name + # if name is None: + # name = input('\nWhat is the name for this account? ') + # if passphrase is None: + # passphrase = getpass.getpass('\nEnter a memborable password: ') + # # if is_group is None: + # # is_group = input('\nIs this a group account? [y/N]').strip().lower() == 'y' - # form request - msg_to_op = { - '_please':'forge_new_keys', - 'name':name, - 'passphrase':hashish(passphrase.encode()) - } + # # form request + # msg_to_op = { + # '_please':'forge_new_keys', + # 'name':name, + # 'passphrase':hashish(passphrase.encode()) + # } - phone_res = self.phone.ring(msg_to_op) + # phone_res = self.phone.ring(msg_to_op) - # URI id - uri_id = phone_res.get('uri_id') - returned_keys = phone_res.get('_keychain') - self.log('got URI from Op:',uri_id) - self.log('got returnd keys from Op:',returned_keys) + # # URI id + # uri_id = phone_res.get('uri_id') + # returned_keys = phone_res.get('_keychain') + # self.log('got URI from Op:',uri_id) + # self.log('got returnd keys from Op:',returned_keys) - stop + # stop - # better have the right keys - assert set(KEYMAKER_DEFAULT_KEYS_TO_SAVE_ON_CLIENT) == set(returned_keys.keys()) + # # better have the right keys + # assert set(KEYMAKER_DEFAULT_KEYS_TO_SAVE_ON_CLIENT) == set(returned_keys.keys()) - # now save these keys! - saved_keys = self.save_keychain(name,returned_keys,uri_id=uri_id) - self.log('saved keys!',saved_keys) + # # now save these keys! + # saved_keys = self.save_keychain(name,returned_keys,uri_id=uri_id) + # self.log('saved keys!',saved_keys) - # better have the right keys - # assert set(KEYMAKER_DEFAULT_KEYS_TO_SAVE) == set(saved_keys.keys()) + # # better have the right keys + # # assert set(KEYMAKER_DEFAULT_KEYS_TO_SAVE) == set(saved_keys.keys()) - # success! - self.log('yay!!!!') - return saved_keys + # # success! + # self.log('yay!!!!') + # return saved_keys diff --git a/komrade/backend/keymaker.py b/komrade/backend/keymaker.py index 01c86a4..1d420d3 100644 --- a/komrade/backend/keymaker.py +++ b/komrade/backend/keymaker.py @@ -91,12 +91,13 @@ class Keymaker(Logger): self.path_crypt_keys=path_crypt_keys self.path_crypt_data=path_crypt_data - @property - def pubkey(self): + + def find_pubkey(self): + global TELEPHONE_KEYCHAIN,OPERATOR_KEYCHAIN #self.log('keychain?',self.keychain()) if 'pubkey' in self._keychain and self._keychain['pubkey']: return self._keychain['pubkey'] - + res = self.crypt_keys.get(self.name, prefix='/pubkey/') if res: return res @@ -104,28 +105,39 @@ class Keymaker(Logger): if res: return res self.log('I don\'t know my public key!') - return None + raise KomradeException(f'I don\'t know my public key!\n{self}\n{self._keychain}') + #return None + + def keychain(self,look_for=KEYMAKER_DEFAULT_ALL_KEY_NAMES): + # load existing keychain keys = self._keychain #self._keychain = keys = {**self._keychain} - uri = self.uri_id + + # make sure we have the pubkey + if not 'pubkey' in self._keychain: self._keychain['pubkey']=self.find_pubkey() + pubkey=self._keychain['pubkey'] + + # get uri + uri = b64encode(pubkey) # get from cache for keyname in look_for: if keyname in keys and keys[keyname]: continue - - # self.log('??',keyname) key = self.crypt_keys.get(uri,prefix=f'/{keyname}/') if key: keys[keyname]=key - # self.log('keys 1!',self._keychain) - # try to assemble keys = self.assemble(self.assemble(keys)) - # self.log('keys 2!',self._keychain) + + #store to existing set + self._keychain = keys + + #return return keys - + @property + def pubkey(self): return self.keychain().get('pubkey') @property def privkey(self): return self.keychain().get('privkey') @property @@ -149,8 +161,8 @@ class Keymaker(Logger): @property def uri_id(self): if not self._uri_id: - if self.pubkey: - self._uri_id = b64encode(self.pubkey) + pubkey = self.find_pubkey() + self._uri_id = b64encode(pubkey) return self._uri_id diff --git a/komrade/backend/messages.py b/komrade/backend/messages.py index ac84338..f36b8c7 100644 --- a/komrade/backend/messages.py +++ b/komrade/backend/messages.py @@ -15,7 +15,7 @@ def is_valid_msg_d(msg_d): class Message(Logger): - def __init__(self,msg_d,caller=None,callee=None): + def __init__(self,msg_d,caller=None,callee=None,messenger=None,embedded_msg=None,is_encrypted=False): # check input if not is_valid_msg_d(msg_d): raise KomradeException('This is not a valid msg_d:',msg_d) @@ -26,33 +26,80 @@ class Message(Logger): self.from_name=msg_d.get('_from_name') self.from_pubkey=msg_d.get('_from_pub') self.msg=msg_d.get('_msg') - self.embedded_msg=None # only if this message has an embedded one + self.embedded_msg=embedded_msg # only if this message has an embedded one self._route=msg_d.get(ROUTE_KEYNAME) - self.caller=caller - self.callee=callee + self._caller=caller + self._callee=callee + self.messenger=None + self.is_encrypted=False # get operators straight away? if not self.caller or not self.callee: self.get_callers() + def __repr__(self): + return f""" + + + self.msg_d={self.msg_d} + self.to_name={self.to_name} + self.to_pubkey={self.to_pubkey} + self.from_name={self.from_name} + self.from_pubkey={self.from_pubkey} + self.msg={self.msg} + self.embedded_msg={self.embedded_msg} + self._route={self._route} + self._caller={self.caller} + self._callee={self.callee} + self.messenger={self.messenger} + + + """ + + + def get_caller(self,name): + if name == OPERATOR_NAME: + return TheOperator() + if name == TELEPHONE_NAME: + return TheTelephone() + return Caller(name) + + @property + def caller(self): + if not self._caller: + self._caller,self._callee = self.get_callers() + return self._caller + + @property + def callee(self): + if not self._callee: + self._caller,self._callee = self.get_callers() + return self._callee + ## loading messages - def get_callers(self,msg_d): + def get_callers(self): if self.caller is not None and self.callee is not None: return (self.caller,self.callee) - alleged_caller = Operator(alleged_caller_name) - alleged_callee = Operator(alleged_callee_name) - if not self.caller_records_match(msg_d,alleged_caller,alleged_callee): + alleged_caller = self.get_caller(self.from_name) + alleged_callee = self.get_caller(self.to_name) + if not self.caller_records_match(alleged_caller,alleged_callee): raise KomradeException('Records of callers on The Operator and the Caller do not match. Something fishy going on?') else: self.caller = alleged_caller self.callee = alleged_callee return (alleged_caller,alleged_caller) - def caller_records_match(alleged_caller,alleged_callee): + def caller_records_match(self,alleged_caller,alleged_callee): alleged_caller_name = self.from_name alleged_caller_pubkey = self.from_pubkey alleged_callee_name = self.to_name - alleged_callee_pubkey = msg_d.get('_to_pub') + alleged_callee_pubkey = self.to_pubkey + + self.log('caller names:',alleged_caller.name, alleged_caller_name) + self.log('caller pubs:',alleged_caller.pubkey, alleged_caller_pubkey) + self.log('callee names:',alleged_callee.name, alleged_callee_name) + self.log('callee pubs:',alleged_callee.pubkey, alleged_callee_pubkey) + if alleged_callee.name != alleged_callee_name: return False if alleged_caller.name != alleged_caller_name: @@ -63,9 +110,6 @@ class Message(Logger): return False return True - def is_encrypted(self): - return type(self.msg) == bytes - def decrypt(self,recursive=True): # get callers caller,callee = self.get_callers() @@ -87,10 +131,141 @@ class Message(Logger): return decr_msg + def encrypt(self,recursive=True): + """ + Assuming that a recursive message looks like this: + + self.msg_d={'_from_pub': b'UEC2\x00\x00\x00-\x10\xdcu\xc7\x03:\xb6}\xd2\x88\x93E\x88\x00\xed\xda&\x8f\xd0\x1ae\xe1\xa3\x1b=\xd6\xadBB~M\x86\xda\xd57\x8e\xb5', '_from_name': 'TheTelephone', '_to_pub': b'UEC2\x00\x00\x00-W\xbe\xc4\xa2\x02Sm\xe0\xfc\xde\x1c\xbb\xa2E\x8fy \xc7~+\xff\xd7p\xc6s\xab\xe5\xb29M/\xf24\x92\x91n0', '_to_name': 'TheOperator', '_msg': b' \'\x04&h\x00\x00\x00\x00\x01\x01@\x0c\x00\x00\x00\x10\x00\x00\x004\x00\x00\x00\x90\x1a\x88\x89\x93-\x10\xfb\x14\x10\x08M\xc0\xf2_i\x842\xa8k\xcc\xff"c\x0e"x\\"\xaf\x9c\x91>\x87\x9f|~PP\xb5\x02\x91q\\X\xd2\xbdQu\xcc\xd0A\x0b7zL)\x80\x94[\xe7+I\xf1m\x0f\xb4\x80\xc7;\x8fO7\x99\x90d_\xb2y\xc4'} + self.to_name=TheOperator + self.to_pubkey=b'UEC2\x00\x00\x00-W\xbe\xc4\xa2\x02Sm\xe0\xfc\xde\x1c\xbb\xa2E\x8fy \xc7~+\xff\xd7p\xc6s\xab\xe5\xb29M/\xf24\x92\x91n0' + self.from_name=Caller + self.from_pubkey=b'UEC2\x00\x00\x00-\x10\xdcu\xc7\x03:\xb6}\xd2\x88\x93E\x88\x00\xed\xda&\x8f\xd0\x1ae\xe1\xa3\x1b=\xd6\xadBB~M\x86\xda\xd57\x8e\xb5' + self.msg= + + self.msg_d={'_from_pub': b'UEC2\x00\x00\x00-\x10\xdcu\xc7\x03:\xb6}\xd2\x88\x93E\x88\x00\xed\xda&\x8f\xd0\x1ae\xe1\xa3\x1b=\xd6\xadBB~M\x86\xda\xd57\x8e\xb5', '_from_name': 'TheTelephone', '_to_pub': b'UEC2\x00\x00\x00-W\xbe\xc4\xa2\x02Sm\xe0\xfc\xde\x1c\xbb\xa2E\x8fy \xc7~+\xff\xd7p\xc6s\xab\xe5\xb29M/\xf24\x92\x91n0', '_to_name': 'TheOperator', '_msg': b' \'\x04&h\x00\x00\x00\x00\x01\x01@\x0c\x00\x00\x00\x10\x00\x00\x004\x00\x00\x00\x90\x1a\x88\x89\x93-\x10\xfb\x14\x10\x08M\xc0\xf2_i\x842\xa8k\xcc\xff"c\x0e"x\\"\xaf\x9c\x91>\x87\x9f|~PP\xb5\x02\x91q\\X\xd2\xbdQu\xcc\xd0A\x0b7zL)\x80\x94[\xe7+I\xf1m\x0f\xb4\x80\xc7;\x8fO7\x99\x90d_\xb2y\xc4'} + self.to_name=TheOperator + self.to_pubkey=b'UEC2\x00\x00\x00-W\xbe\xc4\xa2\x02Sm\xe0\xfc\xde\x1c\xbb\xa2E\x8fy \xc7~+\xff\xd7p\xc6s\xab\xe5\xb29M/\xf24\x92\x91n0' + self.from_name=TheTelephone + self.from_pubkey=b'UEC2\x00\x00\x00-\x10\xdcu\xc7\x03:\xb6}\xd2\x88\x93E\x88\x00\xed\xda&\x8f\xd0\x1ae\xe1\xa3\x1b=\xd6\xadBB~M\x86\xda\xd57\x8e\xb5' + self.msg=b' \'\x04&h\x00\x00\x00\x00\x01\x01@\x0c\x00\x00\x00\x10\x00\x00\x004\x00\x00\x00\x90\x1a\x88\x89\x93-\x10\xfb\x14\x10\x08M\xc0\xf2_i\x842\xa8k\xcc\xff"c\x0e"x\\"\xaf\x9c\x91>\x87\x9f|~PP\xb5\x02\x91q\\X\xd2\xbdQu\xcc\xd0A\x0b7zL)\x80\x94[\xe7+I\xf1m\x0f\xb4\x80\xc7;\x8fO7\x99\x90d_\xb2y\xc4' + self._route=None + self.caller= + self.callee= + self.messenger=None + + self._route=None + self.caller= + self.callee= + self.messenger=None + + """ + if self.is_encrypted: return + self.log(f'attempting to encrypt msg {self.msg} from {self.caller} to {self.callee}') + self.log(f'I now look like v1: {self}') + + if not self.has_embedded_msg: + msg_to_encrypt = self.msg + elif recursive: + # first encrypt that message + self.msg.encrypt() + # then encrypt *that* msg's entire msg_d + msg_to_encrypt = self.msg.msg_d + + # in both cases, overwrite msg + encr_msg = self.encrypt_to_send( + self.msg, + self.caller.privkey, + self.callee.pubkey + ) + self.log('created an encrypted msg:',encr_msg) + self.msg_decr = self.msg + self.msg = encr_msg + self.msg_d['_msg'] = encr_msg + self.log(f'I now look like v2: {self}') + self.is_encrypted = False + + + + + + ## creating/encrypting/rolling up messages + def encrypt_to_send(self,msg_json,from_privkey,to_pubkey): + self.log('msg_json',msg_json) + self.log('from_privkey',from_privkey) + self.log('to_pubkey',to_pubkey) + + + + if not msg_json or not from_privkey or not to_pubkey: + self.log('not enough info!',msg_json,from_privkey,to_pubkey) + whattttttt + return b'' + self.log('packing for transmission: msg_json',type(msg_json),msg_json) + msg_b = package_for_transmission(msg_json) + self.log('packing for transmission: msg_b',type(msg_b),msg_b) + # try: + self.log('from privkey =',from_privkey) + self.log('to pubkey =',to_pubkey) + + msg_encr = SMessage( + from_privkey, + to_pubkey, + ).wrap(msg_b) + self.log('msg_encr',msg_encr) + # stop + return msg_encr + # except ThemisError as e: + # self.log('unable to encrypt to send!',e) + # return b'' + + + def decrypt_from_send(self,msg_encr,from_pubkey,to_privkey): + if not msg_encr or not from_pubkey or not to_privkey: + self.log('not enough info!',msg_encr,from_pubkey,to_privkey) + return {} + try: + # decrypt + msg_b = SMessage( + to_privkey, + from_pubkey, + ).unwrap(msg_encr) + # decode + self.log('msg_b??',msg_b) + msg_json = unpackage_from_transmission(msg_b) + self.log('msg_json??',msg_json) + # return + return msg_json + except ThemisError as e: + self.log('unable to decrypt from send!',e) + return {} + + + + def package_msg_to(self,msg,another): + # otherwise send msg + msg_encr = self.encrypt_to_send(msg, self.privkey, another.pubkey) + msg_d = { + '_from_pub':self.pubkey, + '_from_name':self.name, + '_to_pub':another.pubkey, + '_to_name':another.name, + '_msg':msg_encr, + } + self.log(f'I am a {type(self)} packaging a message to {another}') + return msg_d + + + def unpackage_msg_from(self,msg_encr_b,another): + return self.decrypt_from_send( + msg_encr_b, + from_pubkey=another.pubkey, + to_privkey=self.privkey + ) ## msg properties + @property def has_embedded_msg(self): - return self.embedded_msg is not None + return type(self.msg) == Message @property def messages(self): @@ -102,3 +277,37 @@ class Message(Logger): def route(self): for msg in self.messages: if msg._route: return msg._route + + + + + + + +def test_msg(): + phone = TheTelephone() + op = TheOperator() + + pprint(op.pubkey) + print('?keychains?') + pprint(phone.pubkey) + + msg={'_please':'hello_world'} + + msg_d = { + '_from_pub':phone.pubkey, + '_from_name':phone.name, + '_to_pub':op.pubkey, + '_to_name':op.name, + '_msg':msg, + } + + # msg_obj = Message(msg_d,caller=phone,callee=op) + # msg_obj.encrypt() + + # print(msg_obj) + + # print('\n\n',msg_obj.sealed) + + resp_msp_obj = phone.ring_ring(msg) + print(resp_msp_obj) diff --git a/komrade/backend/operators.py b/komrade/backend/operators.py index fe8097a..64326c2 100644 --- a/komrade/backend/operators.py +++ b/komrade/backend/operators.py @@ -1,11 +1,11 @@ # internal imports import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..'))) from komrade import * -from komrade.backend.crypt import * -from komrade.backend.keymaker import * -from komrade.backend.mazes import * -from komrade.backend.switchboard import * - +# from komrade.backend.crypt import * +# from komrade.backend.keymaker import * +# from komrade.backend.mazes import * +# from komrade.backend.switchboard import * +from komrade.backend import * @@ -16,6 +16,10 @@ class Operator(Keymaker): path_crypt_keys=path_crypt_keys, path_crypt_data=path_crypt_data) self.boot(create=False) + # connect phonelines? + from komrade.backend.phonelines import connect_phonelines + self.operator_keychain,self.telephone_keychain,self.omega_key = connect_phonelines() + def boot(self,create=False): # Do I have my keys? have_keys = self.exists() @@ -53,105 +57,67 @@ class Operator(Keymaker): return OPERATOR - def encrypt_to_send(self,msg_json,from_privkey,to_pubkey): - self.log('msg_json',msg_json) - self.log('from_privkey',from_privkey) - self.log('to_pubkey',to_pubkey) - if not msg_json or not from_privkey or not to_pubkey: - self.log('not enough info!',msg_json,from_privkey,to_pubkey) - whattttttt - return b'' - self.log('packing for transmission: msg_json',type(msg_json),msg_json) - msg_b = package_for_transmission(msg_json) - self.log('packing for transmission: msg_b',type(msg_b),msg_b) - # try: - self.log('from privkey =',from_privkey) - self.log('to pubkey =',to_pubkey) - - msg_encr = SMessage( - from_privkey, - to_pubkey, - ).wrap(msg_b) - self.log('msg_encr',msg_encr) - # stop - return msg_encr - # except ThemisError as e: - # self.log('unable to encrypt to send!',e) - # return b'' - - - def decrypt_from_send(self,msg_encr,from_pubkey,to_privkey): - if not msg_encr or not from_pubkey or not to_privkey: - self.log('not enough info!',msg_encr,from_pubkey,to_privkey) - return {} - try: - # decrypt - msg_b = SMessage( - to_privkey, - from_pubkey, - ).unwrap(msg_encr) - # decode - self.log('msg_b??',msg_b) - msg_json = unpackage_from_transmission(msg_b) - self.log('msg_json??',msg_json) - # return - return msg_json - except ThemisError as e: - self.log('unable to decrypt from send!',e) - return {} - - - - def package_msg_to(self,msg,another): - self.log('KEYCHAINNN ',self.keychain()) - self.log('my privkey',self.privkey) - self.log('my pubkey',self.pubkey,self.keychain().get('pubkey','!!!?!!?!?!?!?')) + + def compose_msg_to(self,msg,another): if not self.privkey or not self.pubkey: - self.log('why do I have no pub/privkey pair!?',self.privkey,self,self.name) - return b'' + raise KomradeException('why do I have no pub/privkey pair!?',self,self.name) if not another.name or not another.pubkey: - self.log('why do I not know whom I\'m writing to?') - return b'' + raise KomradeException('why do I not know whom I\'m writing to?') - # otherwise send msg - msg_encr = self.encrypt_to_send(msg, self.privkey, another.pubkey) + # otherwise create msg msg_d = { '_from_pub':self.pubkey, '_from_name':self.name, '_to_pub':another.pubkey, '_to_name':another.name, - '_msg':msg_encr, + '_msg':msg, } - self.log(f'I am a {type(self)} packaging a message to {another}') - return msg_d + self.log(f'I am a {type(self)} packaging a message to {another}: {msg_d}') + + from komrade.backend.messages import Message + msg_obj = Message(msg_d,caller=self,callee=another) + self.log('created msg obj:',msg_obj) + + return msg_obj + + def seal_msg(self,msg_obj): + # make sure encrypted + msg_obj.encrypt() + # return pure binary version of self's entire msg_d + msg_b = package_for_transmission(msg_obj.msg_d) + # encrypte by omega key + msg_b_encr = self.omega_key.encrypt(msg_b) + return msg_b_encr + + def unseal_msg(self,msg_b_encr): + # decrypt by omega + msg_b = self.omega_key.decrypt(msg_b_encr) + # unpackage from transmission + msg_d = unpackage_from_transmission(msg_b) + # get message obj + msg_obj = Message(msg_d) + # decrypt msg + msg_obj.decrypt() + return msg_obj - def unpackage_msg_from(self,msg_encr_b,another): - return self.decrypt_from_send( - msg_encr_b, - from_pubkey=another.pubkey, - to_privkey=self.privkey - ) - - # def ring(self,with_msg,to_whom=None,by_way_of=None): - # # ring 1: encrypt from me to 'whom' - # msg_encr = self.package_msg_to( - # with_msg, - # whom - # ) - # self.log(f'msg_encr --> {whom} layer 1',msg_encr) - - # # ring 2: keep ringing via mediator - # resp_msg_encr = by_way_of.ring( - # msg_encr - # ) - # self.log('resp_msg_encr',resp_msg_encr) - - # # ring 3: decrypt and send back - # resp_msg = self.unpackage_msg_from( - # resp_msg_encr, - # whom - # ) - # self.log('resp_msg',resp_msg) - - # return resp_msg + # self = caller + # towhom = phone + # bywayof = op + def ring_ring(self,msg,to_whom,get_resp_from=None): + # get encr msg obj + msg_obj = self.compose_msg_to(msg, to_whom) + # pass onto next person + + # get pure encrypted binary, sealed + msg_sealed = self.seal_msg(msg_obj) + + # pass onto next person... + if not get_resp_from: get_resp_from=to_whom.ring_ring + resp_msg_b = get_resp_from(msg_sealed) + + # unseal msg + resp_msg_obj = self.unseal_msg(resp_msg_b) + + return resp_msg_obj + \ No newline at end of file diff --git a/komrade/backend/people.py b/komrade/backend/people.py index a468ccf..e35f98f 100644 --- a/komrade/backend/people.py +++ b/komrade/backend/people.py @@ -5,39 +5,71 @@ from komrade.backend import * class Person(Caller): + # def ring_ring(self,msg,to_whom = None): + # # if no one intended, call the operator + # #return super().ring_ring(with_msg,to_phone=self.op) + # if not to_whom: to_whom = self.op + - def ring_ring(self,with_msg,to_whom = None): - # if no one intended, call the operator - #return super().ring_ring(with_msg,to_phone=self.op) - if not to_whom: to_whom = self.op - - # msg should be unencrypted - msg_unencr = with_msg - self.log('msg_unencr',msg_unencr) - - # ring 1: encrypt caller2phone - msg_encr_caller2caller = self.package_msg_to( - msg_unencr, - to_whom - ) - self.log('msg_encr_caller2caller!',msg_encr_caller2caller) - - # ring 2: use 'Caller' class to dial and get response - resp_msg_encr_caller2caller = super().ring_ring( - msg_encr_caller2caller - ) - self.log('resp_msg_encr_caller2caller',resp_msg_encr_caller2caller) - - # ring 3: decrypt and send back - resp_msg_unencr = self.unpackage_msg_from( - msg_encr_caller2caller, - to_whom + # # create a message, caller 2 caller + # msg_obj = self.compose_msg_to(msg, to_whom) + + # # ring 2: use 'Caller' class to dial and get response + # resp_msg_obj = super().ring_ring( + # msg_obj + # ) + # self.log('resp_msg_encr_caller2caller',resp_msg_encr_caller2caller) + + # # ring 3: decrypt and send back + # resp_msg_unencr = self.unpackage_msg_from( + # msg_encr_caller2caller, + # to_whom + # ) + # self.log('resp_msg_unencr',resp_msg_encr_caller2caller) + + # return resp_msg_unencr + + # def ring_ring(self,with_msg,to_whom = None): + # # if no one intended, call the operator + # #return super().ring_ring(with_msg,to_phone=self.op) + # if not to_whom: to_whom = self.op + + # # msg should be unencrypted + # msg_unencr = with_msg + # self.log('msg_unencr',msg_unencr) + + # # ring 1: encrypt caller2phone + # msg_encr_caller2caller = self.package_msg_to( + # msg_unencr, + # to_whom + # ) + # self.log('msg_encr_caller2caller!',msg_encr_caller2caller) + + # # ring 2: use 'Caller' class to dial and get response + # resp_msg_encr_caller2caller = super().ring_ring( + # msg_encr_caller2caller + # ) + # self.log('resp_msg_encr_caller2caller',resp_msg_encr_caller2caller) + + # # ring 3: decrypt and send back + # resp_msg_unencr = self.unpackage_msg_from( + # msg_encr_caller2caller, + # to_whom + # ) + # self.log('resp_msg_unencr',resp_msg_encr_caller2caller) + + # return resp_msg_unencr + + def send_msg_to(self,msg,to_whom): + return self.ring_ring(msg,to_whom) + + def ring_ring(self,msg,to_whom): + return super().super().ring_ring( + msg, + to_whom, + get_resp_from=super().ring_ring ) - self.log('resp_msg_unencr',resp_msg_encr_caller2caller) - - return resp_msg_unencr - def register(self,name=None,passphrase=DEBUG_DEFAULT_PASSPHRASE, is_group=None): # get needed metadata @@ -52,6 +84,11 @@ class Person(Caller): # form request to operator msg_to_op = {'_please':'forge_new_keys'} + msg_response = self.phone.ring_ring( + msg_to_op, + self.op + ) + # call and ask operator to register us # for only this one! we skip straight to phone, diff --git a/komrade/backend/phonelines.py b/komrade/backend/phonelines.py index 59ded50..9bc4a46 100644 --- a/komrade/backend/phonelines.py +++ b/komrade/backend/phonelines.py @@ -104,7 +104,7 @@ def connect_phonelines(): # globals global OMEGA_KEY,OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN if OMEGA_KEY and OPERATOR_KEYCHAIN and TELEPHONE_KEYCHAIN: - return (OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN) + return (OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN,OMEGA_KEY) print('\n\n\n\nCONNECTING PHONELINES!\n\n\n\n') @@ -167,4 +167,4 @@ def connect_phonelines(): print('>>>> loaded OPERATOR_KEYCHAIN',OPERATOR_KEYCHAIN) print('>>>> loaded TELEPHONE_KEYCHAIN',TELEPHONE_KEYCHAIN) - return (OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN) + return (OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN,OMEGA_KEY) diff --git a/komrade/backend/the_operator.py b/komrade/backend/the_operator.py index 3766f1f..5030253 100644 --- a/komrade/backend/the_operator.py +++ b/komrade/backend/the_operator.py @@ -27,20 +27,13 @@ class TheOperator(Operator): """ Boot up the operator. Requires knowing or setting a password of memory. """ - # init req paths - # if not os.path.exists(PATH_OPERATOR): os.makedirs(PATH_OPERATOR) - global OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN - - from komrade.backend.phonelines import connect_phonelines - if not TELEPHONE_KEYCHAIN or not OPERATOR_KEYCHAIN: - OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN = connect_phonelines() - if not passphrase: self.passphrase=passphrase=getpass.getpass('Hello, this is the Operator speaking. What is the passphrase?\n> ') super().__init__( name, passphrase, path_crypt_keys=PATH_CRYPT_OP_KEYS, - path_crypt_data=PATH_CRYPT_OP_DATA) - self._keychain = OPERATOR_KEYCHAIN + path_crypt_data=PATH_CRYPT_OP_DATA + ) + self._keychain = self.operator_keychain def ring(self, from_caller=None, @@ -79,7 +72,8 @@ class TheOperator(Operator): # route msg back to caller return self.route(msg_obj) - + def find_pubkey(self): + return self.operator_keychain['pubkey'] def send(self,encr_data_b): diff --git a/komrade/backend/the_telephone.py b/komrade/backend/the_telephone.py index 6a47db1..02e39f1 100644 --- a/komrade/backend/the_telephone.py +++ b/komrade/backend/the_telephone.py @@ -10,26 +10,12 @@ class TheTelephone(Operator): API client class for Caller to interact with The Operator. """ def __init__(self, caller=None): - global OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN - print('OP???',OPERATOR_KEYCHAIN) - print('PH???',TELEPHONE_KEYCHAIN) - - super().__init__( - name=TELEPHONE_NAME, - path_crypt_keys=PATH_CRYPT_CA_KEYS, - path_crypt_data=PATH_CRYPT_CA_KEYS - ) - - if not TELEPHONE_KEYCHAIN or not OPERATOR_KEYCHAIN: - OPERATOR_KEYCHAIN,TELEPHONE_KEYCHAIN = connect_phonelines() - - print('OP2???',OPERATOR_KEYCHAIN) - print('PH2???',TELEPHONE_KEYCHAIN) - # stop - + super().__init__(name=TELEPHONE_NAME) self.caller=caller - self._keychain = TELEPHONE_KEYCHAIN - print(type(self._keychain), self._keychain) + self._keychain = self.telephone_keychain + + def find_pubkey(self): + return self.telephone_keychain.get('pubkey') def send_and_receive(self,msg): msg_b64_str = b64encode(msg).decode() @@ -47,35 +33,13 @@ class TheTelephone(Operator): self.log('!! error in request',ringring.status_code,ringring.text) return None - def ring_ring(self,with_msg,to_whom=None): - # usually, I'm calling the operator - if not to_whom: to_whom=self.op - - # msg usually already encrypted twice - msg_encr_caller2caller_caller2phone = with_msg - - # ring 1: encrypt again - msg_encr_caller2caller_caller2phone_phone2phone = self.package_msg_to( - msg_encr_caller2caller_caller2phone, - to_whom + def ring_ring(self,msg): + return super().ring_ring( + msg, + to_whom=self.op, + get_resp_from=self.send_and_receive ) - self.log('msg_encr_caller2caller_caller2phone_phone2phone !',msg_encr_caller2caller_caller2phone_phone2phone) - - # ring 2: dial and get response - resp_msg_encr_caller2caller_caller2phone_phone2phone = self.send_and_receive( - msg_encr_caller2caller_caller2phone_phone2phone - ) - self.log(' got back from Op: resp_msg_encr_caller2caller_caller2phone_phone2phone',resp_msg_encr_caller2caller_caller2phone_phone2phone) - # msg_encr_caller2caller_caller2phone_phone2phone: return - - # ring 3: decrypt - resp_msg_encr_caller2caller_caller2phone = self.unpackage_msg_from( - resp_msg_encr_caller2caller_caller2phone_phone2phone, - to_whom - ) - - return resp_msg_encr_caller2caller_caller2phone - + def test_call(): phone = TheTelephone()