Bugzilla – Attachment 1700 Details for
Bug 1424
Cannot signal a process over a channel (rfc 4254, section 6.9)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
extend the signals patch to accept them over the mux socket
openssh-kill-via-mux.patch (text/plain), 11.85 KB, created by
Salvador Fandiño
on 2009-10-20 06:16:51 AEDT
(
hide
)
Description:
extend the signals patch to accept them over the mux socket
Filename:
MIME Type:
Creator:
Salvador Fandiño
Created:
2009-10-20 06:16:51 AEDT
Size:
11.85 KB
patch
obsolete
>diff --git a/channels.c b/channels.c >index 56047f3..b8cd105 100644 >--- a/channels.c >+++ b/channels.c >@@ -184,6 +184,18 @@ channel_by_id(int id) > return c; > } > >+/* Iterate over channels */ >+Channel * >+channel_next(Channel *current) >+{ >+ int id = (current ? current->self + 1 : 0); >+ for (; id < channels_alloc; id++) { >+ Channel *c = channels[id]; >+ if (c) return c; >+ } >+ return NULL; >+} >+ > /* > * Returns the channel if it is allowed to receive protocol messages. > * Private channels, like listening sockets, may not receive messages. >@@ -317,6 +329,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, > c->output_filter = NULL; > c->filter_ctx = NULL; > c->filter_cleanup = NULL; >+ c->tag = NULL; > TAILQ_INIT(&c->status_confirms); > debug("channel %d: new [%s]", found, remote_name); > return c; >@@ -402,6 +415,10 @@ channel_free(Channel *c) > xfree(c->path); > c->path = NULL; > } >+ if (c->tag) { >+ xfree(c->tag); >+ c->tag = NULL; >+ } > while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { > if (cc->abandon_cb != NULL) > cc->abandon_cb(c, cc->ctx); >diff --git a/channels.h b/channels.h >index 3800b2d..c31bb1b 100644 >--- a/channels.h >+++ b/channels.h >@@ -137,6 +137,9 @@ struct Channel { > > /* non-blocking connect */ > struct channel_connect connect_ctx; >+ >+ /* friendly name */ >+ char *tag; > }; > > #define CHAN_EXTENDED_IGNORE 0 >@@ -183,6 +186,7 @@ struct Channel { > /* channel management */ > > Channel *channel_by_id(int); >+Channel *channel_next(Channel *); > Channel *channel_lookup(int); > Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int); > void channel_set_fds(int, int, int, int, int, int, int, u_int); >diff --git a/clientloop.h b/clientloop.h >index 715dffa..871cdbf 100644 >--- a/clientloop.h >+++ b/clientloop.h >@@ -56,12 +56,14 @@ typedef void global_confirm_cb(int, u_int32_t seq, void *); > void client_register_global_confirm(global_confirm_cb *, void *); > > /* Multiplexing protocol version */ >-#define SSHMUX_VER 2 >+#define SSHMUX_VER 3 > > /* Multiplexing control protocol flags */ > #define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ > #define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */ > #define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */ >+#define SSHMUX_COMMAND_PS 4 /* Get list of slaves */ >+#define SSHMUX_COMMAND_KILL 5 /* Send signal to remote process */ > > #define SSHMUX_FLAG_TTY (1) /* Request tty on open */ > #define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */ >@@ -70,4 +72,4 @@ void client_register_global_confirm(global_confirm_cb *, void *); > > void muxserver_listen(void); > int muxserver_accept_control(void); >-void muxclient(const char *); >+void muxclient(const char *, int ac, char **av); >diff --git a/mux.c b/mux.c >index 0ad269f..4f9189b 100644 >--- a/mux.c >+++ b/mux.c >@@ -67,6 +67,7 @@ > #include "sshpty.h" > #include "key.h" > #include "readconf.h" >+#include "compat.h" > #include "clientloop.h" > > /* from ssh.c */ >@@ -208,11 +209,11 @@ muxserver_accept_control(void) > { > Buffer m; > Channel *c; >- int client_fd, new_fd[3], ver, allowed, window, packetmax; >+ int client_fd, new_fd[3], ver, allowed, window, packetmax, count; > socklen_t addrlen; > struct sockaddr_storage addr; > struct mux_session_confirm_ctx *cctx; >- char *cmd; >+ char *cmd, *tag, *question, *signal; > u_int i, j, len, env_len, mux_command, flags, escape_char; > uid_t euid; > gid_t egid; >@@ -260,66 +261,97 @@ muxserver_accept_control(void) > } > > allowed = 1; >+ question = NULL; > mux_command = buffer_get_int(&m); > flags = buffer_get_int(&m); > >+ /* Process extra arguments and ask user for permission */ >+ switch (mux_command) { >+ case SSHMUX_COMMAND_OPEN: >+ question = "Allow shared connection to %s? "; >+ break; >+ case SSHMUX_COMMAND_TERMINATE: >+ question = "Terminate shared connection to %s? "; >+ break; >+ case SSHMUX_COMMAND_KILL: >+ signal = buffer_get_string(&m, &len); >+ tag = buffer_get_string(&m, &len); >+ c = NULL; >+ if (tag && signal && compat20) { >+ /* channel lookup by tag */ >+ while (c = channel_next(c)) { >+ if (c->tag && (strcmp(tag, c->tag) == 0)) >+ break; >+ } >+ if (c) { >+ question = "Send signal to process in %s? "; >+ break; >+ } >+ } >+ allowed = 0; >+ break; >+ } >+ >+ if (question && (options.control_master == SSHCTL_MASTER_ASK || >+ options.control_master == SSHCTL_MASTER_AUTO_ASK)) >+ allowed = ask_permission(question, host); >+ >+ /* response header */ > buffer_clear(&m); >+ buffer_put_int(&m, allowed); >+ buffer_put_int(&m, getpid()); > > switch (mux_command) { > case SSHMUX_COMMAND_OPEN: >- if (options.control_master == SSHCTL_MASTER_ASK || >- options.control_master == SSHCTL_MASTER_AUTO_ASK) >- allowed = ask_permission("Allow shared connection " >- "to %s? ", host); >- /* continue below */ >+ case SSHMUX_COMMAND_ALIVE_CHECK: > break; >+ > case SSHMUX_COMMAND_TERMINATE: >- if (options.control_master == SSHCTL_MASTER_ASK || >- options.control_master == SSHCTL_MASTER_AUTO_ASK) >- allowed = ask_permission("Terminate shared connection " >- "to %s? ", host); > if (allowed) > start_close = 1; >- /* FALLTHROUGH */ >- case SSHMUX_COMMAND_ALIVE_CHECK: >- /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */ >- buffer_clear(&m); >- buffer_put_int(&m, allowed); >- buffer_put_int(&m, getpid()); >- if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { >- error("%s: client msg_send failed", __func__); >- close(client_fd); >- buffer_free(&m); >- return start_close; >+ break; >+ >+ case SSHMUX_COMMAND_PS: >+ count = 0; >+ c = NULL; >+ while (c = channel_next(c)) >+ if (c->tag) >+ count ++; >+ buffer_put_int(&m, count); >+ >+ while (c = channel_next(c)) >+ if (c->tag) >+ buffer_put_cstring(&m, c->tag); >+ break; >+ >+ case SSHMUX_COMMAND_KILL: >+ if (allowed) { >+ int id = c->self; >+ channel_request_start(id, "signal", 0); >+ packet_put_cstring(signal); >+ packet_send(); > } >- buffer_free(&m); >- close(client_fd); >- return start_close; >+ break; > default: > error("Unsupported command %d", mux_command); >- buffer_free(&m); >- close(client_fd); >- return 0; >+ goto cleanup; > } >- >- /* Reply for SSHMUX_COMMAND_OPEN */ >- buffer_clear(&m); >- buffer_put_int(&m, allowed); >- buffer_put_int(&m, getpid()); >+ if (!allowed) >+ error("Refused control connection"); > if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { > error("%s: client msg_send failed", __func__); >- close(client_fd); >- buffer_free(&m); >- return 0; >+ goto cleanup; > } > >- if (!allowed) { >- error("Refused control connection"); >- close(client_fd); >+ if ((mux_command != SSHMUX_COMMAND_OPEN) || !allowed) { >+ cleanup: > buffer_free(&m); >- return 0; >+ close(client_fd); >+ return start_close; > } > >+ /* Continue SSHMUX_COMMAND_OPEN processing */ >+ > buffer_clear(&m); > if (ssh_msg_recv(client_fd, &m) == -1) { > error("%s: client msg_recv failed", __func__); >@@ -341,6 +373,7 @@ muxserver_accept_control(void) > cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; > cctx->term = buffer_get_string(&m, &len); > escape_char = buffer_get_int(&m); >+ tag = buffer_get_string(&m, &len); > > cmd = buffer_get_string(&m, &len); > buffer_init(&cctx->cmd); >@@ -375,6 +408,7 @@ muxserver_accept_control(void) > buffer_free(&cctx->cmd); > close(client_fd); > xfree(cctx); >+ xfree(tag); > return 0; > } > } >@@ -401,6 +435,8 @@ muxserver_accept_control(void) > xfree(cctx->env[i]); > xfree(cctx->env); > } >+ xfree(cctx); >+ xfree(tag); > return 0; > } > buffer_free(&m); >@@ -427,6 +463,7 @@ muxserver_accept_control(void) > CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); > > c->ctl_fd = client_fd; >+ c->tag = tag; > if (cctx->want_tty && escape_char != 0xffffffff) { > channel_register_filter(c->self, > client_simple_escape_filter, NULL, >@@ -487,17 +524,24 @@ env_permitted(char *env) > > /* Multiplex client main loop. */ > void >-muxclient(const char *path) >+muxclient(const char *path, int ac, char **av) > { > struct sockaddr_un addr; >- int i, r, fd, sock, exitval[2], num_env; >+ int i, r, fd, sock, exitval[2], num_env, count, len; > Buffer m; >- char *term; >+ char *term, *tag = NULL; > extern char **environ; > u_int allowed, flags; > >- if (muxclient_command == 0) >+ switch (muxclient_command) { >+ case 0: > muxclient_command = SSHMUX_COMMAND_OPEN; >+ break; >+ case SSHMUX_COMMAND_KILL: >+ if (ac != 2) >+ fatal("Bad number of arguments for kill command"); >+ break; >+ } > > switch (options.control_master) { > case SSHCTL_MASTER_AUTO: >@@ -562,9 +606,19 @@ muxclient(const char *path) > > buffer_init(&m); > >- /* Send our command to server */ >+ /* Build command header */ > buffer_put_int(&m, muxclient_command); > buffer_put_int(&m, flags); >+ >+ /* Add command specific data */ >+ switch (muxclient_command) { >+ case SSHMUX_COMMAND_KILL: >+ buffer_put_cstring(&m, av[0]); >+ buffer_put_cstring(&m, av[1]); >+ break; >+ } >+ >+ /* Send our command to server */ > if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) { > error("%s: msg_send", __func__); > muxerr: >@@ -599,8 +653,6 @@ muxclient(const char *path) > } > muxserver_pid = buffer_get_int(&m); > >- buffer_clear(&m); >- > switch (muxclient_command) { > case SSHMUX_COMMAND_ALIVE_CHECK: > fprintf(stderr, "Master running (pid=%d)\r\n", >@@ -609,12 +661,34 @@ muxclient(const char *path) > case SSHMUX_COMMAND_TERMINATE: > fprintf(stderr, "Exit request sent.\r\n"); > exit(0); >+ case SSHMUX_COMMAND_KILL: >+ fprintf(stderr, "Signal request sent.\r\n"); >+ exit(0); >+ case SSHMUX_COMMAND_PS: >+ if (buffer_get_int_ret(&count, &m) != 0) { >+ error("%s: bad server reply", __func__); >+ goto muxerr; >+ } >+ for (i = 0; i < count; i++) { >+ char *tag = buffer_get_string(&m, &len); >+ if (!tag) { >+ error("%s: bad server reply", __func__); >+ goto muxerr; >+ } >+ printf("%s\n", tag); >+ xfree(tag); >+ } >+ exit(0); >+ > case SSHMUX_COMMAND_OPEN: >+ buffer_clear(&m); > buffer_put_cstring(&m, term ? term : ""); > if (options.escape_char == SSH_ESCAPECHAR_NONE) > buffer_put_int(&m, 0xffffffff); > else > buffer_put_int(&m, options.escape_char); >+ xasprintf(&tag, "%ld", (long)getpid()); >+ buffer_put_cstring(&m, tag); > buffer_append(&command, "\0", 1); > buffer_put_cstring(&m, buffer_ptr(&command)); > >diff --git a/session.c b/session.c >index 6aef896..0f63d1a 100644 >--- a/session.c >+++ b/session.c >@@ -1838,6 +1838,8 @@ session_env_req(Session *s) > static int > name2sig(char *name) > { >+ char *end; >+ int sig; > #define SSH_SIG(x) if (strcmp(name, #x) == 0) return SIG ## x > SSH_SIG(ABRT); > SSH_SIG(ALRM); >@@ -1853,6 +1855,9 @@ name2sig(char *name) > SSH_SIG(USR1); > SSH_SIG(USR2); > #undef SSH_SIG >+ sig = strtol(name, &end, 10); >+ if (*end == '\0' && end != name) >+ return sig; > return -1; > } > >diff --git a/ssh.c b/ssh.c >index eb46cfd..16d388a 100644 >--- a/ssh.c >+++ b/ssh.c >@@ -187,7 +187,7 @@ static int ssh_session2(void); > static void load_public_identity_files(void); > > /* from muxclient.c */ >-void muxclient(const char *); >+void muxclient(const char *, int ac, char **av); > void muxserver_listen(void); > > /* >@@ -304,6 +304,10 @@ main(int ac, char **av) > muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK; > else if (strcmp(optarg, "exit") == 0) > muxclient_command = SSHMUX_COMMAND_TERMINATE; >+ else if (strcmp(optarg, "ps") == 0) >+ muxclient_command = SSHMUX_COMMAND_PS; >+ else if (strcmp(optarg, "kill") == 0) >+ muxclient_command = SSHMUX_COMMAND_KILL; > else > fatal("Invalid multiplex command."); > break; >@@ -682,7 +686,7 @@ main(int ac, char **av) > if (muxclient_command != 0 && options.control_path == NULL) > fatal("No ControlPath specified for \"-O\" command"); > if (options.control_path != NULL) >- muxclient(options.control_path); >+ muxclient(options.control_path, ac, av); > > timeout_ms = options.connection_timeout * 1000; > >@@ -1156,6 +1160,7 @@ ssh_session2_open(void) > "session", SSH_CHANNEL_OPENING, in, out, err, > window, packetmax, CHAN_EXTENDED_WRITE, > "client-session", /*nonblock*/0); >+ xasprintf(&c->tag, "%ld", (long)getpid()); > > debug3("ssh_session2_open: channel_new: %d", c->self); >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1424
:
1432
|
1438
|
1699
|
1700
|
1709
|
2500
|
3120