Added qfile-unpacker and qfile-daemon

This commit is contained in:
Rafal Wojtczuk 2011-03-15 16:43:43 +01:00
parent b459bcbca0
commit 31c7a7a1c9
4 changed files with 189 additions and 2 deletions

View File

@ -1,12 +1,14 @@
CC=gcc
CFLAGS=-Wall -I../common
all: qubes_penctl qubes_add_pendrive_script qvm-open-in-dvm dvm_file_editor qfile-agent-dvm qfile-agent
all: qubes_penctl qubes_add_pendrive_script qvm-open-in-dvm dvm_file_editor qfile-agent-dvm qfile-agent qfile-unpacker
dvm_file_editor: dvm_file_editor.o ../common/ioall.o
$(CC) -o dvm_file_editor dvm_file_editor.o ../common/ioall.o
qfile-agent-dvm: qfile-agent-dvm.o ../common/ioall.o ../common/gui-fatal.o
$(CC) -o qfile-agent-dvm qfile-agent-dvm.o ../common/ioall.o ../common/gui-fatal.o
qfile-agent: qfile-agent.o ../common/ioall.o ../common/gui-fatal.o copy_file.o
$(CC) -o qfile-agent qfile-agent.o ../common/ioall.o ../common/gui-fatal.o copy_file.o
qfile-unpacker: qfile-unpacker.o ../common/ioall.o ../common/gui-fatal.o copy_file.o unpack.o
$(CC) -o qfile-unpacker qfile-unpacker.o ../common/ioall.o ../common/gui-fatal.o copy_file.o unpack.o
qubes_penctl: qubes_penctl.o
$(CC) -o qubes_penctl qubes_penctl.o -lxenstore
qubes_add_pendrive_script: qubes_add_pendrive_script.o

83
appvm/qfile-unpacker.c Normal file
View File

@ -0,0 +1,83 @@
#define _GNU_SOURCE
#include <ioall.h>
#include <grp.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <sys/fsuid.h>
#include <gui-fatal.h>
#include <errno.h>
#include "filecopy.h"
#define INCOMING_DIR_ROOT "/home/user/incoming"
int prepare_creds_return_uid(char *username)
{
struct passwd *pwd;
pwd = getpwnam(username);
if (!pwd) {
perror("getpwnam");
exit(1);
}
setenv("HOME", pwd->pw_dir, 1);
setenv("USER", username, 1);
setgid(pwd->pw_gid);
initgroups(username, pwd->pw_gid);
setfsuid(pwd->pw_uid);
return pwd->pw_uid;
}
void wait_for_child(int statusfd)
{
int status;
if (read(statusfd, &status, sizeof status)!=sizeof status)
gui_fatal("File copy error: Internal error reading status from unpacker");
errno = status;
switch (status) {
case LEGAL_EOF: break;
case 0: gui_fatal("File copy: Connection terminated unexpectedly"); break;
case EINVAL: gui_fatal("File copy: Corrupted data from packer"); break;
case EEXIST: gui_fatal("File copy: not overwriting existing file. Clean ~/incoming, and retry copy"); break;
default: gui_fatal("File copy");
}
}
extern void do_unpack(int);
int main(int argc, char ** argv)
{
char *incoming_dir;
int pipefds[2];
int uid;
pipe(pipefds);
uid = prepare_creds_return_uid("user");
mkdir(INCOMING_DIR_ROOT, 0700);
asprintf(&incoming_dir, "%s/from-%s", INCOMING_DIR_ROOT, argv[1]);
mkdir(incoming_dir, 0700);
if (chdir(incoming_dir))
gui_fatal("Error chdir to %s", incoming_dir);
switch (fork()) {
case -1:
perror("fork");
exit(1);
case 0:
if (chroot(incoming_dir)) //impossible
gui_fatal("Error chroot to %s", incoming_dir);
setuid(uid);
close(pipefds[0]);
do_unpack(pipefds[1]);
exit(0);
default:;
}
setuid(uid);
close(pipefds[1]);
wait_for_child(pipefds[0]);
return 0;
}

101
appvm/unpack.c Normal file
View File

@ -0,0 +1,101 @@
#include <errno.h>
#include <ioall.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include "filecopy.h"
char namebuf[MAX_PATH_LENGTH];
void notify_progress(int p1, int p2)
{
}
int global_status_fd;
void do_exit(int code)
{
int codebuf = code;
write(global_status_fd, &codebuf, sizeof codebuf);
exit(0);
}
void fix_times_and_perms(struct file_header *hdr, char *name)
{
struct timeval times[2] =
{ {hdr->atime, hdr->atime_nsec / 1000}, {hdr->mtime,
hdr->mtime_nsec / 1000}
};
if (chmod(name, hdr->mode & 07777))
do_exit(errno);
if (utimes(name, times))
do_exit(errno);
}
void process_one_file_reg(struct file_header *hdr, char *name)
{
char *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);
close(fdout);
fix_times_and_perms(hdr, name);
}
void process_one_file_dir(struct file_header *hdr, char *name)
{
if (mkdir(name, 0700) && errno != EEXIST)
do_exit(errno);
fix_times_and_perms(hdr, name);
}
void process_one_file_link(struct file_header *hdr, char *name)
{
char content[MAX_PATH_LENGTH];
if (hdr->filelen > MAX_PATH_LENGTH - 1)
do_exit(ENAMETOOLONG);
if (!read_all(0, content, hdr->filelen))
do_exit(errno);
content[hdr->filelen] = 0;
if (symlink(content, name))
do_exit(errno);
}
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);
namebuf[hdr->namelen] = 0;
if (S_ISREG(hdr->mode))
process_one_file_reg(hdr, namebuf);
else if (S_ISLNK(hdr->mode))
process_one_file_link(hdr, namebuf);
else if (S_ISDIR(hdr->mode))
process_one_file_dir(hdr, namebuf);
else
do_exit(EINVAL);
}
void do_unpack(int fd)
{
global_status_fd = fd;
struct file_header hdr;
while (read_all(0, &hdr, sizeof hdr))
process_one_file(&hdr);
if (errno)
do_exit(errno);
else
do_exit(LEGAL_EOF);
}

View File

@ -76,7 +76,7 @@ cp qubes_timestamp qvm-copy-to-vm qvm-open-in-dvm qvm-open-in-dvm2 $RPM_BUILD_RO
mkdir -p $RPM_BUILD_ROOT/usr/lib/qubes
cp qubes_add_pendrive_script qubes_penctl qvm-copy-to-vm.kde $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 $RPM_BUILD_ROOT/usr/lib/qubes
cp dvm_file_editor qfile-agent qfile-agent-dvm qfile-unpacker $RPM_BUILD_ROOT/usr/lib/qubes
ln -s /usr/bin/qvm-open-in-dvm $RPM_BUILD_ROOT/usr/lib/qubes/qvm-dvm-transfer
cp ../common/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes
mkdir -p $RPM_BUILD_ROOT/%{kde_service_dir}
@ -218,6 +218,7 @@ rm -rf $RPM_BUILD_ROOT
/usr/lib/qubes/qrexec_agent
/usr/lib/qubes/qfile-agent
/usr/lib/qubes/qfile-agent-dvm
/usr/lib/qubes/qfile-unpacker
/etc/udev/rules.d/qubes.rules
/etc/sysconfig/iptables
/var/lib/qubes