From 67779be7464c9134ef08048f7d9a15d7677442e7 Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 21 Sep 2000 14:34:32 +0000 Subject: [PATCH] Miscellaneous ssh2 fixes. plink is now relatively sane git-svn-id: svn://svn.tartarus.org/sgt/putty@608 cda61777-01e9-0310-a592-d414129be87e --- plink.c | 53 ++++++++++++++++++++++++++++++++++++++- putty.h | 18 +++++++++++--- scp.c | 2 +- scp.h | 1 - ssh.c | 86 +++++++++++++++++++++++++++++++++++++++------------------------- window.c | 2 +- 6 files changed, 122 insertions(+), 40 deletions(-) diff --git a/plink.c b/plink.c index 50227610..70aab6de 100644 --- a/plink.c +++ b/plink.c @@ -43,6 +43,50 @@ struct input_data { HANDLE event; }; +static int get_password(const char *prompt, char *str, int maxlen) +{ + HANDLE hin, hout; + DWORD savemode, i; + +#if 0 /* this allows specifying a password some other way */ + if (password) { + static int tried_once = 0; + + if (tried_once) { + return 0; + } else { + strncpy(str, password, maxlen); + str[maxlen-1] = '\0'; + tried_once = 1; + return 1; + } + } +#endif + + hin = GetStdHandle(STD_INPUT_HANDLE); + hout = GetStdHandle(STD_OUTPUT_HANDLE); + if (hin == INVALID_HANDLE_VALUE || hout == INVALID_HANDLE_VALUE) { + fprintf(stderr, "Cannot get standard input/output handles"); + return 0; + } + + GetConsoleMode(hin, &savemode); + SetConsoleMode(hin, (savemode & (~ENABLE_ECHO_INPUT)) | + ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT); + + WriteFile(hout, prompt, strlen(prompt), &i, NULL); + ReadFile(hin, str, maxlen-1, &i, NULL); + + SetConsoleMode(hin, savemode); + + if ((int)i > maxlen) i = maxlen-1; else i = i - 2; + str[i] = '\0'; + + WriteFile(hout, "\r\n", 2, &i, NULL); + + return 1; +} + int WINAPI stdin_read_thread(void *param) { struct input_data *idata = (struct input_data *)param; HANDLE inhandle; @@ -70,7 +114,9 @@ int main(int argc, char **argv) { struct input_data idata; int sending; - flags = FLAG_CONNECTION; + ssh_get_password = get_password; + + flags = FLAG_STDERR; /* * Process the command line. */ @@ -83,6 +129,8 @@ int main(int argc, char **argv) { if (!strcmp(p, "-ssh")) { default_protocol = cfg.protocol = PROT_SSH; default_port = cfg.port = 22; + } else if (!strcmp(p, "-v")) { + flags |= FLAG_VERBOSE; } else if (!strcmp(p, "-log")) { logfile = "putty.log"; } @@ -165,6 +213,9 @@ int main(int argc, char **argv) { } } + if (!*cfg.remote_cmd) + flags |= FLAG_INTERACTIVE; + /* * Select protocol. This is farmed out into a table in a * separate file to enable an ssh-free variant. diff --git a/putty.h b/putty.h index 4b9c30f2..bc9d689e 100644 --- a/putty.h +++ b/putty.h @@ -203,10 +203,21 @@ typedef struct { /* * Some global flags denoting the type of application. + * + * FLAG_VERBOSE is set when the user requests verbose details. + * + * FLAG_STDERR is set in command-line applications (which have a + * functioning stderr that it makes sense to write to) and not in + * GUI applications (which don't). + * + * FLAG_INTERACTIVE is set when a full interactive shell session is + * being run, _either_ because no remote command has been provided + * _or_ because the application is GUI and can't run non- + * interactively. */ -#define FLAG_VERBOSE 0x0001 -#define FLAG_WINDOWED 0x0002 -#define FLAG_CONNECTION 0x0004 +#define FLAG_VERBOSE 0x0001 +#define FLAG_STDERR 0x0002 +#define FLAG_INTERACTIVE 0x0004 GLOBAL int flags; GLOBAL Config cfg; @@ -292,6 +303,7 @@ extern Backend telnet_backend; * Exports from ssh.c. */ +extern int (*ssh_get_password)(const char *prompt, char *str, int maxlen); extern Backend ssh_backend; /* diff --git a/scp.c b/scp.c index b1cae2ff..1160139e 100644 --- a/scp.c +++ b/scp.c @@ -957,7 +957,7 @@ int main(int argc, char *argv[]) default_protocol = PROT_TELNET; - flags = 0; + flags = FLAG_STDERR; ssh_get_password = &get_password; init_winsock(); diff --git a/scp.h b/scp.h index a3eabf57..bb7c0f73 100644 --- a/scp.h +++ b/scp.h @@ -5,7 +5,6 @@ /* Exported from ssh.c */ extern int scp_flags; -extern int (*ssh_get_password)(const char *prompt, char *str, int maxlen); char * ssh_scp_init(char *host, int port, char *cmd, char **realhost); int ssh_scp_recv(unsigned char *buf, int len); void ssh_scp_send(unsigned char *buf, int len); diff --git a/ssh.c b/ssh.c index ff6e8377..88379c57 100644 --- a/ssh.c +++ b/ssh.c @@ -17,7 +17,7 @@ #endif #define logevent(s) { logevent(s); \ - if (!(flags & FLAG_CONNECTION) && (flags & FLAG_VERBOSE)) \ + if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) \ fprintf(stderr, "%s\n", s); } #define SSH1_MSG_DISCONNECT 1 /* 0x1 */ @@ -269,7 +269,7 @@ static int s_read (char *buf, int len) { } static void c_write (char *buf, int len) { - if (!(flags & FLAG_CONNECTION)) { + if ((flags & FLAG_STDERR)) { int i; for (i = 0; i < len; i++) if (buf[i] != '\r') @@ -1190,8 +1190,9 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt) static char username[100]; static int pos = 0; static char c; - if ((flags & FLAG_CONNECTION) && !*cfg.username) { + if ((flags & FLAG_INTERACTIVE) && !*cfg.username) { c_write("login as: ", 10); + ssh_send_ok = 1; while (pos >= 0) { crWaitUntil(!ispkt); while (inlen--) switch (c = *in++) { @@ -1230,7 +1231,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt) char stuff[200]; strncpy(username, cfg.username, 99); username[99] = '\0'; - if (flags & FLAG_VERBOSE) { + if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) { sprintf(stuff, "Sent username \"%s\".\r\n", username); c_write(stuff, strlen(stuff)); } @@ -1362,7 +1363,8 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt) if (*cfg.keyfile && !tried_publickey) pwpkt_type = SSH1_CMSG_AUTH_RSA; - if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD && !FLAG_WINDOWED) { + if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD && + !(flags & FLAG_INTERACTIVE)) { char prompt[200]; sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost); if (!ssh_get_password(prompt, password, sizeof(password))) { @@ -1431,6 +1433,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt) } pos = 0; + ssh_send_ok = 1; while (pos >= 0) { crWaitUntil(!ispkt); while (inlen--) switch (c = *in++) { @@ -2079,8 +2082,9 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) static int pos = 0; static char c; - if ((flags & FLAG_CONNECTION) && !*cfg.username) { + if ((flags & FLAG_INTERACTIVE) && !*cfg.username) { c_write("login as: ", 10); + ssh_send_ok = 1; while (pos >= 0) { crWaitUntilV(!ispkt); while (inlen--) switch (c = *in++) { @@ -2119,13 +2123,13 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) char stuff[200]; strncpy(username, cfg.username, 99); username[99] = '\0'; - if (flags & FLAG_VERBOSE) { + if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) { sprintf(stuff, "Using username \"%s\".\r\n", username); c_write(stuff, strlen(stuff)); } } - if (!(flags & FLAG_WINDOWED)) { + if (!(flags & FLAG_INTERACTIVE)) { char prompt[200]; sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost); if (!ssh_get_password(prompt, password, sizeof(password))) { @@ -2141,6 +2145,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) } } else { c_write("password: ", 10); + ssh_send_ok = 1; pos = 0; while (pos >= 0) { @@ -2222,39 +2227,53 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) /* * Now allocate a pty for the session. */ - ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST); - ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */ - ssh2_pkt_addstring("pty-req"); - ssh2_pkt_addbool(1); /* want reply */ - ssh2_pkt_addstring(cfg.termtype); - ssh2_pkt_adduint32(cols); - ssh2_pkt_adduint32(rows); - ssh2_pkt_adduint32(0); /* pixel width */ - ssh2_pkt_adduint32(0); /* pixel height */ - ssh2_pkt_addstring_start(); - ssh2_pkt_addstring_data("\0", 1); /* TTY_OP_END, no special options */ - ssh2_pkt_send(); + if (!cfg.nopty) { + ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST); + ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */ + ssh2_pkt_addstring("pty-req"); + ssh2_pkt_addbool(1); /* want reply */ + ssh2_pkt_addstring(cfg.termtype); + ssh2_pkt_adduint32(cols); + ssh2_pkt_adduint32(rows); + ssh2_pkt_adduint32(0); /* pixel width */ + ssh2_pkt_adduint32(0); /* pixel height */ + ssh2_pkt_addstring_start(); + ssh2_pkt_addstring_data("\0", 1);/* TTY_OP_END, no special options */ + ssh2_pkt_send(); - do { /* FIXME: pay attention to these */ - crWaitUntilV(ispkt); - } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST); + do { + crWaitUntilV(ispkt); + if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) { + /* FIXME: be able to handle other channels here */ + if (ssh2_pkt_getuint32() != mainchan->localid) + continue; /* wrong channel */ + mainchan->u.v2.remwindow += ssh2_pkt_getuint32(); + } + } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST); - if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) { - if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) { - fatalbox("Server got confused by pty request"); + if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) { + if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) { + fatalbox("Server got confused by pty request"); + } + c_write("Server refused to allocate pty\r\n", 32); + } else { + logevent("Allocated pty"); } - c_write("Server refused to allocate pty\r\n", 32); - } else { - logevent("Allocated pty"); } /* - * Start a shell. + * Start a shell or a remote command. */ ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST); ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */ - ssh2_pkt_addstring("shell"); - ssh2_pkt_addbool(1); /* want reply */ + if (*cfg.remote_cmd) { + ssh2_pkt_addstring("exec"); + ssh2_pkt_addbool(1); /* want reply */ + ssh2_pkt_addstring(cfg.remote_cmd); + } else { + ssh2_pkt_addstring("shell"); + ssh2_pkt_addbool(1); /* want reply */ + } ssh2_pkt_send(); do { crWaitUntilV(ispkt); @@ -2502,13 +2521,14 @@ static void ssh_size(void) { */ static void ssh_special (Telnet_Special code) { if (code == TS_EOF) { - if (ssh_version = 1) { + if (ssh_version == 1) { send_packet(SSH1_CMSG_EOF, PKT_END); } else { ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF); ssh2_pkt_adduint32(mainchan->remoteid); ssh2_pkt_send(); } + logevent("Sent EOF message"); } else { /* do nothing */ } diff --git a/window.c b/window.c index 4e70dfe0..685b4f35 100644 --- a/window.c +++ b/window.c @@ -90,7 +90,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { int guess_width, guess_height; putty_inst = inst; - flags = FLAG_VERBOSE | FLAG_WINDOWED | FLAG_CONNECTION; + flags = FLAG_VERBOSE | FLAG_INTERACTIVE; winsock_ver = MAKEWORD(1, 1); if (WSAStartup(winsock_ver, &wsadata)) { -- 2.11.0