Merge branch 'dispvm'
This commit is contained in:
commit
2298a66ab9
@ -1,9 +1,11 @@
|
|||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS=-Wall
|
CFLAGS=-Wall
|
||||||
all: qubes_penctl qubes_add_pendrive_script
|
all: qubes_penctl qubes_add_pendrive_script qvm-open-in-dvm
|
||||||
qubes_penctl: qubes_penctl.o
|
qubes_penctl: qubes_penctl.o
|
||||||
$(CC) -o qubes_penctl qubes_penctl.o -lxenstore
|
$(CC) -o qubes_penctl qubes_penctl.o -lxenstore
|
||||||
qubes_add_pendrive_script: qubes_add_pendrive_script.o
|
qubes_add_pendrive_script: qubes_add_pendrive_script.o
|
||||||
$(CC) -o qubes_add_pendrive_script qubes_add_pendrive_script.o
|
$(CC) -o qubes_add_pendrive_script qubes_add_pendrive_script.o -lxenstore
|
||||||
|
qvm-open-in-dvm: qvm-open-in-dvm.o
|
||||||
|
$(CC) -o qvm-open-in-dvm qvm-open-in-dvm.o -lxenstore
|
||||||
clean:
|
clean:
|
||||||
rm -f qubes_penctl qubes_add_pendrive_script *.o *~
|
rm -f qubes_penctl qubes_add_pendrive_script qvm-open-in-dvm *.o *~
|
||||||
|
6
appvm/dvm.h
Normal file
6
appvm/dvm.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#define DBDIR "/home/user/.dvm"
|
||||||
|
struct dvm_header {
|
||||||
|
unsigned long long file_size;
|
||||||
|
char name[1024-sizeof(unsigned long long)];
|
||||||
|
};
|
||||||
|
|
@ -8,7 +8,7 @@
|
|||||||
#
|
#
|
||||||
/dev/mapper/dmroot / ext4 defaults,noatime 1 1
|
/dev/mapper/dmroot / ext4 defaults,noatime 1 1
|
||||||
/dev/mapper/dmswap swap swap defaults 0 0
|
/dev/mapper/dmswap swap swap defaults 0 0
|
||||||
/dev/xvdb /rw ext4 defaults 0 0
|
/dev/xvdb /rw ext4 noauto,defaults 0 0
|
||||||
tmpfs /dev/shm tmpfs defaults 0 0
|
tmpfs /dev/shm tmpfs defaults 0 0
|
||||||
devpts /dev/pts devpts gid=5,mode=620 0 0
|
devpts /dev/pts devpts gid=5,mode=620 0 0
|
||||||
sysfs /sys sysfs defaults 0 0
|
sysfs /sys sysfs defaults 0 0
|
||||||
|
@ -1 +1 @@
|
|||||||
SUBSYSTEM=="block", KERNEL=="xvdh", ACTION=="add", RUN+="/usr/bin/qubes_add_pendrive_script"
|
SUBSYSTEM=="block", KERNEL=="xvdh", ACTION=="add", RUN+="/usr/lib/qubes/qubes_add_pendrive_script"
|
||||||
|
@ -18,17 +18,25 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <xs.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "dvm.h"
|
||||||
|
|
||||||
int parse_events(char *buf, int len)
|
int parse_events(char *buf, int len)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < len) {
|
while (i < len) {
|
||||||
struct inotify_event *ev = (struct inotify_event *)(buf + i);
|
struct inotify_event *ev =
|
||||||
|
(struct inotify_event *) (buf + i);
|
||||||
if ((ev->mask & IN_UNMOUNT) || (ev->mask & IN_IGNORED))
|
if ((ev->mask & IN_UNMOUNT) || (ev->mask & IN_IGNORED))
|
||||||
return 1;
|
return 1;
|
||||||
i += sizeof(struct inotify_event) + ev->len;
|
i += sizeof(struct inotify_event) + ev->len;
|
||||||
@ -69,19 +77,201 @@ void background()
|
|||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
case -1:
|
case -1:
|
||||||
exit(1);
|
exit(1);
|
||||||
case 0: break;
|
case 0:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int check_legal_filename(char *name)
|
||||||
|
{
|
||||||
|
if (index(name, '/')) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR,
|
||||||
|
"the received filename contains /");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drop_to_user()
|
||||||
|
{
|
||||||
|
struct passwd *pw = getpwnam("user");
|
||||||
|
if (pw)
|
||||||
|
setuid(pw->pw_uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
int copy_from_xvdh(int destfd, int srcfd, unsigned long long count)
|
||||||
|
{
|
||||||
|
int n, size;
|
||||||
|
char buf[4096];
|
||||||
|
unsigned long long total = 0;
|
||||||
|
while (total < count) {
|
||||||
|
if (count - total > sizeof(buf))
|
||||||
|
size = sizeof(buf);
|
||||||
|
else
|
||||||
|
size = count - total;
|
||||||
|
n = read(srcfd, buf, size);
|
||||||
|
if (n != size) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "reading xvdh");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (write(destfd, buf, size) != size) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "writing file");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
total += size;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void redirect_stderr()
|
||||||
|
{
|
||||||
|
int fd =
|
||||||
|
open("/var/log/dvm.log", O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
||||||
|
if (fd < 0) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "open dvm.log");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
dup2(fd, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void suicide(struct xs_handle *xs)
|
||||||
|
{
|
||||||
|
xs_write(xs, XBT_NULL, "device/qpen", "killme", 6);
|
||||||
|
xs_daemon_close(xs);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvm_transaction_request(char *seq, struct xs_handle *xs)
|
||||||
|
{
|
||||||
|
char filename[1024], cmdbuf[1024];
|
||||||
|
struct dvm_header header;
|
||||||
|
int xvdh_fd, file_fd;
|
||||||
|
char *src_vm;
|
||||||
|
unsigned int len;
|
||||||
|
struct stat stat_pre, stat_post;
|
||||||
|
xvdh_fd = open("/dev/xvdh", O_RDONLY);
|
||||||
|
if (read(xvdh_fd, &header, sizeof(header)) != sizeof(header)) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "read dvm_header");
|
||||||
|
suicide(xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
header.name[sizeof(header.name) - 1] = 0;
|
||||||
|
if (!check_legal_filename(header.name))
|
||||||
|
suicide(xs);
|
||||||
|
snprintf(filename, sizeof(filename), "/tmp/%s", header.name);
|
||||||
|
drop_to_user();
|
||||||
|
|
||||||
|
file_fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
||||||
|
if (file_fd < 0) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "open file");
|
||||||
|
suicide(xs);
|
||||||
|
}
|
||||||
|
if (!copy_from_xvdh(file_fd, xvdh_fd, header.file_size))
|
||||||
|
suicide(xs);
|
||||||
|
close(xvdh_fd);
|
||||||
|
close(file_fd);
|
||||||
|
if (stat(filename, &stat_pre)) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "stat pre");
|
||||||
|
suicide(xs);
|
||||||
|
}
|
||||||
|
snprintf(cmdbuf, sizeof(cmdbuf),
|
||||||
|
"DISPLAY=:0 mimeopen -n '/tmp/%s'", header.name);
|
||||||
|
if (system(cmdbuf))
|
||||||
|
system("DISPLAY=:0 /usr/bin/kdialog --sorry 'Unable to handle mimetype of the requested file'");
|
||||||
|
if (stat(filename, &stat_post)) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "stat post");
|
||||||
|
suicide(xs);
|
||||||
|
}
|
||||||
|
src_vm = xs_read(xs, XBT_NULL, "qubes_blocksrc", &len);
|
||||||
|
xs_write(xs, XBT_NULL, "device/qpen", "umount", 6);
|
||||||
|
if (stat_pre.st_mtime == stat_post.st_mtime)
|
||||||
|
suicide(xs);
|
||||||
|
xs_daemon_close(xs);
|
||||||
|
execl("/usr/lib/qubes/qvm-dvm-transfer", "qvm-dvm-transfer", src_vm,
|
||||||
|
filename, seq, NULL);
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "execl qvm-dvm-transfer");
|
||||||
|
suicide(xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvm_transaction_return(char *seq_string, struct xs_handle *xs)
|
||||||
|
{
|
||||||
|
int seq = strtoul(seq_string, 0, 10);
|
||||||
|
char db_name[1024];
|
||||||
|
char file_name[1024];
|
||||||
|
int db_fd, file_fd, xvdh_fd;
|
||||||
|
|
||||||
|
struct dvm_header header;
|
||||||
|
xvdh_fd = open("/dev/xvdh", O_RDONLY);
|
||||||
|
if (xvdh_fd < 0) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "open xvdh");
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
if (read(xvdh_fd, &header, sizeof(header)) != sizeof(header)) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "read dvm_header");
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
drop_to_user();
|
||||||
|
snprintf(db_name, sizeof(db_name), DBDIR "/%d", seq);
|
||||||
|
db_fd = open(db_name, O_RDONLY);
|
||||||
|
if (!db_fd) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "open db");
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
if (read(db_fd, file_name, sizeof(file_name)) < 0) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "read db");
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
close(db_fd);
|
||||||
|
file_fd = open(file_name, O_WRONLY | O_TRUNC);
|
||||||
|
if (file_fd < 0) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "open filename");
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
copy_from_xvdh(file_fd, xvdh_fd, header.file_size);
|
||||||
|
close(xvdh_fd);
|
||||||
|
close(file_fd);
|
||||||
|
out_err:
|
||||||
|
xs_write(xs, XBT_NULL, "device/qpen", "umount", 6);
|
||||||
|
xs_daemon_close(xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void dvm_transaction(char *seq, struct xs_handle *xs)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
redirect_stderr();
|
||||||
|
if (stat("/etc/this_is_dvm", &st))
|
||||||
|
dvm_transaction_return(seq, xs);
|
||||||
|
else
|
||||||
|
dvm_transaction_request(seq, xs);
|
||||||
|
}
|
||||||
|
|
||||||
#define MOUNTDIR "/mnt/incoming"
|
#define MOUNTDIR "/mnt/incoming"
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
struct xs_handle *xs;
|
||||||
|
char *seq;
|
||||||
|
unsigned int len;
|
||||||
background();
|
background();
|
||||||
|
openlog("qubes_add_pendrive_script", LOG_CONS | LOG_PID,
|
||||||
|
LOG_DAEMON);
|
||||||
|
xs = xs_domain_open();
|
||||||
|
if (!xs) {
|
||||||
|
syslog(LOG_DAEMON | LOG_ERR, "xs_domain_open");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
seq = xs_read(xs, XBT_NULL, "qubes_transaction_seq", &len);
|
||||||
|
if (seq && len > 0 && strcmp(seq, "0")) {
|
||||||
|
dvm_transaction(seq, xs);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
if (!system("su - user -c 'mount " MOUNTDIR "'"))
|
if (!system("su - user -c 'mount " MOUNTDIR "'"))
|
||||||
wait_for_umount(MOUNTDIR "/.");
|
wait_for_umount(MOUNTDIR "/.");
|
||||||
system("xenstore-write device/qpen umount");
|
xs_write(xs, XBT_NULL, "device/qpen", "umount", 6);
|
||||||
|
xs_daemon_close(xs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,18 @@
|
|||||||
# Source function library.
|
# Source function library.
|
||||||
. /etc/rc.d/init.d/functions
|
. /etc/rc.d/init.d/functions
|
||||||
|
|
||||||
|
possibly_run_save_script()
|
||||||
|
{
|
||||||
|
ENCODED_SCRIPT=$(xenstore-read qubes_save_script)
|
||||||
|
if [ -z "$ENCODED_SCRIPT" ] ; then return ; fi
|
||||||
|
echo $ENCODED_SCRIPT|perl -e 'use MIME::Base64 qw(decode_base64); local($/) = undef;print decode_base64(<STDIN>)' >/tmp/qubes_save_script
|
||||||
|
chmod 755 /tmp/qubes_save_script
|
||||||
|
Xorg -config /etc/X11/xorg-preload-apps.conf :0 &
|
||||||
|
sleep 2
|
||||||
|
DISPLAY=:0 su - user -c /tmp/qubes_save_script
|
||||||
|
killall Xorg
|
||||||
|
}
|
||||||
|
|
||||||
start()
|
start()
|
||||||
{
|
{
|
||||||
echo -n $"Executing Qubes Core scripts:"
|
echo -n $"Executing Qubes Core scripts:"
|
||||||
@ -14,6 +26,22 @@ start()
|
|||||||
echo "ERROR: /usr/bin/xenstore-read not found!"
|
echo "ERROR: /usr/bin/xenstore-read not found!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if xenstore-read qubes_save_request 2>/dev/null ; then
|
||||||
|
possibly_run_save_script
|
||||||
|
touch /etc/this_is_dvm
|
||||||
|
dmesg -c >/dev/null
|
||||||
|
# echo 1 >/proc/sys/vm/drop_caches
|
||||||
|
# free | grep buffers/cache |
|
||||||
|
# (read a b c d ; xenstore-write device/qubes_used_mem $c)
|
||||||
|
free | grep Mem: |
|
||||||
|
(read a b c d ; xenstore-write device/qubes_used_mem $c)
|
||||||
|
echo "Waiting for restore"
|
||||||
|
while ! dmesg -c | grep "using vcpu" ; do usleep 10 ; done
|
||||||
|
while ! xenstore-read qubes_vm_type 2>/dev/null ; do
|
||||||
|
usleep 10
|
||||||
|
done
|
||||||
|
echo Back to life.
|
||||||
|
fi
|
||||||
|
|
||||||
name=$(/usr/bin/xenstore-read name)
|
name=$(/usr/bin/xenstore-read name)
|
||||||
hostname $name
|
hostname $name
|
||||||
@ -29,6 +57,9 @@ start()
|
|||||||
echo "nameserver $secondary_dns" >> /etc/resolv.conf
|
echo "nameserver $secondary_dns" >> /etc/resolv.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -e /dev/xvdb ] ; then
|
||||||
|
mount /rw
|
||||||
|
|
||||||
if ! [ -d /rw/home ] ; then
|
if ! [ -d /rw/home ] ; then
|
||||||
echo
|
echo
|
||||||
echo "--> Virgin boot of the VM: Linking /home to /rw/home"
|
echo "--> Virgin boot of the VM: Linking /home to /rw/home"
|
||||||
@ -54,6 +85,9 @@ start()
|
|||||||
if ! [ -d /rw/usrlocal ] ; then
|
if ! [ -d /rw/usrlocal ] ; then
|
||||||
cp -a /usr/local.orig /rw/usrlocal
|
cp -a /usr/local.orig /rw/usrlocal
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
ln -sf /home_volatile /home
|
||||||
|
fi
|
||||||
|
|
||||||
[ -x /rw/config/rc.local ] && /rw/config/rc.local
|
[ -x /rw/config/rc.local ] && /rw/config/rc.local
|
||||||
success
|
success
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <xs.h>
|
#include <xs.h>
|
||||||
int check_name(unsigned char *s)
|
void check_name(unsigned char *s)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
for (; *s; s++) {
|
for (; *s; s++) {
|
||||||
@ -35,14 +35,21 @@ int check_name(unsigned char *s)
|
|||||||
continue;
|
continue;
|
||||||
if (c == '_' || c == '-')
|
if (c == '_' || c == '-')
|
||||||
continue;
|
continue;
|
||||||
return 0;
|
fprintf(stderr, "invalid string %s\n", s);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
return 1;
|
}
|
||||||
|
|
||||||
|
void usage(char *argv0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: %s [new|umount]\n"
|
||||||
|
"%s send vmname [seq]\n", argv0, argv0);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char buf[256] = "new";
|
char buf[256];
|
||||||
struct xs_handle *xs;
|
struct xs_handle *xs;
|
||||||
xs = xs_domain_open();
|
xs = xs_domain_open();
|
||||||
setuid(getuid());
|
setuid(getuid());
|
||||||
@ -50,18 +57,25 @@ int main(int argc, char **argv)
|
|||||||
perror("xs_domain_open");
|
perror("xs_domain_open");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (argc < 2) {
|
switch (argc) {
|
||||||
fprintf(stderr, "usage: %s new\n"
|
case 2:
|
||||||
"%s send vmname\n", argv[0], argv[0]);
|
if (!strcmp(argv[1], "umount"))
|
||||||
exit(1);
|
strcpy(buf, "umount");
|
||||||
}
|
else
|
||||||
if (argc > 2) {
|
strcpy(buf, "new");
|
||||||
if (!check_name((unsigned char*)argv[2])) {
|
break;
|
||||||
fprintf(stderr, "invalid vmname %s\n", argv[2]);
|
case 3:
|
||||||
exit(1);
|
check_name((unsigned char *) argv[2]);
|
||||||
}
|
|
||||||
snprintf(buf, sizeof(buf), "send %s", argv[2]);
|
snprintf(buf, sizeof(buf), "send %s", argv[2]);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
check_name((unsigned char *) argv[2]);
|
||||||
|
check_name((unsigned char *) argv[3]);
|
||||||
|
snprintf(buf, sizeof(buf), "send %s %s", argv[2], argv[3]);
|
||||||
|
default:
|
||||||
|
usage(argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!xs_write(xs, 0, "device/qpen", buf, strlen(buf))) {
|
if (!xs_write(xs, 0, "device/qpen", buf, strlen(buf))) {
|
||||||
perror("xs_write");
|
perror("xs_write");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
2
appvm/qubes_timestamp
Executable file
2
appvm/qubes_timestamp
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
exec xenstore-write device/qubes_timestamp $(date +%s.%N)
|
@ -24,7 +24,7 @@ if [ $# -lt 2 ] ; then
|
|||||||
echo usage: $0 'vmname file [file]*'
|
echo usage: $0 'vmname file [file]*'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
qubes_penctl new || exit 1
|
/usr/lib/qubes/qubes_penctl new || exit 1
|
||||||
echo -n Waiting for the Qubes virtual pendrive
|
echo -n Waiting for the Qubes virtual pendrive
|
||||||
while ! [ -e /dev/xvdg ] ; do
|
while ! [ -e /dev/xvdg ] ; do
|
||||||
echo -n .
|
echo -n .
|
||||||
@ -37,4 +37,4 @@ shift
|
|||||||
cp -v -a "$@" /mnt/outgoing
|
cp -v -a "$@" /mnt/outgoing
|
||||||
#sometimes Dolphin lags a bit
|
#sometimes Dolphin lags a bit
|
||||||
umount /mnt/outgoing || (sleep 1; umount /mnt/outgoing) || exit 1
|
umount /mnt/outgoing || (sleep 1; umount /mnt/outgoing) || exit 1
|
||||||
qubes_penctl send $VMNAME || exit 1
|
/usr/lib/qubes/qubes_penctl send $VMNAME || exit 1
|
||||||
|
@ -4,7 +4,7 @@ Type=Service
|
|||||||
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,inode/directory,all/allfiles
|
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,inode/directory,all/allfiles
|
||||||
|
|
||||||
[Desktop Action QvmCopy]
|
[Desktop Action QvmCopy]
|
||||||
Exec=/usr/bin/qvm-copy-to-vm.kde %U
|
Exec=/usr/lib/qubes/qvm-copy-to-vm.kde %U
|
||||||
Icon=kget
|
Icon=kget
|
||||||
Name=Send To VM
|
Name=Send To VM
|
||||||
|
|
||||||
|
10
appvm/qvm-dvm.desktop
Normal file
10
appvm/qvm-dvm.desktop
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Actions=QvmDvm;
|
||||||
|
Type=Service
|
||||||
|
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,all/allfiles
|
||||||
|
|
||||||
|
[Desktop Action QvmDvm]
|
||||||
|
Exec=/usr/bin/qvm-open-in-dvm disposable %U
|
||||||
|
Icon=kget
|
||||||
|
Name=Open In DisposableVM
|
||||||
|
|
176
appvm/qvm-open-in-dvm.c
Normal file
176
appvm/qvm-open-in-dvm.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* The Qubes OS Project, http://www.qubes-os.org
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <xs.h>
|
||||||
|
#include "dvm.h"
|
||||||
|
|
||||||
|
void check_name(unsigned char *s)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
for (; *s; s++) {
|
||||||
|
c = *s;
|
||||||
|
if (c >= 'a' && c <= 'z')
|
||||||
|
continue;
|
||||||
|
if (c >= 'A' && c <= 'Z')
|
||||||
|
continue;
|
||||||
|
if (c == '_' || c == '-')
|
||||||
|
continue;
|
||||||
|
fprintf(stderr, "invalid string %s\n", s);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_and_set_seq()
|
||||||
|
{
|
||||||
|
int seq_fd, seq, n;
|
||||||
|
mkdir(DBDIR, 0700);
|
||||||
|
seq_fd = open(DBDIR "/seq", O_CREAT | O_RDWR, 0600);
|
||||||
|
if (seq_fd < 0) {
|
||||||
|
perror("open seq_fd");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
n = read(seq_fd, &seq, sizeof(seq));
|
||||||
|
if (n < sizeof(seq))
|
||||||
|
seq = 0;
|
||||||
|
seq++;
|
||||||
|
lseek(seq_fd, 0, SEEK_SET);
|
||||||
|
write(seq_fd, &seq, sizeof(seq));
|
||||||
|
close(seq_fd);
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_db(char *name, int seq)
|
||||||
|
{
|
||||||
|
int db_fd;
|
||||||
|
char dbname[256];
|
||||||
|
struct stat st;
|
||||||
|
if (!stat("/etc/this_is_dvm", &st))
|
||||||
|
return;
|
||||||
|
snprintf(dbname, sizeof(dbname), DBDIR "/%d", seq);
|
||||||
|
db_fd = open(dbname, O_CREAT | O_WRONLY | O_TRUNC, 0600);
|
||||||
|
if (db_fd < 0) {
|
||||||
|
perror("open dbfile");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (write(db_fd, name, strlen(name) + 1) != strlen(name) + 1) {
|
||||||
|
perror("write db");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
close(db_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_file(int xvdg_fd, int file_fd)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
char buf[4096];
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
n = read(file_fd, buf, sizeof(buf));
|
||||||
|
if (n < 0) {
|
||||||
|
perror("read file");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (n == 0)
|
||||||
|
break;
|
||||||
|
if (write(xvdg_fd, buf, n) != n) {
|
||||||
|
perror("write file");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct dvm_header header = { 0, };
|
||||||
|
struct stat st;
|
||||||
|
struct xs_handle *xs;
|
||||||
|
int seq;
|
||||||
|
int xvdg_fd, file_fd;
|
||||||
|
char *abs_filename;
|
||||||
|
char buf[4096];
|
||||||
|
|
||||||
|
if (argc != 3 && argc != 4) {
|
||||||
|
fprintf(stderr, "usage: %s vmname file\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
check_name((unsigned char *) argv[1]);
|
||||||
|
if (argv[2][0] == '/')
|
||||||
|
abs_filename = argv[2];
|
||||||
|
else {
|
||||||
|
char cwd[4096];
|
||||||
|
getcwd(cwd, sizeof(cwd));
|
||||||
|
asprintf(&abs_filename, "%s/%s", cwd, argv[2]);
|
||||||
|
}
|
||||||
|
if (stat(abs_filename, &st)) {
|
||||||
|
perror("stat file");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
header.file_size = st.st_size;
|
||||||
|
strncpy(header.name, rindex(abs_filename, '/') + 1,
|
||||||
|
sizeof(header.name) - 1);
|
||||||
|
xs = xs_domain_open();
|
||||||
|
if (!xs) {
|
||||||
|
perror("xs_domain_open");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!xs_write(xs, 0, "device/qpen", "new", 3)) {
|
||||||
|
perror("xs_write");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
while (stat("/dev/xvdg", &st))
|
||||||
|
usleep(100000);
|
||||||
|
xvdg_fd = open("/dev/xvdg", O_WRONLY);
|
||||||
|
if (xvdg_fd < 0) {
|
||||||
|
perror("open xvdg");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
setuid(getuid());
|
||||||
|
if (argc == 3)
|
||||||
|
seq = get_and_set_seq();
|
||||||
|
else
|
||||||
|
seq = strtoul(argv[3], 0, 0);
|
||||||
|
file_fd = open(abs_filename, O_RDONLY);
|
||||||
|
if (file_fd < 0) {
|
||||||
|
perror("open file");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (write(xvdg_fd, &header, sizeof(header)) != sizeof(header)) {
|
||||||
|
perror("write filesize");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
copy_file(xvdg_fd, file_fd);
|
||||||
|
close(file_fd);
|
||||||
|
close(xvdg_fd);
|
||||||
|
snprintf(buf, sizeof(buf), "send %s %d", argv[1], seq);
|
||||||
|
if (!xs_write(xs, 0, "device/qpen", buf, strlen(buf))) {
|
||||||
|
perror("xs_write");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
write_db(abs_filename, seq);
|
||||||
|
xs_daemon_close(xs);
|
||||||
|
return 0;
|
||||||
|
}
|
30
appvm/xorg-preload-apps.conf
Normal file
30
appvm/xorg-preload-apps.conf
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
Section "ServerLayout"
|
||||||
|
Identifier "Default Layout"
|
||||||
|
Screen 0 "Screen0" 0 0
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
Section "Device"
|
||||||
|
Identifier "Videocard0"
|
||||||
|
Driver "dummy"
|
||||||
|
VideoRam 4001
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
Section "Monitor"
|
||||||
|
Identifier "Monitor0"
|
||||||
|
HorizSync 49-50
|
||||||
|
VertRefresh 62-63
|
||||||
|
Modeline "QB1280x800" 64 1280 1281 1282 1283 800 801 802 803
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
Section "Screen"
|
||||||
|
Identifier "Screen0"
|
||||||
|
Device "Videocard0"
|
||||||
|
Monitor "Monitor0"
|
||||||
|
DefaultDepth 24
|
||||||
|
SubSection "Display"
|
||||||
|
Viewport 0 0
|
||||||
|
Depth 24
|
||||||
|
Modes "QB1280x800"
|
||||||
|
EndSubSection
|
||||||
|
EndSection
|
||||||
|
|
@ -1,2 +1,2 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
/usr/bin/qubes_setup_dnat_to_ns
|
/usr/lib/qubes/qubes_setup_dnat_to_ns
|
||||||
|
@ -10,7 +10,7 @@ addrule()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
export PATH=$PATH:/sbin:/bin
|
export PATH=$PATH:/sbin:/bin
|
||||||
source /var/run/qubes_ns
|
source /var/run/qubes/qubes_ns
|
||||||
if [ "X"$NS1 = "X" ] ; then exit ; fi
|
if [ "X"$NS1 = "X" ] ; then exit ; fi
|
||||||
iptables -t nat -F PREROUTING
|
iptables -t nat -F PREROUTING
|
||||||
FIRSTONE=yes
|
FIRSTONE=yes
|
||||||
|
@ -20,15 +20,17 @@ start()
|
|||||||
|
|
||||||
# Setup gateway for all the VMs this netVM is serviceing...
|
# Setup gateway for all the VMs this netVM is serviceing...
|
||||||
brctl addbr br0
|
brctl addbr br0
|
||||||
|
brctl stp br0 off
|
||||||
|
brctl setfd br0 1
|
||||||
gateway=$(/usr/bin/xenstore-read qubes_netvm_gateway)
|
gateway=$(/usr/bin/xenstore-read qubes_netvm_gateway)
|
||||||
netmask=$(/usr/bin/xenstore-read qubes_netvm_netmask)
|
netmask=$(/usr/bin/xenstore-read qubes_netvm_netmask)
|
||||||
network=$(/usr/bin/xenstore-read qubes_netvm_network)
|
network=$(/usr/bin/xenstore-read qubes_netvm_network)
|
||||||
secondary_dns=$(/usr/bin/xenstore-read qubes_netvm_secondary_dns)
|
secondary_dns=$(/usr/bin/xenstore-read qubes_netvm_secondary_dns)
|
||||||
ifconfig br0 $gateway netmask $netmask up
|
ifconfig br0 $gateway netmask $netmask up
|
||||||
ifconfig br0:1 $secondary_dns netmask $netmask
|
ifconfig br0:1 $secondary_dns netmask $netmask
|
||||||
echo "NS1=$gateway" > /var/run/qubes_ns
|
echo "NS1=$gateway" > /var/run/qubes/qubes_ns
|
||||||
echo "NS2=$secondary_dns" >> /var/run/qubes_ns
|
echo "NS2=$secondary_dns" >> /var/run/qubes/qubes_ns
|
||||||
qubes_setup_dnat_to_ns
|
/usr/lib/qubes/qubes_setup_dnat_to_ns
|
||||||
echo "1" > /proc/sys/net/ipv4/ip_forward
|
echo "1" > /proc/sys/net/ipv4/ip_forward
|
||||||
#now no need for dnsmasq
|
#now no need for dnsmasq
|
||||||
# dnsmasq --listen-address $gateway --bind-interfaces
|
# dnsmasq --listen-address $gateway --bind-interfaces
|
||||||
|
@ -33,6 +33,7 @@ License: GPL
|
|||||||
URL: http://www.qubes-os.org
|
URL: http://www.qubes-os.org
|
||||||
Requires: /usr/bin/xenstore-read
|
Requires: /usr/bin/xenstore-read
|
||||||
Requires: fedora-release = 13
|
Requires: fedora-release = 13
|
||||||
|
Requires: /usr/bin/mimeopen
|
||||||
Provides: qubes-core-vm
|
Provides: qubes-core-vm
|
||||||
|
|
||||||
%define _builddir %(pwd)/appvm
|
%define _builddir %(pwd)/appvm
|
||||||
@ -60,9 +61,12 @@ mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
|||||||
cp qubes_core $RPM_BUILD_ROOT/etc/init.d/
|
cp qubes_core $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_add_pendrive_script qubes_penctl qvm-copy-to-vm qvm-copy-to-vm.kde $RPM_BUILD_ROOT/usr/bin
|
cp qubes_timestamp qvm-copy-to-vm qvm-open-in-dvm $RPM_BUILD_ROOT/usr/bin
|
||||||
|
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
|
||||||
|
ln -s /usr/bin/qvm-open-in-dvm $RPM_BUILD_ROOT/usr/lib/qubes/qvm-dvm-transfer
|
||||||
mkdir -p $RPM_BUILD_ROOT/%{kde_service_dir}
|
mkdir -p $RPM_BUILD_ROOT/%{kde_service_dir}
|
||||||
cp qvm-copy.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/etc/udev/rules.d
|
mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d
|
||||||
cp qubes.rules $RPM_BUILD_ROOT/etc/udev/rules.d
|
cp qubes.rules $RPM_BUILD_ROOT/etc/udev/rules.d
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
||||||
@ -77,6 +81,12 @@ cp ../common/qubes_serial_login $RPM_BUILD_ROOT/sbin
|
|||||||
mkdir -p $RPM_BUILD_ROOT/etc
|
mkdir -p $RPM_BUILD_ROOT/etc
|
||||||
cp ../common/serial.conf $RPM_BUILD_ROOT/var/lib/qubes/
|
cp ../common/serial.conf $RPM_BUILD_ROOT/var/lib/qubes/
|
||||||
|
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/etc/X11
|
||||||
|
cp xorg-preload-apps.conf $RPM_BUILD_ROOT/etc/X11
|
||||||
|
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/home_volatile/user
|
||||||
|
chown 500:500 $RPM_BUILD_ROOT/home_volatile/user
|
||||||
|
|
||||||
%triggerin -- initscripts
|
%triggerin -- initscripts
|
||||||
cp /var/lib/qubes/serial.conf /etc/init/serial.conf
|
cp /var/lib/qubes/serial.conf /etc/init/serial.conf
|
||||||
|
|
||||||
@ -174,10 +184,13 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
/etc/fstab
|
/etc/fstab
|
||||||
/etc/init.d/qubes_core
|
/etc/init.d/qubes_core
|
||||||
/usr/bin/qvm-copy-to-vm
|
/usr/bin/qvm-copy-to-vm
|
||||||
/usr/bin/qvm-copy-to-vm.kde
|
/usr/lib/qubes/qvm-copy-to-vm.kde
|
||||||
|
%attr(4755,root,root) /usr/bin/qvm-open-in-dvm
|
||||||
|
/usr/lib/qubes/qvm-dvm-transfer
|
||||||
%{kde_service_dir}/qvm-copy.desktop
|
%{kde_service_dir}/qvm-copy.desktop
|
||||||
%attr(4755,root,root) /usr/bin/qubes_penctl
|
%{kde_service_dir}/qvm-dvm.desktop
|
||||||
/usr/bin/qubes_add_pendrive_script
|
%attr(4755,root,root) /usr/lib/qubes/qubes_penctl
|
||||||
|
/usr/lib/qubes/qubes_add_pendrive_script
|
||||||
/etc/udev/rules.d/qubes.rules
|
/etc/udev/rules.d/qubes.rules
|
||||||
/etc/sysconfig/iptables
|
/etc/sysconfig/iptables
|
||||||
/var/lib/qubes
|
/var/lib/qubes
|
||||||
@ -186,3 +199,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%dir /mnt/removable
|
%dir /mnt/removable
|
||||||
/etc/yum.repos.d/qubes.repo
|
/etc/yum.repos.d/qubes.repo
|
||||||
/sbin/qubes_serial_login
|
/sbin/qubes_serial_login
|
||||||
|
/usr/bin/qubes_timestamp
|
||||||
|
%dir /home_volatile
|
||||||
|
%attr(700,user,user) /home_volatile/user
|
||||||
|
/etc/X11/xorg-preload-apps.conf
|
||||||
|
@ -59,10 +59,10 @@ cp fstab $RPM_BUILD_ROOT/etc/fstab
|
|||||||
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
||||||
cp qubes_core $RPM_BUILD_ROOT/etc/init.d/
|
cp qubes_core $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/lib/qubes
|
||||||
cp ../common/qubes_setup_dnat_to_ns $RPM_BUILD_ROOT/usr/bin
|
cp ../common/qubes_setup_dnat_to_ns $RPM_BUILD_ROOT/usr/lib/qubes
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc/dhclient.d
|
mkdir -p $RPM_BUILD_ROOT/etc/dhclient.d
|
||||||
ln -s /usr/bin/qubes_setup_dnat_to_ns $RPM_BUILD_ROOT/etc/dhclient.d/qubes_setup_dnat_to_ns.sh
|
ln -s /usr/lib/qubes/qubes_setup_dnat_to_ns $RPM_BUILD_ROOT/etc/dhclient.d/qubes_setup_dnat_to_ns.sh
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/
|
mkdir -p $RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/
|
||||||
cp ../common/qubes_nmhook $RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/
|
cp ../common/qubes_nmhook $RPM_BUILD_ROOT/etc/NetworkManager/dispatcher.d/
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc/yum.repos.d
|
mkdir -p $RPM_BUILD_ROOT/etc/yum.repos.d
|
||||||
@ -71,6 +71,7 @@ mkdir -p $RPM_BUILD_ROOT/sbin
|
|||||||
cp ../common/qubes_serial_login $RPM_BUILD_ROOT/sbin
|
cp ../common/qubes_serial_login $RPM_BUILD_ROOT/sbin
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc
|
mkdir -p $RPM_BUILD_ROOT/etc
|
||||||
cp ../common/serial.conf $RPM_BUILD_ROOT/var/lib/qubes/
|
cp ../common/serial.conf $RPM_BUILD_ROOT/var/lib/qubes/
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/var/run/qubes
|
||||||
|
|
||||||
%triggerin -- initscripts
|
%triggerin -- initscripts
|
||||||
cp /var/lib/qubes/serial.conf /etc/init/serial.conf
|
cp /var/lib/qubes/serial.conf /etc/init/serial.conf
|
||||||
@ -168,8 +169,9 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
/etc/sysconfig/iptables
|
/etc/sysconfig/iptables
|
||||||
/etc/init.d/qubes_core
|
/etc/init.d/qubes_core
|
||||||
/var/lib/qubes
|
/var/lib/qubes
|
||||||
/usr/bin/qubes_setup_dnat_to_ns
|
/usr/lib/qubes/qubes_setup_dnat_to_ns
|
||||||
/etc/dhclient.d/qubes_setup_dnat_to_ns.sh
|
/etc/dhclient.d/qubes_setup_dnat_to_ns.sh
|
||||||
/etc/NetworkManager/dispatcher.d/qubes_nmhook
|
/etc/NetworkManager/dispatcher.d/qubes_nmhook
|
||||||
/etc/yum.repos.d/qubes.repo
|
/etc/yum.repos.d/qubes.repo
|
||||||
/sbin/qubes_serial_login
|
/sbin/qubes_serial_login
|
||||||
|
%dir /var/run/qubes
|
||||||
|
Loading…
Reference in New Issue
Block a user