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:
Marek Marczykowski-Górecki 2015-02-17 04:06:19 +01:00
parent c1cb78e0e8
commit 4b5960daa3
3 changed files with 102 additions and 99 deletions

View File

@ -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

View File

@ -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, &params, 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, &params, sizeof(params)) < 0)
handle_vchan_error("send");
connection_info[id].pid = 0;
release_connection(id);
}
child_exited = 0;
}

View File

@ -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,