diff --git a/doc/conf.py b/doc/conf.py index 63bed890..809d6ba0 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -292,6 +292,9 @@ man_pages = [ ('manpages/qubes-prefs', 'qubes-prefs', u'Display system-wide Qubes settings', _man_pages_author, 1), + + ('manpages/qubesd-query', 'qubesd-query', + u'Low-level qubesd interrogation tool', _man_pages_author, 1), ] if os.path.exists('sandbox.rst'): diff --git a/doc/manpages/qubesd-query.rst b/doc/manpages/qubesd-query.rst new file mode 100644 index 00000000..396b0e78 --- /dev/null +++ b/doc/manpages/qubesd-query.rst @@ -0,0 +1,42 @@ +.. program:: qubesd-query + +:program:`qubesd-query` -- low-level qubesd interrogation tool +============================================================== + +Synopsis +-------- + +:command:`qubesd-query` [-h] [--connect *PATH*] *SRC* *METHOD* *DEST* [*ARGUMENT*] + +Options +------- + +.. option:: --help, -h + + Show the help message and exit. + +.. option:: --connect=PATH, -c PATH + + Change path to qubesd UNIX socket from default. + +.. option:: --empty, -e + + Send empty payload. Do not attempt to read anything from standard input, but + send the request immediately. + +Description +----------- + +This tool is used to directly invoke qubesd. The parameters of RPC call shall be +given as arguments to the command. Payload should be written to standard input. +Result can be read from standard output. + +Authors +------- + +| Joanna Rutkowska +| Rafal Wojtczuk +| Marek Marczykowski +| Wojtek Porczyk + +.. vim: ts=3 sw=3 et tw=80 diff --git a/doc/skel-manpage.py b/doc/skel-manpage.py index afd62912..c650ebba 100755 --- a/doc/skel-manpage.py +++ b/doc/skel-manpage.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import os import sys diff --git a/qubes/tools/qubesd_query.py b/qubes/tools/qubesd_query.py new file mode 100644 index 00000000..69edcd4d --- /dev/null +++ b/qubes/tools/qubesd_query.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3.6 +# pylint: disable=deprecated-method + +import argparse +import asyncio +import signal +import sys + +QUBESD_SOCK = '/var/run/qubesd.sock' + +try: + asyncio.ensure_future +except AttributeError: + asyncio.ensure_future = asyncio.async + +parser = argparse.ArgumentParser( + description='low-level qubesd interrogation tool') + +parser.add_argument('--connect', '-c', metavar='PATH', + dest='socket', + default=QUBESD_SOCK, + help='path to qubesd UNIX socket (default: %(default)s)') + +parser.add_argument('--empty', '-e', + dest='payload', + action='store_false', default=True, + help='do not read from stdin and send empty payload') + +parser.add_argument('src', metavar='SRC', + help='source qube') +parser.add_argument('method', metavar='METHOD', + help='method name') +parser.add_argument('dest', metavar='DEST', + help='destination qube') +parser.add_argument('arg', metavar='ARGUMENT', + nargs='?', default='', + help='argument to method') + +def sighandler(loop, signame, coro): + print('caught {}, exiting'.format(signame)) + coro.cancel() + loop.stop() + +@asyncio.coroutine +def qubesd_client(socket, payload, *args): + try: + reader, writer = yield from asyncio.open_unix_connection(socket) + except asyncio.CancelledError: + return + + for arg in args: + writer.write(arg.encode('ascii')) + writer.write(b'\0') + writer.write(payload) + writer.write_eof() + + try: + data = yield from reader.read() + sys.stdout.buffer.write(data) # pylint: disable=no-member + except asyncio.CancelledError: + return + finally: + writer.close() + +def main(args=None): + args = parser.parse_args(args) + loop = asyncio.get_event_loop() + + # pylint: disable=no-member + payload = sys.stdin.buffer.read() if args.payload else b'' + # pylint: enable=no-member + + coro = asyncio.ensure_future(qubesd_client(args.socket, payload, + args.src, args.method, args.dest, args.arg)) + + for signame in ('SIGINT', 'SIGTERM'): + loop.add_signal_handler(getattr(signal, signame), + sighandler, loop, signame, coro) + + try: + loop.run_until_complete(coro) + finally: + loop.close() + +if __name__ == '__main__': + main() diff --git a/rpm_spec/core-dom0.spec b/rpm_spec/core-dom0.spec index eaf9776f..9077cb9c 100644 --- a/rpm_spec/core-dom0.spec +++ b/rpm_spec/core-dom0.spec @@ -208,7 +208,7 @@ fi /usr/bin/qvm-* /usr/bin/qubes-* /usr/bin/qmemmand -/usr/bin/qubesd +/usr/bin/qubesd* %dir %{python3_sitelib}/qubes-*.egg-info %{python3_sitelib}/qubes-*.egg-info/* @@ -268,6 +268,7 @@ fi %{python3_sitelib}/qubes/tools/qubes_monitor_layout_notify.py %{python3_sitelib}/qubes/tools/qubes_prefs.py %{python3_sitelib}/qubes/tools/qubesd.py +%{python3_sitelib}/qubes/tools/qubesd_query.py %{python3_sitelib}/qubes/tools/qvm_block.py %{python3_sitelib}/qubes/tools/qvm_backup.py %{python3_sitelib}/qubes/tools/qvm_backup_restore.py