зеркало из https://github.com/github/putty.git
Make {term,}get_userpass_input take a bufchain.
NFC for the moment, because the bufchain is always specially constructed to hold exactly the same data that would have been passed in to the function as a (pointer,length) pair. But this API change allows get_userpass_input to express the idea that it consumed some but not all of the data in the bufchain, which means that later on I'll be able to point the same function at a longer-lived bufchain containing the full stream of keyboard input and avoid dropping keystrokes that arrive too quickly after the end of an interactive password prompt.
This commit is contained in:
Родитель
7400653bc8
Коммит
9d495b2176
7
putty.h
7
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);
|
||||
|
||||
|
|
23
rlogin.c
23
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;
|
||||
}
|
||||
|
||||
|
|
67
ssh.c
67
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);
|
||||
bufchain_init(&tmp_user_input);
|
||||
bufchain_add(&tmp_user_input, in, inlen);
|
||||
ret = get_userpass_input(s->cur_prompt,
|
||||
in, inlen);
|
||||
&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) {
|
||||
|
|
11
terminal.c
11
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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче