qrexec: add option to use real stdin/out of qrexec-client-vm

This commit is contained in:
Marek Marczykowski-Górecki 2015-03-17 14:17:01 +01:00
parent 8f00bdb4a6
commit a86d980ff4

View File

@ -78,17 +78,21 @@ int main(int argc, char **argv)
struct trigger_service_params params; struct trigger_service_params params;
struct exec_params exec_params; struct exec_params exec_params;
int ret, i; int ret, i;
int start_local_process = 0;
char *abs_exec_path; char *abs_exec_path;
pid_t child_pid; pid_t child_pid;
int inpipe[2], outpipe[2]; int inpipe[2], outpipe[2];
char pid_s[10]; char pid_s[10];
if (argc < 4) { if (argc < 3) {
fprintf(stderr, fprintf(stderr,
"usage: %s target_vmname program_ident local_program [local program arguments]\n", "usage: %s target_vmname program_ident [local_program [local program arguments]]\n",
argv[0]); argv[0]);
exit(1); exit(1);
} }
if (argc > 3) {
start_local_process = 1;
}
trigger_fd = connect_unix_socket(QREXEC_AGENT_TRIGGER_PATH); trigger_fd = connect_unix_socket(QREXEC_AGENT_TRIGGER_PATH);
@ -113,50 +117,56 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inpipe) || if (start_local_process) {
socketpair(AF_UNIX, SOCK_STREAM, 0, outpipe)) { if (socketpair(AF_UNIX, SOCK_STREAM, 0, inpipe) ||
perror("socketpair"); socketpair(AF_UNIX, SOCK_STREAM, 0, outpipe)) {
exit(1); perror("socketpair");
} exit(1);
snprintf(pid_s, sizeof(pid_s), "%d", getpid());
setenv("QREXEC_AGENT_PID", pid_s, 1);
switch (child_pid = fork()) {
case -1:
perror("fork");
exit(-1);
case 0:
close(inpipe[1]);
close(outpipe[0]);
close(trigger_fd);
for (i = 0; i < 3; i++) {
if (i != 2 || getenv("PASS_LOCAL_STDERR")) {
char *env;
if (asprintf(&env, "SAVED_FD_%d=%d", i, dup(i)) < 0) {
perror("prepare SAVED_FD_");
exit(1);
}
putenv(env);
}
} }
snprintf(pid_s, sizeof(pid_s), "%d", getpid());
setenv("QREXEC_AGENT_PID", pid_s, 1);
dup2(inpipe[0], 0); switch (child_pid = fork()) {
dup2(outpipe[1], 1); case -1:
perror("fork");
exit(-1);
case 0:
close(inpipe[1]);
close(outpipe[0]);
close(trigger_fd);
for (i = 0; i < 3; i++) {
if (i != 2 || getenv("PASS_LOCAL_STDERR")) {
char *env;
if (asprintf(&env, "SAVED_FD_%d=%d", i, dup(i)) < 0) {
perror("prepare SAVED_FD_");
exit(1);
}
putenv(env);
}
}
dup2(inpipe[0], 0);
dup2(outpipe[1], 1);
close(inpipe[0]);
close(outpipe[1]);
abs_exec_path = strdup(argv[3]);
argv[3] = get_program_name(argv[3]);
execv(abs_exec_path, argv + 3);
perror("execv");
exit(-1);
}
close(inpipe[0]); close(inpipe[0]);
close(outpipe[1]); close(outpipe[1]);
abs_exec_path = strdup(argv[3]); ret = handle_data_client(MSG_SERVICE_CONNECT,
argv[3] = get_program_name(argv[3]); exec_params.connect_domain, exec_params.connect_port,
execv(abs_exec_path, argv + 3); inpipe[1], outpipe[0], -1);
perror("execv"); } else {
exit(-1); ret = handle_data_client(MSG_SERVICE_CONNECT,
exec_params.connect_domain, exec_params.connect_port,
1, 0, -1);
} }
close(inpipe[0]);
close(outpipe[1]);
ret = handle_data_client(MSG_SERVICE_CONNECT,
exec_params.connect_domain, exec_params.connect_port,
inpipe[1], outpipe[0], -1);
close(trigger_fd); close(trigger_fd);
waitpid(child_pid, &i, 0); waitpid(child_pid, &i, 0);