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

@ -55,40 +55,52 @@ 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;
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;
/* 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;
}
signal(SIGCHLD, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
execl("/bin/su", "su", "-", cmd, "-c", realcmd, NULL);
perror("execl");
exit(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;
}
int handle_just_exec(char *cmdline)
{
int fdn, pid;

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,18 +248,10 @@ int find_connection(int pid)
return -1;
}
void reap_children()
{
int status;
int pid;
int id;
void release_connection(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;
@ -283,6 +261,18 @@ void reap_children()
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;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
id = find_connection(pid);
if (id < 0)
continue;
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,