]> andersk Git - openssh.git/blobdiff - clientloop.c
- (tim) [contrib/cygwin/README] add minires-devel requirement. Patch from
[openssh.git] / clientloop.c
index eada56033a17f771863a3bfb8979469d85847f3e..79aabbe0614ed06ef9a18c5d36509b9ccf89e3ec 100644 (file)
@@ -59,7 +59,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.124 2004/06/14 01:44:38 djm Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.128 2004/06/18 11:11:54 djm 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;
        }
 }
@@ -538,6 +539,7 @@ 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__);
@@ -545,13 +547,18 @@ client_extra_session2_setup(int id, void *arg)
                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, 
+           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);
@@ -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);
@@ -1626,7 +1674,7 @@ 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, 
+    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.040861 seconds and 4 git commands to generate.