From cd887b528a1b531f527c11c8c74d406d889e4089 Mon Sep 17 00:00:00 2001 From: quadrismegistus Date: Sat, 5 Sep 2020 17:26:37 +0100 Subject: [PATCH] cool stuff --- komrade/__init__.py | 29 ++++--- komrade/api/api.py | 18 +--- komrade/constants.py | 34 ++++++++ komrade/operators/keymaker.py | 93 +++++++++++++-------- komrade/operators/mazes.py | 50 ++++++++++++ komrade/operators/operators.py | 145 ++++++++++++++++++++++++--------- komrade/utils.py | 14 ++++ 7 files changed, 281 insertions(+), 102 deletions(-) create mode 100644 komrade/constants.py create mode 100644 komrade/operators/mazes.py create mode 100644 komrade/utils.py diff --git a/komrade/__init__.py b/komrade/__init__.py index cbf9b45..d241cd8 100644 --- a/komrade/__init__.py +++ b/komrade/__init__.py @@ -1,17 +1,16 @@ -### -# Define some basic things while we're here +# basic config +from .constants import * +from .utils import * -class KomradeException(Exception): pass +# common python imports +import os,sys +from collections import defaultdict +from base64 import b64encode,b64decode -# make sure komrade is on path -import sys,os -sys.path.append(os.path.dirname(__file__)) - -import inspect -class Logger(object): - def log(self,*x): - curframe = inspect.currentframe() - calframe = inspect.getouterframes(curframe, 2) - mytype = type(self).__name__ - caller = calframe[1][3] - print(f'\n[{mytype}.{caller}()]',*x) +# common external imports +from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair +from pythemis.smessage import SMessage, ssign, sverify +from pythemis.skeygen import GenerateSymmetricKey +from pythemis.scell import SCellSeal +from pythemis.exception import ThemisError +import getpass diff --git a/komrade/api/api.py b/komrade/api/api.py index 6954c30..8c2715e 100644 --- a/komrade/api/api.py +++ b/komrade/api/api.py @@ -1,21 +1,5 @@ # ### Constants -# BSEP=b'||||||||||' -# BSEP2=b'@@@@@@@@@@' -# BSEP3=b'##########' -# - -# P2P_PREFIX=b'/persona/' -# P2P_PREFIX_POST=b'/msg/' -# P2P_PREFIX_INBOX=b'/inbox/' -# P2P_PREFIX_OUTBOX=b'/outbox/' - -# DEBUG = True -# UPLOAD_DIR = 'uploads/' -# ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} - -# PORT_LISTEN = 5639 -# NODE_SLEEP_FOR=1 -# NODES_PRIME = [("128.232.229.63",8467)] +from komrade import * LAST_N_IN_INBOX = 10 diff --git a/komrade/constants.py b/komrade/constants.py new file mode 100644 index 0000000..3bc2068 --- /dev/null +++ b/komrade/constants.py @@ -0,0 +1,34 @@ +# addresses +URL_KOMRADE = '128.232.229.63' #'komrade.app' +OPERATOR_API_URL = f'http://{URL_KOMRADE}:6999/op/' + + +# paths +import os +PATH_KOMRADE = os.path.abspath(os.path.join(os.path.expanduser('~'),'.komrade')) +PATH_OPERATOR = os.path.join(PATH_KOMRADE,'.operator') +PATH_OPERATOR_PUBKEY = os.path.join(PATH_OPERATOR,'.op.key.pub.encr') +PATH_OPERATOR_PRIVKEY = os.path.join(PATH_OPERATOR,'.op.key.priv.encr') +PATH_CRYPT_KEYS = os.path.join(PATH_OPERATOR,'.op.db.keys.crypt') +PATH_CRYPT_DATA = os.path.join(PATH_OPERATOR,'.op.db.data.encr') + +# etc +BSEP=b'||||||||||' +BSEP2=b'@@@@@@@@@@' +BSEP3=b'##########' + +OPERATOR_PUBKEY_b64 = b'VUVDMgAAAC2uQwUQAoxUODIy1nGUKc3gnDe94XxFtsMOJMZ8MN9QMrl3nPiP' +import base64 +OPERATOR_PUBKEY = base64.b64decode(OPERATOR_PUBKEY_b64) + +# key names + +KEYNAMES = [ + 'pubkey','privkey','adminkey', + 'pubkey_encr','privkey_encr','adminkey_encr', + 'pubkey_decr','privkey_decr','adminkey_decr', + 'pubkey_encr_encr','privkey_encr_encr','adminkey_encr_encr', + 'pubkey_encr_decr','privkey_encr_decr','adminkey_encr_decr', + 'pubkey_decr_encr','privkey_decr_encr','adminkey_decr_encr', + 'pubkey_decr_decr','privkey_decr_decr','adminkey_decr_decr' +] diff --git a/komrade/operators/keymaker.py b/komrade/operators/keymaker.py index 5a0b7d5..7f64238 100644 --- a/komrade/operators/keymaker.py +++ b/komrade/operators/keymaker.py @@ -1,33 +1,6 @@ -from komrade.operators.crypt import Crypt -from komrade import KomradeException,Logger -from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair -from pythemis.smessage import SMessage, ssign, sverify -from pythemis.skeygen import GenerateSymmetricKey -from pythemis.scell import SCellSeal -from pythemis.exception import ThemisError -import getpass,os -from collections import defaultdict - -PATH_KOMRADE = os.path.abspath(os.path.join(os.path.expanduser('~'),'.komrade')) -PATH_OPERATOR = os.path.join(PATH_KOMRADE,'.operator') -PATH_OPERATOR_PUBKEY = os.path.join(PATH_OPERATOR,'.op.key.pub.encr') -PATH_OPERATOR_PRIVKEY = os.path.join(PATH_OPERATOR,'.op.key.priv.encr') -PATH_CRYPT_KEYS = os.path.join(PATH_OPERATOR,'.op.db.keys.crypt') -PATH_CRYPT_DATA = os.path.join(PATH_OPERATOR,'.op.db.data.encr') -BSEP=b'||||||||||' -BSEP2=b'@@@@@@@@@@' -BSEP3=b'##########' - -KEYNAMES = [ - 'pubkey','privkey','adminkey', - 'pubkey_encr','privkey_encr','adminkey_encr', - 'pubkey_decr','privkey_decr','adminkey_decr', - 'pubkey_encr_encr','privkey_encr_encr','adminkey_encr_encr', - 'pubkey_encr_decr','privkey_encr_decr','adminkey_encr_decr', - 'pubkey_decr_encr','privkey_decr_encr','adminkey_decr_encr', - 'pubkey_decr_decr','privkey_decr_decr','adminkey_decr_decr' - ] - +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.operators.crypt import * class Keymaker(Logger): def __init__(self,name=None,passphrase=None): @@ -185,10 +158,66 @@ class Keymaker(Logger): def adminkey_decr_decr(self, **kwargs): return self.getkey(uri=self.privkey_decr(**kwargs),keyname='adminkey_decr_decr',**kwargs) - ### DECR ENCR KEYS - ## Third level: splitting (encrypted/decryption key) the encrypted keys and decryption keys above + # convenience functions + + # Concrete keys + @property + def pubkey__(self): return self.keychain()['pubkey'] + @property + def privkey_(self, **kwargs): return self.keychain()['privkey'] + @property + def adminkey_(self, **kwargs): return self.keychain()['adminkey'] + ## (1-X) Encrypted halves + @property + def pubkey_encr_(self, **kwargs):return self.keychain()['pubkey_encr'] + @property + def privkey_encr_(self, **kwargs): return self.keychain()['privkey_encr'] + @property + def adminkey_encr_(self, **kwargs): return self.keychain()['adminkey_encr'] + + ## (1-Y) Decrpytor halves + @property + def pubkey_decr_(self, **kwargs): return self.keychain()['pubkey_decr'] + @property + def privkey_decr_(self, **kwargs): return self.keychain()['privkey_decr'] + @property + def adminkey_decr_(self, **kwargs): return self.keychain()['adminkey_decr'] + + ## Second halving! + ## (1-X-X) + @property + def pubkey_encr_encr_(self, **kwargs): return self.keychain()['pubkey_encr_encr'] + @property + def privkey_encr_encr_(self, **kwargs): return self.keychain()['privkey_encr_encr'] + @property + def adminkey_encr_encr_(self, **kwargs): return self.keychain()['adminkey_encr_encr'] + + ## (1-X-Y) + @property + def pubkey_encr_decr_(self, **kwargs): return self.keychain()['pubkey_encr_decr'] + @property + def privkey_encr_decr_(self, **kwargs): return self.keychain()['privkey_encr_decr'] + @property + def adminkey_encr_decr_(self, **kwargs): return self.keychain()['adminkey_encr_decr'] + + ## (1-Y-X) + @property + def pubkey_decr_encr_(self, **kwargs): return self.keychain()['pubkey_decr_encr'] + @property + def privkey_decr_encr_(self, **kwargs): return self.keychain()['privkey_decr_encr'] + @property + def adminkey_decr_encr_(self, **kwargs): return self.keychain()['adminkey_decr_encr'] + + ## (1-Y-Y) + @property + def pubkey_decr_decr_(self, **kwargs): return self.keychain()['pubkey_decr_decr'] + @property + def privkey_decr_decr_(self, **kwargs): return self.keychain()['privkey_decr_decr'] + @property + def adminkey_decr_decr_(self, **kwargs): return self.keychain()['adminkey_decr_decr'] + # Get key de-cryptors def genkey_pass_keycell(self,pass_phrase,q_name='Read permissions?'): diff --git a/komrade/operators/mazes.py b/komrade/operators/mazes.py new file mode 100644 index 0000000..c8a1381 --- /dev/null +++ b/komrade/operators/mazes.py @@ -0,0 +1,50 @@ +log=print + +def get_tor_python_session(): + # from torpy.http.requests import TorRequests + # with TorRequests() as tor_requests: + # with tor_requests.get_session() as s: + # # return s + # from torpy.http.requests import tor_requests_session + # with tor_requests_session() as s: # returns requests.Session() object + # return s + pass + + + +def get_tor_proxy_session(): + import requests + session = requests.session() + # Tor uses the 9050 port as the default socks port + session.proxies = {'http': 'socks5://127.0.0.1:9050', + 'https': 'socks5://127.0.0.1:9050'} + return session + +def get_async_tor_proxy_session(): + import requests_futures + from requests_futures.sessions import FuturesSession + session = FuturesSession() + # Tor uses the 9050 port as the default socks port + session.proxies = {'http': 'socks5://127.0.0.1:9050', + 'https': 'socks5://127.0.0.1:9050'} + return session + + + + +def tor_request(url,method='get',data=None): + with get_tor_proxy_session() as s: + if method=='get': + return s.get(url) + elif method=='post': + log('data',data) + return s.post(url,data=data) + + +def request(Q,**kwargs): + log('request() Q:',Q) + res = tor_request(Q,**kwargs) + log('reqeust() <-',res) + return res + + diff --git a/komrade/operators/operators.py b/komrade/operators/operators.py index b786036..170ad73 100644 --- a/komrade/operators/operators.py +++ b/komrade/operators/operators.py @@ -2,39 +2,16 @@ 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.operators.crypt import Crypt -from komrade.operators.keymaker import Keymaker -from flask import Flask -from flask_classful import FlaskView -from pythemis.skeygen import KEY_PAIR_TYPE, GenerateKeyPair -from pythemis.smessage import SMessage, ssign, sverify -from pythemis.skeygen import GenerateSymmetricKey -from pythemis.scell import SCellSeal -from pythemis.exception import ThemisError -from base64 import b64encode,b64decode -from komrade import KomradeException,Logger -import getpass -PATH_HERE = os.path.dirname(__file__) -sys.path.append(PATH_HERE) -from crypt import * -### Constants -BSEP=b'||||||||||' -BSEP2=b'@@@@@@@@@@' -BSEP3=b'##########' - - -# paths -PATH_KOMRADE = os.path.abspath(os.path.join(os.path.expanduser('~'),'.komrade')) -PATH_OPERATOR = os.path.join(PATH_KOMRADE,'.operator') -PATH_OPERATOR_PUBKEY = os.path.join(PATH_OPERATOR,'.op.key.pub.encr') -PATH_OPERATOR_PRIVKEY = os.path.join(PATH_OPERATOR,'.op.key.priv.encr') -PATH_CRYPT_KEYS = os.path.join(PATH_OPERATOR,'.op.db.keys.crypt') -PATH_CRYPT_DATA = os.path.join(PATH_OPERATOR,'.op.db.data.encr') - -# init req paths -if not os.path.exists(PATH_OPERATOR): os.makedirs(PATH_OPERATOR) +from komrade import * +from komrade.operators.crypt import * +from komrade.operators.keymaker import * +from komrade.operators.mazes import * +# external imports +from flask import Flask, request, jsonify +from flask_classful import FlaskView @@ -55,10 +32,29 @@ class Operator(Keymaker): self._keychain = self.keychain(force = True) + class Caller(Operator): + """ + Variant of an Operator which handles local keys and keymaking. + """ + + @property + def op(self): + """ + Operator on the line. + """ + if not hasattr(self,'_op'): + self._op = TheOperatorOnThePhone(caller = self) + return self._op + def get_new_keys(self,pubkey_pass = None, privkey_pass = None, adminkey_pass = None): + """ + This is the local caller's version. + He never touches the encrypted keys. Only the Operator does! + """ + # Get decryptor keys back from The Operator (one half of the Keymaker) - keychain = self.forge_new_keys(self.name) + keychain = self.op.forge_new_keys(self.name) self.log('create_keys() res from Operator? <-',keychain) # Now lock the decryptor keys away, sealing it with a password of memory! @@ -68,32 +64,105 @@ class TheOperator(Operator): """ The remote operator! Only one! """ + def __init__(self, name = 'TheOperator', passphrase=None): """ 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) + + if not passphrase: passphrase=getpass.getpass('Hello, this is the Operator speaking. What is the passphrase?\n> ') super().__init__(name,passphrase) + ## boot up if necessary + # Do I have my keys? + have_keys = self.exists() + self.log('I have my keys?',have_keys) + # If not, forge them -- only once! + if not have_keys: + self.get_new_keys() + + # load keychain into memory + self._keychain = self.keychain(force = True) + + +### ACTUAL PHONE CONNECTIONS +class TheOperatorOnThePhone(object): + """ + API client class for Caller to interact with The Operator. + """ + def __init__(self, caller): + self.caller = caller + + @property + def sess(self): + """ + Get connection to Tor + """ + if not hasattr(self,'_sess'): + self._sess = get_tor_proxy_session() + return self._sess + + def req(self,req_json={},req_data=None): + req_json_s = jsonify(req_json) + req_json_s.encode() + + # encrypt + from_privkey = self.caller.privkey_ + to_pubkey = OPERATOR_PUBKEY + encrypted_msg = SMessage(from_privkey, for_pubkey).wrap(msg_b64) + return b64encode(encrypted_msg) + + def forge_new_keys(self, name, pubkey_is_public=False): + req_json = {'name':name, 'pubkey_is_public':pubkey_is_public} + req_json_s = jsonify(req_json) + req_json_s_encr = SMessage() + return self.sess.post(json=req_json) OPERATOR = None -class TheOperatorsSwitchboard(FlaskView): - def index(self): - return OPERATOR.keychain()['pubkey'] +class TheSwitchboard(FlaskView): + default_methods = ['POST'] + def forge_new_keys(self): + content = request.json + + #return f'{name}\n{pubkey_is_public}\n{return_all_keys}' + def something(self): return 'something' def run_forever(): + + global OPERATOR OPERATOR = TheOperator() app = Flask(__name__) - TheOperatorsSwitchboard.register(app, route_base='/op/', route_prefix=None) - app.run(debug=True) + TheSwitchboard.register(app, route_base='/op/', route_prefix=None) + app.run(debug=True, port=6999) + + + +def test_op(): + op = TheOperator() + #op.boot() + #pubkey = op.keychain()['pubkey'] + #pubkey_b64 = b64encode(pubkey) + #print(pubkey_b64) + keychain = op.keychain(force=True) + from pprint import pprint + pprint(keychain) + + pubkey = op.keychain()['pubkey'] + pubkey_b64 = b64encode(pubkey) + print(pubkey_b64) + if __name__ == '__main__': - run_forever() + #run_forever() + test_op() \ No newline at end of file diff --git a/komrade/utils.py b/komrade/utils.py new file mode 100644 index 0000000..defe0c3 --- /dev/null +++ b/komrade/utils.py @@ -0,0 +1,14 @@ +class KomradeException(Exception): pass + +# make sure komrade is on path +import sys,os +sys.path.append(os.path.dirname(__file__)) + +import inspect +class Logger(object): + def log(self,*x): + curframe = inspect.currentframe() + calframe = inspect.getouterframes(curframe, 2) + mytype = type(self).__name__ + caller = calframe[1][3] + print(f'\n[{mytype}.{caller}()]',*x)