From 1721b7428e352575b0fefaf84463d9dff52aff40 Mon Sep 17 00:00:00 2001 From: backpacker69 Date: Wed, 17 May 2017 19:11:11 +0000 Subject: [PATCH 1/3] using gpg to encrypt and decrypt keystore --- pacli/__main__.py | 40 +++++++++++++++++++++++++++++++++++----- pacli/config.py | 5 ++++- pacli/default_conf.py | 5 ++++- requirements.txt | 1 + 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/pacli/__main__.py b/pacli/__main__.py index 41c6476..068d5ae 100644 --- a/pacli/__main__.py +++ b/pacli/__main__.py @@ -9,10 +9,13 @@ from pypeerassets.pautils import amount_to_exponent, exponent_to_amount import json import logging +import gnupg +import getpass conf_dir = user_config_dir("pacli") conf_file = os.path.join(conf_dir, "pacli.conf") logfile = os.path.join(conf_dir, "pacli.log") +keyfile = os.path.join(conf_dir, "pacli.gpg") class Settings: pass @@ -20,9 +23,9 @@ class Settings: def load_conf(): '''load user configuration''' - user_config = read_conf(conf_file) - for key in user_config: - setattr(Settings, key, user_config[key]) + settings = read_conf(conf_file) + for key in settings: + setattr(Settings, key, settings[key]) logging.basicConfig(filename=logfile, level=logging.getLevelName(Settings.loglevel)) logging.basicConfig(level=logging.getLevelName(Settings.loglevel), @@ -37,6 +40,8 @@ def first_run(): os.mkdir(conf_dir) if not os.path.exists(conf_file): write_default_config(conf_file) + if not os.path.exists(keyfile): + open(keyfile, 'a').close() def set_up(provider): '''setup''' @@ -50,7 +55,8 @@ def set_up(provider): if not Settings.production: if not provider.listtransactions("PATEST"): pa.pautils.load_p2th_privkeys_into_local_node(provider, prod=False) - + else: + pa.pautils.load_p2th_privkeys_into_local_node(provider,keyfile) def default_account_utxo(provider, amount): '''set default address to be used with pacli''' @@ -804,10 +810,26 @@ def main(): first_run() load_conf() + mypg = None + password = None + mykeys="" + + if Settings.keystore == "gnupg" and Settings.provider != "rpcnode": + mypg = gnupg.GPG(binary='/usr/bin/gpg',homedir=Settings.gnupgdir,keyring='pubring.gpg',secring='secring.gpg') + password = getpass.getpass("Input gpg key password:") + fd = open(keyfile) + data = fd.read() + if len(data)>0: + mykeys = str(mypg.decrypt(data,passphrase=password)) + # print(mykeys) + fd.close() + else: + print("using rpcnode") + if Settings.provider.lower() == "rpcnode": provider = pa.RpcNode(testnet=Settings.testnet) if Settings.provider.lower() == "holy": - provider = pa.Holy(network=Settings.network) + provider = pa.Holy(network=Settings.network,keysJson=mykeys) set_up(provider) args = cli() @@ -858,5 +880,13 @@ def main(): if args.info: vote_info(provider, args.info) + if mypg: + #write keys + data = str(mypg.encrypt(str(provider.dumpprivkeys()),Settings.gnupgkey)) + fd = open(keyfile,"w") + fd.write(data) + fd.close() + + if __name__ == "__main__": main() diff --git a/pacli/config.py b/pacli/config.py index 863bd86..38d6f46 100644 --- a/pacli/config.py +++ b/pacli/config.py @@ -16,7 +16,10 @@ def read_conf(conf_file): "production": config["settings"]["production"], "loglevel": config["settings"]["loglevel"], "change": config["settings"]["change"], - "provider": config["settings"]["provider"] + "provider": config["settings"]["provider"], + "keystore": config["settings"]["keystore"], + "gnupgdir": config["settings"]["gnupgdir"], + "gnupgkey": config["settings"]["gnupgkey"] } if settings["network"].startswith("t"): diff --git a/pacli/default_conf.py b/pacli/default_conf.py index 368a5a2..b29424c 100644 --- a/pacli/default_conf.py +++ b/pacli/default_conf.py @@ -5,5 +5,8 @@ "production": True, "change": "default", "provider": "rpcnode", - "loglevel": "WARNING" # WARNING, INFO, DEBUG + "loglevel": "WARNING", # WARNING, INFO, DEBUG + "keystore": "gnupg", + "gnupgdir": "~/.gnupg/", + "gnupgkey": "any" } diff --git a/requirements.txt b/requirements.txt index df05498..f8cf325 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ pypeerassets>=0.1.1 terminaltables>=3.1.0 +gnupg>=2.1 appdirs From 6dc193055f3eedcd074e0f9498a02094bed05a96 Mon Sep 17 00:00:00 2001 From: backpacker69 Date: Thu, 18 May 2017 12:01:46 +0000 Subject: [PATCH 2/3] separate keystore from main --- pacli/__main__.py | 33 +++++++++++---------------------- pacli/config.py | 36 +++++++++++++++++++++++------------- pacli/default_conf.py | 1 + pacli/keystore.py | 31 +++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 35 deletions(-) create mode 100644 pacli/keystore.py diff --git a/pacli/__main__.py b/pacli/__main__.py index 068d5ae..801a6af 100644 --- a/pacli/__main__.py +++ b/pacli/__main__.py @@ -9,8 +9,8 @@ from pypeerassets.pautils import amount_to_exponent, exponent_to_amount import json import logging -import gnupg -import getpass + +from pacli.keystore import read_keystore, write_keystore conf_dir = user_config_dir("pacli") conf_file = os.path.join(conf_dir, "pacli.conf") @@ -24,6 +24,7 @@ def load_conf(): '''load user configuration''' settings = read_conf(conf_file) + for key in settings: setattr(Settings, key, settings[key]) @@ -809,22 +810,16 @@ def cli(): def main(): first_run() - load_conf() + + try: + load_conf() + except: + raise + mypg = None password = None mykeys="" - - if Settings.keystore == "gnupg" and Settings.provider != "rpcnode": - mypg = gnupg.GPG(binary='/usr/bin/gpg',homedir=Settings.gnupgdir,keyring='pubring.gpg',secring='secring.gpg') - password = getpass.getpass("Input gpg key password:") - fd = open(keyfile) - data = fd.read() - if len(data)>0: - mykeys = str(mypg.decrypt(data,passphrase=password)) - # print(mykeys) - fd.close() - else: - print("using rpcnode") + mykeys = read_keystore(Settings,keyfile) if Settings.provider.lower() == "rpcnode": provider = pa.RpcNode(testnet=Settings.testnet) @@ -880,13 +875,7 @@ def main(): if args.info: vote_info(provider, args.info) - if mypg: - #write keys - data = str(mypg.encrypt(str(provider.dumpprivkeys()),Settings.gnupgkey)) - fd = open(keyfile,"w") - fd.write(data) - fd.close() - + write_keystore(Settings,keyfile,provider.dumpprivkeys()) if __name__ == "__main__": main() diff --git a/pacli/config.py b/pacli/config.py index 38d6f46..e1a7365 100644 --- a/pacli/config.py +++ b/pacli/config.py @@ -1,26 +1,36 @@ import configparser +import sys from .default_conf import default_conf -def write_default_config(conf_file): +def write_default_config(conf_file=None): print("writing default config") config = configparser.ConfigParser() config["settings"] = default_conf - with open(conf_file, 'w') as configfile: - config.write(configfile) + if not conf_file: + config.write() + else: + with open(conf_file, 'w') as configfile: + config.write(configfile) def read_conf(conf_file): config = configparser.ConfigParser() config.read(conf_file) - settings = { - "network": config["settings"]["network"], - "production": config["settings"]["production"], - "loglevel": config["settings"]["loglevel"], - "change": config["settings"]["change"], - "provider": config["settings"]["provider"], - "keystore": config["settings"]["keystore"], - "gnupgdir": config["settings"]["gnupgdir"], - "gnupgkey": config["settings"]["gnupgkey"] - } + try: + settings = { + "network": config["settings"]["network"], + "production": config["settings"]["production"], + "loglevel": config["settings"]["loglevel"], + "change": config["settings"]["change"], + "provider": config["settings"]["provider"], + "keystore": config["settings"]["keystore"], + "gnupgdir": config["settings"]["gnupgdir"], + "gnupgagent": config["settings"]["gnupgagent"], + "gnupgkey": config["settings"]["gnupgkey"] + } + except: + print("config is outdated, saving current default config to",conf_file+".sample") + write_default_config(conf_file+".sample") + raise if settings["network"].startswith("t"): settings["testnet"] = True diff --git a/pacli/default_conf.py b/pacli/default_conf.py index b29424c..bd50756 100644 --- a/pacli/default_conf.py +++ b/pacli/default_conf.py @@ -8,5 +8,6 @@ "loglevel": "WARNING", # WARNING, INFO, DEBUG "keystore": "gnupg", "gnupgdir": "~/.gnupg/", + "gnupgagent": False, "gnupgkey": "any" } diff --git a/pacli/keystore.py b/pacli/keystore.py new file mode 100644 index 0000000..1aec862 --- /dev/null +++ b/pacli/keystore.py @@ -0,0 +1,31 @@ +import gnupg +import getpass +import sys + +mypg = None + +def read_keystore(Settings,keyfile) -> str: + mykeys = "" + + if Settings.keystore == "gnupg" and Settings.provider != "rpcnode": + mypg = gnupg.GPG(binary='/usr/bin/gpg',homedir=Settings.gnupgdir,use_agent=bool(Settings.gnupgagent=="True"),keyring='pubring.gpg',secring='secring.gpg') + password = getpass.getpass("Input gpg key password:") + fd = open(keyfile) + data = fd.read() + + if len(data)>0: + mykeys = str(mypg.decrypt(data,passphrase=password)) + fd.close() + else: + print("using rpcnode") + + return mykeys + +def write_keystore(Settings,keyfile,keys): + + if mypg: + data = str(mypg.encrypt(str(keys),Settings.gnupgkey)) + fd = open(keyfile,"w") + fd.write(data) + fd.close() + From 949c11a95d66c0342105d2d0c4fe56e17897b80b Mon Sep 17 00:00:00 2001 From: backpacker69 Date: Fri, 26 May 2017 14:39:32 +0000 Subject: [PATCH 3/3] keystore fixes --- pacli/__main__.py | 9 ++++++--- pacli/keystore.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/pacli/__main__.py b/pacli/__main__.py index 801a6af..8f733ba 100644 --- a/pacli/__main__.py +++ b/pacli/__main__.py @@ -10,7 +10,7 @@ import json import logging -from pacli.keystore import read_keystore, write_keystore +from pacli.keystore import read_keystore, write_keystore, KeyedProvider conf_dir = user_config_dir("pacli") conf_file = os.path.join(conf_dir, "pacli.conf") @@ -818,14 +818,17 @@ def main(): mypg = None password = None - mykeys="" + mykeys = "" mykeys = read_keystore(Settings,keyfile) if Settings.provider.lower() == "rpcnode": provider = pa.RpcNode(testnet=Settings.testnet) if Settings.provider.lower() == "holy": - provider = pa.Holy(network=Settings.network,keysJson=mykeys) + provider = pa.Holy(network=Settings.network) + + provider = KeyedProvider(provider,keysJson=mykeys) set_up(provider) + args = cli() if args.status: diff --git a/pacli/keystore.py b/pacli/keystore.py index 1aec862..96f260f 100644 --- a/pacli/keystore.py +++ b/pacli/keystore.py @@ -1,6 +1,7 @@ import gnupg import getpass import sys +from pypeerassets.kutil import Kutil mypg = None @@ -28,4 +29,49 @@ def write_keystore(Settings,keyfile,keys): fd = open(keyfile,"w") fd.write(data) fd.close() - + +class KeyedProvider: + + """ + Keystore class + """ + + @classmethod + def __init__(self, provider, keysJson: str=""): + """ + : + """ + self.provider = provider + + if keysJson != "": + self.privkeys = eval(keysJson) + else: + self.privkeys = {} + + @classmethod + def __getattr__(self, name): + return getattr(self.provider, name) + + @classmethod + def importprivkey(self, privkey: str, label: str) -> int: + """import with