commit
						c4c28605c9
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -6,3 +6,4 @@ deb/*
 | 
				
			|||||||
*.o
 | 
					*.o
 | 
				
			||||||
.coverage
 | 
					.coverage
 | 
				
			||||||
*.egg-info
 | 
					*.egg-info
 | 
				
			||||||
 | 
					__pycache__
 | 
				
			||||||
 | 
				
			|||||||
@ -5,11 +5,11 @@ python: '3.5'
 | 
				
			|||||||
install: git clone https://github.com/QubesOS/qubes-builder ~/qubes-builder
 | 
					install: git clone https://github.com/QubesOS/qubes-builder ~/qubes-builder
 | 
				
			||||||
script: ~/qubes-builder/scripts/travis-build
 | 
					script: ~/qubes-builder/scripts/travis-build
 | 
				
			||||||
env:
 | 
					env:
 | 
				
			||||||
 - DISTS_VM=fc24 USE_QUBES_REPO_VERSION=4.0 USE_QUBES_REPO_TESTING=1
 | 
					 | 
				
			||||||
 - DISTS_VM=fc25 USE_QUBES_REPO_VERSION=4.0 USE_QUBES_REPO_TESTING=1
 | 
					 | 
				
			||||||
 - DISTS_VM=fc26 USE_QUBES_REPO_VERSION=4.0 USE_QUBES_REPO_TESTING=1
 | 
					 - DISTS_VM=fc26 USE_QUBES_REPO_VERSION=4.0 USE_QUBES_REPO_TESTING=1
 | 
				
			||||||
 | 
					 - DISTS_VM=fc27 USE_QUBES_REPO_VERSION=4.0 USE_QUBES_REPO_TESTING=1
 | 
				
			||||||
 - DISTS_VM=jessie USE_QUBES_REPO_VERSION=4.0 USE_QUBES_REPO_TESTING=1
 | 
					 - DISTS_VM=jessie USE_QUBES_REPO_VERSION=4.0 USE_QUBES_REPO_TESTING=1
 | 
				
			||||||
 - DISTS_VM=stretch USE_QUBES_REPO_VERSION=4.0 USE_QUBES_REPO_TESTING=1
 | 
					 - DISTS_VM=stretch USE_QUBES_REPO_VERSION=4.0 USE_QUBES_REPO_TESTING=1
 | 
				
			||||||
 | 
					 - DISTS_VM=centos7 USE_QUBES_REPO_VERSION=4.0 USE_QUBES_REPO_TESTING=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  include:
 | 
					  include:
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										34
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								Makefile
									
									
									
									
									
								
							@ -5,15 +5,16 @@ VERSION := $(shell cat version)
 | 
				
			|||||||
DIST ?= fc18
 | 
					DIST ?= fc18
 | 
				
			||||||
KDESERVICEDIR ?= /usr/share/kde4/services
 | 
					KDESERVICEDIR ?= /usr/share/kde4/services
 | 
				
			||||||
KDE5SERVICEDIR ?= /usr/share/kservices5/ServiceMenus/
 | 
					KDE5SERVICEDIR ?= /usr/share/kservices5/ServiceMenus/
 | 
				
			||||||
 | 
					APPLICATIONSDIR ?= /usr/share/applications
 | 
				
			||||||
SBINDIR ?= /usr/sbin
 | 
					SBINDIR ?= /usr/sbin
 | 
				
			||||||
BINDIR ?= /usr/bin
 | 
					BINDIR ?= /usr/bin
 | 
				
			||||||
LIBDIR ?= /usr/lib
 | 
					LIBDIR ?= /usr/lib
 | 
				
			||||||
SYSLIBDIR ?= /lib
 | 
					SYSLIBDIR ?= /lib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PYTHON ?= /usr/bin/python2
 | 
					PYTHON ?= /usr/bin/python2
 | 
				
			||||||
PYTHON_SITEARCH = `python2 -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1)'`
 | 
					PYTHON_SITEARCH = $(shell python2 -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1)')
 | 
				
			||||||
PYTHON2_SITELIB = `python2 -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib()'`
 | 
					PYTHON2_SITELIB = $(shell python2 -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib()')
 | 
				
			||||||
PYTHON3_SITELIB = `python3 -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())'`
 | 
					PYTHON3_SITELIB = $(shell python3 -c 'import distutils.sysconfig; print(distutils.sysconfig.get_python_lib())')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# This makefile uses some bash-isms, make uses /bin/sh by default.
 | 
					# This makefile uses some bash-isms, make uses /bin/sh by default.
 | 
				
			||||||
SHELL = /bin/bash
 | 
					SHELL = /bin/bash
 | 
				
			||||||
@ -46,6 +47,12 @@ clean:
 | 
				
			|||||||
	make -C misc clean
 | 
						make -C misc clean
 | 
				
			||||||
	make -C qrexec clean
 | 
						make -C qrexec clean
 | 
				
			||||||
	make -C qubes-rpc clean
 | 
						make -C qubes-rpc clean
 | 
				
			||||||
 | 
						make -C doc clean
 | 
				
			||||||
 | 
						rm -rf qubesagent/*.pyc qubesagent/__pycache__
 | 
				
			||||||
 | 
						rm -rf test-packages/__pycache__
 | 
				
			||||||
 | 
						rm -rf test-packages/qubesagent.egg-info
 | 
				
			||||||
 | 
						rm -rf __pycache__
 | 
				
			||||||
 | 
						rm -f .coverage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all:
 | 
					all:
 | 
				
			||||||
	make -C misc
 | 
						make -C misc
 | 
				
			||||||
@ -77,6 +84,10 @@ ifeq ($(shell lsb_release -is), Ubuntu)
 | 
				
			|||||||
    SYSTEM_DROPINS := $(strip $(patsubst crond.service, cron.service, $(SYSTEM_DROPINS)))
 | 
					    SYSTEM_DROPINS := $(strip $(patsubst crond.service, cron.service, $(SYSTEM_DROPINS)))
 | 
				
			||||||
    SYSTEM_DROPINS += anacron.service
 | 
					    SYSTEM_DROPINS += anacron.service
 | 
				
			||||||
    SYSTEM_DROPINS += anacron-resume.service
 | 
					    SYSTEM_DROPINS += anacron-resume.service
 | 
				
			||||||
 | 
					    SYSTEM_DROPINS += netfilter-persistent.service
 | 
				
			||||||
 | 
					    SYSTEM_DROPINS += exim4.service
 | 
				
			||||||
 | 
					    SYSTEM_DROPINS += avahi-daemon.service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Debian Dropins
 | 
					# Debian Dropins
 | 
				
			||||||
@ -208,7 +219,7 @@ install-common: install-doc
 | 
				
			|||||||
		misc/20_org.mate.NotificationDaemon.qubes.gschema.override \
 | 
							misc/20_org.mate.NotificationDaemon.qubes.gschema.override \
 | 
				
			||||||
		misc/20_org.gnome.desktop.wm.preferences.qubes.gschema.override \
 | 
							misc/20_org.gnome.desktop.wm.preferences.qubes.gschema.override \
 | 
				
			||||||
		$(DESTDIR)/usr/share/glib-2.0/schemas/
 | 
							$(DESTDIR)/usr/share/glib-2.0/schemas/
 | 
				
			||||||
	install -g user -m 2775 -d $(DESTDIR)/var/lib/qubes/dom0-updates
 | 
						install -m 2775 -d $(DESTDIR)/var/lib/qubes/dom0-updates
 | 
				
			||||||
	install -D -m 0644 misc/qubes-master-key.asc $(DESTDIR)/usr/share/qubes/qubes-master-key.asc
 | 
						install -D -m 0644 misc/qubes-master-key.asc $(DESTDIR)/usr/share/qubes/qubes-master-key.asc
 | 
				
			||||||
	install misc/resize-rootfs $(DESTDIR)$(LIBDIR)/qubes/
 | 
						install misc/resize-rootfs $(DESTDIR)$(LIBDIR)/qubes/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -223,6 +234,8 @@ install-common: install-doc
 | 
				
			|||||||
	install -d $(DESTDIR)$(BINDIR)
 | 
						install -d $(DESTDIR)$(BINDIR)
 | 
				
			||||||
	install -m 0755 misc/qubes-session-autostart $(DESTDIR)$(BINDIR)/qubes-session-autostart
 | 
						install -m 0755 misc/qubes-session-autostart $(DESTDIR)$(BINDIR)/qubes-session-autostart
 | 
				
			||||||
	install -m 0755 misc/qvm-features-request $(DESTDIR)$(BINDIR)/qvm-features-request
 | 
						install -m 0755 misc/qvm-features-request $(DESTDIR)$(BINDIR)/qvm-features-request
 | 
				
			||||||
 | 
						install -m 0755 misc/qubes-run-terminal $(DESTDIR)/$(BINDIR)
 | 
				
			||||||
 | 
						install -D -m 0755 misc/qubes-run-terminal.desktop $(DESTDIR)/$(APPLICATIONSDIR)/qubes-run-terminal.desktop
 | 
				
			||||||
	install -m 0755 qubes-rpc/qvm-sync-clock $(DESTDIR)$(BINDIR)/qvm-sync-clock
 | 
						install -m 0755 qubes-rpc/qvm-sync-clock $(DESTDIR)$(BINDIR)/qvm-sync-clock
 | 
				
			||||||
	install qubes-rpc/{qvm-open-in-dvm,qvm-open-in-vm,qvm-copy-to-vm,qvm-run-vm} $(DESTDIR)/usr/bin
 | 
						install qubes-rpc/{qvm-open-in-dvm,qvm-open-in-vm,qvm-copy-to-vm,qvm-run-vm} $(DESTDIR)/usr/bin
 | 
				
			||||||
	install qubes-rpc/qvm-copy $(DESTDIR)/usr/bin
 | 
						install qubes-rpc/qvm-copy $(DESTDIR)/usr/bin
 | 
				
			||||||
@ -287,23 +300,10 @@ install-common: install-doc
 | 
				
			|||||||
	install -d $(DESTDIR)/usr/share/nautilus-python/extensions
 | 
						install -d $(DESTDIR)/usr/share/nautilus-python/extensions
 | 
				
			||||||
	install -m 0644 qubes-rpc/*_nautilus.py $(DESTDIR)/usr/share/nautilus-python/extensions
 | 
						install -m 0644 qubes-rpc/*_nautilus.py $(DESTDIR)/usr/share/nautilus-python/extensions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(findstring CentOS,$(shell cat /etc/redhat-release)),)
 | 
					 | 
				
			||||||
	install -D -m 0644 misc/dconf-profile-user $(DESTDIR)/etc/dconf/profile/user
 | 
					 | 
				
			||||||
	install -D -m 0644 misc/dconf-db-local-dpi $(DESTDIR)/etc/dconf/db/local.d/dpi
 | 
						install -D -m 0644 misc/dconf-db-local-dpi $(DESTDIR)/etc/dconf/db/local.d/dpi
 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	install -D -m 0755 misc/qubes-desktop-run $(DESTDIR)$(BINDIR)/qubes-desktop-run
 | 
						install -D -m 0755 misc/qubes-desktop-run $(DESTDIR)$(BINDIR)/qubes-desktop-run
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mkdir -p $(DESTDIR)/$(PYTHON_SITEARCH)/qubes/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ifeq ($(shell lsb_release -is), Debian)
 | 
					 | 
				
			||||||
	install -m 0644 misc/qubesxdg.py $(DESTDIR)/$(PYTHON2_SITELIB)/
 | 
					 | 
				
			||||||
else ifeq ($(shell lsb_release -is), Ubuntu)
 | 
					 | 
				
			||||||
	install -m 0644 misc/qubesxdg.py $(DESTDIR)/$(PYTHON2_SITELIB)/
 | 
					 | 
				
			||||||
else
 | 
					 | 
				
			||||||
	install -m 0644 misc/py2/qubesxdg.py* $(DESTDIR)/$(PYTHON2_SITELIB)/
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	install -d $(DESTDIR)/mnt/removable
 | 
						install -d $(DESTDIR)/mnt/removable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	install -D -m 0644 misc/xorg-preload-apps.conf $(DESTDIR)/etc/X11/xorg-preload-apps.conf
 | 
						install -D -m 0644 misc/xorg-preload-apps.conf $(DESTDIR)/etc/X11/xorg-preload-apps.conf
 | 
				
			||||||
 | 
				
			|||||||
@ -82,6 +82,14 @@ update_qubesconfig() {
 | 
				
			|||||||
    #/usr/lib/qubes/update-proxy-configs
 | 
					    #/usr/lib/qubes/update-proxy-configs
 | 
				
			||||||
    # Archlinux pacman configuration is handled in update_finalize
 | 
					    # Archlinux pacman configuration is handled in update_finalize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ! [ -r /etc/dconf/profile/user ]; then
 | 
				
			||||||
 | 
					        mkdir -p /etc/dconf/profile
 | 
				
			||||||
 | 
					        echo "user-db:user" >> /etc/dconf/profile/user
 | 
				
			||||||
 | 
					        echo "system-db:local" >> /etc/dconf/profile/user
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dconf update &> /dev/null || :
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Location of files which contains list of protected files
 | 
					    # Location of files which contains list of protected files
 | 
				
			||||||
    mkdir -p /etc/qubes/protected-files.d
 | 
					    mkdir -p /etc/qubes/protected-files.d
 | 
				
			||||||
    # shellcheck source=init/functions
 | 
					    # shellcheck source=init/functions
 | 
				
			||||||
@ -324,6 +332,8 @@ post_install() {
 | 
				
			|||||||
        cp /etc/init/serial.conf /var/lib/qubes/serial.orig
 | 
					        cp /etc/init/serial.conf /var/lib/qubes/serial.orig
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    chgrp user /var/lib/qubes/dom0-updates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Remove most of the udev scripts to speed up the VM boot time
 | 
					    # Remove most of the udev scripts to speed up the VM boot time
 | 
				
			||||||
    # Just leave the xen* scripts, that are needed if this VM was
 | 
					    # Just leave the xen* scripts, that are needed if this VM was
 | 
				
			||||||
    # ever used as a net backend (e.g. as a VPN domain in the future)
 | 
					    # ever used as a net backend (e.g. as a VPN domain in the future)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										136
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										136
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,139 @@
 | 
				
			|||||||
 | 
					qubes-core-agent (4.0.31-1) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * debian: add Depends: qubesdb-vm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>  Fri, 15 Jun 2018 14:32:23 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qubes-core-agent (4.0.30-1) wheezy; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Christopher Laprise ]
 | 
				
			||||||
 | 
					  * Fixes issue #3939
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>  Tue, 05 Jun 2018 01:39:04 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qubes-core-agent (4.0.29-1) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Drop leftovers of qubes-netwatcher service
 | 
				
			||||||
 | 
					  * qrexec: fix handling remote domain death
 | 
				
			||||||
 | 
					  * network: use iptables-restore --wait if available
 | 
				
			||||||
 | 
					  * rpm: add BR: systemd for pre/post install macros
 | 
				
			||||||
 | 
					  * qubes-rpc: fix code style - indent with spaces
 | 
				
			||||||
 | 
					  * qvm-open-in-vm: implement --view-only option
 | 
				
			||||||
 | 
					  * qvm-open-in-vm: mark file as read-only if opened with --view-only
 | 
				
			||||||
 | 
					  * Add file managers integration for qvm-open-in-dvm --view-only
 | 
				
			||||||
 | 
					  * Add build-time assert for filename buffer size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>  Tue, 29 May 2018 00:40:11 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qubes-core-agent (4.0.28-1) wheezy; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Peter Gerber ]
 | 
				
			||||||
 | 
					  * Qubes firewall: correct syntax for icmpv6 rejects
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>  Thu, 10 May 2018 12:21:39 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qubes-core-agent (4.0.27-1) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ X4lldux ]
 | 
				
			||||||
 | 
					  * Move/Copy many files in one step via nautilus extension
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Marek Marczykowski-Górecki ]
 | 
				
			||||||
 | 
					  * centos: exclude only dconf user profile, keep dpi config
 | 
				
			||||||
 | 
					  * travis: add centos7
 | 
				
			||||||
 | 
					  * Fix packaging: 'user' group, BACKEND_VMM var
 | 
				
			||||||
 | 
					  * Create /etc/dconf/profile/user dynamically, if not present
 | 
				
			||||||
 | 
					  * Require dconf utility to (re)build /etc/dconf/db/local
 | 
				
			||||||
 | 
					  * Fix make clean
 | 
				
			||||||
 | 
					  * qubes-firewall: reject packets instead of dropping
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>  Wed, 02 May 2018 05:05:33 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qubes-core-agent (4.0.26-1) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Change repository URLs to https
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>  Sun, 22 Apr 2018 00:29:02 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qubes-core-agent (4.0.25-1) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Marek Marczykowski-Górecki ]
 | 
				
			||||||
 | 
					  * debian: don't call dconf if it isn't installed
 | 
				
			||||||
 | 
					  * qrexec: add qrexec-client-vm --buffer-size option
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ unman ]
 | 
				
			||||||
 | 
					  * Add missing services in Ubuntu templates.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Simon Gaiser ]
 | 
				
			||||||
 | 
					  * qrexec-fork-server: Always initialize addrlen argument of accept()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Marek Marczykowski-Górecki ]
 | 
				
			||||||
 | 
					  * qrexec: fix arguments handling
 | 
				
			||||||
 | 
					  * Move 'qubesxdg' into qubesagent python package
 | 
				
			||||||
 | 
					  * Fix shell calls in Makefile
 | 
				
			||||||
 | 
					  * Fix waiting for application exit in qubesagent.xdg.launch
 | 
				
			||||||
 | 
					  * Load only test_* files when looking for tests (python)
 | 
				
			||||||
 | 
					  * qubes-session-autostart: do not wait for applications exit
 | 
				
			||||||
 | 
					  * Do not start dkms.service
 | 
				
			||||||
 | 
					  * network: do not assume IPv6 gateway is a link-local address
 | 
				
			||||||
 | 
					  * qubes-firewall: handle only traffic originating from VMs
 | 
				
			||||||
 | 
					  * network: make sure static NM configuration is created before NM
 | 
				
			||||||
 | 
					    start
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Davíð Steinn Geirsson ]
 | 
				
			||||||
 | 
					  * Add misc/qubes-run-terminal to launch any available terminal
 | 
				
			||||||
 | 
					    emulator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Frédéric Pierret ]
 | 
				
			||||||
 | 
					  * Create .spec.in and Source0
 | 
				
			||||||
 | 
					  * Remove _builddir
 | 
				
			||||||
 | 
					  * spec.in: add changelog placeholder
 | 
				
			||||||
 | 
					  * spec.in: fix %if expressions and remove useless conditions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Vladimir Lushnikov ]
 | 
				
			||||||
 | 
					  * Problem: Unable to use pkg.install with Salt in dom0 when using
 | 
				
			||||||
 | 
					    UpdateVM that has only yum due to incorrect options passed by Salt
 | 
				
			||||||
 | 
					    assuming dnf presence
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Marek Marczykowski-Górecki ]
 | 
				
			||||||
 | 
					  * Use only /etc/skel to provision user's home directory of new VM
 | 
				
			||||||
 | 
					  * Update gitignore and make clean target
 | 
				
			||||||
 | 
					  * qubes-firewall: signal service readiness only after initial scripts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Frédéric Pierret ]
 | 
				
			||||||
 | 
					  * Fix GCC8 warnings
 | 
				
			||||||
 | 
					  * Add missing python-setuptools dependency
 | 
				
			||||||
 | 
					  * Use %{python3_pkgversion} instead of duplicating python3 targets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Marek Marczykowski-Górecki ]
 | 
				
			||||||
 | 
					  * travis: update Fedora versions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>  Sat, 21 Apr 2018 15:10:20 +0200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qubes-core-agent (4.0.24-1) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Marek Marczykowski-Górecki ]
 | 
				
			||||||
 | 
					  * Drop Fedora < 22 support
 | 
				
			||||||
 | 
					  * Call qubes.PostInstall service to notify dom0 about all
 | 
				
			||||||
 | 
					    apps/features
 | 
				
			||||||
 | 
					  * dom0-updates: refactor for ease adding new actions with old yum
 | 
				
			||||||
 | 
					  * dom0-update: add some approximation of 'list', 'search' and
 | 
				
			||||||
 | 
					    'reinstall'
 | 
				
			||||||
 | 
					  * Drop fakeroot for list/search actions on Debian
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Rusty Bird ]
 | 
				
			||||||
 | 
					  * Really enable qubes-sync-time.timer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Frédéric Pierret ]
 | 
				
			||||||
 | 
					  * centos: fix conflict with dconf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ Marek Marczykowski-Górecki ]
 | 
				
			||||||
 | 
					  * Speed up initial /rw setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [ awokd ]
 | 
				
			||||||
 | 
					  * reinstal -> reinstall
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>  Tue, 27 Feb 2018 15:17:51 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qubes-core-agent (4.0.23-1) unstable; urgency=medium
 | 
					qubes-core-agent (4.0.23-1) unstable; urgency=medium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  * qrexec: launch services in login shell
 | 
					  * qrexec: launch services in login shell
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@ -26,6 +26,7 @@ Vcs-Git: https://github.com/QubesOS/qubes-core-agent-linux
 | 
				
			|||||||
Package: qubes-core-agent
 | 
					Package: qubes-core-agent
 | 
				
			||||||
Architecture: any
 | 
					Architecture: any
 | 
				
			||||||
Depends:
 | 
					Depends:
 | 
				
			||||||
 | 
					    dconf-cli,
 | 
				
			||||||
    dmsetup,
 | 
					    dmsetup,
 | 
				
			||||||
    gawk,
 | 
					    gawk,
 | 
				
			||||||
    imagemagick,
 | 
					    imagemagick,
 | 
				
			||||||
@ -45,6 +46,7 @@ Depends:
 | 
				
			|||||||
    python-dbus,
 | 
					    python-dbus,
 | 
				
			||||||
    qubes-utils (>= 3.1.3),
 | 
					    qubes-utils (>= 3.1.3),
 | 
				
			||||||
    qubes-core-agent-qrexec,
 | 
					    qubes-core-agent-qrexec,
 | 
				
			||||||
 | 
					    qubesdb-vm,
 | 
				
			||||||
    systemd,
 | 
					    systemd,
 | 
				
			||||||
    x11-xserver-utils,
 | 
					    x11-xserver-utils,
 | 
				
			||||||
    xdg-user-dirs,
 | 
					    xdg-user-dirs,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								debian/qubes-core-agent.install
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								debian/qubes-core-agent.install
									
									
									
									
										vendored
									
									
								
							@ -3,7 +3,6 @@ etc/apt/apt.conf.d/00notify-hook
 | 
				
			|||||||
etc/apt/apt.conf.d/70no-unattended
 | 
					etc/apt/apt.conf.d/70no-unattended
 | 
				
			||||||
etc/apt/sources.list.d/qubes-r4.list
 | 
					etc/apt/sources.list.d/qubes-r4.list
 | 
				
			||||||
etc/apt/trusted.gpg.d/qubes-archive-keyring.gpg
 | 
					etc/apt/trusted.gpg.d/qubes-archive-keyring.gpg
 | 
				
			||||||
etc/dconf/profile/user
 | 
					 | 
				
			||||||
etc/dconf/db/local.d/dpi
 | 
					etc/dconf/db/local.d/dpi
 | 
				
			||||||
etc/default/grub.d/30-qubes.cfg
 | 
					etc/default/grub.d/30-qubes.cfg
 | 
				
			||||||
etc/fstab
 | 
					etc/fstab
 | 
				
			||||||
@ -92,6 +91,7 @@ lib/systemd/system/systemd-timesyncd.service.d/30_qubes.conf
 | 
				
			|||||||
usr/bin/qubes-desktop-run
 | 
					usr/bin/qubes-desktop-run
 | 
				
			||||||
usr/bin/qubes-open
 | 
					usr/bin/qubes-open
 | 
				
			||||||
usr/bin/qubes-session-autostart
 | 
					usr/bin/qubes-session-autostart
 | 
				
			||||||
 | 
					usr/bin/qubes-run-terminal
 | 
				
			||||||
usr/bin/qvm-copy
 | 
					usr/bin/qvm-copy
 | 
				
			||||||
usr/bin/qvm-copy-to-vm
 | 
					usr/bin/qvm-copy-to-vm
 | 
				
			||||||
usr/bin/qvm-features-request
 | 
					usr/bin/qvm-features-request
 | 
				
			||||||
@ -102,7 +102,6 @@ usr/bin/qvm-open-in-vm
 | 
				
			|||||||
usr/bin/qvm-run-vm
 | 
					usr/bin/qvm-run-vm
 | 
				
			||||||
usr/bin/qvm-sync-clock
 | 
					usr/bin/qvm-sync-clock
 | 
				
			||||||
usr/bin/xenstore-watch-qubes
 | 
					usr/bin/xenstore-watch-qubes
 | 
				
			||||||
usr/lib/python2.7/dist-packages/qubesxdg.py
 | 
					 | 
				
			||||||
usr/lib/python2.7/dist-packages/qubesagent-*.egg-info/*
 | 
					usr/lib/python2.7/dist-packages/qubesagent-*.egg-info/*
 | 
				
			||||||
usr/lib/python2.7/dist-packages/qubesagent/*
 | 
					usr/lib/python2.7/dist-packages/qubesagent/*
 | 
				
			||||||
usr/lib/qubes-bind-dirs.d/30_cron.conf
 | 
					usr/lib/qubes-bind-dirs.d/30_cron.conf
 | 
				
			||||||
@ -142,6 +141,7 @@ usr/lib/systemd/user/pulseaudio.socket.d/30_qubes.conf
 | 
				
			|||||||
usr/share/glib-2.0/schemas/*
 | 
					usr/share/glib-2.0/schemas/*
 | 
				
			||||||
usr/share/kde4/services/*.desktop
 | 
					usr/share/kde4/services/*.desktop
 | 
				
			||||||
usr/share/kservices5/ServiceMenus/*.desktop
 | 
					usr/share/kservices5/ServiceMenus/*.desktop
 | 
				
			||||||
 | 
					usr/share/applications/*.desktop
 | 
				
			||||||
usr/share/man/man1/qvm-*
 | 
					usr/share/man/man1/qvm-*
 | 
				
			||||||
usr/share/qubes/mime-override/globs
 | 
					usr/share/qubes/mime-override/globs
 | 
				
			||||||
usr/share/qubes/qubes-master-key.asc
 | 
					usr/share/qubes/qubes-master-key.asc
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								debian/qubes-core-agent.postinst
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								debian/qubes-core-agent.postinst
									
									
									
									
										vendored
									
									
								
							@ -145,6 +145,8 @@ case "${1}" in
 | 
				
			|||||||
        fi
 | 
					        fi
 | 
				
			||||||
        systemctl reenable haveged
 | 
					        systemctl reenable haveged
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        chgrp user /var/lib/qubes/dom0-updates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        debug "UPDATE..."
 | 
					        debug "UPDATE..."
 | 
				
			||||||
        # disable some Upstart services
 | 
					        # disable some Upstart services
 | 
				
			||||||
        for init in plymouth-shutdown \
 | 
					        for init in plymouth-shutdown \
 | 
				
			||||||
@ -179,7 +181,15 @@ case "${1}" in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        glib-compile-schemas /usr/share/glib-2.0/schemas || true
 | 
					        glib-compile-schemas /usr/share/glib-2.0/schemas || true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dconf update || true
 | 
					        if ! [ -r /etc/dconf/profile/user ]; then
 | 
				
			||||||
 | 
					            mkdir -p /etc/dconf/profile
 | 
				
			||||||
 | 
					            echo "user-db:user" >> /etc/dconf/profile/user
 | 
				
			||||||
 | 
					            echo "system-db:local" >> /etc/dconf/profile/user
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if [ -x /usr/bin/dconf ]; then
 | 
				
			||||||
 | 
					            dconf update
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # tell dom0 about installed updates (applications, features etc)
 | 
					        # tell dom0 about installed updates (applications, features etc)
 | 
				
			||||||
        /etc/qubes-rpc/qubes.PostInstall || true
 | 
					        /etc/qubes-rpc/qubes.PostInstall || true
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@ qrexec-client-vm - call Qubes RPC service
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
SYNOPSIS
 | 
					SYNOPSIS
 | 
				
			||||||
========
 | 
					========
 | 
				
			||||||
| qrexec-client-vm *target_vmname* *service* [*local_program* [*local program arguments*]]
 | 
					| qrexec-client-vm [--buffer-size=*BUFFER_SIZE*] *target_vmname* *service* [*local_program* [*local program arguments*]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DESCRIPTION
 | 
					DESCRIPTION
 | 
				
			||||||
===========
 | 
					===========
 | 
				
			||||||
@ -27,6 +27,12 @@ stdin/stdout is connected to those of ``qrexec-client-vm``.
 | 
				
			|||||||
OPTIONS
 | 
					OPTIONS
 | 
				
			||||||
=======
 | 
					=======
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--buffer-size=*BUFFER_SIZE*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Optional buffer size for vchan connection. This size is used as minimum
 | 
				
			||||||
 | 
					    size for a buffer in each connection direction (read and write).
 | 
				
			||||||
 | 
					    Default: 64KiB.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*target_vmname*
 | 
					*target_vmname*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Name of target VM to which service is requested. Qubes RPC policy may
 | 
					    Name of target VM to which service is requested. Qubes RPC policy may
 | 
				
			||||||
 | 
				
			|||||||
@ -158,15 +158,9 @@ initialize_home() {
 | 
				
			|||||||
        homedir=$(echo "$pair" | awk -F : ' { print $4 } ')
 | 
					        homedir=$(echo "$pair" | awk -F : ' { print $4 } ')
 | 
				
			||||||
        homedirwithouthome=${homedir#/home/}
 | 
					        homedirwithouthome=${homedir#/home/}
 | 
				
			||||||
        if ! test -d "$home_root/$homedirwithouthome" || [ "$mode" = "unconditionally" ] ; then
 | 
					        if ! test -d "$home_root/$homedirwithouthome" || [ "$mode" = "unconditionally" ] ; then
 | 
				
			||||||
            if [ "$homedir" == "/home/user" ] && [ -d "/home.orig/$homedirwithouthome" ] ; then
 | 
					            echo "initialize_home: populating $mode $home_root/$homedirwithouthome from /etc/skel" >&2
 | 
				
			||||||
                echo "initialize_home: populating $mode $home_root/$homedirwithouthome from /home.orig/$homedirwithouthome" >&2
 | 
					            mkdir -p "$home_root/$homedirwithouthome"
 | 
				
			||||||
                mkdir -p "$home_root/$homedirwithouthome"
 | 
					            cp -af -T /etc/skel "$home_root/$homedirwithouthome"
 | 
				
			||||||
                cp -af -T "/home.orig/$homedirwithouthome" "$home_root/$homedirwithouthome"
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                echo "initialize_home: populating $mode $home_root/$homedirwithouthome from /etc/skel" >&2
 | 
					 | 
				
			||||||
                mkdir -p "$home_root/$homedirwithouthome"
 | 
					 | 
				
			||||||
                cp -af -T /etc/skel "$home_root/$homedirwithouthome"
 | 
					 | 
				
			||||||
            fi
 | 
					 | 
				
			||||||
            echo "initialize_home: adjusting permissions $mode on $home_root/$homedirwithouthome" >&2
 | 
					            echo "initialize_home: adjusting permissions $mode on $home_root/$homedirwithouthome" >&2
 | 
				
			||||||
            chown -R "$uid" "$home_root/$homedirwithouthome" &
 | 
					            chown -R "$uid" "$home_root/$homedirwithouthome" &
 | 
				
			||||||
            waitpids="$!"
 | 
					            waitpids="$!"
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,7 @@ python2:
 | 
				
			|||||||
python3:
 | 
					python3:
 | 
				
			||||||
	rm -rf py3
 | 
						rm -rf py3
 | 
				
			||||||
	mkdir -p py3
 | 
						mkdir -p py3
 | 
				
			||||||
	cp dnf-qubes-hooks.py qubesxdg.py py3/
 | 
						cp dnf-qubes-hooks.py py3/
 | 
				
			||||||
	python3 -m compileall py3
 | 
						python3 -m compileall py3
 | 
				
			||||||
	python3 -O -m compileall py3
 | 
						python3 -O -m compileall py3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
#!/usr/bin/python
 | 
					#!/usr/bin/python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from qubesxdg import launch
 | 
					from qubesagent.xdg import launch
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
				
			|||||||
@ -53,6 +53,9 @@ fi
 | 
				
			|||||||
YUM="yum"
 | 
					YUM="yum"
 | 
				
			||||||
if type dnf >/dev/null 2>&1; then
 | 
					if type dnf >/dev/null 2>&1; then
 | 
				
			||||||
    YUM="dnf --best --allowerasing --noplugins"
 | 
					    YUM="dnf --best --allowerasing --noplugins"
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					    # salt in dom0 thinks it's using dnf but we only have yum so need to remove extra options
 | 
				
			||||||
 | 
					    OPTS="${OPTS/--best --allowerasing/}"
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ! [ -d "$DOM0_UPDATES_DIR" ]; then
 | 
					if ! [ -d "$DOM0_UPDATES_DIR" ]; then
 | 
				
			||||||
@ -126,7 +129,7 @@ if ! $YUM --help | grep -q downloadonly; then
 | 
				
			|||||||
    elif [ "$YUM_ACTION" == "list" ] || [ "$YUM_ACTION" == "search" ]; then
 | 
					    elif [ "$YUM_ACTION" == "list" ] || [ "$YUM_ACTION" == "search" ]; then
 | 
				
			||||||
        # those actions do not download any package, so lack of --downloadonly is irrelevant
 | 
					        # those actions do not download any package, so lack of --downloadonly is irrelevant
 | 
				
			||||||
        YUM_COMMAND="$YUM $YUM_ACTION -y"
 | 
					        YUM_COMMAND="$YUM $YUM_ACTION -y"
 | 
				
			||||||
    elif [ "$YUM_ACTION" == "reinstal" ]; then
 | 
					    elif [ "$YUM_ACTION" == "reinstall" ]; then
 | 
				
			||||||
        # this is just approximation of 'reinstall' action...
 | 
					        # this is just approximation of 'reinstall' action...
 | 
				
			||||||
        # shellcheck disable=SC2086
 | 
					        # shellcheck disable=SC2086
 | 
				
			||||||
        PKGLIST=$(rpm --root=$DOM0_UPDATES_DIR -q $PKGLIST)
 | 
					        PKGLIST=$(rpm --root=$DOM0_UPDATES_DIR -q $PKGLIST)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
[qubes-vm-r4.0-current]
 | 
					[qubes-vm-r4.0-current]
 | 
				
			||||||
name = Qubes OS Repository for VM (updates)
 | 
					name = Qubes OS Repository for VM (updates)
 | 
				
			||||||
baseurl = http://yum.qubes-os.org/r4.0/current/vm/fc$releasever
 | 
					baseurl = https://yum.qubes-os.org/r4.0/current/vm/fc$releasever
 | 
				
			||||||
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-4-primary
 | 
					gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-4-primary
 | 
				
			||||||
skip_if_unavailable=False
 | 
					skip_if_unavailable=False
 | 
				
			||||||
gpgcheck = 1
 | 
					gpgcheck = 1
 | 
				
			||||||
@ -8,7 +8,7 @@ enabled=1
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[qubes-vm-r4.0-current-testing]
 | 
					[qubes-vm-r4.0-current-testing]
 | 
				
			||||||
name = Qubes OS Repository for VM (updates-testing)
 | 
					name = Qubes OS Repository for VM (updates-testing)
 | 
				
			||||||
baseurl = http://yum.qubes-os.org/r4.0/current-testing/vm/fc$releasever
 | 
					baseurl = https://yum.qubes-os.org/r4.0/current-testing/vm/fc$releasever
 | 
				
			||||||
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-4-primary
 | 
					gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-4-primary
 | 
				
			||||||
skip_if_unavailable=False
 | 
					skip_if_unavailable=False
 | 
				
			||||||
gpgcheck = 1
 | 
					gpgcheck = 1
 | 
				
			||||||
@ -16,7 +16,7 @@ enabled=0
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[qubes-vm-r4.0-security-testing]
 | 
					[qubes-vm-r4.0-security-testing]
 | 
				
			||||||
name = Qubes OS Repository for VM (security-testing)
 | 
					name = Qubes OS Repository for VM (security-testing)
 | 
				
			||||||
baseurl = http://yum.qubes-os.org/r4.0/security-testing/vm/fc$releasever
 | 
					baseurl = https://yum.qubes-os.org/r4.0/security-testing/vm/fc$releasever
 | 
				
			||||||
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-4-primary
 | 
					gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-4-primary
 | 
				
			||||||
skip_if_unavailable=False
 | 
					skip_if_unavailable=False
 | 
				
			||||||
gpgcheck = 1
 | 
					gpgcheck = 1
 | 
				
			||||||
@ -24,7 +24,7 @@ enabled=0
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[qubes-vm-r4.0-unstable]
 | 
					[qubes-vm-r4.0-unstable]
 | 
				
			||||||
name = Qubes OS Repository for VM (unstable)
 | 
					name = Qubes OS Repository for VM (unstable)
 | 
				
			||||||
baseurl = http://yum.qubes-os.org/r4.0/unstable/vm/fc$releasever
 | 
					baseurl = https://yum.qubes-os.org/r4.0/unstable/vm/fc$releasever
 | 
				
			||||||
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-4-unstable
 | 
					gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-qubes-4-unstable
 | 
				
			||||||
gpgcheck = 1
 | 
					gpgcheck = 1
 | 
				
			||||||
enabled=0
 | 
					enabled=0
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								misc/qubes-run-terminal
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										11
									
								
								misc/qubes-run-terminal
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					# Try to find a terminal emulator that's installed and run it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for terminal in x-terminal-emulator gnome-terminal xfce4-terminal konsole urxvt rxvt termit terminator Eterm aterm roxterm termite lxterminal mate-terminal terminology st xterm; do
 | 
				
			||||||
 | 
					    if which $terminal >/dev/null 2>&1 ; then
 | 
				
			||||||
 | 
					        exec "$terminal"
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo "ERROR: No suitable terminal found." > /dev/stderr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								misc/qubes-run-terminal.desktop
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								misc/qubes-run-terminal.desktop
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					[Desktop Entry]
 | 
				
			||||||
 | 
					Name=Run Terminal
 | 
				
			||||||
 | 
					Exec=qubes-run-terminal
 | 
				
			||||||
 | 
					Icon=utilities-terminal
 | 
				
			||||||
 | 
					Type=Application
 | 
				
			||||||
@ -25,7 +25,7 @@ import subprocess
 | 
				
			|||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from xdg.DesktopEntry import DesktopEntry
 | 
					from xdg.DesktopEntry import DesktopEntry
 | 
				
			||||||
from qubesxdg import launch
 | 
					from qubesagent.xdg import launch
 | 
				
			||||||
import xdg.BaseDirectory
 | 
					import xdg.BaseDirectory
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -76,7 +76,7 @@ def process_autostart(environments):
 | 
				
			|||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    entry = DesktopEntry(entry_path)
 | 
					                    entry = DesktopEntry(entry_path)
 | 
				
			||||||
                if entry_should_be_started(entry, environments):
 | 
					                if entry_should_be_started(entry, environments):
 | 
				
			||||||
                    launch(entry_path)
 | 
					                    launch(entry_path, wait=False)
 | 
				
			||||||
            except Exception as e:
 | 
					            except Exception as e:
 | 
				
			||||||
                print >>sys.stderr, "Failed to process '{}': {}".format(
 | 
					                print >>sys.stderr, "Failed to process '{}': {}".format(
 | 
				
			||||||
                    entry_name, str(e)
 | 
					                    entry_name, str(e)
 | 
				
			||||||
 | 
				
			|||||||
@ -59,7 +59,7 @@
 | 
				
			|||||||
</action>
 | 
					</action>
 | 
				
			||||||
<action>
 | 
					<action>
 | 
				
			||||||
	<icon>document-open</icon>
 | 
						<icon>document-open</icon>
 | 
				
			||||||
	<name>Open in DisposableVM</name>
 | 
						<name>Edit in DisposableVM</name>
 | 
				
			||||||
	<unique-id>1507455559234996-8</unique-id>
 | 
						<unique-id>1507455559234996-8</unique-id>
 | 
				
			||||||
	<command>/usr/lib/qubes/qvm-actions.sh opendvm %F</command>
 | 
						<command>/usr/lib/qubes/qvm-actions.sh opendvm %F</command>
 | 
				
			||||||
	<description></description>
 | 
						<description></description>
 | 
				
			||||||
@ -70,3 +70,16 @@
 | 
				
			|||||||
	<text-files/>
 | 
						<text-files/>
 | 
				
			||||||
	<video-files/>
 | 
						<video-files/>
 | 
				
			||||||
</action>
 | 
					</action>
 | 
				
			||||||
 | 
					<action>
 | 
				
			||||||
 | 
						<icon>document-open</icon>
 | 
				
			||||||
 | 
						<name>View in DisposableVM</name>
 | 
				
			||||||
 | 
						<unique-id>1507455559234997-9</unique-id>
 | 
				
			||||||
 | 
						<command>/usr/lib/qubes/qvm-actions.sh viewdvm %F</command>
 | 
				
			||||||
 | 
						<description></description>
 | 
				
			||||||
 | 
						<patterns>*</patterns>
 | 
				
			||||||
 | 
						<audio-files/>
 | 
				
			||||||
 | 
						<image-files/>
 | 
				
			||||||
 | 
						<other-files/>
 | 
				
			||||||
 | 
						<text-files/>
 | 
				
			||||||
 | 
						<video-files/>
 | 
				
			||||||
 | 
					</action>
 | 
				
			||||||
 | 
				
			|||||||
@ -16,4 +16,15 @@ unmanaged_devices=mac:fe:ff:ff:ff:ff:ff
 | 
				
			|||||||
sed -r -i -e "s/^#?unmanaged-devices=.*/unmanaged-devices=$unmanaged_devices/" /etc/NetworkManager/NetworkManager.conf
 | 
					sed -r -i -e "s/^#?unmanaged-devices=.*/unmanaged-devices=$unmanaged_devices/" /etc/NetworkManager/NetworkManager.conf
 | 
				
			||||||
sed -r -i -e "s/^#?plugins=.*/plugins=keyfile/" /etc/NetworkManager/NetworkManager.conf
 | 
					sed -r -i -e "s/^#?plugins=.*/plugins=keyfile/" /etc/NetworkManager/NetworkManager.conf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# setup uplink configuration if applicable - this needs to be done before
 | 
				
			||||||
 | 
					# starting NetworkManager, otherwise it will try default DHCP configuration
 | 
				
			||||||
 | 
					# first and only after a timeout fallback to static one - introducing delay in
 | 
				
			||||||
 | 
					# network connectivity
 | 
				
			||||||
 | 
					export INTERFACE=eth0
 | 
				
			||||||
 | 
					if qubesdb-read /qubes-ip >/dev/null 2>/dev/null &&
 | 
				
			||||||
 | 
					        [ -e /sys/class/net/$INTERFACE ] &&
 | 
				
			||||||
 | 
					        [ ! -r /etc/NetworkManager/system-connections/qubes-uplink-$INTERFACE ]; then
 | 
				
			||||||
 | 
					    /usr/lib/qubes/setup-ip
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exit 0
 | 
					exit 0
 | 
				
			||||||
 | 
				
			|||||||
@ -42,9 +42,15 @@ start() {
 | 
				
			|||||||
    # Do not start if there is no config file.
 | 
					    # Do not start if there is no config file.
 | 
				
			||||||
    [ ! -f "$IPTABLES_DATA" ] && return 6
 | 
					    [ ! -f "$IPTABLES_DATA" ] && return 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CMD_ARGS=
 | 
				
			||||||
 | 
					    if "$CMD-restore" --help 2>&1 | grep -q wait=; then
 | 
				
			||||||
 | 
					        # 'wait' must be last on command line if secs not specified
 | 
				
			||||||
 | 
					        CMD_ARGS=--wait
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    echo -n $"${CMD}: Applying firewall rules: "
 | 
					    echo -n $"${CMD}: Applying firewall rules: "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    "$CMD-restore" "$IPTABLES_DATA"
 | 
					    "$CMD-restore" "$IPTABLES_DATA" $CMD_ARGS
 | 
				
			||||||
    ret="$?"
 | 
					    ret="$?"
 | 
				
			||||||
    if [ "$ret" -eq 0 ]; then
 | 
					    if [ "$ret" -eq 0 ]; then
 | 
				
			||||||
        echo OK
 | 
					        echo OK
 | 
				
			||||||
 | 
				
			|||||||
@ -91,6 +91,9 @@ __EOF__
 | 
				
			|||||||
        fi
 | 
					        fi
 | 
				
			||||||
        /sbin/ifconfig "$INTERFACE" up
 | 
					        /sbin/ifconfig "$INTERFACE" up
 | 
				
			||||||
        /sbin/route add -host "$gateway" dev "$INTERFACE"
 | 
					        /sbin/route add -host "$gateway" dev "$INTERFACE"
 | 
				
			||||||
 | 
					        if [ -n "$gateway6" ] && ! echo "$gateway6" | grep -q "^fe80:"; then
 | 
				
			||||||
 | 
					            /sbin/route -6 add "$gateway6/128" dev "$INTERFACE"
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
        if ! qsvc disable-default-route ; then
 | 
					        if ! qsvc disable-default-route ; then
 | 
				
			||||||
            /sbin/route add default gw "$gateway"
 | 
					            /sbin/route add default gw "$gateway"
 | 
				
			||||||
            if [ -n "$gateway6" ]; then
 | 
					            if [ -n "$gateway6" ]; then
 | 
				
			||||||
 | 
				
			|||||||
@ -40,10 +40,12 @@ if [ "${ip}" ]; then
 | 
				
			|||||||
    # IPs as seen by this VM
 | 
					    # IPs as seen by this VM
 | 
				
			||||||
    netvm_ip="$ip4"
 | 
					    netvm_ip="$ip4"
 | 
				
			||||||
    netvm_gw_ip=$(qubesdb-read /qubes-netvm-gateway)
 | 
					    netvm_gw_ip=$(qubesdb-read /qubes-netvm-gateway)
 | 
				
			||||||
 | 
					    netvm_gw_ip6=$(qubesdb-read /qubes-netvm-gateway6 || :)
 | 
				
			||||||
    netvm_dns1_ip=$(qubesdb-read /qubes-netvm-primary-dns)
 | 
					    netvm_dns1_ip=$(qubesdb-read /qubes-netvm-primary-dns)
 | 
				
			||||||
    netvm_dns2_ip=$(qubesdb-read /qubes-netvm-secondary-dns)
 | 
					    netvm_dns2_ip=$(qubesdb-read /qubes-netvm-secondary-dns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    back_ip="$netvm_gw_ip"
 | 
					    back_ip="$netvm_gw_ip"
 | 
				
			||||||
 | 
					    back_ip6="$netvm_gw_ip6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # IPs as seen by the VM - if other than $netvm_ip
 | 
					    # IPs as seen by the VM - if other than $netvm_ip
 | 
				
			||||||
    appvm_gw_ip="$(qubesdb-read "/mapped-ip/$ip4/visible-gateway" 2>/dev/null || :)"
 | 
					    appvm_gw_ip="$(qubesdb-read "/mapped-ip/$ip4/visible-gateway" 2>/dev/null || :)"
 | 
				
			||||||
@ -106,7 +108,10 @@ if [ "${ip}" ] ; then
 | 
				
			|||||||
        echo -e "*raw\n$iptables_cmd -i ${vif} -j DROP\nCOMMIT" | \
 | 
					        echo -e "*raw\n$iptables_cmd -i ${vif} -j DROP\nCOMMIT" | \
 | 
				
			||||||
            ${cmdprefix} flock $lockfile ip6tables-restore --noflush
 | 
					            ${cmdprefix} flock $lockfile ip6tables-restore --noflush
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
	${cmdprefix} ip addr "${ipcmd}" "${back_ip}/32" dev "${vif}"
 | 
					    ${cmdprefix} ip addr "${ipcmd}" "${back_ip}/32" dev "${vif}"
 | 
				
			||||||
 | 
					    if [ "${back_ip6}" ] && [[ "${back_ip6}" != "fe80:"* ]]; then
 | 
				
			||||||
 | 
					        ${cmdprefix} ip addr "${ipcmd}" "${back_ip6}/128" dev "${vif}"
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log debug "Successful vif-route-qubes $command for $vif."
 | 
					log debug "Successful vif-route-qubes $command for $vif."
 | 
				
			||||||
 | 
				
			|||||||
@ -295,6 +295,7 @@ int process_child_io(libvchan_t *data_vchan,
 | 
				
			|||||||
    int remote_process_status = -1;
 | 
					    int remote_process_status = -1;
 | 
				
			||||||
    int ret, max_fd;
 | 
					    int ret, max_fd;
 | 
				
			||||||
    struct timespec zero_timeout = { 0, 0 };
 | 
					    struct timespec zero_timeout = { 0, 0 };
 | 
				
			||||||
 | 
					    struct timespec normal_timeout = { 10, 0 };
 | 
				
			||||||
    struct buffer stdin_buf;
 | 
					    struct buffer stdin_buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sigemptyset(&selectmask);
 | 
					    sigemptyset(&selectmask);
 | 
				
			||||||
@ -386,7 +387,7 @@ int process_child_io(libvchan_t *data_vchan,
 | 
				
			|||||||
            /* check for other FDs, but exit immediately */
 | 
					            /* check for other FDs, but exit immediately */
 | 
				
			||||||
            ret = pselect(max_fd + 1, &rdset, &wrset, NULL, &zero_timeout, &selectmask);
 | 
					            ret = pselect(max_fd + 1, &rdset, &wrset, NULL, &zero_timeout, &selectmask);
 | 
				
			||||||
        } else
 | 
					        } else
 | 
				
			||||||
            ret = pselect(max_fd + 1, &rdset, &wrset, NULL, NULL, &selectmask);
 | 
					            ret = pselect(max_fd + 1, &rdset, &wrset, NULL, &normal_timeout, &selectmask);
 | 
				
			||||||
        if (ret < 0) {
 | 
					        if (ret < 0) {
 | 
				
			||||||
            if (errno == EINTR)
 | 
					            if (errno == EINTR)
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
@ -490,10 +491,14 @@ int process_child_io(libvchan_t *data_vchan,
 | 
				
			|||||||
 *  MSG_EXEC_CMDLINE - connect to vchan server, fork+exec process given by
 | 
					 *  MSG_EXEC_CMDLINE - connect to vchan server, fork+exec process given by
 | 
				
			||||||
 *    cmdline parameter, pass the data to/from that process, then return local
 | 
					 *    cmdline parameter, pass the data to/from that process, then return local
 | 
				
			||||||
 *    process exit code
 | 
					 *    process exit code
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  buffer_size is about vchan buffer allocated (only for vchan server cases),
 | 
				
			||||||
 | 
					 *  use 0 to use built-in default (64k); needs to be power of 2
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int handle_new_process_common(int type, int connect_domain, int connect_port,
 | 
					int handle_new_process_common(int type, int connect_domain, int connect_port,
 | 
				
			||||||
                char *cmdline, int cmdline_len, /* MSG_JUST_EXEC and MSG_EXEC_CMDLINE */
 | 
					                char *cmdline, int cmdline_len, /* MSG_JUST_EXEC and MSG_EXEC_CMDLINE */
 | 
				
			||||||
                int stdin_fd, int stdout_fd, int stderr_fd /* MSG_SERVICE_CONNECT */)
 | 
					                int stdin_fd, int stdout_fd, int stderr_fd /* MSG_SERVICE_CONNECT */,
 | 
				
			||||||
 | 
					                int buffer_size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    libvchan_t *data_vchan;
 | 
					    libvchan_t *data_vchan;
 | 
				
			||||||
    int exit_code = 0;
 | 
					    int exit_code = 0;
 | 
				
			||||||
@ -504,9 +509,12 @@ int handle_new_process_common(int type, int connect_domain, int connect_port,
 | 
				
			|||||||
        cmdline[cmdline_len-1] = 0;
 | 
					        cmdline[cmdline_len-1] = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (buffer_size == 0)
 | 
				
			||||||
 | 
					        buffer_size = VCHAN_BUFFER_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (type == MSG_SERVICE_CONNECT) {
 | 
					    if (type == MSG_SERVICE_CONNECT) {
 | 
				
			||||||
        data_vchan = libvchan_server_init(connect_domain, connect_port,
 | 
					        data_vchan = libvchan_server_init(connect_domain, connect_port,
 | 
				
			||||||
                VCHAN_BUFFER_SIZE, VCHAN_BUFFER_SIZE);
 | 
					                buffer_size, buffer_size);
 | 
				
			||||||
        if (data_vchan)
 | 
					        if (data_vchan)
 | 
				
			||||||
            libvchan_wait(data_vchan);
 | 
					            libvchan_wait(data_vchan);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@ -563,7 +571,7 @@ pid_t handle_new_process(int type, int connect_domain, int connect_port,
 | 
				
			|||||||
    /* child process */
 | 
					    /* child process */
 | 
				
			||||||
    exit_code = handle_new_process_common(type, connect_domain, connect_port,
 | 
					    exit_code = handle_new_process_common(type, connect_domain, connect_port,
 | 
				
			||||||
            cmdline, cmdline_len,
 | 
					            cmdline, cmdline_len,
 | 
				
			||||||
            -1, -1, -1);
 | 
					            -1, -1, -1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    exit(exit_code);
 | 
					    exit(exit_code);
 | 
				
			||||||
    /* suppress warning */
 | 
					    /* suppress warning */
 | 
				
			||||||
@ -572,13 +580,13 @@ pid_t handle_new_process(int type, int connect_domain, int connect_port,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Returns exit code of remote process */
 | 
					/* Returns exit code of remote process */
 | 
				
			||||||
int handle_data_client(int type, int connect_domain, int connect_port,
 | 
					int handle_data_client(int type, int connect_domain, int connect_port,
 | 
				
			||||||
                int stdin_fd, int stdout_fd, int stderr_fd)
 | 
					                int stdin_fd, int stdout_fd, int stderr_fd, int buffer_size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int exit_code;
 | 
					    int exit_code;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(type == MSG_SERVICE_CONNECT);
 | 
					    assert(type == MSG_SERVICE_CONNECT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    exit_code = handle_new_process_common(type, connect_domain, connect_port,
 | 
					    exit_code = handle_new_process_common(type, connect_domain, connect_port,
 | 
				
			||||||
            NULL, 0, stdin_fd, stdout_fd, stderr_fd);
 | 
					            NULL, 0, stdin_fd, stdout_fd, stderr_fd, buffer_size);
 | 
				
			||||||
    return exit_code;
 | 
					    return exit_code;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -382,7 +382,7 @@ int try_fork_server(int type, int connect_domain, int connect_port,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    remote.sun_family = AF_UNIX;
 | 
					    remote.sun_family = AF_UNIX;
 | 
				
			||||||
    strncpy(remote.sun_path, fork_server_socket_path,
 | 
					    strncpy(remote.sun_path, fork_server_socket_path,
 | 
				
			||||||
            sizeof(remote.sun_path));
 | 
					            sizeof(remote.sun_path) - 1);
 | 
				
			||||||
    free(fork_server_socket_path);
 | 
					    free(fork_server_socket_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
 | 
					    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
 | 
				
			||||||
 | 
				
			|||||||
@ -37,7 +37,8 @@ pid_t handle_new_process(int type,
 | 
				
			|||||||
        char *cmdline, int cmdline_len);
 | 
					        char *cmdline, int cmdline_len);
 | 
				
			||||||
int handle_data_client(int type,
 | 
					int handle_data_client(int type,
 | 
				
			||||||
        int connect_domain, int connect_port,
 | 
					        int connect_domain, int connect_port,
 | 
				
			||||||
        int stdin_fd, int stdout_fd, int stderr_fd);
 | 
					        int stdin_fd, int stdout_fd, int stderr_fd,
 | 
				
			||||||
 | 
					        int buffer_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct qrexec_cmd_info {
 | 
					struct qrexec_cmd_info {
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,7 @@
 | 
				
			|||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <getopt.h>
 | 
				
			||||||
#include "libqrexec-utils.h"
 | 
					#include "libqrexec-utils.h"
 | 
				
			||||||
#include "qrexec.h"
 | 
					#include "qrexec.h"
 | 
				
			||||||
#include "qrexec-agent.h"
 | 
					#include "qrexec-agent.h"
 | 
				
			||||||
@ -54,7 +55,7 @@ int connect_unix_socket(char *path)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    remote.sun_family = AF_UNIX;
 | 
					    remote.sun_family = AF_UNIX;
 | 
				
			||||||
    strncpy(remote.sun_path, path,
 | 
					    strncpy(remote.sun_path, path,
 | 
				
			||||||
            sizeof(remote.sun_path));
 | 
					            sizeof(remote.sun_path) - 1);
 | 
				
			||||||
    len = strlen(remote.sun_path) + sizeof(remote.sun_family);
 | 
					    len = strlen(remote.sun_path) + sizeof(remote.sun_family);
 | 
				
			||||||
    if (connect(s, (struct sockaddr *) &remote, len) == -1) {
 | 
					    if (connect(s, (struct sockaddr *) &remote, len) == -1) {
 | 
				
			||||||
        perror("connect");
 | 
					        perror("connect");
 | 
				
			||||||
@ -85,6 +86,19 @@ void convert_target_name_keyword(char *target)
 | 
				
			|||||||
            target[i] = '@';
 | 
					            target[i] = '@';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct option longopts[] = {
 | 
				
			||||||
 | 
					    { "buffer-size", required_argument, 0,  'b' },
 | 
				
			||||||
 | 
					    { NULL, 0, 0, 0},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_Noreturn void usage(const char *argv0) {
 | 
				
			||||||
 | 
					    fprintf(stderr,
 | 
				
			||||||
 | 
					            "usage: %s [--buffer-size=BUFFER_SIZE] target_vmname program_ident [local_program [local program arguments]]\n",
 | 
				
			||||||
 | 
					            argv0);
 | 
				
			||||||
 | 
					    fprintf(stderr, "BUFFER_SIZE is minimum vchan buffer size (default: 64k)\n");
 | 
				
			||||||
 | 
					    exit(2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int trigger_fd;
 | 
					    int trigger_fd;
 | 
				
			||||||
@ -95,25 +109,37 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    char *abs_exec_path;
 | 
					    char *abs_exec_path;
 | 
				
			||||||
    pid_t child_pid = 0;
 | 
					    pid_t child_pid = 0;
 | 
				
			||||||
    int inpipe[2], outpipe[2];
 | 
					    int inpipe[2], outpipe[2];
 | 
				
			||||||
 | 
					    int buffer_size = 0;
 | 
				
			||||||
 | 
					    int opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (argc < 3) {
 | 
					    while (1) {
 | 
				
			||||||
        fprintf(stderr,
 | 
					        opt = getopt_long(argc, argv, "+", longopts, NULL);
 | 
				
			||||||
                "usage: %s target_vmname program_ident [local_program [local program arguments]]\n",
 | 
					        if (opt == -1)
 | 
				
			||||||
                argv[0]);
 | 
					            break;
 | 
				
			||||||
        exit(1);
 | 
					        switch (opt) {
 | 
				
			||||||
 | 
					            case 'b':
 | 
				
			||||||
 | 
					                buffer_size = atoi(optarg);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case '?':
 | 
				
			||||||
 | 
					                usage(argv[0]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (argc > 3) {
 | 
					
 | 
				
			||||||
 | 
					    if (argc - optind < 2) {
 | 
				
			||||||
 | 
					        usage(argv[0]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (argc - optind > 2) {
 | 
				
			||||||
        start_local_process = 1;
 | 
					        start_local_process = 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    trigger_fd = connect_unix_socket(QREXEC_AGENT_TRIGGER_PATH);
 | 
					    trigger_fd = connect_unix_socket(QREXEC_AGENT_TRIGGER_PATH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(¶ms, 0, sizeof(params));
 | 
					    memset(¶ms, 0, sizeof(params));
 | 
				
			||||||
    strncpy(params.service_name, argv[2], sizeof(params.service_name));
 | 
					    strncpy(params.service_name, argv[optind + 1], sizeof(params.service_name) - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    convert_target_name_keyword(argv[1]);
 | 
					    convert_target_name_keyword(argv[optind]);
 | 
				
			||||||
    strncpy(params.target_domain, argv[1],
 | 
					    strncpy(params.target_domain, argv[optind],
 | 
				
			||||||
            sizeof(params.target_domain));
 | 
					            sizeof(params.target_domain) - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    snprintf(params.request_id.ident,
 | 
					    snprintf(params.request_id.ident,
 | 
				
			||||||
            sizeof(params.request_id.ident), "SOCKET");
 | 
					            sizeof(params.request_id.ident), "SOCKET");
 | 
				
			||||||
@ -164,9 +190,9 @@ int main(int argc, char **argv)
 | 
				
			|||||||
                close(inpipe[0]);
 | 
					                close(inpipe[0]);
 | 
				
			||||||
                close(outpipe[1]);
 | 
					                close(outpipe[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                abs_exec_path = strdup(argv[3]);
 | 
					                abs_exec_path = strdup(argv[optind + 2]);
 | 
				
			||||||
                argv[3] = get_program_name(argv[3]);
 | 
					                argv[optind + 2] = get_program_name(argv[optind + 2]);
 | 
				
			||||||
                execv(abs_exec_path, argv + 3);
 | 
					                execv(abs_exec_path, argv + optind + 2);
 | 
				
			||||||
                perror("execv");
 | 
					                perror("execv");
 | 
				
			||||||
                exit(-1);
 | 
					                exit(-1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -175,11 +201,11 @@ int main(int argc, char **argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        ret = handle_data_client(MSG_SERVICE_CONNECT,
 | 
					        ret = handle_data_client(MSG_SERVICE_CONNECT,
 | 
				
			||||||
                exec_params.connect_domain, exec_params.connect_port,
 | 
					                exec_params.connect_domain, exec_params.connect_port,
 | 
				
			||||||
                inpipe[1], outpipe[0], -1);
 | 
					                inpipe[1], outpipe[0], -1, buffer_size);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        ret = handle_data_client(MSG_SERVICE_CONNECT,
 | 
					        ret = handle_data_client(MSG_SERVICE_CONNECT,
 | 
				
			||||||
                exec_params.connect_domain, exec_params.connect_port,
 | 
					                exec_params.connect_domain, exec_params.connect_port,
 | 
				
			||||||
                1, 0, -1);
 | 
					                1, 0, -1, buffer_size);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    close(trigger_fd);
 | 
					    close(trigger_fd);
 | 
				
			||||||
 | 
				
			|||||||
@ -112,12 +112,15 @@ int main(int argc, char **argv) {
 | 
				
			|||||||
    signal(SIGCHLD, SIG_IGN);
 | 
					    signal(SIGCHLD, SIG_IGN);
 | 
				
			||||||
    register_exec_func(do_exec);
 | 
					    register_exec_func(do_exec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while ((fd = accept(s, (struct sockaddr *) &peer, &addrlen)) >= 0) {
 | 
					    while (1) {
 | 
				
			||||||
 | 
					        addrlen = sizeof(peer);
 | 
				
			||||||
 | 
					        fd = accept(s, (struct sockaddr *) &peer, &addrlen);
 | 
				
			||||||
 | 
					        if (fd < 0)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        if (read_all(fd, &info, sizeof(info))) {
 | 
					        if (read_all(fd, &info, sizeof(info))) {
 | 
				
			||||||
            handle_single_command(fd, &info);
 | 
					            handle_single_command(fd, &info);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        close(fd);
 | 
					        close(fd);
 | 
				
			||||||
        addrlen = sizeof(peer);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    close(s);
 | 
					    close(s);
 | 
				
			||||||
    unlink(socket_path);
 | 
					    unlink(socket_path);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								qubes-rpc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								qubes-rpc/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,6 +1,5 @@
 | 
				
			|||||||
qubes_add_pendrive_script
 | 
					qubes_add_pendrive_script
 | 
				
			||||||
qubes_penctl
 | 
					qubes_penctl
 | 
				
			||||||
qvm-open-in-dvm
 | 
					 | 
				
			||||||
dvm_file_editor
 | 
					dvm_file_editor
 | 
				
			||||||
qfile-agent
 | 
					qfile-agent
 | 
				
			||||||
qfile-agent-dvm
 | 
					qfile-agent-dvm
 | 
				
			||||||
 | 
				
			|||||||
@ -1,2 +1,3 @@
 | 
				
			|||||||
#define DVM_FILENAME_SIZE 256
 | 
					#define DVM_FILENAME_SIZE 256
 | 
				
			||||||
#define DVM_SPOOL "/home/user/.dvmspool"
 | 
					#define DVM_SPOOL "/home/user/.dvmspool"
 | 
				
			||||||
 | 
					#define DVM_VIEW_ONLY_PREFIX "view-only-"
 | 
				
			||||||
 | 
				
			|||||||
@ -10,58 +10,58 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void fix_display(void)
 | 
					static void fix_display(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setenv("DISPLAY", ":0", 1);
 | 
					    setenv("DISPLAY", ":0", 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void produce_message(const char * type, const char *fmt, va_list args)
 | 
					static void produce_message(const char * type, const char *fmt, va_list args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *dialog_msg;
 | 
					    char *dialog_msg;
 | 
				
			||||||
	char buf[1024];
 | 
					    char buf[1024];
 | 
				
			||||||
	(void) vsnprintf(buf, sizeof(buf), fmt, args);
 | 
					    (void) vsnprintf(buf, sizeof(buf), fmt, args);
 | 
				
			||||||
	if (asprintf(&dialog_msg, "%s: %s: %s (error type: %s)",
 | 
					    if (asprintf(&dialog_msg, "%s: %s: %s (error type: %s)",
 | 
				
			||||||
		 program_invocation_short_name, type, buf, strerror(errno)) < 0) {
 | 
					         program_invocation_short_name, type, buf, strerror(errno)) < 0) {
 | 
				
			||||||
		fprintf(stderr, "Failed to allocate memory for error message :(\n");
 | 
					        fprintf(stderr, "Failed to allocate memory for error message :(\n");
 | 
				
			||||||
		return;
 | 
					        return;
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	fprintf(stderr, "%s\n", dialog_msg);
 | 
					    fprintf(stderr, "%s\n", dialog_msg);
 | 
				
			||||||
	switch (fork()) {
 | 
					    switch (fork()) {
 | 
				
			||||||
	case -1:
 | 
					    case -1:
 | 
				
			||||||
		exit(1);	//what else
 | 
					        exit(1);    //what else
 | 
				
			||||||
	case 0:
 | 
					    case 0:
 | 
				
			||||||
		if (geteuid() == 0)
 | 
					        if (geteuid() == 0)
 | 
				
			||||||
			if (setuid(getuid()) != 0)
 | 
					            if (setuid(getuid()) != 0)
 | 
				
			||||||
				perror("setuid failed, calling kdialog/zenity as root");
 | 
					                perror("setuid failed, calling kdialog/zenity as root");
 | 
				
			||||||
		fix_display();
 | 
					        fix_display();
 | 
				
			||||||
#ifdef USE_KDIALOG
 | 
					#ifdef USE_KDIALOG
 | 
				
			||||||
		execlp("/usr/bin/kdialog", "kdialog", "--sorry", dialog_msg, NULL);
 | 
					        execlp("/usr/bin/kdialog", "kdialog", "--sorry", dialog_msg, NULL);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		execlp("/usr/bin/zenity", "zenity", "--error",  "--text", dialog_msg, NULL);
 | 
					        execlp("/usr/bin/zenity", "zenity", "--error",  "--text", dialog_msg, NULL);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	default:;
 | 
					    default:;
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	free(dialog_msg);
 | 
					    free(dialog_msg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void gui_fatal(const char *fmt, ...)
 | 
					void gui_fatal(const char *fmt, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	va_list args;
 | 
					    va_list args;
 | 
				
			||||||
	va_start(args, fmt);
 | 
					    va_start(args, fmt);
 | 
				
			||||||
	produce_message("Fatal error", fmt, args);
 | 
					    produce_message("Fatal error", fmt, args);
 | 
				
			||||||
	va_end(args);
 | 
					    va_end(args);
 | 
				
			||||||
	exit(1);
 | 
					    exit(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void qfile_gui_fatal(const char *fmt, va_list args) {
 | 
					void qfile_gui_fatal(const char *fmt, va_list args) {
 | 
				
			||||||
	produce_message("Fatal error", fmt, args);
 | 
					    produce_message("Fatal error", fmt, args);
 | 
				
			||||||
    exit(1);
 | 
					    exit(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void gui_nonfatal(const char *fmt, ...)
 | 
					void gui_nonfatal(const char *fmt, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	va_list args;
 | 
					    va_list args;
 | 
				
			||||||
	va_start(args, fmt);
 | 
					    va_start(args, fmt);
 | 
				
			||||||
	produce_message("Information", fmt, args);
 | 
					    produce_message("Information", fmt, args);
 | 
				
			||||||
	va_end(args);
 | 
					    va_end(args);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -13,107 +13,107 @@
 | 
				
			|||||||
#include <libqubes-rpc-filecopy.h>
 | 
					#include <libqubes-rpc-filecopy.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
	PROGRESS_FLAG_NORMAL,
 | 
					    PROGRESS_FLAG_NORMAL,
 | 
				
			||||||
	PROGRESS_FLAG_INIT,
 | 
					    PROGRESS_FLAG_INIT,
 | 
				
			||||||
	PROGRESS_FLAG_DONE
 | 
					    PROGRESS_FLAG_DONE
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void do_notify_progress(long long total, int flag)
 | 
					void do_notify_progress(long long total, int flag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *du_size_env = getenv("FILECOPY_TOTAL_SIZE");
 | 
					    const char *du_size_env = getenv("FILECOPY_TOTAL_SIZE");
 | 
				
			||||||
	const char *progress_type_env = getenv("PROGRESS_TYPE");
 | 
					    const char *progress_type_env = getenv("PROGRESS_TYPE");
 | 
				
			||||||
	const char *saved_stdout_env = getenv("SAVED_FD_1");
 | 
					    const char *saved_stdout_env = getenv("SAVED_FD_1");
 | 
				
			||||||
	int ignore;
 | 
					    int ignore;
 | 
				
			||||||
	if (!progress_type_env)
 | 
					    if (!progress_type_env)
 | 
				
			||||||
		return;
 | 
					        return;
 | 
				
			||||||
	if (!strcmp(progress_type_env, "console") && du_size_env) {
 | 
					    if (!strcmp(progress_type_env, "console") && du_size_env) {
 | 
				
			||||||
		char msg[256];
 | 
					        char msg[256];
 | 
				
			||||||
		snprintf(msg, sizeof(msg), "sent %lld/%lld KB\r",
 | 
					        snprintf(msg, sizeof(msg), "sent %lld/%lld KB\r",
 | 
				
			||||||
			 total / 1024, strtoull(du_size_env, NULL, 0));
 | 
					             total / 1024, strtoull(du_size_env, NULL, 0));
 | 
				
			||||||
		ignore = write(2, msg, strlen(msg));
 | 
					        ignore = write(2, msg, strlen(msg));
 | 
				
			||||||
		if (flag == PROGRESS_FLAG_DONE)
 | 
					        if (flag == PROGRESS_FLAG_DONE)
 | 
				
			||||||
			ignore = write(2, "\n", 1);
 | 
					            ignore = write(2, "\n", 1);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (!strcmp(progress_type_env, "gui") && saved_stdout_env) {
 | 
					    if (!strcmp(progress_type_env, "gui") && saved_stdout_env) {
 | 
				
			||||||
		char msg[256];
 | 
					        char msg[256];
 | 
				
			||||||
		snprintf(msg, sizeof(msg), "%lld\n", total);
 | 
					        snprintf(msg, sizeof(msg), "%lld\n", total);
 | 
				
			||||||
		ignore = write(strtoul(saved_stdout_env, NULL, 0), msg,
 | 
					        ignore = write(strtoul(saved_stdout_env, NULL, 0), msg,
 | 
				
			||||||
				strlen(msg));
 | 
					                strlen(msg));
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (ignore < 0) {
 | 
					    if (ignore < 0) {
 | 
				
			||||||
		/* silence gcc warning */
 | 
					        /* silence gcc warning */
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void notify_progress(int size, int flag)
 | 
					void notify_progress(int size, int flag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static long long total = 0;
 | 
					    static long long total = 0;
 | 
				
			||||||
	static long long prev_total = 0;
 | 
					    static long long prev_total = 0;
 | 
				
			||||||
	total += size;
 | 
					    total += size;
 | 
				
			||||||
	if (total > prev_total + PROGRESS_NOTIFY_DELTA
 | 
					    if (total > prev_total + PROGRESS_NOTIFY_DELTA
 | 
				
			||||||
	    || (flag != PROGRESS_FLAG_NORMAL)) {
 | 
					        || (flag != PROGRESS_FLAG_NORMAL)) {
 | 
				
			||||||
		// check for possible error from qfile-unpacker; if error occured,
 | 
					        // check for possible error from qfile-unpacker; if error occured,
 | 
				
			||||||
		// exit() will be called, so don't bother with current state
 | 
					        // exit() will be called, so don't bother with current state
 | 
				
			||||||
		// (notify_progress can be called as callback from copy_file())
 | 
					        // (notify_progress can be called as callback from copy_file())
 | 
				
			||||||
		if (flag == PROGRESS_FLAG_NORMAL)
 | 
					        if (flag == PROGRESS_FLAG_NORMAL)
 | 
				
			||||||
			wait_for_result();
 | 
					            wait_for_result();
 | 
				
			||||||
		do_notify_progress(total, flag);
 | 
					        do_notify_progress(total, flag);
 | 
				
			||||||
		prev_total = total;
 | 
					        prev_total = total;
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *get_abs_path(const char *cwd, const char *pathname)
 | 
					char *get_abs_path(const char *cwd, const char *pathname)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *ret;
 | 
					    char *ret;
 | 
				
			||||||
	if (pathname[0] == '/')
 | 
					    if (pathname[0] == '/')
 | 
				
			||||||
		return strdup(pathname);
 | 
					        return strdup(pathname);
 | 
				
			||||||
	if (asprintf(&ret, "%s/%s", cwd, pathname) < 0)
 | 
					    if (asprintf(&ret, "%s/%s", cwd, pathname) < 0)
 | 
				
			||||||
		return NULL;
 | 
					        return NULL;
 | 
				
			||||||
	else
 | 
					    else
 | 
				
			||||||
		return ret;
 | 
					        return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
					    int i;
 | 
				
			||||||
	char *entry;
 | 
					    char *entry;
 | 
				
			||||||
	char *cwd;
 | 
					    char *cwd;
 | 
				
			||||||
	char *sep;
 | 
					    char *sep;
 | 
				
			||||||
	int ignore_symlinks = 0;
 | 
					    int ignore_symlinks = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qfile_pack_init();
 | 
					    qfile_pack_init();
 | 
				
			||||||
	register_error_handler(qfile_gui_fatal);
 | 
					    register_error_handler(qfile_gui_fatal);
 | 
				
			||||||
	register_notify_progress(¬ify_progress);
 | 
					    register_notify_progress(¬ify_progress);
 | 
				
			||||||
	notify_progress(0, PROGRESS_FLAG_INIT);
 | 
					    notify_progress(0, PROGRESS_FLAG_INIT);
 | 
				
			||||||
	cwd = getcwd(NULL, 0);
 | 
					    cwd = getcwd(NULL, 0);
 | 
				
			||||||
	for (i = 1; i < argc; i++) {
 | 
					    for (i = 1; i < argc; i++) {
 | 
				
			||||||
		if (strcmp(argv[i], "--ignore-symlinks")==0) {
 | 
					        if (strcmp(argv[i], "--ignore-symlinks")==0) {
 | 
				
			||||||
			ignore_symlinks = 1;
 | 
					            ignore_symlinks = 1;
 | 
				
			||||||
			continue;
 | 
					            continue;
 | 
				
			||||||
		}
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		entry = get_abs_path(cwd, argv[i]);
 | 
					        entry = get_abs_path(cwd, argv[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		do {
 | 
					        do {
 | 
				
			||||||
			sep = rindex(entry, '/');
 | 
					            sep = rindex(entry, '/');
 | 
				
			||||||
			if (!sep)
 | 
					            if (!sep)
 | 
				
			||||||
				gui_fatal
 | 
					                gui_fatal
 | 
				
			||||||
				    ("Internal error: nonabsolute filenames not allowed");
 | 
					                    ("Internal error: nonabsolute filenames not allowed");
 | 
				
			||||||
			*sep = 0;
 | 
					            *sep = 0;
 | 
				
			||||||
		} while (sep[1] == 0);
 | 
					        } while (sep[1] == 0);
 | 
				
			||||||
		if (entry[0] == 0) {
 | 
					        if (entry[0] == 0) {
 | 
				
			||||||
			if (chdir("/") < 0) {
 | 
					            if (chdir("/") < 0) {
 | 
				
			||||||
				gui_fatal("Internal error: chdir(\"/\") failed?!");
 | 
					                gui_fatal("Internal error: chdir(\"/\") failed?!");
 | 
				
			||||||
			}
 | 
					            }
 | 
				
			||||||
		} else if (chdir(entry))
 | 
					        } else if (chdir(entry))
 | 
				
			||||||
			gui_fatal("chdir to %s", entry);
 | 
					            gui_fatal("chdir to %s", entry);
 | 
				
			||||||
		do_fs_walk(sep + 1, ignore_symlinks);
 | 
					        do_fs_walk(sep + 1, ignore_symlinks);
 | 
				
			||||||
		free(entry);
 | 
					        free(entry);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	notify_end_and_wait_for_result();
 | 
					    notify_end_and_wait_for_result();
 | 
				
			||||||
	notify_progress(0, PROGRESS_FLAG_DONE);
 | 
					    notify_progress(0, PROGRESS_FLAG_DONE);
 | 
				
			||||||
	return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -17,81 +17,81 @@
 | 
				
			|||||||
#define INCOMING_DIR_ROOT "/home/user/QubesIncoming"
 | 
					#define INCOMING_DIR_ROOT "/home/user/QubesIncoming"
 | 
				
			||||||
int prepare_creds_return_uid(const char *username)
 | 
					int prepare_creds_return_uid(const char *username)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct passwd *pwd;
 | 
					    const struct passwd *pwd;
 | 
				
			||||||
	pwd = getpwnam(username);
 | 
					    pwd = getpwnam(username);
 | 
				
			||||||
	if (!pwd) {
 | 
					    if (!pwd) {
 | 
				
			||||||
		perror("getpwnam");
 | 
					        perror("getpwnam");
 | 
				
			||||||
		exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	setenv("HOME", pwd->pw_dir, 1);
 | 
					    setenv("HOME", pwd->pw_dir, 1);
 | 
				
			||||||
	setenv("USER", username, 1);
 | 
					    setenv("USER", username, 1);
 | 
				
			||||||
	if (setgid(pwd->pw_gid) < 0)
 | 
					    if (setgid(pwd->pw_gid) < 0)
 | 
				
			||||||
		gui_fatal("Error setting group permissions");
 | 
					        gui_fatal("Error setting group permissions");
 | 
				
			||||||
	if (initgroups(username, pwd->pw_gid) < 0)
 | 
					    if (initgroups(username, pwd->pw_gid) < 0)
 | 
				
			||||||
		gui_fatal("Error initializing groups");
 | 
					        gui_fatal("Error initializing groups");
 | 
				
			||||||
	if (setfsuid(pwd->pw_uid) < 0)
 | 
					    if (setfsuid(pwd->pw_uid) < 0)
 | 
				
			||||||
		gui_fatal("Error setting filesystem level permissions");
 | 
					        gui_fatal("Error setting filesystem level permissions");
 | 
				
			||||||
	return pwd->pw_uid;
 | 
					    return pwd->pw_uid;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc __attribute((__unused__)), char ** argv __attribute__((__unused__)))
 | 
					int main(int argc __attribute((__unused__)), char ** argv __attribute__((__unused__)))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *incoming_dir;
 | 
					    char *incoming_dir;
 | 
				
			||||||
	int uid, ret;
 | 
					    int uid, ret;
 | 
				
			||||||
	pid_t pid;
 | 
					    pid_t pid;
 | 
				
			||||||
	const char *remote_domain;
 | 
					    const char *remote_domain;
 | 
				
			||||||
	char *procdir_path;
 | 
					    char *procdir_path;
 | 
				
			||||||
	int procfs_fd;
 | 
					    int procfs_fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uid = prepare_creds_return_uid("user");
 | 
					    uid = prepare_creds_return_uid("user");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	remote_domain = getenv("QREXEC_REMOTE_DOMAIN");
 | 
					    remote_domain = getenv("QREXEC_REMOTE_DOMAIN");
 | 
				
			||||||
	if (!remote_domain) {
 | 
					    if (!remote_domain) {
 | 
				
			||||||
		gui_fatal("Cannot get remote domain name");
 | 
					        gui_fatal("Cannot get remote domain name");
 | 
				
			||||||
		exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	mkdir(INCOMING_DIR_ROOT, 0700);
 | 
					    mkdir(INCOMING_DIR_ROOT, 0700);
 | 
				
			||||||
	if (asprintf(&incoming_dir, "%s/%s", INCOMING_DIR_ROOT, remote_domain) < 0)
 | 
					    if (asprintf(&incoming_dir, "%s/%s", INCOMING_DIR_ROOT, remote_domain) < 0)
 | 
				
			||||||
		gui_fatal("Error allocating memory");
 | 
					        gui_fatal("Error allocating memory");
 | 
				
			||||||
	mkdir(incoming_dir, 0700);
 | 
					    mkdir(incoming_dir, 0700);
 | 
				
			||||||
	if (chdir(incoming_dir))
 | 
					    if (chdir(incoming_dir))
 | 
				
			||||||
		gui_fatal("Error chdir to %s", incoming_dir);
 | 
					        gui_fatal("Error chdir to %s", incoming_dir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mount(".", ".", NULL, MS_BIND | MS_NODEV | MS_NOEXEC | MS_NOSUID, NULL) < 0)
 | 
					    if (mount(".", ".", NULL, MS_BIND | MS_NODEV | MS_NOEXEC | MS_NOSUID, NULL) < 0)
 | 
				
			||||||
		gui_fatal("Failed to mount a directory %s", incoming_dir);
 | 
					        gui_fatal("Failed to mount a directory %s", incoming_dir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* parse the input in unprivileged child process, parent will hold root
 | 
					    /* parse the input in unprivileged child process, parent will hold root
 | 
				
			||||||
	 * access to unmount incoming dir */
 | 
					     * access to unmount incoming dir */
 | 
				
			||||||
	switch (pid=fork()) {
 | 
					    switch (pid=fork()) {
 | 
				
			||||||
		case -1:
 | 
					        case -1:
 | 
				
			||||||
			gui_fatal("Failed to create new process");
 | 
					            gui_fatal("Failed to create new process");
 | 
				
			||||||
		case 0:
 | 
					        case 0:
 | 
				
			||||||
			if (asprintf(&procdir_path, "/proc/%d/fd", getpid()) < 0) {
 | 
					            if (asprintf(&procdir_path, "/proc/%d/fd", getpid()) < 0) {
 | 
				
			||||||
				gui_fatal("Error allocating memory");
 | 
					                gui_fatal("Error allocating memory");
 | 
				
			||||||
			}
 | 
					            }
 | 
				
			||||||
			procfs_fd = open(procdir_path, O_DIRECTORY | O_RDONLY);
 | 
					            procfs_fd = open(procdir_path, O_DIRECTORY | O_RDONLY);
 | 
				
			||||||
			if (procfs_fd < 0)
 | 
					            if (procfs_fd < 0)
 | 
				
			||||||
				perror("Failed to open /proc");
 | 
					                perror("Failed to open /proc");
 | 
				
			||||||
			else
 | 
					            else
 | 
				
			||||||
				set_procfs_fd(procfs_fd);
 | 
					                set_procfs_fd(procfs_fd);
 | 
				
			||||||
			free(procdir_path);
 | 
					            free(procdir_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (chroot("."))
 | 
					            if (chroot("."))
 | 
				
			||||||
				gui_fatal("Error chroot to %s", incoming_dir);
 | 
					                gui_fatal("Error chroot to %s", incoming_dir);
 | 
				
			||||||
			if (setuid(uid) < 0) {
 | 
					            if (setuid(uid) < 0) {
 | 
				
			||||||
				/* no kdialog inside chroot */
 | 
					                /* no kdialog inside chroot */
 | 
				
			||||||
				perror("setuid");
 | 
					                perror("setuid");
 | 
				
			||||||
				exit(1);
 | 
					                exit(1);
 | 
				
			||||||
			}
 | 
					            }
 | 
				
			||||||
			return do_unpack();
 | 
					            return do_unpack();
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (waitpid(pid, &ret, 0) < 0) {
 | 
					    if (waitpid(pid, &ret, 0) < 0) {
 | 
				
			||||||
		gui_fatal("Failed to wait for child process");
 | 
					        gui_fatal("Failed to wait for child process");
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (umount2(".", MNT_DETACH) < 0)
 | 
					    if (umount2(".", MNT_DETACH) < 0)
 | 
				
			||||||
		gui_fatal("Cannot umount incoming directory");
 | 
					        gui_fatal("Cannot umount incoming directory");
 | 
				
			||||||
	if (!WIFEXITED(ret)) {
 | 
					    if (!WIFEXITED(ret)) {
 | 
				
			||||||
		gui_fatal("Child process exited abnormally");
 | 
					        gui_fatal("Child process exited abnormally");
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	return WEXITSTATUS(ret);
 | 
					    return WEXITSTATUS(ret);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -9,99 +9,128 @@
 | 
				
			|||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <libqubes-rpc-filecopy.h>
 | 
					#include <libqubes-rpc-filecopy.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <getopt.h>
 | 
				
			||||||
#include <gui-fatal.h>
 | 
					#include <gui-fatal.h>
 | 
				
			||||||
#include "dvm2.h"
 | 
					#include "dvm2.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void send_file(const char *fname)
 | 
					void send_file(const char *fname, int view_only)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *base;
 | 
					    const char *base;
 | 
				
			||||||
	char sendbuf[DVM_FILENAME_SIZE];
 | 
					    char sendbuf[DVM_FILENAME_SIZE] = {0};
 | 
				
			||||||
	int fd = open(fname, O_RDONLY);
 | 
					    size_t sendbuf_size = DVM_FILENAME_SIZE;
 | 
				
			||||||
	if (fd < 0)
 | 
					    int fd = open(fname, O_RDONLY);
 | 
				
			||||||
		gui_fatal("open %s", fname);
 | 
					    if (fd < 0)
 | 
				
			||||||
	base = rindex(fname, '/');
 | 
					        gui_fatal("open %s", fname);
 | 
				
			||||||
	if (!base)
 | 
					
 | 
				
			||||||
		base = fname;
 | 
					    _Static_assert(DVM_FILENAME_SIZE > sizeof(DVM_VIEW_ONLY_PREFIX),
 | 
				
			||||||
	else
 | 
					            "DVM_FILENAME_SIZE > sizeof(DVM_VIEW_ONLY_PREFIX)");
 | 
				
			||||||
		base++;
 | 
					
 | 
				
			||||||
	if (strlen(base) >= DVM_FILENAME_SIZE)
 | 
					    if (view_only) {
 | 
				
			||||||
		base += strlen(base) - DVM_FILENAME_SIZE + 1;
 | 
					        strncpy(sendbuf, DVM_VIEW_ONLY_PREFIX, sendbuf_size);
 | 
				
			||||||
        strncpy(sendbuf,base,DVM_FILENAME_SIZE); /* fills out with NULs */
 | 
					        sendbuf_size -= strlen(DVM_VIEW_ONLY_PREFIX);
 | 
				
			||||||
	if (!write_all(1, sendbuf, DVM_FILENAME_SIZE))
 | 
					    }
 | 
				
			||||||
		gui_fatal("send filename to dispVM");
 | 
					    base = rindex(fname, '/');
 | 
				
			||||||
	if (!copy_fd_all(1, fd))
 | 
					    if (!base)
 | 
				
			||||||
		gui_fatal("send file to dispVM");
 | 
					        base = fname;
 | 
				
			||||||
	close(1);
 | 
					    else
 | 
				
			||||||
	close(fd);
 | 
					        base++;
 | 
				
			||||||
 | 
					    if (strlen(base) >= sendbuf_size)
 | 
				
			||||||
 | 
					        base += strlen(base) - sendbuf_size + 1;
 | 
				
			||||||
 | 
					    strncat(sendbuf,base,sendbuf_size - 1); /* fills out with NULs */
 | 
				
			||||||
 | 
					    sendbuf[DVM_FILENAME_SIZE - 1] = '\0';
 | 
				
			||||||
 | 
					    if (!write_all(1, sendbuf, DVM_FILENAME_SIZE))
 | 
				
			||||||
 | 
					        gui_fatal("send filename to dispVM");
 | 
				
			||||||
 | 
					    if (!copy_fd_all(1, fd))
 | 
				
			||||||
 | 
					        gui_fatal("send file to dispVM");
 | 
				
			||||||
 | 
					    close(1);
 | 
				
			||||||
 | 
					    close(fd);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int copy_and_return_nonemptiness(int tmpfd)
 | 
					int copy_and_return_nonemptiness(int tmpfd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct stat st;
 | 
					    struct stat st;
 | 
				
			||||||
	if (!copy_fd_all(tmpfd, 0))
 | 
					    if (!copy_fd_all(tmpfd, 0))
 | 
				
			||||||
		gui_fatal("receiving file from dispVM");
 | 
					        gui_fatal("receiving file from dispVM");
 | 
				
			||||||
	if (fstat(tmpfd, &st))
 | 
					    if (fstat(tmpfd, &st))
 | 
				
			||||||
		gui_fatal("fstat");
 | 
					        gui_fatal("fstat");
 | 
				
			||||||
	close(tmpfd);
 | 
					    close(tmpfd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return st.st_size > 0;
 | 
					    return st.st_size > 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void recv_file_nowrite(const char *fname)
 | 
					void recv_file_nowrite(const char *fname)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *tempfile;
 | 
					    char *tempfile;
 | 
				
			||||||
	char *errmsg;
 | 
					    char *errmsg;
 | 
				
			||||||
	int tmpfd = -1;
 | 
					    int tmpfd = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (asprintf(&tempfile, "/tmp/file_edited_in_dvm.XXXXXX") != -1)
 | 
					    if (asprintf(&tempfile, "/tmp/file_edited_in_dvm.XXXXXX") != -1)
 | 
				
			||||||
		tmpfd = mkstemp(tempfile);
 | 
					        tmpfd = mkstemp(tempfile);
 | 
				
			||||||
	if (tmpfd < 0)
 | 
					    if (tmpfd < 0)
 | 
				
			||||||
		gui_fatal("unable to create any temporary file, aborting");
 | 
					        gui_fatal("unable to create any temporary file, aborting");
 | 
				
			||||||
	if (!copy_and_return_nonemptiness(tmpfd)) {
 | 
					    if (!copy_and_return_nonemptiness(tmpfd)) {
 | 
				
			||||||
		unlink(tempfile);
 | 
					        unlink(tempfile);
 | 
				
			||||||
		return;
 | 
					        return;
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (asprintf(&errmsg,
 | 
					    if (asprintf(&errmsg,
 | 
				
			||||||
		 "The file %s has been edited in Disposable VM and the modified content has been received, "
 | 
					         "The file %s has been edited in Disposable VM and the modified content has been received, "
 | 
				
			||||||
		 "but this file is in nonwritable directory and thus cannot be modified safely. The edited file has been "
 | 
					         "but this file is in nonwritable directory and thus cannot be modified safely. The edited file has been "
 | 
				
			||||||
		 "saved to %s", fname, tempfile) != -1)
 | 
					         "saved to %s", fname, tempfile) != -1)
 | 
				
			||||||
        gui_nonfatal(errmsg);
 | 
					        gui_nonfatal(errmsg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void actually_recv_file(const char *fname, const char *tempfile, int tmpfd)
 | 
					void actually_recv_file(const char *fname, const char *tempfile, int tmpfd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!copy_and_return_nonemptiness(tmpfd)) {
 | 
					    if (!copy_and_return_nonemptiness(tmpfd)) {
 | 
				
			||||||
		unlink(tempfile);
 | 
					        unlink(tempfile);
 | 
				
			||||||
		return;
 | 
					        return;
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (rename(tempfile, fname))
 | 
					    if (rename(tempfile, fname))
 | 
				
			||||||
		gui_fatal("rename");
 | 
					        gui_fatal("rename");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void recv_file(const char *fname)
 | 
					void recv_file(const char *fname)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int tmpfd = -1;
 | 
					    int tmpfd = -1;
 | 
				
			||||||
	char *tempfile;
 | 
					    char *tempfile;
 | 
				
			||||||
	if (asprintf(&tempfile, "%s.XXXXXX", fname) != -1) {
 | 
					    if (asprintf(&tempfile, "%s.XXXXXX", fname) != -1) {
 | 
				
			||||||
		tmpfd = mkstemp(tempfile);
 | 
					        tmpfd = mkstemp(tempfile);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (tmpfd < 0)
 | 
					    if (tmpfd < 0)
 | 
				
			||||||
		recv_file_nowrite(fname);
 | 
					        recv_file_nowrite(fname);
 | 
				
			||||||
	else
 | 
					    else
 | 
				
			||||||
		actually_recv_file(fname, tempfile, tmpfd);
 | 
					        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)
 | 
					int main(int argc, char ** argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	signal(SIGPIPE, SIG_IGN);
 | 
					    char *fname;
 | 
				
			||||||
	if (argc!=2)
 | 
					    int view_only = 0;
 | 
				
			||||||
		gui_fatal("OpenInVM - no file given?");
 | 
					    int ret;
 | 
				
			||||||
	talk_to_daemon(argv[1]);
 | 
					    const struct option opts[] = {
 | 
				
			||||||
	return 0;
 | 
					        {"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 (optind >= argc)
 | 
				
			||||||
 | 
					        gui_fatal("OpenInVM - no file given?");
 | 
				
			||||||
 | 
					    fname = argv[optind];
 | 
				
			||||||
 | 
					    send_file(fname, view_only);
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -45,6 +45,12 @@ case "$action" in
 | 
				
			|||||||
            qvm-open-in-dvm "$file" | zenity --notification --text "Opening $file in DisposableVM..." --timeout 3 &
 | 
					            qvm-open-in-dvm "$file" | zenity --notification --text "Opening $file in DisposableVM..." --timeout 3 &
 | 
				
			||||||
        done
 | 
					        done
 | 
				
			||||||
        ;;
 | 
					        ;;
 | 
				
			||||||
 | 
					    viewdvm)
 | 
				
			||||||
 | 
					        for file in "$@"
 | 
				
			||||||
 | 
					        do
 | 
				
			||||||
 | 
					            qvm-open-in-dvm --view-only "$file" | zenity --notification --text "Opening $file in DisposableVM..." --timeout 3 &
 | 
				
			||||||
 | 
					        done
 | 
				
			||||||
 | 
					        ;;
 | 
				
			||||||
    *)
 | 
					    *)
 | 
				
			||||||
        echo "Unknown action. Aborting..."
 | 
					        echo "Unknown action. Aborting..."
 | 
				
			||||||
        exit 1
 | 
					        exit 1
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,15 @@
 | 
				
			|||||||
[Desktop Entry]
 | 
					[Desktop Entry]
 | 
				
			||||||
Actions=QvmDvm;
 | 
					Actions=QvmDvm;QvmViewDvm
 | 
				
			||||||
Type=Service
 | 
					Type=Service
 | 
				
			||||||
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,all/allfiles
 | 
					X-KDE-ServiceTypes=KonqPopupMenu/Plugin,all/allfiles
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Desktop Action QvmDvm]
 | 
					[Desktop Action QvmDvm]
 | 
				
			||||||
Exec=/usr/bin/qvm-open-in-dvm %U
 | 
					Exec=/usr/bin/qvm-open-in-dvm %U
 | 
				
			||||||
Icon=kget
 | 
					Icon=kget
 | 
				
			||||||
Name=Open In DisposableVM
 | 
					Name=Edit In DisposableVM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Desktop Action QvmViewDvm]
 | 
				
			||||||
 | 
					Exec=/usr/bin/qvm-open-in-dvm --view-only %U
 | 
				
			||||||
 | 
					Icon=kget
 | 
				
			||||||
 | 
					Name=View In DisposableVM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -20,10 +20,10 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ! [ $# = 1 ] ; then
 | 
					if ! [ $# = 1 ] && ! [ $# = 2 ]; then
 | 
				
			||||||
	echo "Usage: $0 filename"
 | 
						echo "Usage: $0 [--view-only] filename"
 | 
				
			||||||
	exit 1
 | 
						exit 1
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# shellcheck disable=SC2016
 | 
					# shellcheck disable=SC2016
 | 
				
			||||||
exec qvm-open-in-vm '$dispvm' "$1"
 | 
					exec qvm-open-in-vm '$dispvm' "$@"
 | 
				
			||||||
 | 
				
			|||||||
@ -20,16 +20,37 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ! [ $# = 2 ] ; then
 | 
					usage() {
 | 
				
			||||||
	echo "Usage: $0 vmname filename"
 | 
						echo "Usage: $0 [--view-only] vmname filename"
 | 
				
			||||||
	exit 1
 | 
						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
 | 
					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
 | 
					esac
 | 
				
			||||||
 | 
				
			|||||||
@ -26,11 +26,9 @@ class CopyToAppvmItemExtension(GObject.GObject, Nautilus.MenuProvider):
 | 
				
			|||||||
    def on_menu_item_clicked(self, menu, files):
 | 
					    def on_menu_item_clicked(self, menu, files):
 | 
				
			||||||
        '''Called when user chooses files though Nautilus context menu.
 | 
					        '''Called when user chooses files though Nautilus context menu.
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        for file_obj in files:
 | 
					        cmd = [file_obj.get_location().get_path()
 | 
				
			||||||
 | 
					               for file_obj in files
 | 
				
			||||||
            # Check if file still exists
 | 
					               # Check if file is not gone
 | 
				
			||||||
            if file_obj.is_gone():
 | 
					               if not file_obj.is_gone()]
 | 
				
			||||||
                return
 | 
					        cmd.insert(0, '/usr/lib/qubes/qvm-copy-to-vm.gnome')
 | 
				
			||||||
 | 
					        subprocess.call(cmd)
 | 
				
			||||||
            gio_file = file_obj.get_location()
 | 
					 | 
				
			||||||
            subprocess.call(['/usr/lib/qubes/qvm-copy-to-vm.gnome', gio_file.get_path()])
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -17,15 +17,24 @@ class OpenInDvmItemExtension(GObject.GObject, Nautilus.MenuProvider):
 | 
				
			|||||||
        if not files:
 | 
					        if not files:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        menu_item = Nautilus.MenuItem(name='QubesMenuProvider::OpenInDvm',
 | 
					        menu_item1 = Nautilus.MenuItem(name='QubesMenuProvider::OpenInDvm',
 | 
				
			||||||
                                      label='Open In DisposableVM',
 | 
					                                      label='Edit In DisposableVM',
 | 
				
			||||||
                                      tip='',
 | 
					                                      tip='',
 | 
				
			||||||
                                      icon='')
 | 
					                                      icon='')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        menu_item.connect('activate', self.on_menu_item_clicked, files)
 | 
					        menu_item1.connect('activate', self.on_menu_item_clicked, files)
 | 
				
			||||||
        return menu_item,
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def on_menu_item_clicked(self, menu, files):
 | 
					        menu_item2 = Nautilus.MenuItem(name='QubesMenuProvider::ViewInDvm',
 | 
				
			||||||
 | 
					                                      label='View In DisposableVM',
 | 
				
			||||||
 | 
					                                      tip='',
 | 
				
			||||||
 | 
					                                      icon='')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        menu_item2.connect('activate',
 | 
				
			||||||
 | 
					                self.on_menu_item_clicked,
 | 
				
			||||||
 | 
					                files, True)
 | 
				
			||||||
 | 
					        return menu_item1, menu_item2,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def on_menu_item_clicked(self, menu, files, view_only=False):
 | 
				
			||||||
        '''Called when user chooses files though Nautilus context menu.
 | 
					        '''Called when user chooses files though Nautilus context menu.
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        for file_obj in files:
 | 
					        for file_obj in files:
 | 
				
			||||||
@ -38,6 +47,11 @@ class OpenInDvmItemExtension(GObject.GObject, Nautilus.MenuProvider):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            # Use subprocess.DEVNULL in python >= 3.3
 | 
					            # Use subprocess.DEVNULL in python >= 3.3
 | 
				
			||||||
            devnull = open(os.devnull, 'wb')
 | 
					            devnull = open(os.devnull, 'wb')
 | 
				
			||||||
 | 
					            command = ['nohup', '/usr/bin/qvm-open-in-dvm']
 | 
				
			||||||
 | 
					            if view_only:
 | 
				
			||||||
 | 
					                command.append('--view-only')
 | 
				
			||||||
 | 
					            command.append(gio_file.get_path())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Use Popen instead of subprocess.call to spawn the process
 | 
					            # Use Popen instead of subprocess.call to spawn the process
 | 
				
			||||||
            Popen(['nohup', '/usr/bin/qvm-open-in-dvm', gio_file.get_path()], stdout=devnull, stderr=devnull)
 | 
					            Popen(command, stdout=devnull, stderr=devnull)
 | 
				
			||||||
 | 
					            devnull.close()
 | 
				
			||||||
 | 
				
			|||||||
@ -26,11 +26,9 @@ class MoveToAppvmItemExtension(GObject.GObject, Nautilus.MenuProvider):
 | 
				
			|||||||
    def on_menu_item_clicked(self, menu, files):
 | 
					    def on_menu_item_clicked(self, menu, files):
 | 
				
			||||||
        '''Called when user chooses files though Nautilus context menu.
 | 
					        '''Called when user chooses files though Nautilus context menu.
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        for file_obj in files:
 | 
					        cmd = [file_obj.get_location().get_path()
 | 
				
			||||||
 | 
					               for file_obj in files
 | 
				
			||||||
            # Check if file still exists
 | 
					               # Check if file is not gone
 | 
				
			||||||
            if file_obj.is_gone():
 | 
					               if not file_obj.is_gone()]
 | 
				
			||||||
                return
 | 
					        cmd.insert(0, '/usr/lib/qubes/qvm-move-to-vm.gnome')
 | 
				
			||||||
 | 
					        subprocess.call(cmd)
 | 
				
			||||||
            gio_file = file_obj.get_location()
 | 
					 | 
				
			||||||
            subprocess.call(['/usr/lib/qubes/qvm-move-to-vm.gnome', gio_file.get_path()])
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -708,6 +708,7 @@ ustar_rd (int fd, struct file_header * untrusted_hdr, char *buf, struct stat * s
 | 
				
			|||||||
        // Split the path in directories and recompose it incrementally
 | 
					        // Split the path in directories and recompose it incrementally
 | 
				
			||||||
	char * last_token = strtok(dirbuf,"/");
 | 
						char * last_token = strtok(dirbuf,"/");
 | 
				
			||||||
	char * token = strtok(NULL, "/");
 | 
						char * token = strtok(NULL, "/");
 | 
				
			||||||
 | 
						size_t len_last_token = 0;
 | 
				
			||||||
	while (token != NULL) {
 | 
						while (token != NULL) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
@ -715,21 +716,22 @@ ustar_rd (int fd, struct file_header * untrusted_hdr, char *buf, struct stat * s
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Recompose the path based on last discovered directory
 | 
							// Recompose the path based on last discovered directory
 | 
				
			||||||
 | 
							len_last_token = strlen(last_token);
 | 
				
			||||||
		if (path == NULL) {
 | 
							if (path == NULL) {
 | 
				
			||||||
			path = malloc(sizeof (char) * (strlen(last_token)+1));
 | 
								path = malloc(sizeof (char) * (len_last_token+1));
 | 
				
			||||||
			if (path == NULL)
 | 
								if (path == NULL)
 | 
				
			||||||
				return MEMORY_ALLOC_FAILED;
 | 
									return MEMORY_ALLOC_FAILED;
 | 
				
			||||||
			path = strncpy(path, last_token, strlen(last_token));
 | 
								path = memcpy(path, last_token, len_last_token);
 | 
				
			||||||
			path[strlen(last_token)] = '\0';
 | 
								path[len_last_token] = '\0';
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			pathsize = strlen(path);
 | 
								pathsize = strlen(path);
 | 
				
			||||||
			path = realloc(path, sizeof (char) * (strlen(path)+1+strlen(last_token)+1));
 | 
								path = realloc(path, sizeof (char) * (strlen(path)+1+len_last_token+1));
 | 
				
			||||||
			if (path == NULL)
 | 
								if (path == NULL)
 | 
				
			||||||
				return MEMORY_ALLOC_FAILED;
 | 
									return MEMORY_ALLOC_FAILED;
 | 
				
			||||||
			path[pathsize] = '/';
 | 
								path[pathsize] = '/';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			strncpy(path+pathsize+1, last_token, strlen(last_token));
 | 
								memcpy(path+pathsize+1, last_token, len_last_token);
 | 
				
			||||||
			path[pathsize+strlen(last_token)+1] = '\0';
 | 
								path[pathsize+len_last_token+1] = '\0';
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
		fprintf(stderr,"Path is %s\n",path);
 | 
							fprintf(stderr,"Path is %s\n",path);
 | 
				
			||||||
@ -762,7 +764,8 @@ ustar_rd (int fd, struct file_header * untrusted_hdr, char *buf, struct stat * s
 | 
				
			|||||||
			dirs_headers_sent[n_dirs-1] = malloc(sizeof (char) * (strlen(path)+1));
 | 
								dirs_headers_sent[n_dirs-1] = malloc(sizeof (char) * (strlen(path)+1));
 | 
				
			||||||
			if (dirs_headers_sent[n_dirs-1] == NULL)
 | 
								if (dirs_headers_sent[n_dirs-1] == NULL)
 | 
				
			||||||
				return MEMORY_ALLOC_FAILED;
 | 
									return MEMORY_ALLOC_FAILED;
 | 
				
			||||||
			strncpy(dirs_headers_sent[n_dirs-1], path, strlen(path)+1);
 | 
					
 | 
				
			||||||
 | 
								memcpy(dirs_headers_sent[n_dirs-1], path, strlen(path)+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        // Initialize the qfile headers for the current directory path
 | 
					                        // Initialize the qfile headers for the current directory path
 | 
				
			||||||
			dir_header.namelen = strlen(path)+1;
 | 
								dir_header.namelen = strlen(path)+1;
 | 
				
			||||||
 | 
				
			|||||||
@ -19,217 +19,227 @@ static const char *cleanup_dirname = NULL;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void cleanup_file(void)
 | 
					static void cleanup_file(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (cleanup_filename) {
 | 
					    if (cleanup_filename) {
 | 
				
			||||||
		if (unlink(cleanup_filename) < 0)
 | 
					        if (unlink(cleanup_filename) < 0)
 | 
				
			||||||
			fprintf(stderr, "Failed to remove file at exit\n");
 | 
					            fprintf(stderr, "Failed to remove file at exit\n");
 | 
				
			||||||
		cleanup_filename = NULL;
 | 
					        cleanup_filename = NULL;
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (cleanup_dirname) {
 | 
					    if (cleanup_dirname) {
 | 
				
			||||||
		if (rmdir(cleanup_dirname) < 0)
 | 
					        if (rmdir(cleanup_dirname) < 0)
 | 
				
			||||||
			fprintf(stderr, "Failed to remove directory at exit\n");
 | 
					            fprintf(stderr, "Failed to remove directory at exit\n");
 | 
				
			||||||
		cleanup_dirname = NULL;
 | 
					        cleanup_dirname = NULL;
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *gettime(void)
 | 
					const char *gettime(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char retbuf[60];
 | 
					    static char retbuf[60];
 | 
				
			||||||
	struct timeval tv;
 | 
					    struct timeval tv;
 | 
				
			||||||
	gettimeofday(&tv, NULL);
 | 
					    gettimeofday(&tv, NULL);
 | 
				
			||||||
	snprintf(retbuf, sizeof(retbuf), "%lld.%06lld",
 | 
					    snprintf(retbuf, sizeof(retbuf), "%lld.%06lld",
 | 
				
			||||||
		 (long long) tv.tv_sec, (long long) tv.tv_usec);
 | 
					         (long long) tv.tv_sec, (long long) tv.tv_usec);
 | 
				
			||||||
	return retbuf;
 | 
					    return retbuf;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *get_directory(void)
 | 
					static char *get_directory(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *remote_domain;
 | 
					    const char *remote_domain;
 | 
				
			||||||
	char *dir;
 | 
					    char *dir;
 | 
				
			||||||
	size_t len;
 | 
					    size_t len;
 | 
				
			||||||
	char *ret;
 | 
					    char *ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	remote_domain = getenv("QREXEC_REMOTE_DOMAIN");
 | 
					    remote_domain = getenv("QREXEC_REMOTE_DOMAIN");
 | 
				
			||||||
	if (!remote_domain) {
 | 
					    if (!remote_domain) {
 | 
				
			||||||
		fprintf(stderr, "Cannot get remote domain name\n");
 | 
					        fprintf(stderr, "Cannot get remote domain name\n");
 | 
				
			||||||
		exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (!*remote_domain || index(remote_domain, '/'))
 | 
					    if (!*remote_domain || index(remote_domain, '/'))
 | 
				
			||||||
		goto fail;
 | 
					        goto fail;
 | 
				
			||||||
	if (!strcmp(remote_domain, ".") || !strcmp(remote_domain, ".."))
 | 
					    if (!strcmp(remote_domain, ".") || !strcmp(remote_domain, ".."))
 | 
				
			||||||
		goto fail;
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	len = strlen("/tmp/-XXXXXX")+strlen(remote_domain)+1;
 | 
					    len = strlen("/tmp/-XXXXXX")+strlen(remote_domain)+1;
 | 
				
			||||||
	dir = malloc(len);
 | 
					    dir = malloc(len);
 | 
				
			||||||
	if (!dir) {
 | 
					    if (!dir) {
 | 
				
			||||||
		fprintf(stderr, "Cannot allocate memory\n");
 | 
					        fprintf(stderr, "Cannot allocate memory\n");
 | 
				
			||||||
		exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	snprintf(dir, len, "/tmp/%s-XXXXXX", remote_domain);
 | 
					    snprintf(dir, len, "/tmp/%s-XXXXXX", remote_domain);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = mkdtemp(dir);
 | 
					    ret = mkdtemp(dir);
 | 
				
			||||||
	if (ret == NULL) {
 | 
					    if (ret == NULL) {
 | 
				
			||||||
		perror("mkdtemp");
 | 
					        perror("mkdtemp");
 | 
				
			||||||
		exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	cleanup_dirname = strdup(ret);
 | 
					    cleanup_dirname = strdup(ret);
 | 
				
			||||||
	return ret;
 | 
					    return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fail:
 | 
					fail:
 | 
				
			||||||
	fprintf(stderr, "Invalid remote domain name: %s\n", remote_domain);
 | 
					    fprintf(stderr, "Invalid remote domain name: %s\n", remote_domain);
 | 
				
			||||||
	exit(1);
 | 
					    exit(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *get_filename(void)
 | 
					char *get_filename(int *view_only)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[DVM_FILENAME_SIZE];
 | 
					    char buf[DVM_FILENAME_SIZE];
 | 
				
			||||||
	static char *retname;
 | 
					    char *fname = buf;
 | 
				
			||||||
	int i;
 | 
					    static char *retname;
 | 
				
			||||||
	char *directory;
 | 
					    int i;
 | 
				
			||||||
	size_t len;
 | 
					    char *directory;
 | 
				
			||||||
 | 
					    size_t len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	directory = get_directory();
 | 
					    directory = get_directory();
 | 
				
			||||||
	if (!read_all(0, buf, sizeof(buf)))
 | 
					    if (!read_all(0, buf, sizeof(buf)))
 | 
				
			||||||
		exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	buf[DVM_FILENAME_SIZE-1] = 0;
 | 
					    buf[DVM_FILENAME_SIZE-1] = 0;
 | 
				
			||||||
	if (index(buf, '/')) {
 | 
					    if (index(buf, '/')) {
 | 
				
			||||||
		fprintf(stderr, "filename contains /");
 | 
					        fprintf(stderr, "filename contains /");
 | 
				
			||||||
		exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	for (i=0; buf[i]!=0; i++) {
 | 
					    for (i=0; buf[i]!=0; i++) {
 | 
				
			||||||
		// replace some characters with _ (eg mimeopen have problems with some of them)
 | 
					        // replace some characters with _ (eg mimeopen have problems with some of them)
 | 
				
			||||||
		if (index(" !?\"#$%^&*()[]<>;`~|", buf[i]))
 | 
					        if (index(" !?\"#$%^&*()[]<>;`~|", buf[i]))
 | 
				
			||||||
			buf[i]='_';
 | 
					            buf[i]='_';
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	len = strlen(directory)+1+strlen(buf)+1;
 | 
					    if (strncmp(buf, DVM_VIEW_ONLY_PREFIX, strlen(DVM_VIEW_ONLY_PREFIX)) == 0) {
 | 
				
			||||||
	retname = malloc(len);
 | 
					        *view_only = 1;
 | 
				
			||||||
	if (!retname) {
 | 
					        fname += strlen(DVM_VIEW_ONLY_PREFIX);
 | 
				
			||||||
		fprintf(stderr, "Cannot allocate memory\n");
 | 
					    }
 | 
				
			||||||
		exit(1);
 | 
					    len = strlen(directory)+1+strlen(fname)+1;
 | 
				
			||||||
	}
 | 
					    retname = malloc(len);
 | 
				
			||||||
	snprintf(retname, len, "%s/%s", directory, buf);
 | 
					    if (!retname) {
 | 
				
			||||||
	free(directory);
 | 
					        fprintf(stderr, "Cannot allocate memory\n");
 | 
				
			||||||
	return retname;
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    snprintf(retname, len, "%s/%s", directory, fname);
 | 
				
			||||||
 | 
					    free(directory);
 | 
				
			||||||
 | 
					    return retname;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void copy_file_by_name(const char *filename)
 | 
					void copy_file_by_name(const char *filename)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0600);
 | 
					    int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0600);
 | 
				
			||||||
	if (fd < 0) {
 | 
					    if (fd < 0) {
 | 
				
			||||||
		perror("open file");
 | 
					        perror("open file");
 | 
				
			||||||
		exit(1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	/* we now have created a new file, ensure we delete it at the end */
 | 
					 | 
				
			||||||
	cleanup_filename = strdup(filename);
 | 
					 | 
				
			||||||
	atexit(cleanup_file);
 | 
					 | 
				
			||||||
	if (!copy_fd_all(fd, 0))
 | 
					 | 
				
			||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	close(fd);
 | 
					    }
 | 
				
			||||||
 | 
					    /* we now have created a new file, ensure we delete it at the end */
 | 
				
			||||||
 | 
					    cleanup_filename = strdup(filename);
 | 
				
			||||||
 | 
					    atexit(cleanup_file);
 | 
				
			||||||
 | 
					    if (!copy_fd_all(fd, 0))
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    close(fd);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void send_file_back(const char * filename)
 | 
					void send_file_back(const char * filename)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int fd = open(filename, O_RDONLY);
 | 
					    int fd = open(filename, O_RDONLY);
 | 
				
			||||||
	if (fd < 0) {
 | 
					    if (fd < 0) {
 | 
				
			||||||
		perror("open file");
 | 
					        perror("open file");
 | 
				
			||||||
		exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (!copy_fd_all(1, fd))
 | 
					    if (!copy_fd_all(1, fd))
 | 
				
			||||||
	 exit(1);
 | 
					     exit(1);
 | 
				
			||||||
	close(fd);
 | 
					    close(fd);
 | 
				
			||||||
	close(1);
 | 
					    close(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
main()
 | 
					main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct stat stat_pre, stat_post, session_stat;
 | 
					    struct stat stat_pre, stat_post, session_stat;
 | 
				
			||||||
	char *filename = get_filename();
 | 
					    int view_only = 0;
 | 
				
			||||||
	int child, status, log_fd, null_fd;
 | 
					    char *filename = get_filename(&view_only);
 | 
				
			||||||
	FILE *waiter_pidfile;
 | 
					    int child, status, log_fd, null_fd;
 | 
				
			||||||
 | 
					    FILE *waiter_pidfile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	copy_file_by_name(filename);
 | 
					    copy_file_by_name(filename);
 | 
				
			||||||
	if (stat(filename, &stat_pre)) {
 | 
					    if (view_only) {
 | 
				
			||||||
		perror("stat pre");
 | 
					        // mark file as read-only so applications will signal it to the user
 | 
				
			||||||
		exit(1);
 | 
					        chmod(filename, 0400);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
 | 
					    if (stat(filename, &stat_pre)) {
 | 
				
			||||||
 | 
					        perror("stat pre");
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
	fprintf(stderr, "time=%s, waiting for qubes-session\n", gettime());
 | 
					    fprintf(stderr, "time=%s, waiting for qubes-session\n", gettime());
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	// wait for X server to starts (especially in DispVM)
 | 
					    // wait for X server to starts (especially in DispVM)
 | 
				
			||||||
	if (stat("/tmp/qubes-session-env", &session_stat)) {
 | 
					    if (stat("/tmp/qubes-session-env", &session_stat)) {
 | 
				
			||||||
		switch (child = fork()) {
 | 
					        switch (child = fork()) {
 | 
				
			||||||
			case -1:
 | 
					            case -1:
 | 
				
			||||||
				perror("fork");
 | 
					                perror("fork");
 | 
				
			||||||
				exit(1);
 | 
					                exit(1);
 | 
				
			||||||
			case 0:
 | 
					            case 0:
 | 
				
			||||||
				waiter_pidfile = fopen("/tmp/qubes-session-waiter", "a");
 | 
					                waiter_pidfile = fopen("/tmp/qubes-session-waiter", "a");
 | 
				
			||||||
				if (waiter_pidfile == NULL) {
 | 
					                if (waiter_pidfile == NULL) {
 | 
				
			||||||
					perror("fopen waiter_pidfile");
 | 
					                    perror("fopen waiter_pidfile");
 | 
				
			||||||
					exit(1);
 | 
					                    exit(1);
 | 
				
			||||||
				}
 | 
					                }
 | 
				
			||||||
				fprintf(waiter_pidfile, "%d\n", getpid());
 | 
					                fprintf(waiter_pidfile, "%d\n", getpid());
 | 
				
			||||||
				fclose(waiter_pidfile);
 | 
					                fclose(waiter_pidfile);
 | 
				
			||||||
				// check the second time, to prevent race
 | 
					                // check the second time, to prevent race
 | 
				
			||||||
				if (stat("/tmp/qubes-session-env", &session_stat)) {
 | 
					                if (stat("/tmp/qubes-session-env", &session_stat)) {
 | 
				
			||||||
					// wait for qubes-session notify
 | 
					                    // wait for qubes-session notify
 | 
				
			||||||
					pause();
 | 
					                    pause();
 | 
				
			||||||
				}
 | 
					                }
 | 
				
			||||||
				exit(0);
 | 
					                exit(0);
 | 
				
			||||||
			default:
 | 
					            default:
 | 
				
			||||||
				waitpid(child, &status, 0);
 | 
					                waitpid(child, &status, 0);
 | 
				
			||||||
				if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
 | 
					                if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
 | 
				
			||||||
					//propagate exit code from child
 | 
					                    //propagate exit code from child
 | 
				
			||||||
					exit(WEXITSTATUS(status));
 | 
					                    exit(WEXITSTATUS(status));
 | 
				
			||||||
				}
 | 
					                }
 | 
				
			||||||
		}
 | 
					        }
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
	fprintf(stderr, "time=%s, starting editor\n", gettime());
 | 
					    fprintf(stderr, "time=%s, starting editor\n", gettime());
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	switch (child = fork()) {
 | 
					    switch (child = fork()) {
 | 
				
			||||||
		case -1:
 | 
					        case -1:
 | 
				
			||||||
			perror("fork");
 | 
					            perror("fork");
 | 
				
			||||||
			exit(1);
 | 
					            exit(1);
 | 
				
			||||||
		case 0:
 | 
					        case 0:
 | 
				
			||||||
			null_fd = open("/dev/null", O_RDONLY);
 | 
					            null_fd = open("/dev/null", O_RDONLY);
 | 
				
			||||||
			dup2(null_fd, 0);
 | 
					            dup2(null_fd, 0);
 | 
				
			||||||
			close(null_fd);
 | 
					            close(null_fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			log_fd = open("/tmp/mimeopen.log", O_CREAT | O_APPEND, 0666);
 | 
					            log_fd = open("/tmp/mimeopen.log", O_CREAT | O_APPEND, 0666);
 | 
				
			||||||
			if (log_fd == -1) {
 | 
					            if (log_fd == -1) {
 | 
				
			||||||
				perror("open /tmp/mimeopen.log");
 | 
					                perror("open /tmp/mimeopen.log");
 | 
				
			||||||
				exit(1);
 | 
					                exit(1);
 | 
				
			||||||
			}
 | 
					            }
 | 
				
			||||||
			dup2(log_fd, 1);
 | 
					            dup2(log_fd, 1);
 | 
				
			||||||
			close(log_fd);
 | 
					            close(log_fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			setenv("HOME", USER_HOME, 1);
 | 
					            setenv("HOME", USER_HOME, 1);
 | 
				
			||||||
			setenv("DISPLAY", ":0", 1);
 | 
					            setenv("DISPLAY", ":0", 1);
 | 
				
			||||||
			execl("/usr/bin/qubes-open", "qubes-open", filename, (char*)NULL);
 | 
					            execl("/usr/bin/qubes-open", "qubes-open", filename, (char*)NULL);
 | 
				
			||||||
			perror("execl");
 | 
					            perror("execl");
 | 
				
			||||||
			exit(1);
 | 
					            exit(1);
 | 
				
			||||||
		default:
 | 
					        default:
 | 
				
			||||||
			waitpid(child, &status, 0);
 | 
					            waitpid(child, &status, 0);
 | 
				
			||||||
			if (status != 0) {
 | 
					            if (status != 0) {
 | 
				
			||||||
				char cmd[512];
 | 
					                char cmd[512];
 | 
				
			||||||
#ifdef USE_KDIALOG
 | 
					#ifdef USE_KDIALOG
 | 
				
			||||||
				snprintf(cmd, sizeof(cmd),
 | 
					                snprintf(cmd, sizeof(cmd),
 | 
				
			||||||
						"HOME=/home/user DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
 | 
					                        "HOME=/home/user DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
 | 
				
			||||||
					("HOME=/home/user DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
 | 
					                    ("HOME=/home/user DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
				snprintf(cmd, sizeof(cmd),
 | 
					                snprintf(cmd, sizeof(cmd),
 | 
				
			||||||
						"HOME=/home/user DISPLAY=:0 /usr/bin/zenity --error --text 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
 | 
					                        "HOME=/home/user DISPLAY=:0 /usr/bin/zenity --error --text 'Unable to handle mimetype of the requested file (exit status: %d)!' > /tmp/kdialog.log 2>&1 </dev/null", status);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
				status = system(cmd);
 | 
					                status = system(cmd);
 | 
				
			||||||
			}
 | 
					            }
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (stat(filename, &stat_post)) {
 | 
					    if (stat(filename, &stat_post)) {
 | 
				
			||||||
		perror("stat post");
 | 
					        perror("stat post");
 | 
				
			||||||
		exit(1);
 | 
					        exit(1);
 | 
				
			||||||
	}
 | 
					    }
 | 
				
			||||||
	if (stat_pre.st_mtime != stat_post.st_mtime)
 | 
					    if (stat_pre.st_mtime != stat_post.st_mtime)
 | 
				
			||||||
		send_file_back(filename);
 | 
					        send_file_back(filename);
 | 
				
			||||||
	free(filename);
 | 
					    free(filename);
 | 
				
			||||||
	return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -54,6 +54,22 @@ class FirewallWorker(object):
 | 
				
			|||||||
        '''Create appropriate chains/tables'''
 | 
					        '''Create appropriate chains/tables'''
 | 
				
			||||||
        raise NotImplementedError
 | 
					        raise NotImplementedError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def sd_notify(self, state):
 | 
				
			||||||
 | 
					        '''Send notification to systemd, if available'''
 | 
				
			||||||
 | 
					        # based on sdnotify python module
 | 
				
			||||||
 | 
					        if not 'NOTIFY_SOCKET' in os.environ:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        addr = os.environ['NOTIFY_SOCKET']
 | 
				
			||||||
 | 
					        if addr[0] == '@':
 | 
				
			||||||
 | 
					            addr = '\0' + addr[1:]
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
 | 
				
			||||||
 | 
					            sock.connect(addr)
 | 
				
			||||||
 | 
					            sock.sendall(state.encode())
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            # generally ignore error on systemd notification
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def cleanup(self):
 | 
					    def cleanup(self):
 | 
				
			||||||
        '''Remove tables/chains - reverse work done by init'''
 | 
					        '''Remove tables/chains - reverse work done by init'''
 | 
				
			||||||
        raise NotImplementedError
 | 
					        raise NotImplementedError
 | 
				
			||||||
@ -155,6 +171,7 @@ class FirewallWorker(object):
 | 
				
			|||||||
        self.init()
 | 
					        self.init()
 | 
				
			||||||
        self.run_firewall_dir()
 | 
					        self.run_firewall_dir()
 | 
				
			||||||
        self.run_user_script()
 | 
					        self.run_user_script()
 | 
				
			||||||
 | 
					        self.sd_notify('READY=1')
 | 
				
			||||||
        # initial load
 | 
					        # initial load
 | 
				
			||||||
        for source_addr in self.list_targets():
 | 
					        for source_addr in self.list_targets():
 | 
				
			||||||
            self.handle_addr(source_addr)
 | 
					            self.handle_addr(source_addr)
 | 
				
			||||||
@ -313,6 +330,16 @@ class IptablesWorker(FirewallWorker):
 | 
				
			|||||||
            if dsthosts is None:
 | 
					            if dsthosts is None:
 | 
				
			||||||
                dsthosts = [None]
 | 
					                dsthosts = [None]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if rule['action'] == 'accept':
 | 
				
			||||||
 | 
					                action = 'ACCEPT'
 | 
				
			||||||
 | 
					            elif rule['action'] == 'drop':
 | 
				
			||||||
 | 
					                action = 'REJECT --reject-with {}'.format(
 | 
				
			||||||
 | 
					                    'icmp6-adm-prohibited' if family == 6 else
 | 
				
			||||||
 | 
					                    'icmp-admin-prohibited')
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                raise RuleParseError(
 | 
				
			||||||
 | 
					                    'Invalid rule action {}'.format(rule['action']))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # sorting here is only to ease writing tests
 | 
					            # sorting here is only to ease writing tests
 | 
				
			||||||
            for proto in sorted(protos):
 | 
					            for proto in sorted(protos):
 | 
				
			||||||
                for dsthost in sorted(dsthosts):
 | 
					                for dsthost in sorted(dsthosts):
 | 
				
			||||||
@ -325,8 +352,7 @@ class IptablesWorker(FirewallWorker):
 | 
				
			|||||||
                        ipt_rule += ' --dport {}'.format(dstports)
 | 
					                        ipt_rule += ' --dport {}'.format(dstports)
 | 
				
			||||||
                    if icmptype is not None:
 | 
					                    if icmptype is not None:
 | 
				
			||||||
                        ipt_rule += ' --icmp-type {}'.format(icmptype)
 | 
					                        ipt_rule += ' --icmp-type {}'.format(icmptype)
 | 
				
			||||||
                    ipt_rule += ' -j {}\n'.format(
 | 
					                    ipt_rule += ' -j {}\n'.format(action)
 | 
				
			||||||
                        str(rule['action']).upper())
 | 
					 | 
				
			||||||
                    iptables += ipt_rule
 | 
					                    iptables += ipt_rule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        iptables += 'COMMIT\n'
 | 
					        iptables += 'COMMIT\n'
 | 
				
			||||||
@ -370,8 +396,12 @@ class IptablesWorker(FirewallWorker):
 | 
				
			|||||||
        # starting qubes-firewall
 | 
					        # starting qubes-firewall
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            self.run_ipt(4, ['-F', 'QBS-FORWARD'])
 | 
					            self.run_ipt(4, ['-F', 'QBS-FORWARD'])
 | 
				
			||||||
 | 
					            self.run_ipt(4,
 | 
				
			||||||
 | 
					                ['-A', 'QBS-FORWARD', '!', '-i', 'vif+', '-j', 'RETURN'])
 | 
				
			||||||
            self.run_ipt(4, ['-A', 'QBS-FORWARD', '-j', 'DROP'])
 | 
					            self.run_ipt(4, ['-A', 'QBS-FORWARD', '-j', 'DROP'])
 | 
				
			||||||
            self.run_ipt(6, ['-F', 'QBS-FORWARD'])
 | 
					            self.run_ipt(6, ['-F', 'QBS-FORWARD'])
 | 
				
			||||||
 | 
					            self.run_ipt(6,
 | 
				
			||||||
 | 
					                ['-A', 'QBS-FORWARD', '!', '-i', 'vif+', '-j', 'RETURN'])
 | 
				
			||||||
            self.run_ipt(6, ['-A', 'QBS-FORWARD', '-j', 'DROP'])
 | 
					            self.run_ipt(6, ['-A', 'QBS-FORWARD', '-j', 'DROP'])
 | 
				
			||||||
        except subprocess.CalledProcessError:
 | 
					        except subprocess.CalledProcessError:
 | 
				
			||||||
            self.log_error('\'QBS-FORWARD\' chain not found, create it first')
 | 
					            self.log_error('\'QBS-FORWARD\' chain not found, create it first')
 | 
				
			||||||
@ -470,6 +500,15 @@ class NftablesWorker(FirewallWorker):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            nft_rule = ""
 | 
					            nft_rule = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if rule['action'] == 'accept':
 | 
				
			||||||
 | 
					                action = 'accept'
 | 
				
			||||||
 | 
					            elif rule['action'] == 'drop':
 | 
				
			||||||
 | 
					                action = 'reject with icmp{} type admin-prohibited'.format(
 | 
				
			||||||
 | 
					                    'v6' if family == 6 else '')
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                raise RuleParseError(
 | 
				
			||||||
 | 
					                    'Invalid rule action {}'.format(rule['action']))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if 'proto' in rule:
 | 
					            if 'proto' in rule:
 | 
				
			||||||
                if family == 4:
 | 
					                if family == 4:
 | 
				
			||||||
                    nft_rule += ' ip protocol {}'.format(rule['proto'])
 | 
					                    nft_rule += ' ip protocol {}'.format(rule['proto'])
 | 
				
			||||||
@ -523,16 +562,16 @@ class NftablesWorker(FirewallWorker):
 | 
				
			|||||||
                if 'proto' not in rule:
 | 
					                if 'proto' not in rule:
 | 
				
			||||||
                    nft_rules.append(
 | 
					                    nft_rules.append(
 | 
				
			||||||
                        nft_rule + ' tcp dport {} {}'.format(
 | 
					                        nft_rule + ' tcp dport {} {}'.format(
 | 
				
			||||||
                            dstports, rule['action']))
 | 
					                            dstports, action))
 | 
				
			||||||
                    nft_rules.append(
 | 
					                    nft_rules.append(
 | 
				
			||||||
                        nft_rule + ' udp dport {} {}'.format(
 | 
					                        nft_rule + ' udp dport {} {}'.format(
 | 
				
			||||||
                            dstports, rule['action']))
 | 
					                            dstports, action))
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    nft_rules.append(
 | 
					                    nft_rules.append(
 | 
				
			||||||
                        nft_rule + ' {} dport {} {}'.format(
 | 
					                        nft_rule + ' {} dport {} {}'.format(
 | 
				
			||||||
                            rule['proto'], dstports, rule['action']))
 | 
					                            rule['proto'], dstports, action))
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                nft_rules.append(nft_rule + ' ' + rule['action'])
 | 
					                nft_rules.append(nft_rule + ' ' + action)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            'flush chain {family} {table} {chain}\n'
 | 
					            'flush chain {family} {table} {chain}\n'
 | 
				
			||||||
@ -579,6 +618,7 @@ class NftablesWorker(FirewallWorker):
 | 
				
			|||||||
            '    type filter hook forward priority 0;\n'
 | 
					            '    type filter hook forward priority 0;\n'
 | 
				
			||||||
            '    policy drop;\n'
 | 
					            '    policy drop;\n'
 | 
				
			||||||
            '    ct state established,related accept\n'
 | 
					            '    ct state established,related accept\n'
 | 
				
			||||||
 | 
					            '    meta iifname != "vif*" accept\n'
 | 
				
			||||||
            '  }}\n'
 | 
					            '  }}\n'
 | 
				
			||||||
            '}}\n'
 | 
					            '}}\n'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
				
			|||||||
@ -198,10 +198,14 @@ class TestIptablesWorker(TestCase):
 | 
				
			|||||||
            "-A chain -d 2.2.2.2/32 -p tcp --dport 53:53 -j ACCEPT\n"
 | 
					            "-A chain -d 2.2.2.2/32 -p tcp --dport 53:53 -j ACCEPT\n"
 | 
				
			||||||
            "-A chain -d 1.1.1.1/32 -p udp --dport 53:53 -j ACCEPT\n"
 | 
					            "-A chain -d 1.1.1.1/32 -p udp --dport 53:53 -j ACCEPT\n"
 | 
				
			||||||
            "-A chain -d 2.2.2.2/32 -p udp --dport 53:53 -j ACCEPT\n"
 | 
					            "-A chain -d 2.2.2.2/32 -p udp --dport 53:53 -j ACCEPT\n"
 | 
				
			||||||
            "-A chain -d 1.1.1.1/32 -p udp --dport 53:53 -j DROP\n"
 | 
					            "-A chain -d 1.1.1.1/32 -p udp --dport 53:53 -j REJECT "
 | 
				
			||||||
            "-A chain -d 2.2.2.2/32 -p udp --dport 53:53 -j DROP\n"
 | 
					            "--reject-with icmp-admin-prohibited\n"
 | 
				
			||||||
            "-A chain -p icmp -j DROP\n"
 | 
					            "-A chain -d 2.2.2.2/32 -p udp --dport 53:53 -j REJECT "
 | 
				
			||||||
            "-A chain -j DROP\n"
 | 
					            "--reject-with icmp-admin-prohibited\n"
 | 
				
			||||||
 | 
					            "-A chain -p icmp -j REJECT "
 | 
				
			||||||
 | 
					            "--reject-with icmp-admin-prohibited\n"
 | 
				
			||||||
 | 
					            "-A chain -j REJECT "
 | 
				
			||||||
 | 
					            "--reject-with icmp-admin-prohibited\n"
 | 
				
			||||||
            "COMMIT\n"
 | 
					            "COMMIT\n"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.assertEqual(self.obj.prepare_rules('chain', rules, 4),
 | 
					        self.assertEqual(self.obj.prepare_rules('chain', rules, 4),
 | 
				
			||||||
@ -232,10 +236,14 @@ class TestIptablesWorker(TestCase):
 | 
				
			|||||||
            "-A chain -d 2001::2/128 -p tcp --dport 53:53 -j ACCEPT\n"
 | 
					            "-A chain -d 2001::2/128 -p tcp --dport 53:53 -j ACCEPT\n"
 | 
				
			||||||
            "-A chain -d 2001::1/128 -p udp --dport 53:53 -j ACCEPT\n"
 | 
					            "-A chain -d 2001::1/128 -p udp --dport 53:53 -j ACCEPT\n"
 | 
				
			||||||
            "-A chain -d 2001::2/128 -p udp --dport 53:53 -j ACCEPT\n"
 | 
					            "-A chain -d 2001::2/128 -p udp --dport 53:53 -j ACCEPT\n"
 | 
				
			||||||
            "-A chain -d 2001::1/128 -p udp --dport 53:53 -j DROP\n"
 | 
					            "-A chain -d 2001::1/128 -p udp --dport 53:53 -j REJECT "
 | 
				
			||||||
            "-A chain -d 2001::2/128 -p udp --dport 53:53 -j DROP\n"
 | 
					            "--reject-with icmp6-adm-prohibited\n"
 | 
				
			||||||
            "-A chain -p icmpv6 -j DROP\n"
 | 
					            "-A chain -d 2001::2/128 -p udp --dport 53:53 -j REJECT "
 | 
				
			||||||
            "-A chain -j DROP\n"
 | 
					            "--reject-with icmp6-adm-prohibited\n"
 | 
				
			||||||
 | 
					            "-A chain -p icmpv6 -j REJECT "
 | 
				
			||||||
 | 
					            "--reject-with icmp6-adm-prohibited\n"
 | 
				
			||||||
 | 
					            "-A chain -j REJECT "
 | 
				
			||||||
 | 
					            "--reject-with icmp6-adm-prohibited\n"
 | 
				
			||||||
            "COMMIT\n"
 | 
					            "COMMIT\n"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self.assertEqual(self.obj.prepare_rules('chain', rules, 6),
 | 
					        self.assertEqual(self.obj.prepare_rules('chain', rules, 6),
 | 
				
			||||||
@ -271,10 +279,14 @@ class TestIptablesWorker(TestCase):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def test_006_init(self):
 | 
					    def test_006_init(self):
 | 
				
			||||||
        self.obj.init()
 | 
					        self.obj.init()
 | 
				
			||||||
        self.assertEqual(self.obj.called_commands[4],
 | 
					        self.assertEqual(self.obj.called_commands[4], [
 | 
				
			||||||
            [['-F', 'QBS-FORWARD'], ['-A', 'QBS-FORWARD', '-j', 'DROP']])
 | 
					            ['-F', 'QBS-FORWARD'],
 | 
				
			||||||
        self.assertEqual(self.obj.called_commands[6],
 | 
					            ['-A', 'QBS-FORWARD', '!', '-i', 'vif+', '-j', 'RETURN'],
 | 
				
			||||||
            [['-F', 'QBS-FORWARD'], ['-A', 'QBS-FORWARD', '-j', 'DROP']])
 | 
					            ['-A', 'QBS-FORWARD', '-j', 'DROP']])
 | 
				
			||||||
 | 
					        self.assertEqual(self.obj.called_commands[6], [
 | 
				
			||||||
 | 
					            ['-F', 'QBS-FORWARD'],
 | 
				
			||||||
 | 
					            ['-A', 'QBS-FORWARD', '!', '-i', 'vif+', '-j', 'RETURN'],
 | 
				
			||||||
 | 
					            ['-A', 'QBS-FORWARD', '-j', 'DROP']])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_007_cleanup(self):
 | 
					    def test_007_cleanup(self):
 | 
				
			||||||
        self.obj.init()
 | 
					        self.obj.init()
 | 
				
			||||||
@ -363,9 +375,9 @@ class TestNftablesWorker(TestCase):
 | 
				
			|||||||
            '    ip daddr { 1.1.1.1/32, 2.2.2.2/32 } tcp dport 53 accept\n'
 | 
					            '    ip daddr { 1.1.1.1/32, 2.2.2.2/32 } tcp dport 53 accept\n'
 | 
				
			||||||
            '    ip daddr { 1.1.1.1/32, 2.2.2.2/32 } udp dport 53 accept\n'
 | 
					            '    ip daddr { 1.1.1.1/32, 2.2.2.2/32 } udp dport 53 accept\n'
 | 
				
			||||||
            '    ip protocol udp ip daddr { 1.1.1.1/32, 2.2.2.2/32 } udp dport '
 | 
					            '    ip protocol udp ip daddr { 1.1.1.1/32, 2.2.2.2/32 } udp dport '
 | 
				
			||||||
            '53 drop\n'
 | 
					            '53 reject with icmp type admin-prohibited\n'
 | 
				
			||||||
            '    ip protocol icmp drop\n'
 | 
					            '    ip protocol icmp reject with icmp type admin-prohibited\n'
 | 
				
			||||||
            '    drop\n'
 | 
					            '    reject with icmp type admin-prohibited\n'
 | 
				
			||||||
            '  }\n'
 | 
					            '  }\n'
 | 
				
			||||||
            '}\n'
 | 
					            '}\n'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@ -399,9 +411,10 @@ class TestNftablesWorker(TestCase):
 | 
				
			|||||||
            '    ip6 daddr { 2001::1/128, 2001::2/128 } tcp dport 53 accept\n'
 | 
					            '    ip6 daddr { 2001::1/128, 2001::2/128 } tcp dport 53 accept\n'
 | 
				
			||||||
            '    ip6 daddr { 2001::1/128, 2001::2/128 } udp dport 53 accept\n'
 | 
					            '    ip6 daddr { 2001::1/128, 2001::2/128 } udp dport 53 accept\n'
 | 
				
			||||||
            '    ip6 nexthdr udp ip6 daddr { 2001::1/128, 2001::2/128 } '
 | 
					            '    ip6 nexthdr udp ip6 daddr { 2001::1/128, 2001::2/128 } '
 | 
				
			||||||
            'udp dport 53 drop\n'
 | 
					            'udp dport 53 reject with icmpv6 type admin-prohibited\n'
 | 
				
			||||||
            '    ip6 nexthdr icmpv6 icmpv6 type 128 drop\n'
 | 
					            '    ip6 nexthdr icmpv6 icmpv6 type 128 reject with icmpv6 type '
 | 
				
			||||||
            '    drop\n'
 | 
					            'admin-prohibited\n'
 | 
				
			||||||
 | 
					            '    reject with icmpv6 type admin-prohibited\n'
 | 
				
			||||||
            '  }\n'
 | 
					            '  }\n'
 | 
				
			||||||
            '}\n'
 | 
					            '}\n'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@ -435,6 +448,7 @@ class TestNftablesWorker(TestCase):
 | 
				
			|||||||
            '    type filter hook forward priority 0;\n'
 | 
					            '    type filter hook forward priority 0;\n'
 | 
				
			||||||
            '    policy drop;\n'
 | 
					            '    policy drop;\n'
 | 
				
			||||||
            '    ct state established,related accept\n'
 | 
					            '    ct state established,related accept\n'
 | 
				
			||||||
 | 
					            '    meta iifname != "vif*" accept\n'
 | 
				
			||||||
            '  }\n'
 | 
					            '  }\n'
 | 
				
			||||||
            '}\n'
 | 
					            '}\n'
 | 
				
			||||||
            'table ip6 qubes-firewall {\n'
 | 
					            'table ip6 qubes-firewall {\n'
 | 
				
			||||||
@ -442,6 +456,7 @@ class TestNftablesWorker(TestCase):
 | 
				
			|||||||
            '    type filter hook forward priority 0;\n'
 | 
					            '    type filter hook forward priority 0;\n'
 | 
				
			||||||
            '    policy drop;\n'
 | 
					            '    policy drop;\n'
 | 
				
			||||||
            '    ct state established,related accept\n'
 | 
					            '    ct state established,related accept\n'
 | 
				
			||||||
 | 
					            '    meta iifname != "vif*" accept\n'
 | 
				
			||||||
            '  }\n'
 | 
					            '  }\n'
 | 
				
			||||||
            '}\n'
 | 
					            '}\n'
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,15 @@
 | 
				
			|||||||
#!/usr/bin/python
 | 
					#!/usr/bin/python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from gi.repository import Gio
 | 
					from gi.repository import Gio  # pylint: disable=import-error
 | 
				
			||||||
 | 
					from gi.repository import GLib  # pylint: disable=import-error
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def launch(desktop, *files):
 | 
					def pid_callback(launcher, pid, pid_list):
 | 
				
			||||||
 | 
					    pid_list.append(pid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def launch(desktop, *files, **kwargs):
 | 
				
			||||||
 | 
					    wait = kwargs.pop('wait', True)
 | 
				
			||||||
    launcher = Gio.DesktopAppInfo.new_from_filename(desktop)
 | 
					    launcher = Gio.DesktopAppInfo.new_from_filename(desktop)
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        import dbus
 | 
					        import dbus
 | 
				
			||||||
@ -18,10 +24,17 @@ def launch(desktop, *files):
 | 
				
			|||||||
                    bus.start_service_by_name(service_id)
 | 
					                    bus.start_service_by_name(service_id)
 | 
				
			||||||
                except dbus.DBusException:
 | 
					                except dbus.DBusException:
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
        return launcher.launch(files, None)
 | 
					 | 
				
			||||||
    except ImportError:
 | 
					    except ImportError:
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
    launcher.launch(files, None)
 | 
					    if wait:
 | 
				
			||||||
 | 
					        pid_list = []
 | 
				
			||||||
 | 
					        flags = GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD
 | 
				
			||||||
 | 
					        launcher.launch_uris_as_manager(files, None, flags, None, None,
 | 
				
			||||||
 | 
					                pid_callback, pid_list)
 | 
				
			||||||
 | 
					        for pid in pid_list:
 | 
				
			||||||
 | 
					            os.waitpid(pid, 0)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        launcher.launch(files, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    launch(*sys.argv[1:])
 | 
					    launch(*sys.argv[1:])
 | 
				
			||||||
@ -23,9 +23,6 @@
 | 
				
			|||||||
%define qubes_services qubes-core qubes-core-netvm qubes-core-early qubes-firewall qubes-iptables qubes-updates-proxy qubes-qrexec-agent qubes-updates-proxy-forwarder
 | 
					%define qubes_services qubes-core qubes-core-netvm qubes-core-early qubes-firewall qubes-iptables qubes-updates-proxy qubes-qrexec-agent qubes-updates-proxy-forwarder
 | 
				
			||||||
%define qubes_preset_file 75-qubes-vm.preset
 | 
					%define qubes_preset_file 75-qubes-vm.preset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%{!?version: %define version %(cat version)}
 | 
					 | 
				
			||||||
%{!?backend_vmm: %define backend_vmm %(echo $BACKEND_VMM)}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
%define scriptletfuns is_static() { \
 | 
					%define scriptletfuns is_static() { \
 | 
				
			||||||
    [ -f "%{_unitdir}/$1" ] && ! grep -q '^[[].nstall]' "%{_unitdir}/$1" \
 | 
					    [ -f "%{_unitdir}/$1" ] && ! grep -q '^[[].nstall]' "%{_unitdir}/$1" \
 | 
				
			||||||
} \
 | 
					} \
 | 
				
			||||||
@ -104,7 +101,7 @@ restore_units() { \
 | 
				
			|||||||
} \
 | 
					} \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Name:		qubes-core-agent
 | 
					Name:		qubes-core-agent
 | 
				
			||||||
Version:	%{version}
 | 
					Version:	@VERSION@
 | 
				
			||||||
Release:	1%{dist}
 | 
					Release:	1%{dist}
 | 
				
			||||||
Summary:	The Qubes core files for VM
 | 
					Summary:	The Qubes core files for VM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -112,14 +109,9 @@ Group:		Qubes
 | 
				
			|||||||
Vendor:		Invisible Things Lab
 | 
					Vendor:		Invisible Things Lab
 | 
				
			||||||
License:	GPL
 | 
					License:	GPL
 | 
				
			||||||
URL:		http://www.qubes-os.org
 | 
					URL:		http://www.qubes-os.org
 | 
				
			||||||
%if %{fedora} < 22
 | 
					
 | 
				
			||||||
Requires:   yum-plugin-post-transaction-actions
 | 
					 | 
				
			||||||
%endif
 | 
					 | 
				
			||||||
%if %{fedora} >= 18
 | 
					 | 
				
			||||||
# Fedora >= 18 defaults to firewalld, which isn't supported nor needed by Qubes
 | 
					 | 
				
			||||||
Conflicts:  firewalld
 | 
					Conflicts:  firewalld
 | 
				
			||||||
%endif
 | 
					Requires:   xdg-utils
 | 
				
			||||||
Requires:	xdg-utils
 | 
					 | 
				
			||||||
Requires:   qubes-utils >= 3.1.3
 | 
					Requires:   qubes-utils >= 3.1.3
 | 
				
			||||||
Requires:   qubes-utils-libs >= 4.0.16
 | 
					Requires:   qubes-utils-libs >= 4.0.16
 | 
				
			||||||
Requires:   initscripts
 | 
					Requires:   initscripts
 | 
				
			||||||
@ -137,10 +129,11 @@ Requires:   python2-qubesdb
 | 
				
			|||||||
Requires:   ImageMagick
 | 
					Requires:   ImageMagick
 | 
				
			||||||
Requires:   librsvg2-tools
 | 
					Requires:   librsvg2-tools
 | 
				
			||||||
Requires:   zenity
 | 
					Requires:   zenity
 | 
				
			||||||
 | 
					Requires:   dconf
 | 
				
			||||||
Requires:   qubes-core-agent-qrexec
 | 
					Requires:   qubes-core-agent-qrexec
 | 
				
			||||||
Requires:   qubes-libvchan
 | 
					Requires:   qubes-libvchan
 | 
				
			||||||
Requires:   qubes-db-vm
 | 
					Requires:   qubes-db-vm
 | 
				
			||||||
%if 0%{fedora} >= 23
 | 
					%if 0%{?fedora} >= 23
 | 
				
			||||||
Requires:   python3-dnf-plugins-qubes-hooks
 | 
					Requires:   python3-dnf-plugins-qubes-hooks
 | 
				
			||||||
%else
 | 
					%else
 | 
				
			||||||
Requires:   python2-dnf-plugins-qubes-hooks
 | 
					Requires:   python2-dnf-plugins-qubes-hooks
 | 
				
			||||||
@ -158,8 +151,13 @@ BuildRequires: pandoc
 | 
				
			|||||||
BuildRequires: xen-devel
 | 
					BuildRequires: xen-devel
 | 
				
			||||||
BuildRequires: libX11-devel
 | 
					BuildRequires: libX11-devel
 | 
				
			||||||
BuildRequires: qubes-utils-devel >= 3.1.3
 | 
					BuildRequires: qubes-utils-devel >= 3.1.3
 | 
				
			||||||
BuildRequires: qubes-libvchan-%{backend_vmm}-devel
 | 
					BuildRequires: qubes-libvchan-@BACKEND_VMM@-devel
 | 
				
			||||||
BuildRequires: pam-devel
 | 
					BuildRequires: pam-devel
 | 
				
			||||||
 | 
					%if 0%{?rhel} >= 7
 | 
				
			||||||
 | 
					BuildRequires: python-setuptools
 | 
				
			||||||
 | 
					%endif
 | 
				
			||||||
 | 
					BuildRequires: systemd
 | 
				
			||||||
 | 
					Source0: %{name}-%{version}.tar.gz
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%description
 | 
					%description
 | 
				
			||||||
The Qubes core files for installation inside a Qubes VM.
 | 
					The Qubes core files for installation inside a Qubes VM.
 | 
				
			||||||
@ -174,29 +172,15 @@ DNF plugin for Qubes specific post-installation actions:
 | 
				
			|||||||
 * notify dom0 that updates were installed
 | 
					 * notify dom0 that updates were installed
 | 
				
			||||||
 * refresh applications shortcut list
 | 
					 * refresh applications shortcut list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%if 0%{fedora} >= 23
 | 
					%package -n python%{python3_pkgversion}-dnf-plugins-qubes-hooks
 | 
				
			||||||
%package -n python3-dnf-plugins-qubes-hooks
 | 
					 | 
				
			||||||
Summary:        DNF plugin for Qubes specific post-installation actions
 | 
					Summary:        DNF plugin for Qubes specific post-installation actions
 | 
				
			||||||
BuildRequires: python3-devel
 | 
					BuildRequires: python%{python3_pkgversion}-devel
 | 
				
			||||||
%{?python_provide:%python_provide python3-dnf-plugins-qubes-hooks}
 | 
					%{?python_provide:%python_provide python%{python3_pkgversion}-dnf-plugins-qubes-hooks}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%description -n python3-dnf-plugins-qubes-hooks
 | 
					%description -n python%{python3_pkgversion}-dnf-plugins-qubes-hooks
 | 
				
			||||||
DNF plugin for Qubes specific post-installation actions:
 | 
					DNF plugin for Qubes specific post-installation actions:
 | 
				
			||||||
 * notify dom0 that updates were installed
 | 
					 * notify dom0 that updates were installed
 | 
				
			||||||
 * refresh applications shortcut list
 | 
					 * refresh applications shortcut list
 | 
				
			||||||
%endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
%if 0%{?rhel} >= 7
 | 
					 | 
				
			||||||
%package -n python34-dnf-plugins-qubes-hooks
 | 
					 | 
				
			||||||
Summary:        DNF plugin for Qubes specific post-installation actions
 | 
					 | 
				
			||||||
BuildRequires: python34-devel
 | 
					 | 
				
			||||||
%{?python_provide:%python_provide python34-dnf-plugins-qubes-hooks}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
%description -n python34-dnf-plugins-qubes-hooks
 | 
					 | 
				
			||||||
DNF plugin for Qubes specific post-installation actions:
 | 
					 | 
				
			||||||
 * notify dom0 that updates were installed
 | 
					 | 
				
			||||||
 * refresh applications shortcut list
 | 
					 | 
				
			||||||
%endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
%package qrexec
 | 
					%package qrexec
 | 
				
			||||||
Summary:    Qubes qrexec agent
 | 
					Summary:    Qubes qrexec agent
 | 
				
			||||||
@ -277,21 +261,15 @@ Requires: Thunar
 | 
				
			|||||||
%description thunar
 | 
					%description thunar
 | 
				
			||||||
Thunar support for Qubes VM tools
 | 
					Thunar support for Qubes VM tools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%define _builddir %(pwd)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
%define kde_service_dir /usr/share/kde4/services
 | 
					%define kde_service_dir /usr/share/kde4/services
 | 
				
			||||||
%define kde5_service_dir /usr/share/kservices5/ServiceMenus
 | 
					%define kde5_service_dir /usr/share/kservices5/ServiceMenus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%prep
 | 
					%prep
 | 
				
			||||||
# we operate on the current directory, so no need to unpack anything
 | 
					%setup -q
 | 
				
			||||||
# symlink is to generate useful debuginfo packages
 | 
					 | 
				
			||||||
rm -f %{name}-%{version}
 | 
					 | 
				
			||||||
ln -sf . %{name}-%{version}
 | 
					 | 
				
			||||||
%setup -T -D
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
%build
 | 
					%build
 | 
				
			||||||
for dir in qubes-rpc qrexec misc; do
 | 
					for dir in qubes-rpc qrexec misc; do
 | 
				
			||||||
  (cd $dir; make)
 | 
					  make -C $dir BACKEND_VMM=@BACKEND_VMM@
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
make -C doc manpages
 | 
					make -C doc manpages
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -353,6 +331,7 @@ for F in plymouth-shutdown prefdm splash-manager start-ttys tty ; do
 | 
				
			|||||||
	fi
 | 
						fi
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					chgrp user /var/lib/qubes/dom0-updates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Remove old firmware updates link
 | 
					# Remove old firmware updates link
 | 
				
			||||||
if [ -L /lib/firmware/updates ]; then
 | 
					if [ -L /lib/firmware/updates ]; then
 | 
				
			||||||
@ -365,6 +344,12 @@ if test -f /etc/yum.conf && ! grep -q '/etc/yum\.conf\.d/qubes-proxy\.conf' /etc
 | 
				
			|||||||
  echo 'include=file:///etc/yum.conf.d/qubes-proxy.conf' >> /etc/yum.conf
 | 
					  echo 'include=file:///etc/yum.conf.d/qubes-proxy.conf' >> /etc/yum.conf
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ! [ -r /etc/dconf/profile/user ]; then
 | 
				
			||||||
 | 
					    mkdir -p /etc/dconf/profile
 | 
				
			||||||
 | 
					    echo "user-db:user" >> /etc/dconf/profile/user
 | 
				
			||||||
 | 
					    echo "system-db:local" >> /etc/dconf/profile/user
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dconf update &> /dev/null || :
 | 
					dconf update &> /dev/null || :
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# And actually setup the proxy usage in package managers
 | 
					# And actually setup the proxy usage in package managers
 | 
				
			||||||
@ -609,10 +594,7 @@ rm -f %{name}-%{version}
 | 
				
			|||||||
%config(noreplace) /etc/yum.repos.d/qubes-r4.repo
 | 
					%config(noreplace) /etc/yum.repos.d/qubes-r4.repo
 | 
				
			||||||
/etc/yum/pluginconf.d/yum-qubes-hooks.conf
 | 
					/etc/yum/pluginconf.d/yum-qubes-hooks.conf
 | 
				
			||||||
%config(noreplace) /etc/dnf/plugins/qubes-hooks.conf
 | 
					%config(noreplace) /etc/dnf/plugins/qubes-hooks.conf
 | 
				
			||||||
%if 0%{?fedora} >= 23
 | 
					 | 
				
			||||||
%config(noreplace) /etc/dconf/profile/user
 | 
					 | 
				
			||||||
%config(noreplace) /etc/dconf/db/local.d/dpi
 | 
					%config(noreplace) /etc/dconf/db/local.d/dpi
 | 
				
			||||||
%endif
 | 
					 | 
				
			||||||
/usr/lib/systemd/system/user@.service.d/90-session-stop-timeout.conf
 | 
					/usr/lib/systemd/system/user@.service.d/90-session-stop-timeout.conf
 | 
				
			||||||
/usr/sbin/qubes-serial-login
 | 
					/usr/sbin/qubes-serial-login
 | 
				
			||||||
/usr/bin/qvm-copy-to-vm
 | 
					/usr/bin/qvm-copy-to-vm
 | 
				
			||||||
@ -626,6 +608,7 @@ rm -f %{name}-%{version}
 | 
				
			|||||||
/usr/bin/qvm-sync-clock
 | 
					/usr/bin/qvm-sync-clock
 | 
				
			||||||
/usr/bin/xenstore-watch-qubes
 | 
					/usr/bin/xenstore-watch-qubes
 | 
				
			||||||
/usr/bin/qubes-desktop-run
 | 
					/usr/bin/qubes-desktop-run
 | 
				
			||||||
 | 
					/usr/bin/qubes-run-terminal
 | 
				
			||||||
/usr/bin/qubes-open
 | 
					/usr/bin/qubes-open
 | 
				
			||||||
/usr/bin/qubes-session-autostart
 | 
					/usr/bin/qubes-session-autostart
 | 
				
			||||||
%dir /usr/lib/qubes
 | 
					%dir /usr/lib/qubes
 | 
				
			||||||
@ -664,7 +647,7 @@ rm -f %{name}-%{version}
 | 
				
			|||||||
/usr/lib/qubes/init/functions
 | 
					/usr/lib/qubes/init/functions
 | 
				
			||||||
%dir /usr/lib/qubes-bind-dirs.d
 | 
					%dir /usr/lib/qubes-bind-dirs.d
 | 
				
			||||||
/usr/lib/qubes-bind-dirs.d/30_cron.conf
 | 
					/usr/lib/qubes-bind-dirs.d/30_cron.conf
 | 
				
			||||||
/usr/lib/python2.7/site-packages/qubesxdg.py*
 | 
					/usr/share/applications/qubes-run-terminal.desktop
 | 
				
			||||||
/usr/share/qubes/serial.conf
 | 
					/usr/share/qubes/serial.conf
 | 
				
			||||||
/usr/share/glib-2.0/schemas/20_org.gnome.settings-daemon.plugins.updates.qubes.gschema.override
 | 
					/usr/share/glib-2.0/schemas/20_org.gnome.settings-daemon.plugins.updates.qubes.gschema.override
 | 
				
			||||||
/usr/share/glib-2.0/schemas/20_org.gnome.nautilus.qubes.gschema.override
 | 
					/usr/share/glib-2.0/schemas/20_org.gnome.nautilus.qubes.gschema.override
 | 
				
			||||||
@ -678,6 +661,7 @@ rm -f %{name}-%{version}
 | 
				
			|||||||
%{python_sitelib}/qubesagent/__init__.py*
 | 
					%{python_sitelib}/qubesagent/__init__.py*
 | 
				
			||||||
%{python_sitelib}/qubesagent/firewall.py*
 | 
					%{python_sitelib}/qubesagent/firewall.py*
 | 
				
			||||||
%{python_sitelib}/qubesagent/test_firewall.py*
 | 
					%{python_sitelib}/qubesagent/test_firewall.py*
 | 
				
			||||||
 | 
					%{python_sitelib}/qubesagent/xdg.py*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/usr/share/qubes/mime-override/globs
 | 
					/usr/share/qubes/mime-override/globs
 | 
				
			||||||
/usr/share/qubes/qubes-master-key.asc
 | 
					/usr/share/qubes/qubes-master-key.asc
 | 
				
			||||||
@ -687,7 +671,7 @@ rm -f %{name}-%{version}
 | 
				
			|||||||
%files -n python2-dnf-plugins-qubes-hooks
 | 
					%files -n python2-dnf-plugins-qubes-hooks
 | 
				
			||||||
%{python2_sitelib}/dnf-plugins/*
 | 
					%{python2_sitelib}/dnf-plugins/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%if 0%{fedora} >= 23
 | 
					%if 0%{?fedora} >= 23
 | 
				
			||||||
%files -n python3-dnf-plugins-qubes-hooks
 | 
					%files -n python3-dnf-plugins-qubes-hooks
 | 
				
			||||||
%{python3_sitelib}/dnf-plugins/*
 | 
					%{python3_sitelib}/dnf-plugins/*
 | 
				
			||||||
%endif
 | 
					%endif
 | 
				
			||||||
@ -817,9 +801,6 @@ for svc in %qubes_services ; do
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# dropped services
 | 
					 | 
				
			||||||
chkconfig qubes-netwatcher off || :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# TODO: make this not display the silly message about security context...
 | 
					# TODO: make this not display the silly message about security context...
 | 
				
			||||||
sed -i s/^id:.:initdefault:/id:3:initdefault:/ /etc/inittab
 | 
					sed -i s/^id:.:initdefault:/id:3:initdefault:/ /etc/inittab
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -967,3 +948,6 @@ if [ "x$changed" != "x" ]
 | 
				
			|||||||
then
 | 
					then
 | 
				
			||||||
    systemctl daemon-reload
 | 
					    systemctl daemon-reload
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%changelog
 | 
				
			||||||
 | 
					@CHANGELOG@
 | 
				
			||||||
@ -10,4 +10,4 @@ export PYTHONPATH
 | 
				
			|||||||
[ -r version ] || ln -s ${ROOTDIR}/version ./
 | 
					[ -r version ] || ln -s ${ROOTDIR}/version ./
 | 
				
			||||||
[ -r setup.py ] || ln -s ${ROOTDIR}/setup.py ./
 | 
					[ -r setup.py ] || ln -s ${ROOTDIR}/setup.py ./
 | 
				
			||||||
"${PYTHON}" ./setup.py egg_info --egg-base "${TESTPYTHONPATH}"
 | 
					"${PYTHON}" ./setup.py egg_info --egg-base "${TESTPYTHONPATH}"
 | 
				
			||||||
"${PYTHON}" -m coverage run -m unittest discover -p '*.py' -v "$@"
 | 
					"${PYTHON}" -m coverage run -m unittest discover -p 'test_*.py' -v "$@"
 | 
				
			||||||
 | 
				
			|||||||
@ -56,6 +56,7 @@ disable smartd.service
 | 
				
			|||||||
disable upower.service
 | 
					disable upower.service
 | 
				
			||||||
disable colord.service
 | 
					disable colord.service
 | 
				
			||||||
disable wpa_supplicant@.service
 | 
					disable wpa_supplicant@.service
 | 
				
			||||||
 | 
					disable dkms.service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Fedora only services
 | 
					# Fedora only services
 | 
				
			||||||
disable cpuspeed.service
 | 
					disable cpuspeed.service
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@ After=qubes-iptables.service
 | 
				
			|||||||
Before=qubes-network.service
 | 
					Before=qubes-network.service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Service]
 | 
					[Service]
 | 
				
			||||||
 | 
					Type=notify
 | 
				
			||||||
ExecStart=/usr/sbin/qubes-firewall
 | 
					ExecStart=/usr/sbin/qubes-firewall
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Install]
 | 
					[Install]
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
[Unit]
 | 
					[Unit]
 | 
				
			||||||
Description=Qubes misc post-boot actions
 | 
					Description=Qubes misc post-boot actions
 | 
				
			||||||
After=network-pre.target qubes-mount-dirs.service qubes-network.service qubes-firewall.service qubes-netwatcher.service
 | 
					After=network-pre.target qubes-mount-dirs.service qubes-network.service qubes-firewall.service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Service]
 | 
					[Service]
 | 
				
			||||||
Type=oneshot
 | 
					Type=oneshot
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user