Implemented mechanism to trigger predefined execution in dom0.
Processes in AppVM can ask qrexec-agent to send a MSG_AGENT_TO_SERVER_TRIGGER_EXEC message to qrexec-daemon. The latter will execute predefined program. It is useful for the purpose of file copy; the predefined program will create a connected qfile-daemon<->qfile-agent pair.
This commit is contained in:
parent
8f90623661
commit
f1a7df6e95
@ -25,6 +25,8 @@
|
||||
|
||||
#define REXEC_PORT 512
|
||||
|
||||
#define QREXEC_AGENT_TRIGGER_PATH "/var/run/qubes/qrexec_agent"
|
||||
|
||||
enum {
|
||||
MSG_CLIENT_TO_SERVER_EXEC_CMDLINE = 0x100,
|
||||
MSG_CLIENT_TO_SERVER_JUST_EXEC,
|
||||
@ -40,12 +42,18 @@ enum {
|
||||
MSG_AGENT_TO_SERVER_STDOUT,
|
||||
MSG_AGENT_TO_SERVER_STDERR,
|
||||
MSG_AGENT_TO_SERVER_EXIT_CODE,
|
||||
MSG_AGENT_TO_SERVER_TRIGGER_EXEC,
|
||||
|
||||
MSG_SERVER_TO_CLIENT_STDOUT,
|
||||
MSG_SERVER_TO_CLIENT_STDERR,
|
||||
MSG_SERVER_TO_CLIENT_EXIT_CODE
|
||||
};
|
||||
|
||||
enum {
|
||||
QREXEC_EXECUTE_FILE_COPY=0x700,
|
||||
QREXEC_EXECUTE_FILE_COPY_FOR_DISPVM
|
||||
};
|
||||
|
||||
struct server_header {
|
||||
unsigned int type;
|
||||
unsigned int clid;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <sys/stat.h>
|
||||
#include "qrexec.h"
|
||||
#include "buffer.h"
|
||||
#include "glue.h"
|
||||
@ -63,9 +64,16 @@ struct _process_fd process_fd[MAX_FDS];
|
||||
/* indexed by client id, which is descriptor number of a client in daemon */
|
||||
struct _client_info client_info[MAX_FDS];
|
||||
|
||||
int trigger_fd;
|
||||
|
||||
void init()
|
||||
{
|
||||
peer_server_init(REXEC_PORT);
|
||||
umask(0);
|
||||
mkfifo(QREXEC_AGENT_TRIGGER_PATH, 0666);
|
||||
umask(077);
|
||||
trigger_fd =
|
||||
open(QREXEC_AGENT_TRIGGER_PATH, O_RDONLY | O_NONBLOCK);
|
||||
}
|
||||
|
||||
void no_colon_in_cmd()
|
||||
@ -418,6 +426,11 @@ int fill_fds_for_select(fd_set * rdset, fd_set * wrset)
|
||||
FD_SET(i, rdset);
|
||||
max = i;
|
||||
}
|
||||
|
||||
FD_SET(trigger_fd, rdset);
|
||||
if (trigger_fd > max)
|
||||
max = trigger_fd;
|
||||
|
||||
for (i = 0; i < MAX_FDS; i++)
|
||||
if (client_info[i].pid > 0 && client_info[i].is_blocked) {
|
||||
fd = client_info[i].stdin_fd;
|
||||
@ -446,6 +459,28 @@ void flush_client_data_agent(int clid)
|
||||
}
|
||||
}
|
||||
|
||||
void handle_trigger_io()
|
||||
{
|
||||
struct server_header s_hdr;
|
||||
char buf[5];
|
||||
|
||||
s_hdr.clid = 0;
|
||||
s_hdr.len = 0;
|
||||
if (read(trigger_fd, buf, 4) == 4) {
|
||||
buf[4] = 0;
|
||||
if (!strcmp(buf, "FCPR"))
|
||||
s_hdr.clid = QREXEC_EXECUTE_FILE_COPY;
|
||||
else if (!strcmp(buf, "DVMR"))
|
||||
s_hdr.clid = QREXEC_EXECUTE_FILE_COPY_FOR_DISPVM;
|
||||
if (s_hdr.clid) {
|
||||
s_hdr.type = MSG_AGENT_TO_SERVER_TRIGGER_EXEC;
|
||||
write_all_vchan_ext(&s_hdr, sizeof s_hdr);
|
||||
}
|
||||
}
|
||||
close(trigger_fd);
|
||||
trigger_fd =
|
||||
open(QREXEC_AGENT_TRIGGER_PATH, O_RDONLY | O_NONBLOCK);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -469,6 +504,9 @@ int main()
|
||||
while (read_ready_vchan_ext())
|
||||
handle_server_data();
|
||||
|
||||
if (FD_ISSET(trigger_fd, &rdset))
|
||||
handle_trigger_io();
|
||||
|
||||
handle_process_data_all(&rdset);
|
||||
for (i = 0; i <= MAX_FDS; i++)
|
||||
if (client_info[i].pid > 0
|
||||
|
@ -51,9 +51,11 @@ int server_fd;
|
||||
|
||||
void handle_usr1(int x)
|
||||
{
|
||||
exit(0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
char domain_id[64];
|
||||
|
||||
void init(int xid)
|
||||
{
|
||||
char dbg_log[256];
|
||||
@ -63,6 +65,7 @@ void init(int xid)
|
||||
fprintf(stderr, "domain id=0?\n");
|
||||
exit(1);
|
||||
}
|
||||
snprintf(domain_id, sizeof(domain_id), "%d", xid);
|
||||
signal(SIGUSR1, handle_usr1);
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
@ -71,7 +74,7 @@ void init(int xid)
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
pause();
|
||||
pause();
|
||||
exit(0);
|
||||
}
|
||||
close(0);
|
||||
@ -94,6 +97,7 @@ void init(int xid)
|
||||
peer_client_init(xid, REXEC_PORT);
|
||||
setuid(getuid());
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
signal(SIGUSR1, SIG_DFL);
|
||||
kill(getppid(), SIGUSR1);
|
||||
}
|
||||
@ -242,6 +246,41 @@ void pass_to_client(int clid, struct client_header *hdr)
|
||||
}
|
||||
}
|
||||
|
||||
void handle_trigger_exec(int req)
|
||||
{
|
||||
char *rcmd = NULL, *lcmd = NULL;
|
||||
int i;
|
||||
switch (req) {
|
||||
case QREXEC_EXECUTE_FILE_COPY:
|
||||
rcmd = "directly:user:/usr/lib/qubes/qfile-agent";
|
||||
lcmd = "/usr/lib/qubes/qfile-daemon";
|
||||
break;
|
||||
case QREXEC_EXECUTE_FILE_COPY_FOR_DISPVM:
|
||||
rcmd = "directly:user:/usr/lib/qubes/qfile-agent-dvm";
|
||||
lcmd = "/usr/lib/qubes/qfile-daemon-dvm";
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "got trigger exec no %d\n", req);
|
||||
exit(1);
|
||||
}
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
perror("fork");
|
||||
exit(1);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
for (i = 3; i < 256; i++)
|
||||
close(i);
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
execl("/usr/lib/qubes/qrexec_client", "qrexec_client", "-d",
|
||||
domain_id, "-l", lcmd, rcmd, NULL);
|
||||
perror("execl");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void handle_agent_data()
|
||||
{
|
||||
struct client_header hdr;
|
||||
@ -251,6 +290,11 @@ void handle_agent_data()
|
||||
// fprintf(stderr, "got %x %x %x\n", s_hdr.type, s_hdr.clid,
|
||||
// s_hdr.len);
|
||||
|
||||
if (s_hdr.type == MSG_AGENT_TO_SERVER_TRIGGER_EXEC) {
|
||||
handle_trigger_exec(s_hdr.clid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_hdr.clid >= MAX_FDS || s_hdr.clid < 0) {
|
||||
fprintf(stderr, "from agent: clid=%d\n", s_hdr.clid);
|
||||
exit(1);
|
||||
|
@ -107,6 +107,7 @@ install -D ../u2mfn/u2mfn-kernel.h $RPM_BUILD_ROOT/usr/include/u2mfn-kernel.h
|
||||
install -D ../vchan/libvchan.so $RPM_BUILD_ROOT/%{_libdir}/libvchan.so
|
||||
install -D ../u2mfn/libu2mfn.so $RPM_BUILD_ROOT/%{_libdir}/libu2mfn.so
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/var/run/qubes
|
||||
|
||||
%triggerin -- initscripts
|
||||
cp /var/lib/qubes/serial.conf /etc/init/serial.conf
|
||||
@ -227,6 +228,7 @@ rm -rf $RPM_BUILD_ROOT
|
||||
/usr/include/libvchan.h
|
||||
%{_libdir}/libvchan.so
|
||||
%{_libdir}/libu2mfn.so
|
||||
%dir /var/run/qubes
|
||||
|
||||
|
||||
%package devel
|
||||
|
@ -83,6 +83,7 @@ cp ../common/vif-route-qubes $RPM_BUILD_ROOT/etc/xen/scripts
|
||||
install -D ../vchan/libvchan.so $RPM_BUILD_ROOT/%{_libdir}/libvchan.so
|
||||
install -D ../u2mfn/libu2mfn.so $RPM_BUILD_ROOT/%{_libdir}/libu2mfn.so
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/var/run/qubes
|
||||
|
||||
%triggerin -- initscripts
|
||||
cp /var/lib/qubes/serial.conf /etc/init/serial.conf
|
||||
@ -193,3 +194,4 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%dir /var/run/qubes
|
||||
%{_libdir}/libvchan.so
|
||||
%{_libdir}/libu2mfn.so
|
||||
%dir /var/run/qubes
|
||||
|
Loading…
Reference in New Issue
Block a user