Correct issues with argument parsing.

This commit is contained in:
Manuel Amador (Rudd-O) 2020-04-18 19:09:26 +00:00
parent ecb4ad91fa
commit bd1d9b63c6
3 changed files with 89 additions and 86 deletions

View File

@ -56,110 +56,87 @@ echo = 0
nosymbols = 0 nosymbols = 0
parser = argparse.ArgumentParser( parser_for_discrimination = argparse.ArgumentParser(
description="A Qubes-RPC inter-vm client for the pass password manager."#, description="(nobody sees this)"#
#usage=usage
) )
parser.add_argument("-d", "--dest-vm", type=str, parser_for_discrimination.add_argument("-d", "--dest-vm", type=str,
help="Set the Qubes domain to consult.", help="Set the Qubes domain to operate with.",
default=os.environ.get('QUBES_PASS_DOMAIN', "")) default=os.environ.get('QUBES_PASS_DOMAIN', ""))
cmd = None
if len(sys.argv) == 2 and not sys.argv[1].startswith("-"):
cmd = "get"
elif len(sys.argv) == 3 and sys.argv[1] == "--":
cmd = "get"
elif len(sys.argv) == 4 and not sys.argv[3].startswith("--"):
cmd = "get"
elif len(sys.argv) == 5 and sys.argv[3] == "--":
cmd = "get"
elif len(sys.argv) == 1:
cmd = "list"
if cmd in ("get", "list"): parser_for_subcommands = argparse.ArgumentParser(
# The user just specified a key, or no key, in the command line. description="A Qubes-RPC inter-vm client for the pass password manager.",
# Omit subparser setup. usage=usage
parser.add_argument("key", help="key to retrieve from pass store", type=str, nargs='?') )
parser.set_defaults(subcommand='get-or-list') parser_for_subcommands.add_argument("-d", "--dest-vm", type=str,
else: help="Set the Qubes domain to operate with.",
subparsers = parser.add_subparsers( default=os.environ.get('QUBES_PASS_DOMAIN', ""))
help='sub-command help (run subcommand with --help as first parameter)'
)
_parsers = {} subparsers = parser_for_subcommands.add_subparsers(
def _newcmd(name, desc): help='sub-command help (run subcommand with --help as first parameter)',
if name not in _parsers: required=False,
_parsers[name] = subparsers.add_parser(name, help=desc) )
_parsers[name].set_defaults(subcommand=name)
return _parsers[name]
for cmd in [("mv", "renames / moves a key in the store"), _parsers = {}
("cp", "renames / copies a key in the store to a new location")]: def _newcmd(name, desc):
p = _newcmd(*cmd) if name not in _parsers:
p.add_argument("original", help="original name of the key", type=str) _parsers[name] = subparsers.add_parser(name, help=desc)
p.add_argument("new", help="new name for the original key", type=str) _parsers[name].set_defaults(subcommand=name)
return _parsers[name]
p = _newcmd("init", "initializes a new pass store if none exists") for cmd in [("mv", "renames / moves a key in the store"),
p.add_argument("gpgid", type=str, nargs="+", ("cp", "renames / copies a key in the store to a new location")]:
help="list of GPG IDs to initialize the store with") p = _newcmd(*cmd)
p.add_argument("original", help="original name of the key", type=str)
p.add_argument("new", help="new name for the original key", type=str)
p = _newcmd("rm", "removes a key in the store") p = _newcmd("init", "initializes a new pass store if none exists")
p.add_argument("key", help="name of the key to be removed", type=str) p.add_argument("gpgid", type=str, nargs="+",
help="list of GPG IDs to initialize the store with")
p = _newcmd("get-or-generate", p = _newcmd("rm", "removes a key in the store")
"retrieves a key from the password store, generating one if it does not exist") p.add_argument("key", help="name of the key to be removed", type=str)
p.add_argument("key", help="name of the key to be retrieved / generated", type=str)
p = _newcmd("generate", p = _newcmd("get-or-generate",
"generates a key in the password store") "retrieves a key from the password store, generating one if it does not exist")
p.add_argument("key", help="name of the key to be generated", type=str) p.add_argument("key", help="name of the key to be retrieved / generated", type=str)
p = _newcmd("insert", p = _newcmd("generate",
"inserts a new key into the pass store") "generates a key in the password store")
p.add_argument("key", help="name of the key to be inserted", type=str) p.add_argument("key", help="name of the key to be generated", type=str)
for p in ["get-or-generate", "generate"]: p = _newcmd("insert",
_parsers[p].add_argument("pass_length", type=int, nargs='?', "inserts a new key into the pass store")
help="number of characters in generated password", p.add_argument("key", help="name of the key to be inserted", type=str)
default=25)
_parsers[p].add_argument("-n", "--no-symbols", action="store_true", for p in ["get-or-generate", "generate"]:
help="no symbols in generated password", _parsers[p].add_argument("pass_length", type=int, nargs='?',
default=False) help="number of characters in generated password",
for p in ["mv", "cp", "rm", "insert", "generate"]: default=25)
_parsers[p].add_argument("-f", "--force", action="store_true", _parsers[p].add_argument("-n", "--no-symbols", action="store_true",
help="force overwriting / removing passwords instead of prompting", help="no symbols in generated password",
default=False) default=False)
for p in ["insert"]: for p in ["mv", "cp", "rm", "insert", "generate"]:
_parsers[p].add_argument("-m", "--multiline", action="store_true", _parsers[p].add_argument("-f", "--force", action="store_true",
help="accept multi-line input, ending it with Ctrl+D (EOF)", help="force overwriting / removing passwords instead of prompting",
default=False) default=False)
_parsers[p].add_argument("-e", "--echo", action="store_true", for p in ["insert"]:
help="echo the password to the console during entry", _parsers[p].add_argument("-m", "--multiline", action="store_true",
default=False) help="accept multi-line input, ending it with Ctrl+D (EOF)",
default=False)
_parsers[p].add_argument("-e", "--echo", action="store_true",
help="echo the password to the console during entry",
default=False)
def usage(string, *args): def usage(string, *args):
if args: if args:
string = string % args string = string % args
print(string, file=sys.stderr) print(string, file=sys.stderr)
parser.print_help(sys.stderr) parser_for_subcommands.print_help(sys.stderr)
sys.exit(2) sys.exit(2)
opts = parser.parse_args()
if not opts.dest_vm:
try:
with open("/rw/config/pass-split-domain") as domain:
opts.dest_vm = domain.readlines()[0].strip()
except FileNotFoundError:
pass
if not opts.dest_vm:
usage("error: the QUBES_PASS_DOMAIN variable is not defined."
" Either create /rw/config/pass-split-domain with the VM containing"
" your pass setup, set the environment variable yourself,"
" or pass -d on the command line.",)
PASS_READ = "ruddo.PassRead" PASS_READ = "ruddo.PassRead"
PASS_MANAGE = "ruddo.PassManage" PASS_MANAGE = "ruddo.PassManage"
@ -197,6 +174,29 @@ def pass_manage(*args, **kwargs):
return send_args(PASS_MANAGE, *args, **kwargs) return send_args(PASS_MANAGE, *args, **kwargs)
if not any(x in sys.argv[1:] for x in ['--help', '-h', '-?']):
opts, args = parser_for_discrimination.parse_known_args()
if not opts.dest_vm:
try:
with open("/rw/config/pass-split-domain") as domain:
opts.dest_vm = domain.readlines()[0].strip()
except FileNotFoundError:
pass
if not opts.dest_vm:
usage("error: the QUBES_PASS_DOMAIN variable is not defined."
" Either create /rw/config/pass-split-domain with the VM containing"
" your pass setup, set the environment variable yourself,"
" or pass -d on the command line.",)
if len(args) == 0 or (len(args) == 1 and args[0] == "--"):
sys.exit(pass_read("list"))
elif len(args) == 1 or (len(args) == 2 and args[0] == "--"):
sys.exit(pass_read("get", args[-1]))
opts = parser_for_subcommands.parse_args()
args = None
if opts.subcommand == "get-or-list": if opts.subcommand == "get-or-list":
if opts.key: if opts.key:
sys.exit(pass_read("get", opts.key)) sys.exit(pass_read("get", opts.key))

View File

@ -19,7 +19,7 @@ elif [ "$cmd" == "get" ] ; then
tmp=$(mktemp) tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT trap 'rm -f "$tmp"' EXIT
ret=0 ; pass -- "$entry" 2> "$tmp" || ret=$? ret=0 ; pass -- "$entry" 2> "$tmp" || ret=$?
if grep -qF "$entry is not in the password store." "$tmp" ; then if grep -qF -- "$entry is not in the password store." "$tmp" ; then
cat "$tmp" >&2 cat "$tmp" >&2
exit 8 exit 8
fi fi

View File

@ -3,7 +3,7 @@
%define mybuildnumber %{?build_number}%{?!build_number:1} %define mybuildnumber %{?build_number}%{?!build_number:1}
Name: qubes-pass Name: qubes-pass
Version: 0.0.19 Version: 0.0.20
Release: %{mybuildnumber}%{?dist} Release: %{mybuildnumber}%{?dist}
Summary: Inter-VM pass password management for Qubes OS AppVMs and StandaloneVMs Summary: Inter-VM pass password management for Qubes OS AppVMs and StandaloneVMs
BuildArch: noarch BuildArch: noarch
@ -79,6 +79,9 @@ fi
%config(noreplace) %attr(0664, root, qubes) %{_sysconfdir}/qubes-rpc/policy/ruddo.PassManage %config(noreplace) %attr(0664, root, qubes) %{_sysconfdir}/qubes-rpc/policy/ruddo.PassManage
%changelog %changelog
* Sat Apr 18 2020 Manuel Amador (Rudd-O) <rudd-o@rudd-o.com>
- Correct issues with argument parsing.
* Sun Mar 07 2016 Manuel Amador (Rudd-O) <rudd-o@rudd-o.com> * Sun Mar 07 2016 Manuel Amador (Rudd-O) <rudd-o@rudd-o.com>
- Fixed bug in get-or-generate subcommand. - Fixed bug in get-or-generate subcommand.