diff --git a/putty.h b/putty.h index a96230f2..a8cfcf27 100644 --- a/putty.h +++ b/putty.h @@ -706,9 +706,9 @@ char *get_ttymode(void *frontend, const char *mode); /* * >0 = `got all results, carry on' * 0 = `user cancelled' (FIXME distinguish "give up entirely" and "next auth"?) - * <0 = `please call back later with more in/inlen' + * <0 = `please call back later with a fuller bufchain' */ -int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen); +int get_userpass_input(prompts_t *p, bufchain *input); #define OPTIMISE_IS_SCROLL 1 void set_iconic(void *frontend, int iconic); @@ -1119,8 +1119,7 @@ void term_provide_resize_fn(Terminal *term, void term_provide_logctx(Terminal *term, void *logctx); void term_set_focus(Terminal *term, int has_focus); char *term_get_ttymode(Terminal *term, const char *mode); -int term_get_userpass_input(Terminal *term, prompts_t *p, - const unsigned char *in, int inlen); +int term_get_userpass_input(Terminal *term, prompts_t *p, bufchain *input); int format_arrow_key(char *buf, Terminal *term, int xkey, int ctrl); diff --git a/rlogin.c b/rlogin.c index ff2c0a8f..cd6260d2 100644 --- a/rlogin.c +++ b/rlogin.c @@ -230,7 +230,7 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle, rlogin->prompt->to_server = TRUE; rlogin->prompt->name = dupstr("Rlogin login name"); add_prompt(rlogin->prompt, dupstr("rlogin username: "), TRUE); - ret = get_userpass_input(rlogin->prompt, NULL, 0); + ret = get_userpass_input(rlogin->prompt, NULL); if (ret >= 0) { rlogin_startup(rlogin, rlogin->prompt->prompts[0]->result); } @@ -264,26 +264,39 @@ static void rlogin_reconfig(void *handle, Conf *conf) static int rlogin_send(void *handle, const char *buf, int len) { Rlogin rlogin = (Rlogin) handle; + bufchain bc; if (rlogin->s == NULL) return 0; + bufchain_init(&bc); + bufchain_add(&bc, buf, len); + if (rlogin->prompt) { /* * We're still prompting for a username, and aren't talking * directly to the network connection yet. */ - int ret = get_userpass_input(rlogin->prompt, - (unsigned char *)buf, len); + int ret = get_userpass_input(rlogin->prompt, &bc); if (ret >= 0) { rlogin_startup(rlogin, rlogin->prompt->prompts[0]->result); /* that nulls out rlogin->prompt, so then we'll start sending * data down the wire in the obvious way */ } - } else { - rlogin->bufsize = sk_write(rlogin->s, buf, len); } + if (!rlogin->prompt) { + while (bufchain_size(&bc) > 0) { + void *data; + int len; + bufchain_prefix(&bc, &data, &len); + rlogin->bufsize = sk_write(rlogin->s, data, len); + bufchain_consume(&bc, len); + } + } + + bufchain_clear(&bc); + return rlogin->bufsize; } diff --git a/ssh.c b/ssh.c index 59c3046d..8665ad2a 100644 --- a/ssh.c +++ b/ssh.c @@ -4497,11 +4497,15 @@ static int do_ssh1_login(Ssh ssh, const unsigned char *in, int inlen, s->cur_prompt->to_server = TRUE; s->cur_prompt->name = dupstr("SSH login name"); add_prompt(s->cur_prompt, dupstr("login as: "), TRUE); - ret = get_userpass_input(s->cur_prompt, NULL, 0); + ret = get_userpass_input(s->cur_prompt, NULL); while (ret < 0) { + bufchain tmp_user_input; ssh->send_ok = 1; crWaitUntil(!pktin); - ret = get_userpass_input(s->cur_prompt, in, inlen); + bufchain_init(&tmp_user_input); + bufchain_add(&tmp_user_input, in, inlen); + ret = get_userpass_input(s->cur_prompt, &tmp_user_input); + bufchain_clear(&tmp_user_input); ssh->send_ok = 0; } if (!ret) { @@ -4804,11 +4808,16 @@ static int do_ssh1_login(Ssh ssh, const unsigned char *in, int inlen, add_prompt(s->cur_prompt, dupprintf("Passphrase for key \"%.100s\": ", s->publickey_comment), FALSE); - ret = get_userpass_input(s->cur_prompt, NULL, 0); + ret = get_userpass_input(s->cur_prompt, NULL); while (ret < 0) { + bufchain tmp_user_input; ssh->send_ok = 1; crWaitUntil(!pktin); - ret = get_userpass_input(s->cur_prompt, in, inlen); + bufchain_init(&tmp_user_input); + bufchain_add(&tmp_user_input, in, inlen); + ret = get_userpass_input(s->cur_prompt, + &tmp_user_input); + bufchain_clear(&tmp_user_input); ssh->send_ok = 0; } if (!ret) { @@ -5024,11 +5033,15 @@ static int do_ssh1_login(Ssh ssh, const unsigned char *in, int inlen, */ { int ret; /* need not be kept over crReturn */ - ret = get_userpass_input(s->cur_prompt, NULL, 0); + ret = get_userpass_input(s->cur_prompt, NULL); while (ret < 0) { + bufchain tmp_user_input; ssh->send_ok = 1; crWaitUntil(!pktin); - ret = get_userpass_input(s->cur_prompt, in, inlen); + bufchain_init(&tmp_user_input); + bufchain_add(&tmp_user_input, in, inlen); + ret = get_userpass_input(s->cur_prompt, &tmp_user_input); + bufchain_clear(&tmp_user_input); ssh->send_ok = 0; } if (!ret) { @@ -10313,11 +10326,15 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen, s->cur_prompt->to_server = TRUE; s->cur_prompt->name = dupstr("SSH login name"); add_prompt(s->cur_prompt, dupstr("login as: "), TRUE); - ret = get_userpass_input(s->cur_prompt, NULL, 0); + ret = get_userpass_input(s->cur_prompt, NULL); while (ret < 0) { + bufchain tmp_user_input; ssh->send_ok = 1; crWaitUntilV(!pktin); - ret = get_userpass_input(s->cur_prompt, in, inlen); + bufchain_init(&tmp_user_input); + bufchain_add(&tmp_user_input, in, inlen); + ret = get_userpass_input(s->cur_prompt, &tmp_user_input); + bufchain_clear(&tmp_user_input); ssh->send_ok = 0; } if (!ret) { @@ -10749,12 +10766,16 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen, dupprintf("Passphrase for key \"%.100s\": ", s->publickey_comment), FALSE); - ret = get_userpass_input(s->cur_prompt, NULL, 0); + ret = get_userpass_input(s->cur_prompt, NULL); while (ret < 0) { + bufchain tmp_user_input; ssh->send_ok = 1; crWaitUntilV(!pktin); - ret = get_userpass_input(s->cur_prompt, - in, inlen); + bufchain_init(&tmp_user_input); + bufchain_add(&tmp_user_input, in, inlen); + ret = get_userpass_input(s->cur_prompt, + &tmp_user_input); + bufchain_clear(&tmp_user_input); ssh->send_ok = 0; } if (!ret) { @@ -11135,11 +11156,16 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen, */ { int ret; /* not live over crReturn */ - ret = get_userpass_input(s->cur_prompt, NULL, 0); + ret = get_userpass_input(s->cur_prompt, NULL); while (ret < 0) { + bufchain tmp_user_input; ssh->send_ok = 1; crWaitUntilV(!pktin); - ret = get_userpass_input(s->cur_prompt, in, inlen); + bufchain_init(&tmp_user_input); + bufchain_add(&tmp_user_input, in, inlen); + ret = get_userpass_input(s->cur_prompt, + &tmp_user_input); + bufchain_clear(&tmp_user_input); ssh->send_ok = 0; } if (!ret) { @@ -11203,11 +11229,15 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen, ssh->savedhost), FALSE); - ret = get_userpass_input(s->cur_prompt, NULL, 0); + ret = get_userpass_input(s->cur_prompt, NULL); while (ret < 0) { + bufchain tmp_user_input; ssh->send_ok = 1; crWaitUntilV(!pktin); - ret = get_userpass_input(s->cur_prompt, in, inlen); + bufchain_init(&tmp_user_input); + bufchain_add(&tmp_user_input, in, inlen); + ret = get_userpass_input(s->cur_prompt, &tmp_user_input); + bufchain_clear(&tmp_user_input); ssh->send_ok = 0; } if (!ret) { @@ -11313,11 +11343,16 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen, */ while (!got_new) { - ret = get_userpass_input(s->cur_prompt, NULL, 0); + ret = get_userpass_input(s->cur_prompt, NULL); while (ret < 0) { + bufchain tmp_user_input; ssh->send_ok = 1; crWaitUntilV(!pktin); - ret = get_userpass_input(s->cur_prompt, in, inlen); + bufchain_init(&tmp_user_input); + bufchain_add(&tmp_user_input, in, inlen); + ret = get_userpass_input(s->cur_prompt, + &tmp_user_input); + bufchain_clear(&tmp_user_input); ssh->send_ok = 0; } if (!ret) { diff --git a/terminal.c b/terminal.c index 20ab1769..667a29b3 100644 --- a/terminal.c +++ b/terminal.c @@ -6718,8 +6718,7 @@ struct term_userpass_state { * Process some terminal data in the course of username/password * input. */ -int term_get_userpass_input(Terminal *term, prompts_t *p, - const unsigned char *in, int inlen) +int term_get_userpass_input(Terminal *term, prompts_t *p, bufchain *input) { struct term_userpass_state *s = (struct term_userpass_state *)p->data; if (!s) { @@ -6766,12 +6765,12 @@ int term_get_userpass_input(Terminal *term, prompts_t *p, /* Breaking out here ensures that the prompt is printed even * if we're now waiting for user data. */ - if (!in || !inlen) break; + if (!input || !bufchain_size(input)) break; /* FIXME: should we be using local-line-editing code instead? */ - while (!finished_prompt && inlen) { - char c = *in++; - inlen--; + while (!finished_prompt && bufchain_size(input) > 0) { + char c; + bufchain_fetch_consume(input, &c, 1); switch (c) { case 10: case 13: diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 8dc3b2d4..0771b0b5 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -321,13 +321,13 @@ int from_backend_eof(void *frontend) return TRUE; /* do respond to incoming EOF with outgoing */ } -int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen) +int get_userpass_input(prompts_t *p, bufchain *input) { struct gui_data *inst = (struct gui_data *)p->frontend; int ret; ret = cmdline_get_passwd_input(p); if (ret == -1) - ret = term_get_userpass_input(inst->term, p, in, inlen); + ret = term_get_userpass_input(inst->term, p, input); return ret; } diff --git a/unix/uxplink.c b/unix/uxplink.c index 9ff6f530..c042f459 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -432,7 +432,7 @@ int from_backend_eof(void *frontend_handle) return FALSE; /* do not respond to incoming EOF with outgoing */ } -int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen) +int get_userpass_input(prompts_t *p, bufchain *input) { int ret; ret = cmdline_get_passwd_input(p); diff --git a/unix/uxsftp.c b/unix/uxsftp.c index 861baabe..718a29c9 100644 --- a/unix/uxsftp.c +++ b/unix/uxsftp.c @@ -68,7 +68,7 @@ Filename *platform_default_filename(const char *name) char *get_ttymode(void *frontend, const char *mode) { return NULL; } -int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen) +int get_userpass_input(prompts_t *p, bufchain *input) { int ret; ret = cmdline_get_passwd_input(p); diff --git a/windows/window.c b/windows/window.c index 608eb220..5340f7d4 100644 --- a/windows/window.c +++ b/windows/window.c @@ -5934,12 +5934,12 @@ int from_backend_eof(void *frontend) return TRUE; /* do respond to incoming EOF with outgoing */ } -int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen) +int get_userpass_input(prompts_t *p, bufchain *input) { int ret; ret = cmdline_get_passwd_input(p); if (ret == -1) - ret = term_get_userpass_input(term, p, in, inlen); + ret = term_get_userpass_input(term, p, input); return ret; } diff --git a/windows/winplink.c b/windows/winplink.c index 1e5f9f65..5b026b52 100644 --- a/windows/winplink.c +++ b/windows/winplink.c @@ -131,12 +131,12 @@ int from_backend_eof(void *frontend_handle) return FALSE; /* do not respond to incoming EOF with outgoing */ } -int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen) +int get_userpass_input(prompts_t *p, bufchain *input) { int ret; ret = cmdline_get_passwd_input(p); if (ret == -1) - ret = console_get_userpass_input(p, in, inlen); + ret = console_get_userpass_input(p); return ret; } diff --git a/windows/winsftp.c b/windows/winsftp.c index 17d332b7..e9d5d4cb 100644 --- a/windows/winsftp.c +++ b/windows/winsftp.c @@ -15,12 +15,12 @@ char *get_ttymode(void *frontend, const char *mode) { return NULL; } -int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen) +int get_userpass_input(prompts_t *p, bufchain *input) { int ret; ret = cmdline_get_passwd_input(p); if (ret == -1) - ret = console_get_userpass_input(p, in, inlen); + ret = console_get_userpass_input(p); return ret; }