Merge branch 'qrexec2' of git://git.qubes-os.org/rafal/core

This commit is contained in:
Marek Marczykowski 2011-07-09 13:10:35 +02:00
commit f1321e0904
16 changed files with 101 additions and 234 deletions

View File

@ -1,9 +1,9 @@
CC=gcc CC=gcc
CFLAGS=-g -Wall -I../common -fPIC -pie CFLAGS=-g -Wall -I../common -fPIC -pie
all: dvm_file_editor qfile-agent-dvm qfile-agent qfile-unpacker all: vm-file-editor qopen-in-vm qfile-agent qfile-unpacker
dvm_file_editor: dvm_file_editor.o ../common/ioall.o vm-file-editor: vm-file-editor.o ../common/ioall.o
$(CC) -pie -g -o $@ $^ $(CC) -pie -g -o $@ $^
qfile-agent-dvm: qfile-agent-dvm.o ../common/ioall.o ../common/gui-fatal.o qopen-in-vm: qopen-in-vm.o ../common/ioall.o ../common/gui-fatal.o
$(CC) -pie -g -o $@ $^ $(CC) -pie -g -o $@ $^
qfile-agent: qfile-agent.o ../common/ioall.o ../common/gui-fatal.o ../common/copy_file.o ../common/crc32.o qfile-agent: qfile-agent.o ../common/ioall.o ../common/gui-fatal.o ../common/copy_file.o ../common/crc32.o
$(CC) -pie -g -o $@ $^ $(CC) -pie -g -o $@ $^
@ -11,4 +11,4 @@ qfile-unpacker: qfile-unpacker.o ../common/ioall.o ../common/gui-fatal.o ../comm
$(CC) -pie -g -o $@ $^ $(CC) -pie -g -o $@ $^
clean: clean:
rm -f qfile-agent-dvm qfile-agent qfile-unpacker dvm_file_editor *.o *~ rm -f qopen-in-vm qfile-agent qfile-unpacker vm-file-editor *.o *~

View File

@ -20,24 +20,33 @@ enum {
}; };
unsigned long crc32_sum; unsigned long crc32_sum;
int write_all_with_crc(int fd, void *buf, int size) { int write_all_with_crc(int fd, void *buf, int size)
{
crc32_sum = Crc32_ComputeBuf(crc32_sum, buf, size); crc32_sum = Crc32_ComputeBuf(crc32_sum, buf, size);
return write_all(fd, buf, size); return write_all(fd, buf, size);
} }
char *client_flags;
void do_notify_progress(long long total, int flag) void do_notify_progress(long long total, int flag)
{ {
FILE *progress; char *du_size_env = getenv("FILECOPY_TOTAL_SIZE");
if (!client_flags[0]) char *progress_type_env = getenv("PROGRESS_TYPE");
char *saved_stdout_env = getenv("SAVED_FD_1");
if (!progress_type_env)
return; return;
progress = fopen(client_flags, "w"); if (!strcmp(progress_type_env, "console") && du_size_env) {
if (!progress) char msg[256];
return; snprintf(msg, sizeof(msg), "sent %lld/%lld KB\r",
fprintf(progress, "%d %lld %s", getpid(), total, total / 1024, strtoull(du_size_env, NULL, 0));
flag == PROGRESS_FLAG_DONE ? "DONE" : "BUSY"); write(2, msg, strlen(msg));
fclose(progress); if (flag == PROGRESS_FLAG_DONE)
write(2, "\n", 1);
}
if (!strcmp(progress_type_env, "gui") && saved_stdout_env) {
char msg[256];
snprintf(msg, sizeof(msg), "%lld\n", total);
write(strtoul(saved_stdout_env, NULL, 0), msg,
strlen(msg));
}
} }
void notify_progress(int size, int flag) void notify_progress(int size, int flag)
@ -136,25 +145,6 @@ int do_fs_walk(char *file)
return 0; return 0;
} }
void send_vmname(char *vmname)
{
char buf[FILECOPY_VMNAME_SIZE];
memset(buf, 0, sizeof(buf));
strncat(buf, vmname, sizeof(buf) - 1);
if (!write_all(1, buf, sizeof buf))
exit(1);
}
char *get_item(char *data, char **current, int size)
{
char *ret;
if ((unsigned long) *current >= (unsigned long) data + size)
return NULL;
ret = *current;
*current += strlen(ret) + 1;
return ret;
}
void notify_end_and_wait_for_result() void notify_end_and_wait_for_result()
{ {
struct result_header hdr; struct result_header hdr;
@ -168,26 +158,40 @@ void notify_end_and_wait_for_result()
/* wait for result */ /* wait for result */
if (!read_all(0, &hdr, sizeof(hdr))) { if (!read_all(0, &hdr, sizeof(hdr))) {
exit(1); // hopefully remote has produced error message exit(1); // hopefully remote has produced error message
} }
if (hdr.error_code != 0) { if (hdr.error_code != 0) {
gui_fatal("Error writing files: %s", strerror(hdr.error_code)); gui_fatal("Error writing files: %s",
strerror(hdr.error_code));
} }
if (hdr.crc32 != crc32_sum) { if (hdr.crc32 != crc32_sum) {
gui_fatal("File transfer failed: checksum mismatch"); gui_fatal("File transfer failed: checksum mismatch");
} }
} }
void parse_entry(char *data, int datasize) char *get_abs_path(char *cwd, char *pathname)
{ {
char *current = data; char *ret;
char *vmname, *entry, *sep; if (pathname[0] == '/')
vmname = get_item(data, &current, datasize); return strdup(pathname);
client_flags = get_item(data, &current, datasize); asprintf(&ret, "%s/%s", cwd, pathname);
return ret;
}
int main(int argc, char **argv)
{
int i;
char *entry;
char *cwd;
char *sep;
signal(SIGPIPE, SIG_IGN);
notify_progress(0, PROGRESS_FLAG_INIT); notify_progress(0, PROGRESS_FLAG_INIT);
send_vmname(vmname);
crc32_sum = 0; crc32_sum = 0;
while ((entry = get_item(data, &current, datasize))) { cwd = getcwd(NULL, 0);
for (i = 1; i < argc; i++) {
entry = get_abs_path(cwd, argv[i]);
do { do {
sep = rindex(entry, '/'); sep = rindex(entry, '/');
if (!sep) if (!sep)
@ -200,53 +204,9 @@ void parse_entry(char *data, int datasize)
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); do_fs_walk(sep + 1);
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);
}
void process_spoolentry(char *entry_name)
{
char *abs_spool_entry_name;
int entry_fd;
struct stat st;
char *entry;
int entry_size;
asprintf(&abs_spool_entry_name, "%s/%s", FILECOPY_SPOOL,
entry_name);
entry_fd = open(abs_spool_entry_name, O_RDONLY);
unlink(abs_spool_entry_name);
if (entry_fd < 0 || fstat(entry_fd, &st))
gui_fatal("bad file copy spool entry");
entry_size = st.st_size;
entry = calloc(1, entry_size + 1);
if (!entry)
gui_fatal("malloc");
if (!read_all(entry_fd, entry, entry_size))
gui_fatal("read filecopy entry");
close(entry_fd);
parse_entry(entry, entry_size);
}
void scan_spool(char *name)
{
struct dirent *ent;
DIR *dir = opendir(name);
if (!dir)
gui_fatal("opendir %s", name);
while ((ent = readdir(dir))) {
char *fname = ent->d_name;
if (fname[0] != '.') {
process_spoolentry(fname);
break;
}
}
closedir(dir);
}
int main()
{
signal(SIGPIPE, SIG_IGN);
scan_spool(FILECOPY_SPOOL);
return 0; return 0;
} }

View File

@ -93,47 +93,11 @@ void talk_to_daemon(char *fname)
recv_file(fname); recv_file(fname);
} }
void process_spoolentry(char *entry_name) int main(int argc, char ** argv)
{
char *abs_spool_entry_name;
int entry_fd;
struct stat st;
char *filename;
int entry_size;
asprintf(&abs_spool_entry_name, "%s/%s", DVM_SPOOL, entry_name);
entry_fd = open(abs_spool_entry_name, O_RDONLY);
unlink(abs_spool_entry_name);
if (entry_fd < 0 || fstat(entry_fd, &st))
gui_fatal("bad dvm_entry");
entry_size = st.st_size;
filename = calloc(1, entry_size + DVM_FILENAME_SIZE);
if (!filename)
gui_fatal("malloc");
if (!read_all(entry_fd, filename, entry_size))
gui_fatal("read dvm entry %s", abs_spool_entry_name);
close(entry_fd);
talk_to_daemon(filename);
}
void scan_spool(char *name)
{
struct dirent *ent;
DIR *dir = opendir(name);
if (!dir)
gui_fatal("opendir %s", name);
while ((ent = readdir(dir))) {
char *fname = ent->d_name;
if (!strcmp(fname, ".") || !strcmp(fname, ".."))
continue;
process_spoolentry(fname);
break;
}
closedir(dir);
}
int main()
{ {
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
scan_spool(DVM_SPOOL); if (argc!=2)
gui_fatal("OpenInVM - no file given?");
talk_to_daemon(argv[1]);
return 0; return 0;
} }

1
appvm/qubes.Filecopy Normal file
View File

@ -0,0 +1 @@
/usr/lib/qubes/qfile-unpacker

View File

@ -0,0 +1 @@
anyvm anyvm ask,user=root

1
appvm/qubes.OpenInVM Normal file
View File

@ -0,0 +1 @@
/usr/lib/qubes/vm-file-editor

View File

@ -0,0 +1,2 @@
anyvm dispvm allow
anyvm anyvm ask

View File

@ -20,50 +20,24 @@
# #
# #
if [ x"$1" = "x--without-progress" ] ; then
DO_PROGRESS=0
shift
else
DO_PROGRESS=1
fi
if [ $# -lt 2 ] ; then if [ $# -lt 2 ] ; then
echo usage: $0 '[--without-progress] dest_vmname file [file]+' echo usage: $0 '[--without-progress] dest_vmname file [file]+'
exit 1 exit 1
fi fi
if [ x"$1" = "x--without-progress" ] ; then
export PROGRESS_TYPE=none
shift
else
export PROGRESS_TYPE=console
fi
VM="$1" VM="$1"
shift shift
if [ $DO_PROGRESS = 1 ] ; then if [ $PROGRESS_TYPE = console ] ; then
SIZE=$(du --apparent-size -c "$@" | tail -1 | cut -f 1) export FILECOPY_TOTAL_SIZE=$(du --apparent-size -c "$@" | tail -1 | cut -f 1)
fi fi
export PROGRESS_FILE=$(mktemp) exec /usr/lib/qubes/qrexec_client_vm $VM qubes.Filecopy /usr/lib/qubes/qfile-agent "$@"
/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

View File

@ -25,19 +25,10 @@ if [ X$VM = X ] ; then exit 0 ; fi
SIZE=$(du --apparent-size -c "$@" | tail -1 | cut -f 1) SIZE=$(du --apparent-size -c "$@" | tail -1 | cut -f 1)
export PROGRESS_FILE=$(mktemp) export PROGRESS_TYPE=gui
/usr/lib/qubes/qvm-trigger-copy-to-vm $VM "$@"
while ! [ -s $PROGRESS_FILE ] ; do /usr/lib/qubes/qrexec_client_vm $VM qubes.Filecopy /usr/lib/qubes/qfile-agent "$@" |
sleep 0.1 (while read sentsize ; do
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)) CURRSIZE=$(($sentsize/1024))
echo $((100*$CURRSIZE/$SIZE)) echo $((100*$CURRSIZE/$SIZE))
sleep 0.1
done) | zenity --progress --text="Copying files to domain: $VM..." --auto-close done) | zenity --progress --text="Copying files to domain: $VM..." --auto-close
rm -f $PROGRESS_FILE

View File

@ -27,23 +27,16 @@ SIZE=$(du --apparent-size -c "$@" | tail -1 | cut -f 1)
REF=$(kdialog --progressbar "Copy progress") REF=$(kdialog --progressbar "Copy progress")
qdbus $REF org.freedesktop.DBus.Properties.Set "" maximum $SIZE qdbus $REF org.freedesktop.DBus.Properties.Set "" maximum $SIZE
export PROGRESS_FILE=$(mktemp) export PROGRESS_TYPE=gui
/usr/lib/qubes/qvm-trigger-copy-to-vm $VM "$@"
while ! [ -s $PROGRESS_FILE ] ; do /usr/lib/qubes/qrexec_client_vm $VM qubes.Filecopy \
sleep 0.1 /usr/lib/qubes/qfile-agent "$@" |
done (while read sentsize ; do
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)) CURRSIZE=$(($sentsize/1024))
qdbus $REF org.freedesktop.DBus.Properties.Set "" value $CURRSIZE qdbus $REF org.freedesktop.DBus.Properties.Set "" value $CURRSIZE
sleep 0.4 done)
done
qdbus $REF close qdbus $REF close
rm -f $PROGRESS_FILE
# we do not want a dozen error messages, do we # we do not want a dozen error messages, do we
# if ! [ "x"$agentstatus = xDONE ] ; then # if ! [ "x"$agentstatus = xDONE ] ; then
# kdialog --sorry 'Abnormal file copy termination; see /var/log/qubes/qrexec.xid.log in dom0 for more details' # kdialog --sorry 'Abnormal file copy termination; see /var/log/qubes/qrexec.xid.log in dom0 for more details'

View File

@ -25,16 +25,4 @@ if ! [ $# = 1 ] ; then
exit 1 exit 1
fi fi
FILE="$1" exec /usr/lib/qubes/qrexec_client_vm dispvm qubes.OpenInVM "/usr/lib/qubes/qopen-in-vm" "$1"
if ! [ "X""${FILE:0:1}" = X/ ] ; then
FILE="$PWD"/"$1"
fi
DVMSPOOL=/home/user/.dvmspool
if ! [ -e $DVMSPOOL ] ; then
mkdir $DVMSPOOL || exit 1
fi
echo -n "$FILE" > $DVMSPOOL/req.$$
echo -n DVMR > /var/run/qubes/qrexec_agent

View File

@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
# #
# The Qubes OS Project, http://www.qubes-os.org # The Qubes OS Project, http://www.qubes-os.org
# #
@ -20,27 +20,9 @@
# #
# #
if [ $# -lt 2 ] ; then if ! [ $# = 2 ] ; then
echo usage: $0 'vmname file [file]*' echo "Usage: $0 vmname filename"
exit 1 exit 1
fi fi
FILECOPY_SPOOL=/home/user/.filecopyspool exec /usr/lib/qubes/qrexec_client_vm "$1" qubes.OpenInVM "/usr/lib/qubes/qopen-in-vm" "$2"
if ! [ -e $FILECOPY_SPOOL ] ; then
mkdir $FILECOPY_SPOOL
fi
REQ_FILE_TMP=$FILECOPY_SPOOL/.req.$$
echo -ne "$1""\x00" > $REQ_FILE_TMP
echo -ne "$PROGRESS_FILE""\x00" >> $REQ_FILE_TMP
shift
for FILE in "$@" ; do
if ! [ "X""${FILE:0:1}" = X/ ] ; then
FILE="$PWD"/"$FILE"
fi
echo -ne "$FILE""\x00" >> $REQ_FILE_TMP
done
mv $REQ_FILE_TMP $FILECOPY_SPOOL/req.$$
echo -n FCPR > /var/run/qubes/qrexec_agent

View File

@ -67,4 +67,4 @@ else
fi fi
# qvm-copy-to-vm works only from user # qvm-copy-to-vm works only from user
su -c "qvm-copy-to-vm @dom0updates $DOM0_UPDATES_DIR/packages/*.rpm" user su -c "/usr/lib/qubes/qrexec_client_vm dom0 qubes.ReceiveUpdates /usr/lib/qubes/qfile-agent $DOM0_UPDATES_DIR/packages/*.rpm" user

View File

@ -3,5 +3,5 @@
UPDATEABLE=`/usr/bin/xenstore-read qubes_vm_updateable` UPDATEABLE=`/usr/bin/xenstore-read qubes_vm_updateable`
if [ "$UPDATEABLE" = "True" ]; then if [ "$UPDATEABLE" = "True" ]; then
echo -n SYNC > /var/run/qubes/qrexec_agent /usr/lib/qubes/qrexec_client_vm dom0 qubes.SyncAppMenus /bin/grep -H = /usr/share/applications/*.desktop
fi fi

View File

@ -75,17 +75,22 @@ cp qubes_core_appvm $RPM_BUILD_ROOT/etc/init.d/
mkdir -p $RPM_BUILD_ROOT/var/lib/qubes mkdir -p $RPM_BUILD_ROOT/var/lib/qubes
mkdir -p $RPM_BUILD_ROOT/usr/bin mkdir -p $RPM_BUILD_ROOT/usr/bin
cp qubes_timestamp qvm-open-in-dvm2 $RPM_BUILD_ROOT/usr/bin cp qubes_timestamp qvm-open-in-dvm2 $RPM_BUILD_ROOT/usr/bin
cp qvm-open-in-vm $RPM_BUILD_ROOT/usr/bin
cp qvm-copy-to-vm $RPM_BUILD_ROOT/usr/bin cp qvm-copy-to-vm $RPM_BUILD_ROOT/usr/bin
mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes
cp qvm-copy-to-vm2.kde $RPM_BUILD_ROOT/usr/lib/qubes cp qvm-copy-to-vm2.kde $RPM_BUILD_ROOT/usr/lib/qubes
cp qvm-copy-to-vm2.gnome $RPM_BUILD_ROOT/usr/lib/qubes cp qvm-copy-to-vm2.gnome $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 ../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 ../qrexec/qrexec_client_vm $RPM_BUILD_ROOT/usr/lib/qubes
cp ../qrexec/qubes_rpc_multiplexer $RPM_BUILD_ROOT/usr/lib/qubes
cp vm-file-editor qfile-agent qopen-in-vm qfile-unpacker $RPM_BUILD_ROOT/usr/lib/qubes
cp ../common/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes cp ../common/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes
mkdir -p $RPM_BUILD_ROOT/%{kde_service_dir} mkdir -p $RPM_BUILD_ROOT/%{kde_service_dir}
cp qvm-copy.desktop qvm-dvm.desktop $RPM_BUILD_ROOT/%{kde_service_dir} cp qvm-copy.desktop qvm-dvm.desktop $RPM_BUILD_ROOT/%{kde_service_dir}
mkdir -p $RPM_BUILD_ROOT/mnt/removable mkdir -p $RPM_BUILD_ROOT/mnt/removable
mkdir -p $RPM_BUILD_ROOT/etc/qubes_rpc
cp qubes.Filecopy $RPM_BUILD_ROOT/etc/qubes_rpc
cp qubes.OpenInVM $RPM_BUILD_ROOT/etc/qubes_rpc
mkdir -p $RPM_BUILD_ROOT/etc/X11 mkdir -p $RPM_BUILD_ROOT/etc/X11
cp xorg-preload-apps.conf $RPM_BUILD_ROOT/etc/X11 cp xorg-preload-apps.conf $RPM_BUILD_ROOT/etc/X11
@ -136,16 +141,21 @@ rm -rf $RPM_BUILD_ROOT
/usr/lib/qubes/qvm-copy-to-vm2.kde /usr/lib/qubes/qvm-copy-to-vm2.kde
/usr/lib/qubes/qvm-copy-to-vm2.gnome /usr/lib/qubes/qvm-copy-to-vm2.gnome
/usr/bin/qvm-open-in-dvm2 /usr/bin/qvm-open-in-dvm2
/usr/bin/qvm-open-in-vm
/usr/lib/qubes/meminfo-writer /usr/lib/qubes/meminfo-writer
/usr/lib/qubes/dvm_file_editor /usr/lib/qubes/vm-file-editor
%{kde_service_dir}/qvm-copy.desktop %{kde_service_dir}/qvm-copy.desktop
%{kde_service_dir}/qvm-dvm.desktop %{kde_service_dir}/qvm-dvm.desktop
/usr/lib/qubes/qvm-trigger-copy-to-vm
/usr/lib/qubes/qrexec_agent /usr/lib/qubes/qrexec_agent
/usr/lib/qubes/qrexec_client_vm
/usr/lib/qubes/qubes_rpc_multiplexer
/usr/lib/qubes/qfile-agent /usr/lib/qubes/qfile-agent
/usr/lib/qubes/qfile-agent-dvm /usr/lib/qubes/qopen-in-vm
/usr/lib/qubes/qfile-unpacker /usr/lib/qubes/qfile-unpacker
%dir /mnt/removable %dir /mnt/removable
%dir /etc/qubes_rpc
/etc/qubes_rpc/qubes.Filecopy
/etc/qubes_rpc/qubes.OpenInVM
/usr/bin/qubes_timestamp /usr/bin/qubes_timestamp
%dir /home_volatile %dir /home_volatile
%attr(700,user,user) /home_volatile/user %attr(700,user,user) /home_volatile/user