ssh_get_password has become ssh_get_line, so it can handle usernames
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 12 Mar 2001 15:31:53 +0000 (15:31 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 12 Mar 2001 15:31:53 +0000 (15:31 +0000)
as well. This should fix the multiple-reads-on-stdin bug in plink.

git-svn-id: svn://svn.tartarus.org/sgt/putty@994 cda61777-01e9-0310-a592-d414129be87e

plink.c
psftp.c
putty.h
scp.c
ssh.c

diff --git a/plink.c b/plink.c
index 5efcd45..121c65f 100644 (file)
--- a/plink.c
+++ b/plink.c
@@ -160,12 +160,12 @@ struct input_data {
     HANDLE event, eventback;
 };
 
-static int get_password(const char *prompt, char *str, int maxlen)
+static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
 {
     HANDLE hin, hout;
-    DWORD savemode, i;
+    DWORD savemode, newmode, i;
 
-    if (password) {
+    if (is_pw && password) {
         static int tried_once = 0;
 
         if (tried_once) {
@@ -186,8 +186,12 @@ static int get_password(const char *prompt, char *str, int maxlen)
     }
 
     GetConsoleMode(hin, &savemode);
-    SetConsoleMode(hin, (savemode & (~ENABLE_ECHO_INPUT)) |
-                   ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT);
+    newmode = savemode | ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT;
+    if (is_pw)
+        newmode &= ~ENABLE_ECHO_INPUT;
+    else
+        newmode |= ENABLE_ECHO_INPUT;
+    SetConsoleMode(hin, newmode);
 
     WriteFile(hout, prompt, strlen(prompt), &i, NULL);
     ReadFile(hin, str, maxlen-1, &i, NULL);
@@ -197,7 +201,8 @@ static int get_password(const char *prompt, char *str, int maxlen)
     if ((int)i > maxlen) i = maxlen-1; else i = i - 2;
     str[i] = '\0';
 
-    WriteFile(hout, "\r\n", 2, &i, NULL);
+    if (is_pw)
+        WriteFile(hout, "\r\n", 2, &i, NULL);
 
     return 1;
 }
@@ -265,7 +270,7 @@ int main(int argc, char **argv) {
     int skcount, sksize;
     int connopen;
 
-    ssh_get_password = get_password;
+    ssh_get_line = get_line;
 
     sklist = NULL; skcount = sksize = 0;
 
diff --git a/psftp.c b/psftp.c
index 0cf01be..1e89575 100644 (file)
--- a/psftp.c
+++ b/psftp.c
@@ -860,10 +860,10 @@ static void ssh_sftp_init(void) {
 }
 
 static char *password = NULL;
-static int get_password(const char *prompt, char *str, int maxlen)
+static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
 {
     HANDLE hin, hout;
-    DWORD savemode, i;
+    DWORD savemode, newmode, i;
 
     if (password) {
         static int tried_once = 0;
@@ -886,8 +886,12 @@ static int get_password(const char *prompt, char *str, int maxlen)
     }
 
     GetConsoleMode(hin, &savemode);
-    SetConsoleMode(hin, (savemode & (~ENABLE_ECHO_INPUT)) |
-                  ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT);
+    newmode = savemode | ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT;
+    if (is_pw)
+        newmode &= ~ENABLE_ECHO_INPUT;
+    else
+        newmode |= ENABLE_ECHO_INPUT;
+    SetConsoleMode(hin, newmode);
 
     WriteFile(hout, prompt, strlen(prompt), &i, NULL);
     ReadFile(hin, str, maxlen-1, &i, NULL);
@@ -897,7 +901,8 @@ static int get_password(const char *prompt, char *str, int maxlen)
     if ((int)i > maxlen) i = maxlen-1; else i = i - 2;
     str[i] = '\0';
 
-    WriteFile(hout, "\r\n", 2, &i, NULL);
+    if (is_pw)
+        WriteFile(hout, "\r\n", 2, &i, NULL);
 
     return 1;
 }
@@ -948,7 +953,7 @@ int main(int argc, char *argv[])
     char *err;
 
     flags = FLAG_STDERR;
-    ssh_get_password = &get_password;
+    ssh_get_line = &get_line;
     init_winsock();
     sk_init();
 
diff --git a/putty.h b/putty.h
index cf917ab..e4ca786 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -382,7 +382,8 @@ extern Backend telnet_backend;
  * Exports from ssh.c.
  */
 
-extern int (*ssh_get_password)(const char *prompt, char *str, int maxlen);
+extern int (*ssh_get_line)(const char *prompt, char *str, int maxlen,
+                           int is_pw);
 extern Backend ssh_backend;
 
 /*
diff --git a/scp.c b/scp.c
index fcd5e1a..2d02191 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -395,12 +395,12 @@ static void bump(char *fmt, ...)
     exit(1);
 }
 
-static int get_password(const char *prompt, char *str, int maxlen)
+static int get_line(const char *prompt, char *str, int maxlen, int is_pw)
 {
     HANDLE hin, hout;
-    DWORD savemode, i;
+    DWORD savemode, newmode, i;
 
-    if (password) {
+    if (is_pw && password) {
         static int tried_once = 0;
 
         if (tried_once) {
@@ -423,8 +423,12 @@ static int get_password(const char *prompt, char *str, int maxlen)
            bump("Cannot get standard input/output handles");
 
        GetConsoleMode(hin, &savemode);
-       SetConsoleMode(hin, (savemode & (~ENABLE_ECHO_INPUT)) |
-                      ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT);
+        newmode = savemode | ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT;
+        if (is_pw)
+            newmode &= ~ENABLE_ECHO_INPUT;
+        else
+            newmode |= ENABLE_ECHO_INPUT;
+        SetConsoleMode(hin, newmode);
 
        WriteFile(hout, prompt, strlen(prompt), &i, NULL);
        ReadFile(hin, str, maxlen-1, &i, NULL);
@@ -434,7 +438,8 @@ static int get_password(const char *prompt, char *str, int maxlen)
        if ((int)i > maxlen) i = maxlen-1; else i = i - 2;
        str[i] = '\0';
 
-       WriteFile(hout, "\r\n", 2, &i, NULL);
+       if (is_pw)
+            WriteFile(hout, "\r\n", 2, &i, NULL);
     }
 
     return 1;
@@ -1223,7 +1228,7 @@ int main(int argc, char *argv[])
     default_protocol = PROT_TELNET;
 
     flags = FLAG_STDERR;
-    ssh_get_password = &get_password;
+    ssh_get_line = &get_line;
     init_winsock();
     sk_init();
 
diff --git a/ssh.c b/ssh.c
index 7b4bff4..549a1e5 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -269,7 +269,8 @@ static const struct ssh_compress *sccomp = NULL;
 static const struct ssh_kex *kex = NULL;
 static const struct ssh_signkey *hostkey = NULL;
 static unsigned char ssh2_session_id[20];
-int (*ssh_get_password)(const char *prompt, char *str, int maxlen) = NULL;
+int (*ssh_get_line)(const char *prompt, char *str, int maxlen,
+                    int is_pw) = NULL;
 
 static char *savedhost;
 static int savedport;
@@ -1503,43 +1504,56 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
        static int pos = 0;
        static char c;
        if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
-           c_write_str("login as: ");
-            ssh_send_ok = 1;
-           while (pos >= 0) {
-               crWaitUntil(!ispkt);
-               while (inlen--) switch (c = *in++) {
-                 case 10: case 13:
-                   username[pos] = 0;
-                   pos = -1;
-                   break;
-                 case 8: case 127:
-                   if (pos > 0) {
-                       c_write_str("\b \b");
-                       pos--;
-                   }
-                   break;
-                 case 21: case 27:
-                   while (pos > 0) {
-                       c_write_str("\b \b");
-                       pos--;
-                   }
-                   break;
-                 case 3: case 4:
-                   random_save_seed();
-                   exit(0);
-                   break;
-                 default:
-                   if (((c >= ' ' && c <= '~') ||
-                         ((unsigned char)c >= 160)) && pos < 40) {
-                       username[pos++] = c;
-                       c_write(&c, 1);
-                   }
-                   break;
-               }
-           }
-           c_write_str("\r\n");
-           username[strcspn(username, "\n\r")] = '\0';
-       } else {
+            if (ssh_get_line) {
+                if (!ssh_get_line("login as: ",
+                                  username, sizeof(username), FALSE)) {
+                    /*
+                     * get_line failed to get a username.
+                     * Terminate.
+                     */
+                    logevent("No username provided. Abandoning session.");
+                    ssh_state = SSH_STATE_CLOSED;
+                    crReturn(1);
+                }
+            } else {
+                c_write_str("login as: ");
+                ssh_send_ok = 1;
+                while (pos >= 0) {
+                    crWaitUntil(!ispkt);
+                    while (inlen--) switch (c = *in++) {
+                      case 10: case 13:
+                        username[pos] = 0;
+                        pos = -1;
+                        break;
+                      case 8: case 127:
+                        if (pos > 0) {
+                            c_write_str("\b \b");
+                            pos--;
+                        }
+                        break;
+                      case 21: case 27:
+                        while (pos > 0) {
+                            c_write_str("\b \b");
+                            pos--;
+                        }
+                        break;
+                      case 3: case 4:
+                        random_save_seed();
+                        exit(0);
+                        break;
+                      default:
+                        if (((c >= ' ' && c <= '~') ||
+                             ((unsigned char)c >= 160)) && pos < 40) {
+                            username[pos++] = c;
+                            c_write(&c, 1);
+                        }
+                        break;
+                    }
+                }
+                c_write_str("\r\n");
+                username[strcspn(username, "\n\r")] = '\0';
+            }
+        } else {
            strncpy(username, cfg.username, 99);
            username[99] = '\0';
        }
@@ -1741,13 +1755,12 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
             sfree(comment);
         }
 
-       if (ssh_get_password) {
-           if (!ssh_get_password(prompt, password, sizeof(password))) {
+       if (ssh_get_line) {
+           if (!ssh_get_line(prompt, password, sizeof(password), TRUE)) {
                 /*
-                 * get_password failed to get a password (for
-                 * example because one was supplied on the command
-                 * line which has already failed to work).
-                 * Terminate.
+                 * get_line failed to get a password (for example
+                 * because one was supplied on the command line
+                 * which has already failed to work). Terminate.
                  */
                 logevent("No more passwords to try");
                 ssh_state = SSH_STATE_CLOSED;
@@ -2843,40 +2856,53 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
         */
        pos = 0;
        if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
-           c_write_str("login as: ");
-           ssh_send_ok = 1;
-           while (pos >= 0) {
-               crWaitUntilV(!ispkt);
-               while (inlen--) switch (c = *in++) {
-                 case 10: case 13:
-                   username[pos] = 0;
-                   pos = -1;
-                   break;
-                 case 8: case 127:
-                   if (pos > 0) {
-                       c_write_str("\b \b");
-                       pos--;
-                   }
-                   break;
-                 case 21: case 27:
-                   while (pos > 0) {
-                       c_write_str("\b \b");
-                       pos--;
-                   }
-                   break;
-                 case 3: case 4:
-                   random_save_seed();
-                   exit(0);
-                   break;
-                 default:
-                   if (((c >= ' ' && c <= '~') ||
-                        ((unsigned char)c >= 160)) && pos < 40) {
-                       username[pos++] = c;
-                       c_write(&c, 1);
-                   }
-                   break;
-               }
-           }
+            if (ssh_get_line) {
+                if (!ssh_get_line("login as: ",
+                                  username, sizeof(username), FALSE)) {
+                    /*
+                     * get_line failed to get a username.
+                     * Terminate.
+                     */
+                    logevent("No username provided. Abandoning session.");
+                    ssh_state = SSH_STATE_CLOSED;
+                    crReturn(1);
+                }
+            } else {
+                c_write_str("login as: ");
+                ssh_send_ok = 1;
+                while (pos >= 0) {
+                    crWaitUntilV(!ispkt);
+                    while (inlen--) switch (c = *in++) {
+                      case 10: case 13:
+                        username[pos] = 0;
+                        pos = -1;
+                        break;
+                      case 8: case 127:
+                        if (pos > 0) {
+                            c_write_str("\b \b");
+                            pos--;
+                        }
+                        break;
+                      case 21: case 27:
+                        while (pos > 0) {
+                            c_write_str("\b \b");
+                            pos--;
+                        }
+                        break;
+                      case 3: case 4:
+                        random_save_seed();
+                        exit(0);
+                        break;
+                      default:
+                        if (((c >= ' ' && c <= '~') ||
+                             ((unsigned char)c >= 160)) && pos < 40) {
+                            username[pos++] = c;
+                            c_write(&c, 1);
+                        }
+                        break;
+                    }
+                }
+            }
            c_write_str("\r\n");
            username[strcspn(username, "\n\r")] = '\0';
        } else {
@@ -3158,13 +3184,14 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
            }
 
            if (need_pw) {
-               if (ssh_get_password) {
-                   if (!ssh_get_password(pwprompt, password, sizeof(password))) {
+               if (ssh_get_line) {
+                   if (!ssh_get_line(pwprompt, password,
+                                      sizeof(password), TRUE)) {
                        /*
-                        * get_password failed to get a password (for
-                        * example because one was supplied on the command
-                        * line which has already failed to work).
-                        * Terminate.
+                        * get_line failed to get a password (for
+                        * example because one was supplied on the
+                        * command line which has already failed to
+                        * work). Terminate.
                         */
                        logevent("No more passwords to try");
                        ssh_state = SSH_STATE_CLOSED;