]> andersk Git - openssh.git/blobdiff - clientloop.c
- (tim) [configure.ac] updwtmpx() on OpenServer seems to add duplicate entry.
[openssh.git] / clientloop.c
index 6401588a92cd170bd8955408ad97ae440dd929fa..def4d8a7baac0fa3c04f53c8f8dc17dd0dd85f5f 100644 (file)
@@ -59,7 +59,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.123 2004/06/13 15:03:02 djm Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.129 2004/07/11 17:48:47 deraadt Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -143,6 +143,7 @@ struct confirm_ctx {
        Buffer cmd;
        char *term;
        struct termios tio;
+       char **env;
 };
 
 /*XXX*/
@@ -156,7 +157,7 @@ static void
 leave_non_blocking(void)
 {
        if (in_non_blocking_mode) {
-               (void) fcntl(fileno(stdin), F_SETFL, 0);
+               unset_nonblock(fileno(stdin));
                in_non_blocking_mode = 0;
        }
 }
@@ -167,7 +168,7 @@ static void
 enter_non_blocking(void)
 {
        in_non_blocking_mode = 1;
-       (void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+       set_nonblock(fileno(stdin));
 }
 
 /*
@@ -401,7 +402,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
 
        if (options.server_alive_interval == 0 || !compat20)
                tvp = NULL;
-       else {  
+       else {
                tv.tv_sec = options.server_alive_interval;
                tv.tv_usec = 0;
                tvp = &tv;
@@ -516,7 +517,7 @@ client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
 {
        int id;
        Channel *c;
-       
+
        id = packet_get_int();
        packet_check_eom();
 
@@ -538,20 +539,26 @@ client_extra_session2_setup(int id, void *arg)
 {
        struct confirm_ctx *cctx = arg;
        Channel *c;
-       
+       int i;
+
        if (cctx == NULL)
                fatal("%s: cctx == NULL", __func__);
        if ((c = channel_lookup(id)) == NULL)
                fatal("%s: no channel for id %d", __func__, id);
 
-       client_session2_setup(id, cctx->want_tty, cctx->want_subsys, 
-           cctx->term, &cctx->tio, c->rfd, &cctx->cmd, 
+       client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
+           cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env,
            client_subsystem_reply);
-       
+
        c->confirm_ctx = NULL;
        buffer_free(&cctx->cmd);
-       free(cctx->term);
-       free(cctx);
+       xfree(cctx->term);
+       if (cctx->env != NULL) {
+               for (i = 0; cctx->env[i] != NULL; i++)
+                       xfree(cctx->env[i]);
+               xfree(cctx->env);
+       }
+       xfree(cctx);
 }
 
 static void
@@ -559,12 +566,12 @@ client_process_control(fd_set * readset)
 {
        Buffer m;
        Channel *c;
-       int client_fd, new_fd[3], ver;
+       int client_fd, new_fd[3], ver, i, allowed;
        socklen_t addrlen;
        struct sockaddr_storage addr;
        struct confirm_ctx *cctx;
        char *cmd;
-       u_int len;
+       u_int len, env_len;
        uid_t euid;
        gid_t egid;
 
@@ -593,23 +600,52 @@ client_process_control(fd_set * readset)
                close(client_fd);
                return;
        }
-       /* XXX: implement use of ssh-askpass to confirm additional channels */
+
+       allowed = 1;
+       if (options.control_master == 2) {
+               char *p, prompt[1024];
+
+               allowed = 0;
+               snprintf(prompt, sizeof(prompt),
+                   "Allow shared connection to %s? ", host);
+               p = read_passphrase(prompt, RP_USE_ASKPASS|RP_ALLOW_EOF);
+               if (p != NULL) {
+                       /*
+                        * Accept empty responses and responses consisting
+                        * of the word "yes" as affirmative.
+                        */
+                       if (*p == '\0' || *p == '\n' ||
+                           strcasecmp(p, "yes") == 0)
+                               allowed = 1;
+                       xfree(p);
+               }
+       }
 
        unset_nonblock(client_fd);
 
        buffer_init(&m);
 
+       buffer_put_int(&m, allowed);
        buffer_put_int(&m, getpid());
        if (ssh_msg_send(client_fd, /* version */0, &m) == -1) {
                error("%s: client msg_send failed", __func__);
                close(client_fd);
+               buffer_free(&m);
                return;
        }
        buffer_clear(&m);
 
+       if (!allowed) {
+               error("Refused control connection");
+               close(client_fd);
+               buffer_free(&m);
+               return;
+       }
+
        if (ssh_msg_recv(client_fd, &m) == -1) {
                error("%s: client msg_recv failed", __func__);
                close(client_fd);
+               buffer_free(&m);
                return;
        }
 
@@ -631,6 +667,16 @@ client_process_control(fd_set * readset)
        buffer_init(&cctx->cmd);
        buffer_append(&cctx->cmd, cmd, strlen(cmd));
 
+       env_len = buffer_get_int(&m);
+       env_len = MIN(env_len, 4096);
+       debug3("%s: receiving %d env vars", __func__, env_len);
+       if (env_len != 0) {
+               cctx->env = xmalloc(sizeof(*cctx->env) * (env_len + 1));
+               for (i = 0; i < env_len; i++)
+                       cctx->env[i] = buffer_get_string(&m, &len);
+               cctx->env[i] = NULL;
+       }
+
        debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__,
            cctx->want_tty, cctx->want_subsys, cmd);
 
@@ -653,6 +699,7 @@ client_process_control(fd_set * readset)
                close(new_fd[0]);
                close(new_fd[1]);
                close(new_fd[2]);
+               buffer_free(&m);
                return;
        }
        buffer_free(&m);
@@ -667,7 +714,7 @@ client_process_control(fd_set * readset)
 
        set_nonblock(client_fd);
 
-       c = channel_new("session", SSH_CHANNEL_OPENING, 
+       c = channel_new("session", SSH_CHANNEL_OPENING,
            new_fd[0], new_fd[1], new_fd[2],
            CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT,
            CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
@@ -1579,8 +1626,9 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
        debug("client_input_channel_req: channel %d rtype %s reply %d",
            id, rtype, reply);
 
-       c = channel_lookup(id);
-       if (c == NULL) {
+       if (id == -1) {
+               error("client_input_channel_req: request for channel -1");
+       } else if ((c = channel_lookup(id)) == NULL) {
                error("client_input_channel_req: channel %d: unknown channel", id);
        } else if (strcmp(rtype, "exit-status") == 0) {
                exitval = packet_get_int();
@@ -1599,7 +1647,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
        if (reply) {
                packet_start(success ?
                    SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
-               packet_put_int(c->remote_id);
+               packet_put_int(id);
                packet_send();
        }
        xfree(rtype);
@@ -1625,8 +1673,8 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt)
 }
 
 void
-client_session2_setup(int id, int want_tty, int want_subsystem, 
-    const char *term, struct termios *tiop, int in_fd, Buffer *cmd, 
+client_session2_setup(int id, int want_tty, int want_subsystem,
+    const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env,
     dispatch_fn *subsys_repl)
 {
        int len;
@@ -1654,15 +1702,14 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
        }
 
        /* Transfer any environment variables from client to server */
-       if (options.num_send_env != 0) {
+       if (options.num_send_env != 0 && env != NULL) {
                int i, j, matched;
-               extern char **environ;
                char *name, *val;
 
                debug("Sending environment.");
-               for (i = 0; environ && environ[i] != NULL; i++) {
+               for (i = 0; env[i] != NULL; i++) {
                        /* Split */
-                       name = xstrdup(environ[i]);
+                       name = xstrdup(env[i]);
                        if ((val = strchr(name, '=')) == NULL) {
                                free(name);
                                continue;
This page took 0.049828 seconds and 4 git commands to generate.