parent
042b6717a8
commit
7486078769
@ -13,7 +13,7 @@ arch=("x86_64")
|
|||||||
url="http://qubes-os.org/"
|
url="http://qubes-os.org/"
|
||||||
license=('GPL')
|
license=('GPL')
|
||||||
groups=()
|
groups=()
|
||||||
makedepends=(gcc make pkgconfig 'qubes-libvchan' 'python-setuptools' 'python2-setuptools')
|
makedepends=(gcc make pkgconfig 'python-setuptools' 'python2-setuptools')
|
||||||
checkdepends=()
|
checkdepends=()
|
||||||
optdepends=()
|
optdepends=()
|
||||||
provides=()
|
provides=()
|
||||||
@ -45,7 +45,7 @@ make -C imgconverter all
|
|||||||
}
|
}
|
||||||
|
|
||||||
package_qubes-vm-utils() {
|
package_qubes-vm-utils() {
|
||||||
depends=(qubes-libvchan imagemagick python2-cairo python2-pillow python2-numpy python-pillow python-numpy)
|
depends=(imagemagick python2-cairo python2-pillow python2-numpy python-pillow python-numpy)
|
||||||
install=PKGBUILD-qubes-vm-utils.install
|
install=PKGBUILD-qubes-vm-utils.install
|
||||||
|
|
||||||
# Install all for python2
|
# Install all for python2
|
||||||
@ -57,7 +57,7 @@ make -C imgconverter install DESTDIR=$pkgdir LIBDIR=/usr/lib SYSLIBDIR=/usr/lib
|
|||||||
}
|
}
|
||||||
|
|
||||||
package_qubes-vm-kernel-support() {
|
package_qubes-vm-kernel-support() {
|
||||||
depends=(qubes-libvchan mkinitcpio dkms grub)
|
depends=(mkinitcpio dkms grub)
|
||||||
install=PKGBUILD-qubes-vm-kernel-support.install
|
install=PKGBUILD-qubes-vm-kernel-support.install
|
||||||
|
|
||||||
mkdir -p ${pkgdir}/usr/lib/initcpio/install/
|
mkdir -p ${pkgdir}/usr/lib/initcpio/install/
|
||||||
|
20
debian/control
vendored
20
debian/control
vendored
@ -3,7 +3,6 @@ Section: admin
|
|||||||
Priority: extra
|
Priority: extra
|
||||||
Maintainer: Davíð Steinn Geirsson <david@dsg.is>
|
Maintainer: Davíð Steinn Geirsson <david@dsg.is>
|
||||||
Build-Depends:
|
Build-Depends:
|
||||||
libvchan-xen-dev,
|
|
||||||
libxen-dev,
|
libxen-dev,
|
||||||
pkg-config,
|
pkg-config,
|
||||||
debhelper (>= 9.0.0),
|
debhelper (>= 9.0.0),
|
||||||
@ -17,7 +16,7 @@ Vcs-Git: http://dsg.is/qubes/qubes-linux-utils.git
|
|||||||
|
|
||||||
Package: qubes-utils
|
Package: qubes-utils
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: libvchan-xen, lsb-base, python-pil, python-numpy, python3-pil, python3-numpy, ${shlibs:Depends}, ${misc:Depends}
|
Depends: lsb-base, python-pil, python-numpy, python3-pil, python3-numpy, ${shlibs:Depends}, ${misc:Depends}
|
||||||
Conflicts: qubes-linux-utils
|
Conflicts: qubes-linux-utils
|
||||||
Breaks: qubes-core-agent (<< 3.1.4)
|
Breaks: qubes-core-agent (<< 3.1.4)
|
||||||
Recommends: python2.7
|
Recommends: python2.7
|
||||||
@ -37,14 +36,6 @@ Description: Qubes VM kernel and initramfs modules
|
|||||||
2. u2mfn kernel module sources (dkms) required by GUI agent and R2 version of
|
2. u2mfn kernel module sources (dkms) required by GUI agent and R2 version of
|
||||||
libvchan library.
|
libvchan library.
|
||||||
|
|
||||||
Package: libqrexec-utils2
|
|
||||||
Architecture: any
|
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
|
||||||
Breaks: qubes-utils (<< 3.1.4)
|
|
||||||
Replaces: qubes-utils (<< 3.1.4)
|
|
||||||
Description: Library of common functions of qrexec agent and daemon
|
|
||||||
This library contains common helper functions for qrexec agent and daemon.
|
|
||||||
|
|
||||||
Package: libqubes-rpc-filecopy2
|
Package: libqubes-rpc-filecopy2
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||||
@ -54,15 +45,6 @@ Description: Qubes file copy protocol library
|
|||||||
This library can be used for both sending files using qfile protocol and for
|
This library can be used for both sending files using qfile protocol and for
|
||||||
receiving them.
|
receiving them.
|
||||||
|
|
||||||
Package: libqrexec-utils-dev
|
|
||||||
Architecture: any
|
|
||||||
Section: libdevel
|
|
||||||
Depends: libqrexec-utils2 (= ${binary:Version}), ${misc:Depends}
|
|
||||||
Breaks: qubes-utils (<< 3.1.4)
|
|
||||||
Replaces: qubes-utils (<< 3.1.4)
|
|
||||||
Description: Development headers for libqrexec-utils
|
|
||||||
This package contains files required to compile qrexec-agent and qrexec-daemon.
|
|
||||||
|
|
||||||
Package: libqubes-rpc-filecopy-dev
|
Package: libqubes-rpc-filecopy-dev
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Section: libdevel
|
Section: libdevel
|
||||||
|
3
debian/libqrexec-utils-dev.install
vendored
3
debian/libqrexec-utils-dev.install
vendored
@ -1,3 +0,0 @@
|
|||||||
usr/include/libqrexec-utils.h
|
|
||||||
usr/include/qrexec.h
|
|
||||||
usr/lib/libqrexec-utils.so
|
|
1
debian/libqrexec-utils2.install
vendored
1
debian/libqrexec-utils2.install
vendored
@ -1 +0,0 @@
|
|||||||
usr/lib/libqrexec-utils.so.2*
|
|
1
debian/libqrexec-utils2.shlibs
vendored
1
debian/libqrexec-utils2.shlibs
vendored
@ -1 +0,0 @@
|
|||||||
libqrexec-utils 2 libqrexec-utils2 (>= 4.0.16)
|
|
@ -1,19 +1,9 @@
|
|||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS+=-I. -g -O2 -Wall -Wextra -Werror -pie -fPIC `pkg-config --cflags vchan-$(BACKEND_VMM)`
|
CFLAGS+=-I. -g -O2 -Wall -Wextra -Werror -pie -fPIC
|
||||||
COMMONIOALL=ioall.o
|
|
||||||
SO_VER=2
|
SO_VER=2
|
||||||
LDFLAGS+=-shared
|
LDFLAGS+=-shared
|
||||||
VCHANLIBS = `pkg-config --libs vchan-$(BACKEND_VMM)`
|
|
||||||
|
|
||||||
_XENSTORE_H=$(shell ls /usr/include/xenstore.h)
|
all: libqubes-rpc-filecopy.so.$(SO_VER)
|
||||||
ifneq "$(_XENSTORE_H)" ""
|
|
||||||
CFLAGS+= -DUSE_XENSTORE_H
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
all: libqrexec-utils.so.$(SO_VER) libqubes-rpc-filecopy.so.$(SO_VER)
|
|
||||||
libqrexec-utils.so.$(SO_VER): unix-server.o ioall.o buffer.o exec.o txrx-vchan.o write-stdin.o
|
|
||||||
$(CC) $(LDFLAGS) -Wl,-soname,$@ -o $@ $^ $(VCHANLIBS)
|
|
||||||
libqubes-rpc-filecopy.so.$(SO_VER): ioall.o copy-file.o crc32.o unpack.o pack.o
|
libqubes-rpc-filecopy.so.$(SO_VER): ioall.o copy-file.o crc32.o unpack.o pack.o
|
||||||
$(CC) $(LDFLAGS) -Wl,-soname,$@ -o $@ $^
|
$(CC) $(LDFLAGS) -Wl,-soname,$@ -o $@ $^
|
||||||
|
|
||||||
@ -24,12 +14,7 @@ clean:
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
mkdir -p $(DESTDIR)$(LIBDIR)
|
mkdir -p $(DESTDIR)$(LIBDIR)
|
||||||
cp libqrexec-utils.so.$(SO_VER) $(DESTDIR)$(LIBDIR)
|
|
||||||
ln -s libqrexec-utils.so.$(SO_VER) $(DESTDIR)$(LIBDIR)/libqrexec-utils.so
|
|
||||||
cp libqubes-rpc-filecopy.so.$(SO_VER) $(DESTDIR)$(LIBDIR)
|
cp libqubes-rpc-filecopy.so.$(SO_VER) $(DESTDIR)$(LIBDIR)
|
||||||
ln -s libqubes-rpc-filecopy.so.$(SO_VER) $(DESTDIR)$(LIBDIR)/libqubes-rpc-filecopy.so
|
ln -s libqubes-rpc-filecopy.so.$(SO_VER) $(DESTDIR)$(LIBDIR)/libqubes-rpc-filecopy.so
|
||||||
mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
||||||
cp libqrexec-utils.h $(DESTDIR)$(INCLUDEDIR)
|
|
||||||
cp libqubes-rpc-filecopy.h $(DESTDIR)$(INCLUDEDIR)
|
cp libqubes-rpc-filecopy.h $(DESTDIR)$(INCLUDEDIR)
|
||||||
cp qrexec.h $(DESTDIR)$(INCLUDEDIR)
|
|
||||||
|
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "libqrexec-utils.h"
|
|
||||||
|
|
||||||
#define BUFFER_LIMIT 50000000
|
|
||||||
static int total_mem;
|
|
||||||
static char *limited_malloc(int len)
|
|
||||||
{
|
|
||||||
char *ret;
|
|
||||||
total_mem += len;
|
|
||||||
if (total_mem > BUFFER_LIMIT) {
|
|
||||||
fprintf(stderr, "attempt to allocate >BUFFER_LIMIT\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
ret = malloc(len);
|
|
||||||
if (!ret) {
|
|
||||||
perror("malloc");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void limited_free(char *ptr, int len)
|
|
||||||
{
|
|
||||||
free(ptr);
|
|
||||||
total_mem -= len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void buffer_init(struct buffer *b)
|
|
||||||
{
|
|
||||||
b->buflen = 0;
|
|
||||||
b->data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void buffer_free(struct buffer *b)
|
|
||||||
{
|
|
||||||
if (b->buflen)
|
|
||||||
limited_free(b->data, b->buflen);
|
|
||||||
buffer_init(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
The following two functions can be made much more efficient.
|
|
||||||
Yet the profiling output show they are not significant CPU hogs, so
|
|
||||||
we keep them so simple to make them obviously correct.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void buffer_append(struct buffer *b, const char *data, int len)
|
|
||||||
{
|
|
||||||
int newsize;
|
|
||||||
char *qdata;
|
|
||||||
if (len < 0 || len > BUFFER_LIMIT) {
|
|
||||||
fprintf(stderr, "buffer_append %d\n", len);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (len == 0)
|
|
||||||
return;
|
|
||||||
newsize = len + b->buflen;
|
|
||||||
qdata = limited_malloc(len + b->buflen);
|
|
||||||
memcpy(qdata, b->data, b->buflen);
|
|
||||||
memcpy(qdata + b->buflen, data, len);
|
|
||||||
buffer_free(b);
|
|
||||||
b->buflen = newsize;
|
|
||||||
b->data = qdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
void buffer_remove(struct buffer *b, int len)
|
|
||||||
{
|
|
||||||
int newsize;
|
|
||||||
char *qdata = NULL;
|
|
||||||
if (len < 0 || len > b->buflen) {
|
|
||||||
fprintf(stderr, "buffer_remove %d/%d\n", len, b->buflen);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
newsize = b->buflen - len;
|
|
||||||
if (newsize > 0) {
|
|
||||||
qdata = limited_malloc(newsize);
|
|
||||||
memcpy(qdata, b->data + len, newsize);
|
|
||||||
}
|
|
||||||
buffer_free(b);
|
|
||||||
b->buflen = newsize;
|
|
||||||
b->data = qdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
int buffer_len(struct buffer *b)
|
|
||||||
{
|
|
||||||
return b->buflen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *buffer_data(struct buffer *b)
|
|
||||||
{
|
|
||||||
return b->data;
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "qrexec.h"
|
|
||||||
#include "libqrexec-utils.h"
|
|
||||||
|
|
||||||
static do_exec_t *exec_func = NULL;
|
|
||||||
void register_exec_func(do_exec_t *func) {
|
|
||||||
exec_func = func;
|
|
||||||
}
|
|
||||||
|
|
||||||
void exec_qubes_rpc_if_requested(char *prog, char *const envp[]) {
|
|
||||||
/* avoid calling qubes-rpc-multiplexer through shell */
|
|
||||||
if (strncmp(prog, RPC_REQUEST_COMMAND, RPC_REQUEST_COMMAND_LEN) == 0) {
|
|
||||||
char *tok;
|
|
||||||
char *argv[16]; // right now 6 are used, but allow future extensions
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
tok=strtok(prog, " ");
|
|
||||||
do {
|
|
||||||
if (i >= sizeof(argv)/sizeof(argv[0])-1) {
|
|
||||||
fprintf(stderr, "To many arguments to %s\n", RPC_REQUEST_COMMAND);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
argv[i++] = tok;
|
|
||||||
} while ((tok=strtok(NULL, " ")));
|
|
||||||
argv[i] = NULL;
|
|
||||||
argv[0] = QUBES_RPC_MULTIPLEXER_PATH;
|
|
||||||
execve(QUBES_RPC_MULTIPLEXER_PATH, argv, envp);
|
|
||||||
perror("exec qubes-rpc-multiplexer");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fix_fds(int fdin, int fdout, int fderr)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
if (i != fdin && i != fdout && i != fderr)
|
|
||||||
close(i);
|
|
||||||
dup2(fdin, 0);
|
|
||||||
dup2(fdout, 1);
|
|
||||||
dup2(fderr, 2);
|
|
||||||
close(fdin);
|
|
||||||
close(fdout);
|
|
||||||
if (fderr != 2)
|
|
||||||
close(fderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void do_fork_exec(const char *cmdline, int *pid, int *stdin_fd, int *stdout_fd,
|
|
||||||
int *stderr_fd)
|
|
||||||
{
|
|
||||||
int inpipe[2], outpipe[2], errpipe[2];
|
|
||||||
|
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inpipe) ||
|
|
||||||
socketpair(AF_UNIX, SOCK_STREAM, 0, outpipe) ||
|
|
||||||
(stderr_fd && socketpair(AF_UNIX, SOCK_STREAM, 0, errpipe))) {
|
|
||||||
perror("socketpair");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
switch (*pid = fork()) {
|
|
||||||
case -1:
|
|
||||||
perror("fork");
|
|
||||||
exit(-1);
|
|
||||||
case 0:
|
|
||||||
if (stderr_fd) {
|
|
||||||
fix_fds(inpipe[0], outpipe[1], errpipe[1]);
|
|
||||||
} else
|
|
||||||
fix_fds(inpipe[0], outpipe[1], 2);
|
|
||||||
|
|
||||||
if (exec_func != NULL)
|
|
||||||
exec_func((char*)cmdline);
|
|
||||||
exit(-1);
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
close(inpipe[0]);
|
|
||||||
close(outpipe[1]);
|
|
||||||
*stdin_fd = inpipe[1];
|
|
||||||
*stdout_fd = outpipe[0];
|
|
||||||
if (stderr_fd) {
|
|
||||||
close(errpipe[1]);
|
|
||||||
*stderr_fd = errpipe[0];
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
|
||||||
* Copyright (C) 2013 Marek Marczykowski <marmarek@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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <libvchan.h>
|
|
||||||
|
|
||||||
struct buffer {
|
|
||||||
char *data;
|
|
||||||
int buflen;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* return codes for buffered writes */
|
|
||||||
#define WRITE_STDIN_OK 0 /* all written */
|
|
||||||
#define WRITE_STDIN_BUFFERED 1 /* something still in the buffer */
|
|
||||||
#define WRITE_STDIN_ERROR 2 /* write error, errno set */
|
|
||||||
|
|
||||||
typedef void (do_exec_t)(char *);
|
|
||||||
void register_exec_func(do_exec_t *func);
|
|
||||||
/*
|
|
||||||
* exec() qubes-rpc-multiplexer if *prog* starts with magic "QUBESRPC" keyword,
|
|
||||||
* do not return in that case; pass *envp* to execve() as en environment
|
|
||||||
* otherwise, return false without any action
|
|
||||||
*/
|
|
||||||
void exec_qubes_rpc_if_requested(char *prog, char *const envp[]);
|
|
||||||
|
|
||||||
void buffer_init(struct buffer *b);
|
|
||||||
void buffer_free(struct buffer *b);
|
|
||||||
void buffer_append(struct buffer *b, const char *data, int len);
|
|
||||||
void buffer_remove(struct buffer *b, int len);
|
|
||||||
int buffer_len(struct buffer *b);
|
|
||||||
void *buffer_data(struct buffer *b);
|
|
||||||
|
|
||||||
int flush_client_data(int fd, struct buffer *buffer);
|
|
||||||
int write_stdin(int fd, const char *data, int len, struct buffer *buffer);
|
|
||||||
int fork_and_flush_stdin(int fd, struct buffer *buffer);
|
|
||||||
|
|
||||||
void do_fork_exec(const char *cmdline, int *pid, int *stdin_fd, int *stdout_fd,
|
|
||||||
int *stderr_fd);
|
|
||||||
void wait_for_vchan_or_argfd(libvchan_t *vchan, int max, fd_set * rdset, fd_set * wrset);
|
|
||||||
int read_vchan_all(libvchan_t *vchan, void *data, size_t size);
|
|
||||||
int write_vchan_all(libvchan_t *vchan, const void *data, size_t size);
|
|
||||||
int read_all(int fd, void *buf, int size);
|
|
||||||
int write_all(int fd, const void *buf, int size);
|
|
||||||
void fix_fds(int fdin, int fdout, int fderr);
|
|
||||||
void set_nonblock(int fd);
|
|
||||||
void set_block(int fd);
|
|
||||||
|
|
||||||
int get_server_socket(const char *);
|
|
||||||
int do_accept(int s);
|
|
||||||
|
|
||||||
void set_nonblock(int fd);
|
|
@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* See also http://wiki.qubes-os.org/trac/wiki/Qrexec */
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define QREXEC_PROTOCOL_VERSION 2
|
|
||||||
#define MAX_FDS 256
|
|
||||||
#define MAX_DATA_CHUNK 4096
|
|
||||||
|
|
||||||
#define RPC_REQUEST_COMMAND "QUBESRPC"
|
|
||||||
#define RPC_REQUEST_COMMAND_LEN (sizeof(RPC_REQUEST_COMMAND)-1)
|
|
||||||
#define NOGUI_CMD_PREFIX "nogui:"
|
|
||||||
#define NOGUI_CMD_PREFIX_LEN (sizeof(NOGUI_CMD_PREFIX)-1)
|
|
||||||
#define VCHAN_BASE_PORT 512
|
|
||||||
|
|
||||||
/* Messages sent over control vchan between daemon(dom0) and agent(vm).
|
|
||||||
* The same are used between client(dom0) and daemon(dom0).
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
/* daemon->agent messages */
|
|
||||||
|
|
||||||
/* start process in VM and pass its stdin/out/err to dom0
|
|
||||||
* struct exec_params passed as data */
|
|
||||||
MSG_EXEC_CMDLINE = 0x200,
|
|
||||||
|
|
||||||
/* start process in VM discarding its stdin/out/err (connect to /dev/null)
|
|
||||||
* struct exec_params passed as data */
|
|
||||||
MSG_JUST_EXEC,
|
|
||||||
|
|
||||||
/* connect to existing process in VM to receive its stdin/out/err
|
|
||||||
* struct service_params passed as cmdline field in exec_params */
|
|
||||||
MSG_SERVICE_CONNECT,
|
|
||||||
|
|
||||||
/* refuse to start a service (denied by policy, invalid parameters etc)
|
|
||||||
* struct service_params passed as data to identify which service call was
|
|
||||||
* refused */
|
|
||||||
MSG_SERVICE_REFUSED,
|
|
||||||
|
|
||||||
/* agent->daemon messages */
|
|
||||||
/* call Qubes RPC service
|
|
||||||
* struct trigger_service_params passed as data */
|
|
||||||
MSG_TRIGGER_SERVICE = 0x210,
|
|
||||||
|
|
||||||
|
|
||||||
/* connection was terminated, struct exec_params passed as data (with empty
|
|
||||||
* cmdline field) informs about released vchan port */
|
|
||||||
MSG_CONNECTION_TERMINATED,
|
|
||||||
|
|
||||||
/* common messages */
|
|
||||||
/* initialize connection, struct peer_info passed as data
|
|
||||||
* should be sent as the first message (server first, then client) */
|
|
||||||
MSG_HELLO = 0x300,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* uniform for all peers, data type depends on message type */
|
|
||||||
struct msg_header {
|
|
||||||
uint32_t type; /* message type */
|
|
||||||
uint32_t len; /* data length */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* variable size */
|
|
||||||
struct exec_params {
|
|
||||||
uint32_t connect_domain; /* target domain name */
|
|
||||||
uint32_t connect_port; /* target vchan port for i/o exchange */
|
|
||||||
char cmdline[0]; /* command line to execute, null terminated, size = msg_header.len - sizeof(struct exec_params) */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct service_params {
|
|
||||||
char ident[32]; /* null terminated ASCII string */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct trigger_service_params {
|
|
||||||
char service_name[64]; /* null terminated ASCII string */
|
|
||||||
char target_domain[32]; /* null terminated ASCII string */
|
|
||||||
struct service_params request_id; /* service request id */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct peer_info {
|
|
||||||
uint32_t version; /* qrexec protocol version */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* data vchan client<->agent, separate for each VM process */
|
|
||||||
enum {
|
|
||||||
/* stdin dom0->VM */
|
|
||||||
MSG_DATA_STDIN = 0x190,
|
|
||||||
/* stdout VM->dom0 */
|
|
||||||
MSG_DATA_STDOUT,
|
|
||||||
/* stderr VM->dom0 */
|
|
||||||
MSG_DATA_STDERR,
|
|
||||||
/* VM process exit code VM->dom0 (uint32_t) */
|
|
||||||
MSG_DATA_EXIT_CODE,
|
|
||||||
};
|
|
||||||
|
|
||||||
// linux-specific stuff below
|
|
||||||
|
|
||||||
#define QREXEC_AGENT_TRIGGER_PATH "/var/run/qubes/qrexec-agent"
|
|
||||||
#define QREXEC_AGENT_FDPASS_PATH "/var/run/qubes/qrexec-agent-fdpass"
|
|
||||||
#define MEMINFO_WRITER_PIDFILE "/var/run/meminfo-writer.pid"
|
|
||||||
#define QUBES_RPC_MULTIPLEXER_PATH "/usr/lib/qubes/qubes-rpc-multiplexer"
|
|
||||||
#define QREXEC_DAEMON_SOCKET_DIR "/var/run/qubes"
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <libvchan.h>
|
|
||||||
|
|
||||||
int wait_for_vchan_or_argfd_once(libvchan_t *ctrl, int max, fd_set * rdset, fd_set * wrset)
|
|
||||||
{
|
|
||||||
int vfd, ret;
|
|
||||||
struct timespec tv = { 1, 100000000 };
|
|
||||||
sigset_t empty_set;
|
|
||||||
|
|
||||||
sigemptyset(&empty_set);
|
|
||||||
|
|
||||||
vfd = libvchan_fd_for_select(ctrl);
|
|
||||||
FD_SET(vfd, rdset);
|
|
||||||
if (vfd > max)
|
|
||||||
max = vfd;
|
|
||||||
max++;
|
|
||||||
ret = pselect(max, rdset, wrset, NULL, &tv, &empty_set);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (errno != EINTR) {
|
|
||||||
perror("select");
|
|
||||||
exit(1);
|
|
||||||
} else {
|
|
||||||
FD_ZERO(rdset);
|
|
||||||
FD_ZERO(wrset);
|
|
||||||
fprintf(stderr, "eintr\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (!libvchan_is_open(ctrl)) {
|
|
||||||
fprintf(stderr, "libvchan_is_eof\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
if (FD_ISSET(vfd, rdset))
|
|
||||||
// the following will never block; we need to do this to
|
|
||||||
// clear libvchan_fd pending state
|
|
||||||
libvchan_wait(ctrl);
|
|
||||||
if (libvchan_data_ready(ctrl))
|
|
||||||
return 1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wait_for_vchan_or_argfd(libvchan_t *ctrl, int max, fd_set * rdset, fd_set * wrset)
|
|
||||||
{
|
|
||||||
fd_set r = *rdset, w = *wrset;
|
|
||||||
do {
|
|
||||||
*rdset = r;
|
|
||||||
*wrset = w;
|
|
||||||
}
|
|
||||||
while (wait_for_vchan_or_argfd_once(ctrl, max, rdset, wrset) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int write_vchan_all(libvchan_t *vchan, const void *data, size_t size) {
|
|
||||||
size_t pos;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
pos = 0;
|
|
||||||
while (pos < size) {
|
|
||||||
ret = libvchan_write(vchan, data+pos, size-pos);
|
|
||||||
if (ret < 0)
|
|
||||||
return 0;
|
|
||||||
pos += ret;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int read_vchan_all(libvchan_t *vchan, void *data, size_t size) {
|
|
||||||
size_t pos;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
pos = 0;
|
|
||||||
while (pos < size) {
|
|
||||||
ret = libvchan_read(vchan, data+pos, size-pos);
|
|
||||||
if (ret < 0)
|
|
||||||
return 0;
|
|
||||||
pos += ret;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
//#include "qrexec.h"
|
|
||||||
|
|
||||||
int get_server_socket(const char *socket_address)
|
|
||||||
{
|
|
||||||
struct sockaddr_un sockname;
|
|
||||||
int s;
|
|
||||||
|
|
||||||
unlink(socket_address);
|
|
||||||
|
|
||||||
s = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
||||||
if (s < 0) {
|
|
||||||
printf("socket() failed\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
memset(&sockname, 0, sizeof(sockname));
|
|
||||||
sockname.sun_family = AF_UNIX;
|
|
||||||
strncpy(sockname.sun_path, socket_address, sizeof sockname.sun_path);
|
|
||||||
sockname.sun_path[sizeof sockname.sun_path - 1] = 0;
|
|
||||||
|
|
||||||
if (bind(s, (struct sockaddr *) &sockname, sizeof(sockname)) == -1) {
|
|
||||||
printf("bind() failed\n");
|
|
||||||
close(s);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
// chmod(sockname.sun_path, 0666);
|
|
||||||
if (listen(s, 5) == -1) {
|
|
||||||
perror("listen() failed\n");
|
|
||||||
close(s);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
int do_accept(int s)
|
|
||||||
{
|
|
||||||
struct sockaddr_un peer;
|
|
||||||
unsigned int addrlen;
|
|
||||||
int fd;
|
|
||||||
addrlen = sizeof(peer);
|
|
||||||
fd = accept(s, (struct sockaddr *) &peer, &addrlen);
|
|
||||||
if (fd == -1) {
|
|
||||||
perror("unix accept");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <libvchan.h>
|
|
||||||
#include "qrexec.h"
|
|
||||||
#include "libqrexec-utils.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
There is buffered data in "buffer" for client and select()
|
|
||||||
reports that "fd" is writable. Write as much as possible to fd.
|
|
||||||
*/
|
|
||||||
int flush_client_data(int fd, struct buffer *buffer)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int len;
|
|
||||||
for (;;) {
|
|
||||||
len = buffer_len(buffer);
|
|
||||||
if (!len) {
|
|
||||||
return WRITE_STDIN_OK;
|
|
||||||
}
|
|
||||||
if (len > MAX_DATA_CHUNK)
|
|
||||||
len = MAX_DATA_CHUNK;
|
|
||||||
ret = write(fd, buffer_data(buffer), len);
|
|
||||||
if (ret == -1) {
|
|
||||||
if (errno != EAGAIN) {
|
|
||||||
return WRITE_STDIN_ERROR;
|
|
||||||
} else
|
|
||||||
return WRITE_STDIN_BUFFERED;
|
|
||||||
}
|
|
||||||
// we previously called buffer_remove(buffer, len)
|
|
||||||
// it will be wrong if we change MAX_DATA_CHUNK to something large
|
|
||||||
// as pipes writes are atomic only to PIPE_MAX limit
|
|
||||||
buffer_remove(buffer, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write "len" bytes from "data" to "fd". If not all written, buffer the rest
|
|
||||||
* to "buffer".
|
|
||||||
*/
|
|
||||||
int write_stdin(int fd, const char *data, int len, struct buffer *buffer)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int written = 0;
|
|
||||||
|
|
||||||
if (buffer_len(buffer)) {
|
|
||||||
buffer_append(buffer, data, len);
|
|
||||||
return WRITE_STDIN_BUFFERED;
|
|
||||||
}
|
|
||||||
while (written < len) {
|
|
||||||
ret = write(fd, data + written, len - written);
|
|
||||||
if (ret == 0) {
|
|
||||||
perror("write_stdin: write returns 0 ???");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (ret == -1) {
|
|
||||||
if (errno != EAGAIN)
|
|
||||||
return WRITE_STDIN_ERROR;
|
|
||||||
|
|
||||||
buffer_append(buffer, data + written,
|
|
||||||
len - written);
|
|
||||||
|
|
||||||
return WRITE_STDIN_BUFFERED;
|
|
||||||
}
|
|
||||||
written += ret;
|
|
||||||
}
|
|
||||||
return WRITE_STDIN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data feed process has exited, so we need to clear all control structures for
|
|
||||||
* the client. However, if we have buffered data for the client (which is rare btw),
|
|
||||||
* fire&forget a separate process to flush them.
|
|
||||||
*/
|
|
||||||
int fork_and_flush_stdin(int fd, struct buffer *buffer)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if (!buffer_len(buffer))
|
|
||||||
return 0;
|
|
||||||
switch (fork()) {
|
|
||||||
case -1:
|
|
||||||
perror("fork");
|
|
||||||
exit(1);
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
for (i = 0; i < MAX_FDS; i++)
|
|
||||||
if (i != fd && i != 2)
|
|
||||||
close(i);
|
|
||||||
set_block(fd);
|
|
||||||
write_all(fd, buffer_data(buffer), buffer_len(buffer));
|
|
||||||
_exit(0);
|
|
||||||
}
|
|
@ -14,7 +14,6 @@ Requires: ImageMagick
|
|||||||
Requires: python%{python3_pkgversion}-qubesimgconverter
|
Requires: python%{python3_pkgversion}-qubesimgconverter
|
||||||
%{?systemd_requires}
|
%{?systemd_requires}
|
||||||
BuildRequires: systemd
|
BuildRequires: systemd
|
||||||
BuildRequires: qubes-libvchan-devel
|
|
||||||
BuildRequires: python-setuptools
|
BuildRequires: python-setuptools
|
||||||
BuildRequires: python%{python3_pkgversion}-setuptools
|
BuildRequires: python%{python3_pkgversion}-setuptools
|
||||||
BuildRequires: python2-rpm-macros
|
BuildRequires: python2-rpm-macros
|
||||||
@ -122,15 +121,11 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%{python3_sitelib}/qubesimgconverter/__pycache__
|
%{python3_sitelib}/qubesimgconverter/__pycache__
|
||||||
|
|
||||||
%files libs
|
%files libs
|
||||||
%{_libdir}/libqrexec-utils.so.2
|
|
||||||
%{_libdir}/libqubes-rpc-filecopy.so.2
|
%{_libdir}/libqubes-rpc-filecopy.so.2
|
||||||
|
|
||||||
%files devel
|
%files devel
|
||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
/usr/include/libqrexec-utils.h
|
|
||||||
/usr/include/libqubes-rpc-filecopy.h
|
/usr/include/libqubes-rpc-filecopy.h
|
||||||
/usr/include/qrexec.h
|
|
||||||
%{_libdir}/libqrexec-utils.so
|
|
||||||
%{_libdir}/libqubes-rpc-filecopy.so
|
%{_libdir}/libqubes-rpc-filecopy.so
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
Loading…
Reference in New Issue
Block a user