2
0
mirror of https://github.com/ComradCollective/Comrad synced 2024-11-05 21:20:51 +00:00
Comrad/komrade/backend/operators.py

268 lines
8.2 KiB
Python
Raw Normal View History

2020-09-05 16:26:37 +00:00
# internal imports
2020-09-04 15:50:08 +00:00
import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..')))
2020-09-05 16:26:37 +00:00
from komrade import *
2020-09-09 14:38:37 +00:00
# from komrade.backend.crypt import *
# from komrade.backend.keymaker import *
# from komrade.backend.mazes import *
# from komrade.backend.switchboard import *
from komrade.backend import *
2020-09-09 22:01:41 +00:00
2020-09-06 06:50:23 +00:00
2020-09-09 22:09:08 +00:00
def locate_an_operator(name):
2020-09-09 22:10:58 +00:00
global OPERATOR,TELEPHONE
from komrade.backend.the_operator import TheOperator
from komrade.backend.the_telephone import TheTelephone
from komrade.backend.callers import Caller
2020-09-09 22:09:08 +00:00
if name == OPERATOR_NAME:
2020-09-09 22:10:58 +00:00
return OPERATOR if OPERATOR else TheOperator()
2020-09-09 22:09:08 +00:00
if name == TELEPHONE_NAME:
2020-09-09 22:10:58 +00:00
return TELEPHONE if TELEPHONE else TheTelephone()
2020-09-09 22:09:08 +00:00
return Caller(name)
2020-09-04 15:50:08 +00:00
2020-09-10 11:11:46 +00:00
from komrade.constants import OPERATOR_ROUTES
2020-09-04 15:50:08 +00:00
class Operator(Keymaker):
2020-09-10 11:11:02 +00:00
ROUTES = OPERATOR_ROUTES
2020-09-04 15:50:08 +00:00
2020-09-08 07:20:42 +00:00
def __init__(self, name, passphrase=DEBUG_DEFAULT_PASSPHRASE, keychain = {}, path_crypt_keys=PATH_CRYPT_CA_KEYS, path_crypt_data=PATH_CRYPT_CA_DATA):
2020-09-07 17:11:52 +00:00
super().__init__(name=name,passphrase=passphrase, keychain=keychain,
path_crypt_keys=path_crypt_keys, path_crypt_data=path_crypt_data)
2020-09-09 17:34:19 +00:00
# self.boot(create=False)
2020-09-04 15:50:08 +00:00
2020-09-09 14:38:37 +00:00
# connect phonelines?
from komrade.backend.phonelines import connect_phonelines
2020-09-10 09:58:29 +00:00
try:
self.operator_keychain,self.telephone_keychain,self.world_keychain,self.omega_key = connect_phonelines()
except KeyError:
pass
2020-09-09 14:38:37 +00:00
2020-09-09 17:34:19 +00:00
# def boot(self,create=False):
# # Do I have my keys?
# have_keys = self.exists()
2020-09-05 14:09:31 +00:00
2020-09-09 17:34:19 +00:00
# # If not, forge them -- only once!
# if not have_keys and create:
# self.get_new_keys()
2020-09-08 07:01:35 +00:00
2020-09-07 17:11:52 +00:00
@property
def phone(self):
2020-09-07 20:00:21 +00:00
from komrade.backend.the_telephone import TheTelephone
if type(self)==TheTelephone: return self
2020-09-07 17:50:58 +00:00
if hasattr(self,'_phone'): return self._phone
2020-09-07 20:00:21 +00:00
2020-09-07 17:11:52 +00:00
global TELEPHONE,TELEPHONE_KEYCHAIN
if TELEPHONE: return TELEPHONE
2020-09-07 20:00:21 +00:00
2020-09-07 17:50:58 +00:00
self._phone=TELEPHONE=TheTelephone()
2020-09-07 20:00:21 +00:00
2020-09-07 17:11:52 +00:00
return TELEPHONE
@property
def op(self):
2020-09-07 20:00:21 +00:00
from komrade.backend.the_operator import TheOperator
if type(self)==TheOperator: return self
if hasattr(self,'_op'): return self._op
2020-09-07 17:11:52 +00:00
global OPERATOR,OPERATOR_KEYCHAIN
if OPERATOR: return OPERATOR
2020-09-07 20:00:21 +00:00
self._op=OPERATOR=TheOperator()
2020-09-07 17:11:52 +00:00
return OPERATOR
2020-09-09 14:38:37 +00:00
2020-09-12 14:32:03 +00:00
def compose_msg_to(self,msg,another,route=None):
2020-09-08 15:14:48 +00:00
if not self.privkey or not self.pubkey:
2020-09-09 15:41:33 +00:00
raise KomradeException('why do I have no pub/privkey pair!?',self,self.name,self.pubkey,self.privkey,self.keychain())
2020-09-08 15:14:48 +00:00
if not another.name or not another.pubkey:
2020-09-09 14:38:37 +00:00
raise KomradeException('why do I not know whom I\'m writing to?')
2020-09-08 15:14:48 +00:00
2020-09-09 14:38:37 +00:00
# otherwise create msg
2020-09-09 11:01:27 +00:00
msg_d = {
2020-09-08 11:23:41 +00:00
'_from_pub':self.pubkey,
'_from_name':self.name,
'_to_pub':another.pubkey,
2020-09-08 15:14:48 +00:00
'_to_name':another.name,
2020-09-09 14:38:37 +00:00
'_msg':msg,
2020-09-12 14:32:03 +00:00
ROUTE_KEYNAME:route
2020-09-08 11:23:41 +00:00
}
2020-09-09 18:31:36 +00:00
# self.log(f'I am {self} packaging a message to {another}: {msg_d}')
2020-09-09 22:10:58 +00:00
from komrade.backend.messages import Message
2020-09-09 14:38:37 +00:00
2020-09-09 22:01:41 +00:00
msg_obj = Message(msg_d,from_whom=self,to_whom=another)
2020-09-09 18:31:36 +00:00
2020-09-09 19:15:35 +00:00
# encrypt!
2020-09-09 22:26:48 +00:00
# msg_obj.encrypt()
2020-09-09 14:38:37 +00:00
return msg_obj
2020-09-09 22:23:51 +00:00
# def compose_reply(self,msg,another):
2020-09-09 19:15:35 +00:00
def seal_msg(self,msg_d):
2020-09-09 14:38:37 +00:00
# make sure encrypted
2020-09-09 19:15:35 +00:00
self.log('sealing msg!:',dict_format(msg_d))
# msg_obj.encrypt(recursive=True)
2020-09-09 14:38:37 +00:00
# return pure binary version of self's entire msg_d
2020-09-09 19:22:13 +00:00
msg_b = pickle.dumps(msg_d)
2020-09-09 19:15:35 +00:00
self.log('pickled!',msg_b)
2020-09-09 18:31:36 +00:00
# encrypt by omega key
2020-09-09 14:38:37 +00:00
msg_b_encr = self.omega_key.encrypt(msg_b)
2020-09-09 19:15:35 +00:00
self.log('final seal:',msg_b_encr)
2020-09-09 14:38:37 +00:00
return msg_b_encr
2020-09-09 21:30:14 +00:00
def unseal_msg(self,msg_b_encr,from_whom=None,to_whom=None):
# default to assumption that I am the recipient
if not to_whom: to_whom=self
2020-09-09 14:38:37 +00:00
# decrypt by omega
msg_b = self.omega_key.decrypt(msg_b_encr)
# unpackage from transmission
2020-09-09 19:22:13 +00:00
msg_d = pickle.loads(msg_b)
2020-09-09 14:38:37 +00:00
# get message obj
2020-09-10 09:31:32 +00:00
# print('unsealed msg:',msg_d)
2020-09-09 14:50:10 +00:00
from komrade.backend.messages import Message
2020-09-09 22:01:41 +00:00
msg_obj = Message(msg_d,from_whom=from_whom,to_whom=to_whom)
2020-09-09 14:38:37 +00:00
# decrypt msg
return msg_obj
2020-09-07 20:00:21 +00:00
2020-09-09 18:31:36 +00:00
def __repr__(self):
clsname=(type(self)).__name__
2020-09-10 08:19:08 +00:00
name = clsname+' '+self.name if self.name!=clsname else clsname
2020-09-10 12:24:06 +00:00
try:
keystr='+'.join(self.top_keys) if self.pubkey else ''
except TypeError:
keystr=''
2020-09-10 08:23:44 +00:00
# if self.pubkey:
if False:
2020-09-10 08:22:21 +00:00
pubk=self.pubkey_b64.decode()
2020-09-10 08:23:05 +00:00
pubk=pubk[-5:]
2020-09-10 08:22:21 +00:00
pubk = f' ({pubk})'# if pubk else ''
else:
pubk = ''
return f'[{name}]{pubk} ({keystr})'
2020-09-09 18:31:36 +00:00
2020-09-09 21:30:14 +00:00
def locate_an_operator(self,name):
if name == OPERATOR_NAME:
return TheOperator()
if name == TELEPHONE_NAME:
return TheTelephone()
2020-09-09 22:09:08 +00:00
return Caller(name)
2020-09-09 21:30:14 +00:00
2020-09-10 12:04:12 +00:00
def route_msg(self,msg_obj,reencrypt=True):
2020-09-09 21:30:14 +00:00
# decrypt
2020-09-10 07:44:03 +00:00
self.log('got msg_obj!',msg_obj)
2020-09-10 07:53:40 +00:00
if msg_obj.is_encrypted:
msg_obj.decrypt()
2020-09-10 11:57:53 +00:00
# try route
2020-09-10 11:58:17 +00:00
if msg_obj.route:
2020-09-10 11:57:53 +00:00
data,route = msg_obj.data, msg_obj.route
2020-09-10 11:59:06 +00:00
if not hasattr(self,route) or route not in self.ROUTES:
2020-09-10 11:57:53 +00:00
raise KomradeException(f'Not a valid route!: {route}')
# route it!
func = getattr(self,route)
new_data = func(**data)
msg_obj.msg = msg_obj.msg_d['_msg'] = new_data
# try passing it on?
if msg_obj.has_embedded_msg:
new_data = self.route_msg(msg_obj.msg)
msg_obj.msg = msg_obj.msg_d['_msg'] = new_data
# time to turn around and encrypt
msg_obj.mark_return_to_sender()
self.log('returning to sender as:',msg_obj)
# encrypt
2020-09-10 12:04:12 +00:00
if reencrypt:
msg_obj.encrypt()
2020-09-10 11:57:53 +00:00
2020-09-10 07:53:40 +00:00
return msg_obj
2020-09-10 11:57:53 +00:00
2020-09-12 14:32:03 +00:00
def ring_ring(self,msg,to_whom,from_whom=None,get_resp_from=None,route=None):
2020-09-09 23:23:27 +00:00
# ring ring
2020-09-12 13:11:39 +00:00
from komrade.cli.artcode import ART_PHONE_SM1
2020-09-12 14:32:03 +00:00
import textwrap as tw
self.log(f'''
{ART_PHONE_SM1}
ring ring ring!
2020-09-12 14:52:55 +00:00
I am {self}. I have been given a message by {from_whom}, and told to pass it onto {to_whom}, by way of the function {get_resp_from}.
2020-09-12 14:32:03 +00:00
The message is:
{dict_format(msg)}
2020-09-12 13:11:39 +00:00
''')
2020-09-09 23:23:27 +00:00
# get encr msg obj
msg_obj = self.compose_msg_to(
msg,
2020-09-12 14:32:03 +00:00
to_whom,
route=route
2020-09-09 23:23:27 +00:00
)
self.log(f'ring ring! here is the message object I made, to send to {to_whom}: {msg_obj}')
# encrypting
msg_obj.encrypt()
2020-09-10 11:57:53 +00:00
# pass through the telephone wire by the get_resp_from function
2020-09-09 23:23:27 +00:00
if not get_resp_from: get_resp_from=to_whom.ring_ring
2020-09-12 14:52:55 +00:00
resp_msg_obj = get_resp_from(msg_obj.msg_d,from_whom=from_whom)
2020-09-09 23:23:27 +00:00
self.log('resp_msg_obj <-',resp_msg_obj)
2020-09-10 11:57:53 +00:00
# decrypt
2020-09-10 08:08:50 +00:00
if resp_msg_obj.is_encrypted:
resp_msg_obj.decrypt()
2020-09-09 23:23:27 +00:00
# route back?
2020-09-10 12:05:03 +00:00
return self.route_msg(resp_msg_obj,reencrypt=False).msg
2020-09-09 23:23:27 +00:00
2020-09-09 23:18:22 +00:00
def pronto_pronto(self, msg_obj):
self.log(f'''
pronto pronto!
>> {msg_obj}
''')
2020-09-10 12:04:12 +00:00
return self.route_msg(msg_obj,reencrypt=True)
2020-09-10 11:57:53 +00:00
# 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)
2020-09-09 22:23:51 +00:00
2020-09-10 11:57:53 +00:00
# # re-encrypt
# if not resp_msg_obj.is_encrypted:
# resp_msg_obj.encrypt()
# self.log(f're-encrypted: {resp_msg_obj}')
2020-09-09 21:30:14 +00:00
2020-09-10 11:57:53 +00:00
# # pass msg back the chain
# return resp_msg_obj
2020-09-09 14:38:37 +00:00