You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Comrad/komrade/backend/the_operator.py

173 lines
5.0 KiB
Python

4 years ago
"""
There is only one operator!
Running on node prime.
"""
# 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 *
4 years ago
from komrade.backend import *
4 years ago
# print(PATH_OPERATOR_WEB_KEYS_URL)
4 years ago
class TheOperator(Operator):
"""
4 years ago
The remote operator
4 years ago
"""
4 years ago
@property
def phone(self):
4 years ago
global TELEPHONE
4 years ago
from komrade.backend.the_telephone import TheTelephone
4 years ago
if not TELEPHONE: TELEPHONE=TheTelephone()
4 years ago
return TELEPHONE
4 years ago
4 years ago
def __init__(self, name = OPERATOR_NAME, passphrase='acc'):
4 years ago
"""
Boot up the operator. Requires knowing or setting a password of memory.
"""
4 years ago
super().__init__(
name,
passphrase,
path_crypt_keys=PATH_CRYPT_OP_KEYS,
4 years ago
path_crypt_data=PATH_CRYPT_OP_DATA
)
self._keychain = self.operator_keychain
4 years ago
4 years ago
def ring(self,
4 years ago
from_caller=None,
to_caller=None,
json_phone2phone={},
json_caller2phone={}, # (person) -> operator or operator -> (person)
json_caller2caller={}):
4 years ago
encr_msg_to_send = super().ring(
4 years ago
from_phone=self,
to_phone=self.phone,
from_caller=from_caller,
to_caller=to_caller,
json_phone2phone=json_phone2phone,
json_caller2phone=json_caller2phone, # (person) -> operator
json_caller2caller=json_caller2caller)
return self.send(encr_msg_to_send)
4 years ago
# ends the ring_ring() chain
4 years ago
def answer_phone(self,data_b):
4 years ago
# route incoming call from the switchboard
4 years ago
self.log('Hello, this is the Operator. You said: ',data_b)
4 years ago
# unseal
4 years ago
msg_obj = self.unseal_msg(
data_b,
from_whom=self.phone
)
4 years ago
self.log(f'Operator understood message: {msg_obj} {msg_obj.route}')
4 years ago
4 years ago
# decrypt?
msg_obj.decrypt()
4 years ago
# carry out message instructions
4 years ago
resp_msg_obj = self.pronto_pronto(msg_obj) #,route=msg_obj.route)
4 years ago
self.log('route_result <-',resp_msg_obj)
4 years ago
# send back down encrypted
4 years ago
msg_sealed = self.seal_msg(resp_msg_obj.msg_d)
4 years ago
# return back to phone and back down to chain
return msg_sealed
4 years ago
4 years ago
def find_pubkey(self):
return self.operator_keychain['pubkey']
4 years ago
4 years ago
4 years ago
def send(self,encr_data_b):
4 years ago
self.log(type(encr_data_b),encr_data_b,'sending!')
4 years ago
return encr_data_b
4 years ago
### ROUTES
4 years ago
def does_username_exist(self,name,**data):
4 years ago
pubkey=self.crypt_keys.get(name,prefix='/pubkey/')
4 years ago
self.log(f'looking for {name}, found {pubkey} as pubkey')
return bool(pubkey)
4 years ago
4 years ago
def register_new_user(self,name,pubkey,**data):
4 years ago
# self.log('setting pubkey under name')
success,ck,cv = self.crypt_keys.set(name,pubkey,prefix='/pubkey/')
4 years ago
# self.log('got result from crypt:',res)
4 years ago
# check input back from crypt
assert cv==pubkey
assert name==self.crypt_keys.key2hash(name) #(self.crypt_keys.prepare_key()
res = {
'success':success,
'pubkey':cv,
'name':name,
}
## success msg
if success:
res['status'] = f'''
{OPERATOR_INTRO} I have managed to register user {name}.
4 years ago
I've stored their public key ({b64encode(cv).decode()}) under their name.
I never mention this name directly, but record it only
in a disguised, "hashed" form: by running it through a 1-way
information process which will always yield the same scrambled result,
but which is unpredictable to anyone without the secret key,
which I keep protected and encrypted on my local hard drive.
The content of tour subsequent data will therefore not only be encrypted,
but its location in my database is obscured, and even I couldn't find it
again unless you gave me exactly what information to run through the 1-way
information scrambler once again.'''
4 years ago
else:
res['status']= f'''
{OPERATOR_INTRO}. I'm sorry, but I can'tregister username {name}.
4 years ago
Someone has already registered under that name.
'''
4 years ago
self.log('Operator returning result:',res)
4 years ago
return res
4 years ago
4 years ago
4 years ago
def test_op():
4 years ago
from komrade.backend.the_telephone import TheTelephone
op = TheOperator()
# op.boot()
4 years ago
keychain_op = op.keychain(force=True)
4 years ago
4 years ago
4 years ago
phone = TheTelephone()
# phone.boot()
4 years ago
keychain_ph = phone.keychain(force=True)
4 years ago
from pprint import pprint
4 years ago
print('REASSEMBLED OPERATOR KEYCHAIN')
pprint(keychain_op)
# stop
4 years ago
print('REASSEMBLED TELEPHONE KEYCHAIN')
4 years ago
pprint(keychain_ph)
4 years ago
4 years ago
# print(op.pubkey(keychain=keychain))
4 years ago
# print(op.crypt_keys.get(op.pubkey(), prefix='/privkey_encr/'))
4 years ago
# print(op.crypt_keys.get(op.name, prefix='/pubkey_encr/'))
4 years ago
# print(op.pubkey_)
4 years ago
4 years ago
4 years ago
# stop
4 years ago
4 years ago
# pubkey = op.keychain()['pubkey']
# pubkey_b64 = b64encode(pubkey)
# print(pubkey)
4 years ago
if __name__ == '__main__': test_op()