diff --git a/dom0/aux-tools/create_apps_for_appvm.sh b/dom0/aux-tools/create_apps_for_appvm.sh index 0b6e53dd..0624162f 100755 --- a/dom0/aux-tools/create_apps_for_appvm.sh +++ b/dom0/aux-tools/create_apps_for_appvm.sh @@ -45,10 +45,13 @@ if [ "$SRCDIR" != "none" ]; then /usr/lib/qubes/convert_apptemplate2vm.sh /usr/share/qubes/qubes-appmenu-select.desktop $APPSDIR $VMNAME $VMDIR if [ "$VMTYPE" = "vm-templates" ]; then - /usr/lib/qubes/convert_dirtemplate2vm.sh /usr/share/qubes/qubes-templatevm.directory.template $APPSDIR/$VMNAME-vm.directory $VMNAME $VMDIR + DIR_TEMPLATE=/usr/share/qubes/qubes-templatevm.directory.template + elif [ "$VMTYPE" = "servicevms" ]; then + DIR_TEMPLATE=/usr/share/qubes/qubes-servicevm.directory.template else - /usr/lib/qubes/convert_dirtemplate2vm.sh /usr/share/qubes/qubes-vm.directory.template $APPSDIR/$VMNAME-vm.directory $VMNAME $VMDIR + DIR_TEMPLATE=/usr/share/qubes/qubes-vm.directory.template fi + /usr/lib/qubes/convert_dirtemplate2vm.sh $DIR_TEMPLATE $APPSDIR/$VMNAME-vm.directory $VMNAME $VMDIR fi echo "--> Adding Apps to the Menu..." diff --git a/dom0/misc/qubes-servicevm.directory.template b/dom0/misc/qubes-servicevm.directory.template new file mode 100644 index 00000000..74ce62f3 --- /dev/null +++ b/dom0/misc/qubes-servicevm.directory.template @@ -0,0 +1,5 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=Directory +Name=ServiceVM: %VMNAME% +Icon=%VMDIR%/icon.png diff --git a/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index 7e13c407..25634f0c 100755 --- a/dom0/qvm-core/qubes.py +++ b/dom0/qvm-core/qubes.py @@ -1286,9 +1286,14 @@ class QubesVm(object): return conf - def run(self, command, verbose = True, autostart = False, notify_function = None, passio = False, passio_popen = False, localcmd = None, wait = False, gui = True): - """command should be in form 'user:cmdline'""" + def run(self, command, verbose = True, autostart = False, notify_function = None, passio = False, passio_popen = False, passio_stderr=False, ignore_stderr=False, localcmd = None, wait = False, gui = True): + """command should be in form 'user:cmdline' + When passio_popen=True, popen object with stdout connected to pipe. + When additionally passio_stderr=True, stderr also is connected to pipe. + When ignore_stderr=True, stderr is connected to /dev/null. + """ + null = None if not self.is_running(): if not autostart: raise QubesException("VM not running") @@ -1315,12 +1320,28 @@ class QubesVm(object): if passio: os.execv(qrexec_client_path, args) exit(1) + + call_kwargs = {} + if ignore_stderr: + null = open("/dev/null", "w") + call_kwargs['stderr'] = null + if passio_popen: - p = subprocess.Popen (args, stdout=subprocess.PIPE) + popen_kwargs={'stdout': subprocess.PIPE} + if passio_stderr: + popen_kwargs['stderr'] = subprocess.PIPE + else: + popen_kwargs['stderr'] = call_kwargs.get('stderr', None) + p = subprocess.Popen (args, **popen_kwargs) + if null: + null.close() return p if not wait: args += ["-e"] - return subprocess.call(args) + retcode = subprocess.call(args, **call_kwargs) + if null: + null.close() + return retcode def attach_network(self, verbose = False, wait = True, netvm = None): if dry_run: @@ -1510,13 +1531,6 @@ class QubesVm(object): xc.domain_unpause(self.get_xid()) - def remove_from_disk(self): - if dry_run: - return - - - shutil.rmtree (self.dir_path) - def get_xml_attrs(self): attrs = {} attrs_config = self._get_attrs_config() @@ -1870,6 +1884,15 @@ class QubesNetVm(QubesVm): if not self.internal: self.create_appmenus (verbose, source_template=source_template) + def remove_from_disk(self): + if dry_run: + return + + if not self.internal: + self.remove_appmenus() + super(QubesNetVm, self).remove_from_disk() + + class QubesProxyVm(QubesNetVm): """ A class that represents a ProxyVM, ex FirewallVM. A child of QubesNetVM. diff --git a/dom0/qvm-tools/qubes-dom0-update b/dom0/qvm-tools/qubes-dom0-update index 6ff8603f..6a31ad22 100755 --- a/dom0/qvm-tools/qubes-dom0-update +++ b/dom0/qvm-tools/qubes-dom0-update @@ -1,6 +1,8 @@ #!/bin/bash UPDATEVM=`qubes-prefs --get updatevm` +UPDATES_STAT_FILE=/var/lib/qubes/updates/dom0-updates-available + if [ -z "$UPDATEVM" ]; then echo "UpdateVM not set, exiting" exit 1 @@ -73,7 +75,7 @@ echo "Checking for dom0 updates" >&2 # Start VM if not running already qvm-run -a $UPDATEVM true || exit 1 -/usr/lib/qubes/qrexec_client -d "$UPDATEVM" -l 'tar c /var/lib/rpm /etc/yum.repos.d /etc/yum.conf 2>/dev/null' 'user:tar x -C /var/lib/qubes/dom0-updates' +/usr/lib/qubes/qrexec_client -d "$UPDATEVM" -l 'tar c /var/lib/rpm /etc/yum.repos.d /etc/yum.conf 2>/dev/null' 'user:tar x -C /var/lib/qubes/dom0-updates' 2> /dev/null qvm-run --pass-io $UPDATEVM "/usr/lib/qubes/qubes_download_dom0_updates.sh --doit --nogui $ALL_OPTS" RETCODE=$? @@ -97,6 +99,7 @@ elif [ -f /var/lib/qubes/updates/repodata/repomd.xml ]; then yum $YUM_OPTS update fi fi + yum -q check-updates && rm $UPDATES_STAT_FILE else echo "No updates avaliable" >&2 fi diff --git a/dom0/qvm-tools/qvm-sync-appmenus b/dom0/qvm-tools/qvm-sync-appmenus index fa9db396..fef07274 100755 --- a/dom0/qvm-tools/qvm-sync-appmenus +++ b/dom0/qvm-tools/qvm-sync-appmenus @@ -62,7 +62,7 @@ def get_appmenus(xid): raise QubesException("Line count limit exceeded") else: p = subprocess.Popen ([qrexec_client_path, '-d', str(xid), - 'user:grep -H = /usr/share/applications/*.desktop'], stdout=subprocess.PIPE) + 'user:QUBESRPC qubes.GetAppmenus dom0'], stdout=subprocess.PIPE) while appmenus_line_count > 0: line = p.stdout.readline(appmenus_line_size) if line == "": diff --git a/dom0/qvm-tools/qvm-sync-clock b/dom0/qvm-tools/qvm-sync-clock index c162aa89..8066f09c 100755 --- a/dom0/qvm-tools/qvm-sync-clock +++ b/dom0/qvm-tools/qvm-sync-clock @@ -64,14 +64,14 @@ def main(): # Ignore retcode, try even if nm-online failed - user can setup network manually # on-online has timeout 30sec by default - net_vm.run('user:nm-online -x', verbose=verbose, wait=True) + net_vm.run('user:nm-online -x', verbose=verbose, wait=True, ignore_stderr=True) # Sync clock - if clock_vm.run('root:QUBESRPC qubes.SyncNtpClock dom0', verbose=verbose, wait=True) != 0: + if clock_vm.run('root:QUBESRPC qubes.SyncNtpClock dom0', verbose=verbose, wait=True, ignore_stderr=True) != 0: print >> sys.stderr, 'Time sync failed, aborting!' sys.exit(1) - p = clock_vm.run('user:date -u', verbose=verbose, passio_popen=True) + p = clock_vm.run('user:date -u', verbose=verbose, passio_popen=True, ignore_stderr=True) date_out = p.stdout.read(100) date_out = date_out.strip() if not re.match(r'^[A-Za-z]* [A-Za-z]* [ 0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [A-Z]* [0-9][0-9][0-9][0-9]$', date_out): diff --git a/misc/qubes_trigger_sync_appmenus.sh b/misc/qubes_trigger_sync_appmenus.sh index 5390c2d2..e848ea34 100755 --- a/misc/qubes_trigger_sync_appmenus.sh +++ b/misc/qubes_trigger_sync_appmenus.sh @@ -3,5 +3,5 @@ UPDATEABLE=`/usr/bin/xenstore-read qubes_vm_updateable` if [ "$UPDATEABLE" = "True" ]; then - /usr/lib/qubes/qrexec_client_vm dom0 qubes.SyncAppMenus /bin/grep -H = /usr/share/applications/*.desktop + /usr/lib/qubes/qrexec_client_vm dom0 qubes.SyncAppMenus /bin/sh /etc/qubes_rpc/qubes.GetAppmenus fi diff --git a/qrexec/qubes_rpc_multiplexer b/qrexec/qubes_rpc_multiplexer index 8f03137a..191be91b 100755 --- a/qrexec/qubes_rpc_multiplexer +++ b/qrexec/qubes_rpc_multiplexer @@ -5,8 +5,9 @@ if ! [ $# = 2 ] ; then exit 1 fi CFG_FILE=$QUBES_RPC/"$1" +export QREXEC_REMOTE_DOMAIN="$2" if [ -s "$CFG_FILE" ] ; then - exec $(cat "$CFG_FILE") "$2" + exec /bin/sh "$CFG_FILE" echo "$0: failed to execute handler for" "$1" >&2 exit 1 fi diff --git a/qubes_rpc/qfile-unpacker.c b/qubes_rpc/qfile-unpacker.c index eaa5c067..dd0a510d 100644 --- a/qubes_rpc/qfile-unpacker.c +++ b/qubes_rpc/qfile-unpacker.c @@ -51,13 +51,19 @@ int main(int argc, char ** argv) char *incoming_dir; int pipefds[2]; int uid; + char *remote_domain; pipe(pipefds); uid = prepare_creds_return_uid("user"); + remote_domain = getenv("QREXEC_REMOTE_DOMAIN"); + if (!remote_domain) { + gui_fatal("Cannot get remote domain name"); + exit(1); + } mkdir(INCOMING_DIR_ROOT, 0700); - asprintf(&incoming_dir, "%s/from-%s", INCOMING_DIR_ROOT, argv[1]); + asprintf(&incoming_dir, "%s/from-%s", INCOMING_DIR_ROOT, remote_domain); mkdir(incoming_dir, 0700); if (chdir(incoming_dir)) gui_fatal("Error chdir to %s", incoming_dir); diff --git a/qubes_rpc/qubes.GetAppmenus b/qubes_rpc/qubes.GetAppmenus new file mode 100644 index 00000000..cada68ca --- /dev/null +++ b/qubes_rpc/qubes.GetAppmenus @@ -0,0 +1,2 @@ +shopt -s nullglob +/bin/grep -H = /usr/share/applications/*.desktop /usr/local/share/applications/*.desktop 2> /dev/null diff --git a/qubes_rpc/qubes.VMShell b/qubes_rpc/qubes.VMShell index 7ca3b5e5..01dca2d7 100644 --- a/qubes_rpc/qubes.VMShell +++ b/qubes_rpc/qubes.VMShell @@ -1 +1 @@ -/usr/lib/qubes/vm-shell \ No newline at end of file +/bin/bash diff --git a/qubes_rpc/vm-shell b/qubes_rpc/vm-shell deleted file mode 100755 index d06e3986..00000000 --- a/qubes_rpc/vm-shell +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# just ignore the cmdline argument (the remote vm name) -exec /bin/bash diff --git a/rpm_spec/core-dom0.spec b/rpm_spec/core-dom0.spec index fe48739c..62aefa24 100644 --- a/rpm_spec/core-dom0.spec +++ b/rpm_spec/core-dom0.spec @@ -155,6 +155,7 @@ mkdir -p $RPM_BUILD_ROOT/usr/share/qubes/icons cp icons/*.png $RPM_BUILD_ROOT/usr/share/qubes/icons cp misc/qubes-vm.directory.template $RPM_BUILD_ROOT/usr/share/qubes/ cp misc/qubes-templatevm.directory.template $RPM_BUILD_ROOT/usr/share/qubes/ +cp misc/qubes-servicevm.directory.template $RPM_BUILD_ROOT/usr/share/qubes/ cp misc/qubes-dispvm.directory $RPM_BUILD_ROOT/usr/share/qubes/ cp misc/qubes-dispvm-firefox.desktop $RPM_BUILD_ROOT/usr/share/qubes/ cp misc/qubes-appmenu-select.desktop $RPM_BUILD_ROOT/usr/share/qubes/ @@ -365,6 +366,7 @@ fi /usr/share/qubes/icons/*.png /usr/share/qubes/qubes-vm.directory.template /usr/share/qubes/qubes-templatevm.directory.template +/usr/share/qubes/qubes-servicevm.directory.template /usr/share/qubes/qubes-dispvm.directory /usr/share/qubes/qubes-dispvm-firefox.desktop /usr/share/qubes/qubes-appmenu-select.desktop diff --git a/rpm_spec/core-vm.spec b/rpm_spec/core-vm.spec index f24c679b..7e2b0348 100644 --- a/rpm_spec/core-vm.spec +++ b/rpm_spec/core-vm.spec @@ -156,14 +156,14 @@ install qubes_rpc/wrap_in_html_if_url.sh $RPM_BUILD_ROOT/usr/lib/qubes install qubes_rpc/qvm-copy-to-vm.kde $RPM_BUILD_ROOT/usr/lib/qubes install qubes_rpc/qvm-copy-to-vm.gnome $RPM_BUILD_ROOT/usr/lib/qubes install qubes_rpc/{vm-file-editor,qfile-agent,qopen-in-vm,qfile-unpacker} $RPM_BUILD_ROOT/usr/lib/qubes -install qubes_rpc/{vm-shell,qrun-in-vm} $RPM_BUILD_ROOT/usr/lib/qubes +install qubes_rpc/qrun-in-vm $RPM_BUILD_ROOT/usr/lib/qubes install qubes_rpc/sync-ntp-clock $RPM_BUILD_ROOT/usr/lib/qubes install qubes_rpc/prepare-suspend $RPM_BUILD_ROOT/usr/lib/qubes install -d $RPM_BUILD_ROOT/%{kde_service_dir} install -m 0644 qubes_rpc/{qvm-copy.desktop,qvm-dvm.desktop} $RPM_BUILD_ROOT/%{kde_service_dir} install -d $RPM_BUILD_ROOT/etc/qubes_rpc install -m 0644 qubes_rpc/{qubes.Filecopy,qubes.OpenInVM,qubes.VMShell,qubes.SyncNtpClock} $RPM_BUILD_ROOT/etc/qubes_rpc -install -m 0644 qubes_rpc/{qubes.SuspendPre,qubes.SuspendPost} $RPM_BUILD_ROOT/etc/qubes_rpc +install -m 0644 qubes_rpc/{qubes.SuspendPre,qubes.SuspendPost,qubes.GetAppmenus} $RPM_BUILD_ROOT/etc/qubes_rpc install qrexec/qrexec_agent $RPM_BUILD_ROOT/usr/lib/qubes install qrexec/qrexec_client_vm $RPM_BUILD_ROOT/usr/lib/qubes @@ -188,13 +188,6 @@ install -D u2mfn/libu2mfn.so $RPM_BUILD_ROOT/%{_libdir}/libu2mfn.so %triggerin -- initscripts cp /usr/lib/qubes/serial.conf /etc/init/serial.conf -%triggerin -- systemd -# Disable pam_systemd - we (hopefully) don't need it, but it cause some minor -# problems (http://wiki.qubes-os.org/trac/ticket/607) -# /etc/pam.d/common-* are automatically (re)generated by authconfig, so its -# modification will not be persistent -> must be done this way -mv -f /%{_lib}/security/pam_systemd.so /%{_lib}/security/pam_systemd.so.disabled 2> /dev/null || : - %post # disable some Upstart services @@ -336,7 +329,6 @@ if [ "$1" = 0 ] ; then mv /var/lib/qubes/fstab.orig /etc/fstab mv /var/lib/qubes/removed-udev-scripts/* /etc/udev/rules.d/ mv /var/lib/qubes/serial.orig /etc/init/serial.conf - mv /%{_lib}/security/pam_systemd.so.disabled /%{_lib}/security/pam_systemd.so fi %postun @@ -371,6 +363,7 @@ rm -rf $RPM_BUILD_ROOT %dir /etc/qubes_rpc /etc/qubes_rpc/qubes.Filecopy /etc/qubes_rpc/qubes.OpenInVM +/etc/qubes_rpc/qubes.GetAppmenus /etc/qubes_rpc/qubes.VMShell /etc/qubes_rpc/qubes.SyncNtpClock /etc/qubes_rpc/qubes.SuspendPre @@ -419,7 +412,6 @@ rm -rf $RPM_BUILD_ROOT /usr/lib/qubes/serial.conf /usr/lib/qubes/setup_ip /usr/lib/qubes/vm-file-editor -/usr/lib/qubes/vm-shell /usr/lib/qubes/wrap_in_html_if_url.sh /usr/lib/yum-plugins/yum-qubes-hooks.py* /usr/sbin/qubes_firewall