From 06b6276c1ca638c0f451c668c026a9af82747781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Sat, 26 May 2018 01:39:07 +0200 Subject: [PATCH] qvm-open-in-vm: implement --view-only option Implement option to disallow (ignore in fact) modifications of file opened in another VM (including DispVM). This commit implements actual services part and handling in wrapping scripts. Fixes QubesOS/qubes-issues#1118 (cherry picked from commit ef557ca4601ecbd4a3d5dc8f9429c6b172bc402d) --- qubes-rpc/qopen-in-vm.c | 35 +++++++++++++++++++++++++++-------- qubes-rpc/qvm-open-in-dvm | 7 ++++--- qubes-rpc/qvm-open-in-vm | 33 +++++++++++++++++++++++++++------ 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/qubes-rpc/qopen-in-vm.c b/qubes-rpc/qopen-in-vm.c index 45949df..8d2b24f 100644 --- a/qubes-rpc/qopen-in-vm.c +++ b/qubes-rpc/qopen-in-vm.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "dvm2.h" @@ -92,17 +93,35 @@ void recv_file(const char *fname) actually_recv_file(fname, tempfile, tmpfd); } -void talk_to_daemon(const char *fname) -{ - send_file(fname); - recv_file(fname); -} - int main(int argc, char ** argv) { + char *fname; + int view_only = 0; + int ret; + const struct option opts[] = { + {"view-only", no_argument, &view_only, 1}, + {0} + }; + + while ((ret=getopt_long(argc, argv, "", opts, NULL)) != -1) { + if (ret == '?') { + exit(2); + } + } + signal(SIGPIPE, SIG_IGN); - if (argc!=2) + + if (optind >= argc) gui_fatal("OpenInVM - no file given?"); - talk_to_daemon(argv[1]); + fname = argv[optind]; + send_file(fname); + if (!view_only) { + recv_file(fname); + } else { + /* discard received data */ + int null_fd = open("/dev/null", O_WRONLY); + copy_fd_all(null_fd, 0); + close(null_fd); + } return 0; } diff --git a/qubes-rpc/qvm-open-in-dvm b/qubes-rpc/qvm-open-in-dvm index 3a01cdf..8046858 100755 --- a/qubes-rpc/qvm-open-in-dvm +++ b/qubes-rpc/qvm-open-in-dvm @@ -20,9 +20,10 @@ # # -if ! [ $# = 1 ] ; then - echo "Usage: $0 filename" +if ! [ $# = 1 ] && ! [ $# = 2 ]; then + echo "Usage: $0 [--view-only] filename" exit 1 fi -exec qvm-open-in-vm '$dispvm' "$1" +# shellcheck disable=SC2016 +exec qvm-open-in-vm '$dispvm' "$@" diff --git a/qubes-rpc/qvm-open-in-vm b/qubes-rpc/qvm-open-in-vm index d109e6b..ead9acf 100755 --- a/qubes-rpc/qvm-open-in-vm +++ b/qubes-rpc/qvm-open-in-vm @@ -20,16 +20,37 @@ # # -if ! [ $# = 2 ] ; then - echo "Usage: $0 vmname filename" - exit 1 +usage() { + echo "Usage: $0 [--view-only] vmname filename" + exit 2 +} + +qopen_opts= +target= +filename= + +while [ $# -gt 0 ]; do + if [ "x$1" = "x--view-only" ]; then + qopen_opts=--view-only + elif [ -z "$target" ]; then + target="$1" + elif [ -z "$filename" ]; then + filename="$1" + else + usage + fi + shift +done + +if [ -z "$target" ] || [ -z "$filename" ]; then + usage fi -case "$2" in +case "$filename" in *://*) - exec /usr/lib/qubes/qrexec-client-vm "$1" qubes.OpenURL /bin/echo "$2" + exec /usr/lib/qubes/qrexec-client-vm "$target" qubes.OpenURL /bin/echo "$filename" ;; *) - exec /usr/lib/qubes/qrexec-client-vm "$1" qubes.OpenInVM "/usr/lib/qubes/qopen-in-vm" "$2" + exec /usr/lib/qubes/qrexec-client-vm "$target" qubes.OpenInVM "/usr/lib/qubes/qopen-in-vm" $qopen_opts "$filename" ;; esac