qrexec: reorganise code for upcoming change
Move (qrexec-agent version of) do_exec to qrexec-agent.c, move handle_handshake to qrexec-agent-data.c (common to all agent binaries). Fix indentation (tabs -> spaces).
This commit is contained in:
parent
c1cb78e0e8
commit
4b5960daa3
@ -45,8 +45,8 @@ pid_t child_process_pid;
|
||||
|
||||
static void sigchld_handler(int __attribute__((__unused__))x)
|
||||
{
|
||||
child_exited = 1;
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
child_exited = 1;
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
}
|
||||
|
||||
static void sigusr1_handler(int __attribute__((__unused__))x)
|
||||
@ -55,43 +55,55 @@ static void sigusr1_handler(int __attribute__((__unused__))x)
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
}
|
||||
|
||||
|
||||
void no_colon_in_cmd()
|
||||
int handle_handshake(libvchan_t *ctrl)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"cmdline is supposed to be in user:command form\n");
|
||||
exit(1);
|
||||
struct msg_header hdr;
|
||||
struct peer_info info;
|
||||
|
||||
/* send own HELLO */
|
||||
hdr.type = MSG_HELLO;
|
||||
hdr.len = sizeof(info);
|
||||
info.version = QREXEC_PROTOCOL_VERSION;
|
||||
|
||||
if (libvchan_send(ctrl, &hdr, sizeof(hdr)) != sizeof(hdr)) {
|
||||
fprintf(stderr, "Failed to send HELLO hdr to agent\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libvchan_send(ctrl, &info, sizeof(info)) != sizeof(info)) {
|
||||
fprintf(stderr, "Failed to send HELLO hdr to agent\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* receive MSG_HELLO from remote */
|
||||
if (libvchan_recv(ctrl, &hdr, sizeof(hdr)) != sizeof(hdr)) {
|
||||
fprintf(stderr, "Failed to read agent HELLO hdr\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hdr.type != MSG_HELLO || hdr.len != sizeof(info)) {
|
||||
fprintf(stderr, "Invalid HELLO packet received: type %d, len %d\n", hdr.type, hdr.len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libvchan_recv(ctrl, &info, sizeof(info)) != sizeof(info)) {
|
||||
fprintf(stderr, "Failed to read agent HELLO body\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (info.version != QREXEC_PROTOCOL_VERSION) {
|
||||
fprintf(stderr, "Incompatible agent protocol version (remote %d, local %d)\n", info.version, QREXEC_PROTOCOL_VERSION);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void do_exec(char *cmd)
|
||||
{
|
||||
char buf[strlen(QUBES_RPC_MULTIPLEXER_PATH) + strlen(cmd) - strlen(RPC_REQUEST_COMMAND) + 1];
|
||||
char *realcmd = index(cmd, ':');
|
||||
if (!realcmd)
|
||||
no_colon_in_cmd();
|
||||
/* mark end of username and move to command */
|
||||
*realcmd = 0;
|
||||
realcmd++;
|
||||
/* ignore "nogui:" prefix in linux agent */
|
||||
if (strncmp(realcmd, "nogui:", 6) == 0)
|
||||
realcmd+=6;
|
||||
/* replace magic RPC cmd with RPC multiplexer path */
|
||||
if (strncmp(realcmd, RPC_REQUEST_COMMAND " ", strlen(RPC_REQUEST_COMMAND)+1)==0) {
|
||||
strcpy(buf, QUBES_RPC_MULTIPLEXER_PATH);
|
||||
strcpy(buf + strlen(QUBES_RPC_MULTIPLEXER_PATH), realcmd + strlen(RPC_REQUEST_COMMAND));
|
||||
realcmd = buf;
|
||||
}
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
|
||||
execl("/bin/su", "su", "-", cmd, "-c", realcmd, NULL);
|
||||
perror("execl");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int handle_just_exec(char *cmdline)
|
||||
{
|
||||
int fdn, pid;
|
||||
int fdn, pid;
|
||||
|
||||
switch (pid = fork()) {
|
||||
case -1:
|
||||
@ -105,20 +117,20 @@ int handle_just_exec(char *cmdline)
|
||||
exit(1);
|
||||
default:;
|
||||
}
|
||||
fprintf(stderr, "executed (nowait) %s pid %d\n", cmdline, pid);
|
||||
fprintf(stderr, "executed (nowait) %s pid %d\n", cmdline, pid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void send_exit_code(libvchan_t *data_vchan, int status)
|
||||
{
|
||||
struct msg_header hdr;
|
||||
hdr.type = MSG_DATA_EXIT_CODE;
|
||||
hdr.len = sizeof(status);
|
||||
if (libvchan_send(data_vchan, &hdr, sizeof(hdr)) < 0)
|
||||
handle_vchan_error("write hdr");
|
||||
if (libvchan_send(data_vchan, &status, sizeof(status)) < 0)
|
||||
handle_vchan_error("write status");
|
||||
fprintf(stderr, "send exit code %d\n", status);
|
||||
struct msg_header hdr;
|
||||
hdr.type = MSG_DATA_EXIT_CODE;
|
||||
hdr.len = sizeof(status);
|
||||
if (libvchan_send(data_vchan, &hdr, sizeof(hdr)) < 0)
|
||||
handle_vchan_error("write hdr");
|
||||
if (libvchan_send(data_vchan, &status, sizeof(status)) < 0)
|
||||
handle_vchan_error("write status");
|
||||
fprintf(stderr, "send exit code %d\n", status);
|
||||
}
|
||||
|
||||
/* handle data from specified FD and send over vchan link
|
||||
|
@ -55,7 +55,38 @@ int passfd_socket;
|
||||
|
||||
int meminfo_write_started = 0;
|
||||
|
||||
void do_exec(const char *cmd);
|
||||
void no_colon_in_cmd()
|
||||
{
|
||||
fprintf(stderr,
|
||||
"cmdline is supposed to be in user:command form\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void do_exec(const char *cmd)
|
||||
{
|
||||
char buf[strlen(QUBES_RPC_MULTIPLEXER_PATH) + strlen(cmd) - strlen(RPC_REQUEST_COMMAND) + 1];
|
||||
char *realcmd = index(cmd, ':');
|
||||
if (!realcmd)
|
||||
no_colon_in_cmd();
|
||||
/* mark end of username and move to command */
|
||||
*realcmd = 0;
|
||||
realcmd++;
|
||||
/* ignore "nogui:" prefix in linux agent */
|
||||
if (strncmp(realcmd, "nogui:", 6) == 0)
|
||||
realcmd+=6;
|
||||
/* replace magic RPC cmd with RPC multiplexer path */
|
||||
if (strncmp(realcmd, RPC_REQUEST_COMMAND " ", strlen(RPC_REQUEST_COMMAND)+1)==0) {
|
||||
strcpy(buf, QUBES_RPC_MULTIPLEXER_PATH);
|
||||
strcpy(buf + strlen(QUBES_RPC_MULTIPLEXER_PATH), realcmd + strlen(RPC_REQUEST_COMMAND));
|
||||
realcmd = buf;
|
||||
}
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
|
||||
execl("/bin/su", "su", "-", cmd, "-c", realcmd, NULL);
|
||||
perror("execl");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void handle_vchan_error(const char *op)
|
||||
{
|
||||
@ -63,51 +94,6 @@ void handle_vchan_error(const char *op)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int handle_handshake(libvchan_t *ctrl)
|
||||
{
|
||||
struct msg_header hdr;
|
||||
struct peer_info info;
|
||||
|
||||
/* send own HELLO */
|
||||
hdr.type = MSG_HELLO;
|
||||
hdr.len = sizeof(info);
|
||||
info.version = QREXEC_PROTOCOL_VERSION;
|
||||
|
||||
if (libvchan_send(ctrl, &hdr, sizeof(hdr)) != sizeof(hdr)) {
|
||||
fprintf(stderr, "Failed to send HELLO hdr to agent\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libvchan_send(ctrl, &info, sizeof(info)) != sizeof(info)) {
|
||||
fprintf(stderr, "Failed to send HELLO hdr to agent\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* receive MSG_HELLO from remote */
|
||||
if (libvchan_recv(ctrl, &hdr, sizeof(hdr)) != sizeof(hdr)) {
|
||||
fprintf(stderr, "Failed to read agent HELLO hdr\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hdr.type != MSG_HELLO || hdr.len != sizeof(info)) {
|
||||
fprintf(stderr, "Invalid HELLO packet received: type %d, len %d\n", hdr.type, hdr.len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libvchan_recv(ctrl, &info, sizeof(info)) != sizeof(info)) {
|
||||
fprintf(stderr, "Failed to read agent HELLO body\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (info.version != QREXEC_PROTOCOL_VERSION) {
|
||||
fprintf(stderr, "Incompatible agent protocol version (remote %d, local %d)\n", info.version, QREXEC_PROTOCOL_VERSION);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
/* FIXME: This 0 is remote domain ID */
|
||||
@ -262,27 +248,31 @@ int find_connection(int pid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void release_connection(int id) {
|
||||
struct msg_header hdr;
|
||||
struct exec_params params;
|
||||
|
||||
hdr.type = MSG_CONNECTION_TERMINATED;
|
||||
hdr.len = sizeof(struct exec_params);
|
||||
params.connect_domain = connection_info[id].connect_domain;
|
||||
params.connect_port = connection_info[id].connect_port;
|
||||
if (libvchan_send(ctrl_vchan, &hdr, sizeof(hdr)) < 0)
|
||||
handle_vchan_error("send");
|
||||
if (libvchan_send(ctrl_vchan, ¶ms, sizeof(params)) < 0)
|
||||
handle_vchan_error("send");
|
||||
connection_info[id].pid = 0;
|
||||
}
|
||||
|
||||
void reap_children()
|
||||
{
|
||||
int status;
|
||||
int pid;
|
||||
int id;
|
||||
struct msg_header hdr;
|
||||
struct exec_params params;
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||
id = find_connection(pid);
|
||||
if (id < 0)
|
||||
continue;
|
||||
hdr.type = MSG_CONNECTION_TERMINATED;
|
||||
hdr.len = sizeof(struct exec_params);
|
||||
params.connect_domain = connection_info[id].connect_domain;
|
||||
params.connect_port = connection_info[id].connect_port;
|
||||
if (libvchan_send(ctrl_vchan, &hdr, sizeof(hdr)) < 0)
|
||||
handle_vchan_error("send");
|
||||
if (libvchan_send(ctrl_vchan, ¶ms, sizeof(params)) < 0)
|
||||
handle_vchan_error("send");
|
||||
connection_info[id].pid = 0;
|
||||
release_connection(id);
|
||||
}
|
||||
child_exited = 0;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
int handle_handshake(libvchan_t *ctrl);
|
||||
void handle_vchan_error(const char *op);
|
||||
void do_exec(const char *cmd);
|
||||
|
||||
pid_t handle_new_process(int type,
|
||||
int connect_domain, int connect_port,
|
||||
|
Loading…
Reference in New Issue
Block a user