]> andersk Git - openssh.git/blobdiff - ssh.c
- OpenBSD CVS updates:
[openssh.git] / ssh.c
diff --git a/ssh.c b/ssh.c
index aac8866e97b20272190c4140d9d3cf10f789307b..a387d66c7d6186312079fc7214b2e2be10aaab58 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -21,6 +21,10 @@ RCSID("$Id$");
 #include "readconf.h"
 #include "uidswap.h"
 
+#include "ssh2.h"
+#include "compat.h"
+#include "channels.h"
+
 #ifdef HAVE___PROGNAME
 extern char *__progname;
 #else /* HAVE___PROGNAME */
@@ -38,8 +42,13 @@ int IPv4or6 = AF_UNSPEC;
 /* Flag indicating whether debug mode is on.  This can be set on the command line. */
 int debug_flag = 0;
 
+/* Flag indicating whether a tty should be allocated */
 int tty_flag = 0;
 
+/* don't exec a shell */
+int no_shell_flag = 0;
+int no_tty_flag = 0;
+
 /*
  * Flag indicating that nothing should be read from stdin.  This can be set
  * on the command line.
@@ -89,6 +98,9 @@ RSA *host_private_key = NULL;
 /* Original real UID. */
 uid_t original_real_uid;
 
+/* command to be executed */
+Buffer command;
+
 /* Prints a help message to the user.  This function never returns. */
 
 void
@@ -103,9 +115,9 @@ usage()
        fprintf(stderr, "  -k          Disable Kerberos ticket and AFS token forwarding.\n");
 #endif                         /* AFS */
        fprintf(stderr, "  -x          Disable X11 connection forwarding.\n");
-       fprintf(stderr, "  -X          Enable X11 connection forwarding.\n");
        fprintf(stderr, "  -i file     Identity for RSA authentication (default: ~/.ssh/identity).\n");
        fprintf(stderr, "  -t          Tty; allocate a tty even if command is given.\n");
+       fprintf(stderr, "  -T          Do not allocate a tty.\n");
        fprintf(stderr, "  -v          Verbose; display verbose debugging messages.\n");
        fprintf(stderr, "  -V          Display version number only.\n");
        fprintf(stderr, "  -P          Don't allocate a privileged port.\n");
@@ -122,6 +134,7 @@ usage()
        fprintf(stderr, "              These cause %s to listen for connections on a port, and\n", av0);
        fprintf(stderr, "              forward them to the other side by connecting to host:port.\n");
        fprintf(stderr, "  -C          Enable compression.\n");
+       fprintf(stderr, "  -N          Do not execute a shell or command.\n");
        fprintf(stderr, "  -g          Allow remote hosts to connect to forwarded ports.\n");
        fprintf(stderr, "  -4          Use IPv4 only.\n");
        fprintf(stderr, "  -6          Use IPv6 only.\n");
@@ -167,22 +180,22 @@ rsh_connect(char *host, char *user, Buffer * command)
        exit(1);
 }
 
+int ssh_session(void);
+int ssh_session2(void);
+
 /*
  * Main program for the ssh client.
  */
 int
 main(int ac, char **av)
 {
-       int i, opt, optind, type, exit_status, ok, authfd;
+       int i, opt, optind, exit_status, ok;
        u_short fwd_port, fwd_host_port;
        char *optarg, *cp, buf[256];
-       Buffer command;
-       struct winsize ws;
        struct stat st;
        struct passwd *pw, pwcopy;
-       int interactive = 0, dummy;
+       int dummy;
        uid_t original_effective_uid;
-       int plen;
 
        /*
         * Save the original real uid.  It will be needed later (uid-swapping
@@ -324,9 +337,11 @@ main(int ac, char **av)
 
                case 'v':
                case 'V':
-                       fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n",
-                           SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR);
-                       fprintf(stderr, "Compiled with SSL.\n");
+                       fprintf(stderr, "SSH Version %s, protocol versions %d.%d/%d.%d.\n",
+                           SSH_VERSION,
+                           PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1,
+                           PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2);
+                       fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay());
                        if (opt == 'V')
                                exit(0);
                        debug_flag = 1;
@@ -395,6 +410,15 @@ main(int ac, char **av)
                        options.compression = 1;
                        break;
 
+               case 'N':
+                       no_shell_flag = 1;
+                       no_tty_flag = 1;
+                       break;
+
+               case 'T':
+                       no_tty_flag = 1;
+                       break;
+
                case 'o':
                        dummy = 1;
                        if (process_config_line(&options, host ? host : "", optarg,
@@ -453,6 +477,10 @@ main(int ac, char **av)
                        fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n");
                tty_flag = 0;
        }
+       /* force */
+       if (no_tty_flag)
+               tty_flag = 0;
+
        /* Get user data. */
        pw = getpwuid(original_real_uid);
        if (!pw) {
@@ -618,8 +646,22 @@ main(int ac, char **av)
        if (host_private_key_loaded)
                RSA_free(host_private_key);     /* Destroys contents safely */
 
-       /* Close connection cleanly after attack. */
-       cipher_attack_detected = packet_disconnect;
+       exit_status = compat20 ? ssh_session2() : ssh_session();
+       packet_close();
+       return exit_status;
+}
+
+int
+ssh_session(void)
+{
+       int type;
+       int i;
+       int plen;
+       int interactive = 0;
+       int have_tty = 0;
+       struct winsize ws;
+       int authfd;
+       char *cp;
 
        /* Enable compression if requested. */
        if (options.compression) {
@@ -672,9 +714,10 @@ main(int ac, char **av)
 
                /* Read response from the server. */
                type = packet_read(&plen);
-               if (type == SSH_SMSG_SUCCESS)
+               if (type == SSH_SMSG_SUCCESS) {
                        interactive = 1;
-               else if (type == SSH_SMSG_FAILURE)
+                       have_tty = 1;
+               } else if (type == SSH_SMSG_FAILURE)
                        log("Warning: Remote host failed or refused to allocate a pseudo tty.");
                else
                        packet_disconnect("Protocol error waiting for pty request response.");
@@ -802,11 +845,103 @@ main(int ac, char **av)
        }
 
        /* Enter the interactive session. */
-       exit_status = client_loop(tty_flag, tty_flag ? options.escape_char : -1);
+       return client_loop(have_tty, tty_flag ? options.escape_char : -1);
+}
 
-       /* Close the connection to the remote host. */
-       packet_close();
+void
+init_local_fwd(void)
+{
+       int i;
+       /* Initiate local TCP/IP port forwardings. */
+       for (i = 0; i < options.num_local_forwards; i++) {
+               debug("Connections to local port %d forwarded to remote address %.200s:%d",
+                     options.local_forwards[i].port,
+                     options.local_forwards[i].host,
+                     options.local_forwards[i].host_port);
+               channel_request_local_forwarding(options.local_forwards[i].port,
+                                                options.local_forwards[i].host,
+                                                options.local_forwards[i].host_port,
+                                                options.gateway_ports);
+       }
+}
+
+extern void client_set_session_ident(int id);
+
+void
+client_init(int id, void *arg)
+{
+       int len;
+       debug("client_init id %d arg %d", id, (int)arg);
+
+       if (no_shell_flag)
+               goto done;
+
+       if (tty_flag) {
+               struct winsize ws;
+               char *cp;
+               cp = getenv("TERM");
+               if (!cp)
+                       cp = "";
+               /* Store window size in the packet. */
+               if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
+                       memset(&ws, 0, sizeof(ws));
+
+               channel_request_start(id, "pty-req", 0);
+               packet_put_cstring(cp);
+               packet_put_int(ws.ws_col);
+               packet_put_int(ws.ws_row);
+               packet_put_int(ws.ws_xpixel);
+               packet_put_int(ws.ws_ypixel);
+               packet_put_cstring("");         /* XXX: encode terminal modes */
+               packet_send();
+               /* XXX wait for reply */
+       }
+       len = buffer_len(&command);
+       if (len > 0) {
+               if (len > 900)
+                       len = 900;
+               debug("Sending command: %.*s", len, buffer_ptr(&command));
+               channel_request_start(id, "exec", 0);
+               packet_put_string(buffer_ptr(&command), len);
+               packet_send();
+       } else {
+               channel_request(id, "shell", 0);
+       }
+       /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */
+done:
+       /* register different callback, etc. XXX */
+       client_set_session_ident(id);
+}
+
+int
+ssh_session2(void)
+{
+       int window, packetmax, id;
+       int in  = dup(STDIN_FILENO);
+       int out = dup(STDOUT_FILENO);
+       int err = dup(STDERR_FILENO);
+
+       if (in < 0 || out < 0 || err < 0)
+               fatal("dump in/out/err failed");
+
+       /* should be pre-session */
+       init_local_fwd();
+       
+       window = 32*1024;
+       if (tty_flag) {
+               packetmax = window/8;
+       } else {
+               window *= 2;
+               packetmax = window/2;
+       }
+
+       id = channel_new(
+           "session", SSH_CHANNEL_OPENING, in, out, err,
+           window, packetmax, CHAN_EXTENDED_WRITE, xstrdup("client-session"));
+
+
+       channel_open(id);
+       channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0);
 
-       /* Exit with the status returned by the program on the remote side. */
-       exit(exit_status);
+       return client_loop(tty_flag, tty_flag ? options.escape_char : -1);
 }
This page took 0.078301 seconds and 4 git commands to generate.