diff --git a/appvm/copy_file.c b/appvm/copy_file.c index 5f7fc793..9e65c652 100644 --- a/appvm/copy_file.c +++ b/appvm/copy_file.c @@ -1,8 +1,10 @@ #include #include +#include "filecopy.h" + extern void notify_progress(int, int); -char * copy_file(int outfd, int infd, long long size) +int copy_file(int outfd, int infd, long long size) { char buf[4096]; long long written = 0; @@ -15,14 +17,24 @@ char * copy_file(int outfd, int infd, long long size) count = size - written; ret = read(infd, buf, count); if (!ret) - return("EOF while reading file"); + return COPY_FILE_READ_EOF; if (ret < 0) - return("error reading file"); + return COPY_FILE_READ_ERROR; if (!write_all(outfd, buf, ret)) - return("error writing file content"); + return COPY_FILE_WRITE_ERROR; notify_progress(ret, 0); written += ret; } - return NULL; + return COPY_FILE_OK; } +char * copy_file_status_to_str(int status) +{ + switch (status) { + case COPY_FILE_OK: return "OK"; + case COPY_FILE_READ_EOF: return "Unexpected end of data while reading"; + case COPY_FILE_READ_ERROR: return "Error reading"; + case COPY_FILE_WRITE_ERROR: return "Error writing"; + default: return "????????"; + } +} diff --git a/appvm/filecopy.h b/appvm/filecopy.h index b4f6638c..1fcd2d04 100644 --- a/appvm/filecopy.h +++ b/appvm/filecopy.h @@ -6,13 +6,21 @@ #define LEGAL_EOF 31415926 struct file_header { -unsigned int namelen; -unsigned int mode; -unsigned long long filelen; -unsigned int atime; -unsigned int atime_nsec; -unsigned int mtime; -unsigned int mtime_nsec; + unsigned int namelen; + unsigned int mode; + unsigned long long filelen; + unsigned int atime; + unsigned int atime_nsec; + unsigned int mtime; + unsigned int mtime_nsec; }; -char * copy_file(int outfd, int infd, long long size); +enum { + COPY_FILE_OK, + COPY_FILE_READ_EOF, + COPY_FILE_READ_ERROR, + COPY_FILE_WRITE_ERROR +}; + +int copy_file(int outfd, int infd, long long size); +char *copy_file_status_to_str(int status); diff --git a/appvm/qfile-agent.c b/appvm/qfile-agent.c index f7e27a98..e33b61c6 100644 --- a/appvm/qfile-agent.c +++ b/appvm/qfile-agent.c @@ -50,7 +50,7 @@ void write_headers(struct file_header *hdr, char *filename) { if (!write_all(1, hdr, sizeof(*hdr)) || !write_all(1, filename, hdr->namelen)) - gui_fatal("writing file headers to remove AppVM"); + exit(1); } int single_file_processor(char *filename, struct stat *st) @@ -67,15 +67,21 @@ int single_file_processor(char *filename, struct stat *st) hdr.mtime_nsec = st->st_mtim.tv_nsec; if (S_ISREG(mode)) { - char *ret; + int ret; fd = open(filename, O_RDONLY); if (!fd) gui_fatal("open %s", filename); hdr.filelen = st->st_size; write_headers(&hdr, filename); ret = copy_file(1, fd, hdr.filelen); - if (ret) - gui_fatal("Copying file %s: %s", filename, ret); + // if COPY_FILE_WRITE_ERROR, hopefully remote will produce a message + if (ret != COPY_FILE_OK) { + if (ret != COPY_FILE_WRITE_ERROR) + gui_fatal("Copying file %s: %s", filename, + copy_file_status_to_str(ret)); + else + exit(1); + } close(fd); } if (S_ISDIR(mode)) { @@ -89,7 +95,7 @@ int single_file_processor(char *filename, struct stat *st) hdr.filelen = st->st_size + 1; write_headers(&hdr, filename); if (!write_all(1, name, st->st_size + 1)) - gui_fatal("write to remote VM"); + exit(1); } return 0; } @@ -130,7 +136,7 @@ void send_vmname(char *vmname) memset(buf, 0, sizeof(buf)); strncat(buf, vmname, sizeof(buf) - 1); if (!write_all(1, buf, sizeof buf)) - gui_fatal("writing vmname to remote VM"); + exit(1); } char *get_item(char *data, char **current, int size) diff --git a/appvm/qvm-copy-to-vm b/appvm/qvm-copy-to-vm new file mode 100755 index 00000000..4817b43b --- /dev/null +++ b/appvm/qvm-copy-to-vm @@ -0,0 +1,69 @@ +#!/bin/sh +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010 Rafal Wojtczuk +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + +if [ x"$1" = "x--with-progress" ] ; then + DO_PROGRESS=1 + shift +else + DO_PROGRESS=0 +fi + +if [ $# -lt 2 ] ; then + echo usage: $0 '[--with-progress] dest_vmname file [file]+' + exit 1 +fi + +VM="$1" +shift + +if [ $DO_PROGRESS = 1 ] ; then + SIZE=$(du --apparent-size -c "$@" | tail -1 | cut -f 1) +fi + +export PROGRESS_FILE=$(mktemp) +/usr/lib/qubes/qvm-trigger-copy-to-vm $VM "$@" +while ! [ -s $PROGRESS_FILE ] ; do + sleep 0.1 +done + +while true ; do + read agentpid sentsize agentstatus < $PROGRESS_FILE + if [ "x"$agentstatus = x ] ; then continue ; fi + if ! [ -e /proc/$agentpid ] ; then break ; fi + if [ "x"$agentstatus = xdone ] ; then break ; fi + CURRSIZE=$(($sentsize/1024)) + if [ $DO_PROGRESS = 1 ] ; then + echo -ne "\r sent $CURRSIZE/$SIZE KB " + fi + sleep 0.4 +done + +rm -f $PROGRESS_FILE +if [ $DO_PROGRESS = 1 ] ; then + echo +fi + +if ! [ "x"$agentstatus = xDONE ] ; then + exit 1 +else + exit 0 +fi diff --git a/appvm/qvm-copy-to-vm2.kde b/appvm/qvm-copy-to-vm2.kde index 879279be..7600bb56 100755 --- a/appvm/qvm-copy-to-vm2.kde +++ b/appvm/qvm-copy-to-vm2.kde @@ -23,17 +23,18 @@ VM=$(kdialog -inputbox "Enter the VM name to send files to:") if [ X$VM = X ] ; then exit 0 ; fi -SIZE=$(du -c "$@" | tail -1 | cut -f 1) +SIZE=$(du --apparent-size -c "$@" | tail -1 | cut -f 1) REF=$(kdialog --progressbar "Copy progress") qdbus $REF org.freedesktop.DBus.Properties.Set "" maximum $SIZE export PROGRESS_FILE=$(mktemp) -qvm-copy-to-vm2 $VM "$@" +/usr/lib/qubes/qvm-trigger-copy-to-vm $VM "$@" while ! [ -s $PROGRESS_FILE ] ; do sleep 0.1 done while true ; do read agentpid sentsize agentstatus < $PROGRESS_FILE + if [ "x"$agentstatus = x ] ; then continue ; fi if ! [ -e /proc/$agentpid ] ; then break ; fi if [ "x"$agentstatus = xdone ] ; then break ; fi CURRSIZE=$(($sentsize/1024)) @@ -43,6 +44,7 @@ done qdbus $REF close rm -f $PROGRESS_FILE -if ! [ "x"$agentstatus = xDONE ] ; then - kdialog --sorry 'Abnormal file copy termination; see /var/log/qubes/qrexec.xid.log in dom0 for more details' -fi +# we do not want a dozen error messages, do we +# if ! [ "x"$agentstatus = xDONE ] ; then +# kdialog --sorry 'Abnormal file copy termination; see /var/log/qubes/qrexec.xid.log in dom0 for more details' +# fi diff --git a/appvm/qvm-copy-to-vm2 b/appvm/qvm-trigger-copy-to-vm similarity index 100% rename from appvm/qvm-copy-to-vm2 rename to appvm/qvm-trigger-copy-to-vm diff --git a/appvm/unpack.c b/appvm/unpack.c index ad53ebf5..eaa1744c 100644 --- a/appvm/unpack.c +++ b/appvm/unpack.c @@ -38,14 +38,19 @@ void fix_times_and_perms(struct file_header *hdr, char *name) void process_one_file_reg(struct file_header *hdr, char *name) { - char *ret; + int ret; int fdout = open(name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0700); if (fdout < 0) do_exit(errno); ret = copy_file(fdout, 0, hdr->filelen); - if (ret) - do_exit(errno); + if (ret != COPY_FILE_OK) { + if (ret == COPY_FILE_READ_EOF + || ret == COPY_FILE_READ_ERROR) + do_exit(LEGAL_EOF); // hopefully remote will produce error message + else + do_exit(errno); + } close(fdout); fix_times_and_perms(hdr, name); } @@ -68,7 +73,7 @@ void process_one_file_link(struct file_header *hdr, char *name) if (hdr->filelen > MAX_PATH_LENGTH - 1) do_exit(ENAMETOOLONG); if (!read_all(0, content, hdr->filelen)) - do_exit(errno); + do_exit(LEGAL_EOF); // hopefully remote has produced error message content[hdr->filelen] = 0; if (symlink(content, name)) do_exit(errno); @@ -80,7 +85,7 @@ void process_one_file(struct file_header *hdr) if (hdr->namelen > MAX_PATH_LENGTH - 1) do_exit(ENAMETOOLONG); if (!read_all(0, namebuf, hdr->namelen)) - do_exit(errno); + do_exit(LEGAL_EOF); // hopefully remote has produced error message namebuf[hdr->namelen] = 0; if (S_ISREG(hdr->mode)) process_one_file_reg(hdr, namebuf); diff --git a/common/qubes_fix_nm_conf.sh b/common/qubes_fix_nm_conf.sh index 5a6bb305..613fa159 100755 --- a/common/qubes_fix_nm_conf.sh +++ b/common/qubes_fix_nm_conf.sh @@ -3,6 +3,8 @@ FILE=/etc/NetworkManager/NetworkManager.conf VIFMAC=mac:fe:ff:ff:ff:ff:ff if ! grep -q ^plugins.*keyfile $FILE ; then sed -i 's/^plugins.*$/&,keyfile/' $FILE +fi +if ! grep -q '^\[keyfile\]$' $FILE ; then echo '[keyfile]' >> $FILE fi if ! grep -q ^unmanaged-devices $FILE ; then diff --git a/dom0/init.d/qubes_setupdvm b/dom0/init.d/qubes_setupdvm index 25a12903..4bc13349 100755 --- a/dom0/init.d/qubes_setupdvm +++ b/dom0/init.d/qubes_setupdvm @@ -30,20 +30,33 @@ start() if ! [ -f $ROOT ] ; then create_neeed=1 ; fi if [ $ROOT -nt $DEFAULT ] ; then create_neeed=1 ; fi if [ $create_neeed = 1 ] ; then - echo Creating the default DVM. This may take up to 2 minutes... - qvm-create-default-dvm --default-template --default-script + MSG="Creating default DVM. This may take up to 2 minutes..." + echo " $MSG" + if [ -x /usr/bin/plymouth ]; then + /usr/bin/plymouth message --text="$MSG" + /usr/bin/plymouth pause-progress + fi + qvm-create-default-dvm --default-template --default-script + DVMDIR="/var/lib/qubes/appvms/`qvm-get-default-template`-dvm" + /bin/chown -R root.qubes "$DVMDIR" + /bin/chmod -R ug=rwX,o=rX "$DVMDIR" + if [ -x /usr/bin/plymouth ]; then + /usr/bin/plymouth message --text="" + /usr/bin/plymouth unpause-progress + fi + success return - fi + fi if [ -f /var/lib/qubes/dvmdata/dont_use_shm ] ; then ln -s $DEFAULT /var/run/qubes/current_savefile else - mkdir -m 770 /dev/shm/qubes - chown root.qubes /dev/shm/qubes - cp $DEFAULT /dev/shm/qubes/current_savefile - chown root.qubes /dev/shm/qubes/current_savefile - chmod 660 /dev/shm/qubes/current_savefile - ln -s /dev/shm/qubes/current_savefile /var/run/qubes/current_savefile - fi + mkdir -m 770 /dev/shm/qubes + chown root.qubes /dev/shm/qubes + cp $DEFAULT /dev/shm/qubes/current_savefile + chown root.qubes /dev/shm/qubes/current_savefile + chmod 660 /dev/shm/qubes/current_savefile + ln -s /dev/shm/qubes/current_savefile /var/run/qubes/current_savefile + fi touch /var/lock/subsys/qubes_setupdvm success @@ -60,15 +73,15 @@ stop() case "$1" in start) - start - ;; + start + ;; stop) - stop - ;; + stop + ;; *) - echo $"Usage: $0 {start|stop}" - exit 3 - ;; + echo $"Usage: $0 {start|stop}" + exit 3 + ;; esac exit $RETVAL diff --git a/dom0/qvm-core/qubes.py b/dom0/qvm-core/qubes.py index 8ce6897b..59f3a416 100755 --- a/dom0/qvm-core/qubes.py +++ b/dom0/qvm-core/qubes.py @@ -1340,7 +1340,7 @@ class QubesProxyVm(QubesNetVm): iptables += "-A FORWARD -i vif{0}.0 -j {1}\n".format(xid, default_action) iptables += "#End of VM rules\n" - iptables += "-A FORWARD -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT\n" + iptables += "-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n" iptables += "-A FORWARD -j DROP\n" iptables += "COMMIT" diff --git a/dom0/restore/qfile-daemon-dvm b/dom0/restore/qfile-daemon-dvm index 886d858b..9cfa629e 100755 --- a/dom0/restore/qfile-daemon-dvm +++ b/dom0/restore/qfile-daemon-dvm @@ -23,6 +23,7 @@ import os import dbus import subprocess import sys +import fcntl from qubes.qubes import QubesVmCollection from qubes.qubes import QubesException @@ -123,7 +124,10 @@ def main(): global notify_object notify_object = dbus.SessionBus().get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications") qfile = QfileDaemonDvm(os.getenv("QREXEC_REMOTE_DOMAIN")) + lockf = open("/var/run/qubes/qfile-daemon-dvm.lock", 'a') + fcntl.flock(lockf, fcntl.LOCK_EX) dispname = qfile.get_dvm() + lockf.close() if dispname is not None: subprocess.call(['/usr/lib/qubes/qrexec_client', '-d', dispname, 'directly:user:/usr/lib/qubes/dvm_file_editor']) subprocess.call(['/usr/sbin/xm', 'destroy', dispname]) diff --git a/proxyvm/bin/qubes_netwatcher b/proxyvm/bin/qubes_netwatcher index 8f9d2e9c..a2568079 100755 --- a/proxyvm/bin/qubes_netwatcher +++ b/proxyvm/bin/qubes_netwatcher @@ -18,6 +18,7 @@ while true; do /sbin/service qubes_firewall stop /sbin/service qubes_firewall start CURR_NETCFG="$NETCFG" + /usr/bin/xenstore-write qubes_netvm_external_ip "$CURR_NETCFG" fi /usr/bin/xenstore-watch /local/domain/$NET_DOMID/qubes_netvm_external_ip diff --git a/rpm_spec/core-appvm.spec b/rpm_spec/core-appvm.spec index f5b8fa0f..5b4005b0 100644 --- a/rpm_spec/core-appvm.spec +++ b/rpm_spec/core-appvm.spec @@ -54,6 +54,9 @@ exit 0 fi adduser --create-home user +su user -c 'mkdir -p /home/user/.gnome2/nautilus-scripts' +su user -c 'ln -s /usr/lib/qubes/qvm-copy-to-vm2.kde /home/user/.gnome2/nautilus-scripts/"Copy to other AppVM"' +su user -c 'ln -s /usr/bin/qvm-open-in-dvm2 /home/user/.gnome2/nautilus-scripts/"Open in DisposableVM"' mkdir -p $RPM_BUILD_ROOT/var/lib/qubes @@ -71,9 +74,10 @@ cp qubes_core_appvm $RPM_BUILD_ROOT/etc/init.d/ mkdir -p $RPM_BUILD_ROOT/var/lib/qubes mkdir -p $RPM_BUILD_ROOT/usr/bin cp qubes_timestamp qvm-open-in-dvm2 $RPM_BUILD_ROOT/usr/bin -cp qvm-copy-to-vm2 $RPM_BUILD_ROOT/usr/bin +cp qvm-copy-to-vm $RPM_BUILD_ROOT/usr/bin mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes cp qvm-copy-to-vm2.kde $RPM_BUILD_ROOT/usr/lib/qubes +cp qvm-trigger-copy-to-vm $RPM_BUILD_ROOT/usr/lib/qubes cp ../qrexec/qrexec_agent $RPM_BUILD_ROOT/usr/lib/qubes cp dvm_file_editor qfile-agent qfile-agent-dvm qfile-unpacker $RPM_BUILD_ROOT/usr/lib/qubes cp ../common/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes @@ -123,13 +127,14 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) /etc/init.d/qubes_core_appvm -/usr/bin/qvm-copy-to-vm2 +/usr/bin/qvm-copy-to-vm /usr/lib/qubes/qvm-copy-to-vm2.kde /usr/bin/qvm-open-in-dvm2 /usr/lib/qubes/meminfo-writer /usr/lib/qubes/dvm_file_editor %{kde_service_dir}/qvm-copy.desktop %{kde_service_dir}/qvm-dvm.desktop +/usr/lib/qubes/qvm-trigger-copy-to-vm /usr/lib/qubes/qrexec_agent /usr/lib/qubes/qfile-agent /usr/lib/qubes/qfile-agent-dvm diff --git a/rpm_spec/core-commonvm.spec b/rpm_spec/core-commonvm.spec index ee4c49ba..ea4bacca 100644 --- a/rpm_spec/core-commonvm.spec +++ b/rpm_spec/core-commonvm.spec @@ -33,6 +33,7 @@ License: GPL URL: http://www.qubes-os.org Requires: /usr/bin/xenstore-read Requires: fedora-release +BuildRequires: xen-devel %define _builddir %(pwd)/common diff --git a/rpm_spec/core-netvm.spec b/rpm_spec/core-netvm.spec index d09139b0..a4c966b9 100644 --- a/rpm_spec/core-netvm.spec +++ b/rpm_spec/core-netvm.spec @@ -68,6 +68,12 @@ cp ../common/vif-route-qubes $RPM_BUILD_ROOT/etc/xen/scripts %post +# Create NetworkManager configuration if we do not have it +if ! [ -e /etc/NetworkManager/NetworkManager.conf ]; then +echo '[main]' > /etc/NetworkManager/NetworkManager.conf +echo 'plugins = keyfile' >> /etc/NetworkManager/NetworkManager.conf +echo '[keyfile]' >> /etc/NetworkManager/NetworkManager.conf +fi /usr/lib/qubes/qubes_fix_nm_conf.sh chkconfig --add qubes_core_netvm || echo "WARNING: Cannot add service qubes_core!" diff --git a/version_dom0 b/version_dom0 index 4cda8f19..94fe62c2 100644 --- a/version_dom0 +++ b/version_dom0 @@ -1 +1 @@ -1.5.2 +1.5.4 diff --git a/version_vm b/version_vm index 4cda8f19..94fe62c2 100644 --- a/version_vm +++ b/version_vm @@ -1 +1 @@ -1.5.2 +1.5.4