diff --git a/pacli/__main__.py b/pacli/__main__.py index 41c6476..8f733ba 100644 --- a/pacli/__main__.py +++ b/pacli/__main__.py @@ -10,9 +10,12 @@ import json import logging +from pacli.keystore import read_keystore, write_keystore, KeyedProvider + 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,10 @@ 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 +41,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 +56,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''' @@ -803,12 +810,25 @@ def cli(): def main(): first_run() - load_conf() + + try: + load_conf() + except: + raise + + mypg = None + password = None + 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) + + provider = KeyedProvider(provider,keysJson=mykeys) set_up(provider) + args = cli() if args.status: @@ -858,5 +878,7 @@ def main(): if args.info: vote_info(provider, args.info) + write_keystore(Settings,keyfile,provider.dumpprivkeys()) + if __name__ == "__main__": main() diff --git a/pacli/config.py b/pacli/config.py index 863bd86..e1a7365 100644 --- a/pacli/config.py +++ b/pacli/config.py @@ -1,23 +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"] - } + 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 368a5a2..bd50756 100644 --- a/pacli/default_conf.py +++ b/pacli/default_conf.py @@ -5,5 +5,9 @@ "production": True, "change": "default", "provider": "rpcnode", - "loglevel": "WARNING" # WARNING, INFO, DEBUG + "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..96f260f --- /dev/null +++ b/pacli/keystore.py @@ -0,0 +1,77 @@ +import gnupg +import getpass +import sys +from pypeerassets.kutil import Kutil + +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() + +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