{
struct ssh_rportfwd *a = (struct ssh_rportfwd *) av;
struct ssh_rportfwd *b = (struct ssh_rportfwd *) bv;
- int i;
+
if (a->sport > b->sport)
return +1;
if (a->sport < b->sport)
memcpy(buf + nowlen, pktin.body + 4, msglen);
buf[nowlen + msglen] = '\0';
logevent(buf);
+ bombout(("Server sent disconnect message:\n\"%s\"", buf+nowlen));
}
crFinish(0);
memcpy(buf + nowlen, pktin.data + 14, msglen);
buf[nowlen + msglen] = '\0';
logevent(buf);
+ bombout(("Server sent disconnect message\ntype %d (%s):\n\"%s\"",
+ reason,
+ (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?
+ ssh2_disconnect_reasons[reason] : "unknown",
+ buf+nowlen));
}
crFinish(0);
/*
* Try to find host.
*/
+ {
+ char buf[200];
+ sprintf(buf, "Looking up host \"%.170s\"", host);
+ logevent(buf);
+ }
addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr)))
return err;
/*
* Open socket.
*/
+ {
+ char buf[200], addrbuf[100];
+ sk_getaddr(addr, addrbuf, 100);
+ sprintf(buf, "Connecting to %.100s port %d", addrbuf, port);
+ logevent(buf);
+ }
s = sk_new(addr, port, 0, 1, &fn_table_ptr);
if ((err = sk_socket_error(s)))
return err;
struct MD5Context md5c;
static unsigned long supported_ciphers_mask, supported_auths_mask;
static int tried_publickey;
+ static int tis_auth_refused, ccard_auth_refused;
static unsigned char session_id[16];
static int cipher_type;
static char username[100];
crWaitUntil(ispkt);
tried_publickey = 0;
+ tis_auth_refused = ccard_auth_refused = 0;
while (pktin.type == SSH1_SMSG_FAILURE) {
static char password[100];
static int pos;
static char c;
static int pwpkt_type;
- /*
- * Show password prompt, having first obtained it via a TIS
- * or CryptoCard exchange if we're doing TIS or CryptoCard
- * authentication.
- */
pwpkt_type = SSH1_CMSG_AUTH_PASSWORD;
+
if (agent_exists()) {
/*
* Attempt RSA authentication using Pageant.
if (*cfg.keyfile && !tried_publickey)
pwpkt_type = SSH1_CMSG_AUTH_RSA;
- if (pktin.type == SSH1_SMSG_FAILURE &&
- cfg.try_tis_auth &&
- (supported_auths_mask & (1 << SSH1_AUTH_TIS))) {
+ if (cfg.try_tis_auth &&
+ (supported_auths_mask & (1 << SSH1_AUTH_TIS)) &&
+ !tis_auth_refused) {
pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
logevent("Requested TIS authentication");
send_packet(SSH1_CMSG_AUTH_TIS, PKT_END);
logevent("TIS authentication declined");
if (flags & FLAG_INTERACTIVE)
c_write_str("TIS authentication refused.\r\n");
+ tis_auth_refused = 1;
+ continue;
} else {
int challengelen = ((pktin.body[0] << 24) |
(pktin.body[1] << 16) |
if (challengelen > sizeof(prompt) - 1)
challengelen = sizeof(prompt) - 1; /* prevent overrun */
memcpy(prompt, pktin.body + 4, challengelen);
- prompt[challengelen] = '\0';
+ /* Prompt heuristic comes from OpenSSH */
+ strncpy(prompt + challengelen,
+ memchr(prompt, '\n', challengelen) ?
+ "": "\r\nResponse: ",
+ (sizeof prompt) - challengelen);
+ prompt[(sizeof prompt) - 1] = '\0';
}
}
- if (pktin.type == SSH1_SMSG_FAILURE &&
- cfg.try_tis_auth &&
- (supported_auths_mask & (1 << SSH1_AUTH_CCARD))) {
+ if (cfg.try_tis_auth &&
+ (supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
+ !ccard_auth_refused) {
pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
logevent("Requested CryptoCard authentication");
send_packet(SSH1_CMSG_AUTH_CCARD, PKT_END);
if (pktin.type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
logevent("CryptoCard authentication declined");
c_write_str("CryptoCard authentication refused.\r\n");
+ ccard_auth_refused = 1;
+ continue;
} else {
int challengelen = ((pktin.body[0] << 24) |
(pktin.body[1] << 16) |
if (challengelen > sizeof(prompt) - 1)
challengelen = sizeof(prompt) - 1; /* prevent overrun */
memcpy(prompt, pktin.body + 4, challengelen);
- strncpy(prompt + challengelen, "\r\nResponse : ",
+ strncpy(prompt + challengelen,
+ memchr(prompt, '\n', challengelen) ?
+ "" : "\r\nResponse: ",
sizeof(prompt) - challengelen);
prompt[sizeof(prompt) - 1] = '\0';
}
sfree(comment);
}
+ /*
+ * Show password prompt, having first obtained it via a TIS
+ * or CryptoCard exchange if we're doing TIS or CryptoCard
+ * authentication.
+ */
if (ssh_get_line) {
if (!ssh_get_line(prompt, password, sizeof(password), TRUE)) {
/*
crReturn(1);
}
} else {
- c_write_str(prompt);
+ /* Prompt may have come from server. We've munged it a bit, so
+ * we know it to be zero-terminated at least once. */
+ c_write_untrusted(prompt, strlen(prompt));
pos = 0;
ssh_send_ok = 1;
while (pos >= 0) {
tried_publickey = 1;
i = loadrsakey(cfg.keyfile, &pubkey, password);
if (i == 0) {
- c_write_str("Couldn't load public key from ");
+ c_write_str("Couldn't load private key from ");
c_write_str(cfg.keyfile);
c_write_str(".\r\n");
continue; /* go and try password */
int bufsize =
from_backend(pktin.type == SSH1_SMSG_STDERR_DATA,
pktin.body + 4, len);
- if (bufsize > SSH1_BUFFER_LIMIT) {
+ if (!ssh1_stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) {
ssh1_stdout_throttling = 1;
ssh1_throttle(+1);
}
bufsize = 0; /* agent channels never back up */
break;
}
- if (bufsize > SSH1_BUFFER_LIMIT) {
+ if (!c->v.v1.throttling && bufsize > SSH1_BUFFER_LIMIT) {
c->v.v1.throttling = 1;
ssh1_throttle(+1);
}
in_commasep_string("publickey", methods, methlen);
can_passwd =
in_commasep_string("password", methods, methlen);
- can_passwd =
- in_commasep_string("password", methods, methlen);
can_keyb_inter =
in_commasep_string("keyboard-interactive", methods, methlen);
}
method = 0;
- if (!method && can_keyb_inter && !tried_keyb_inter) {
- method = AUTH_KEYBOARD_INTERACTIVE;
- type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
- tried_keyb_inter = TRUE;
-
- ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
- ssh2_pkt_addstring(username);
- ssh2_pkt_addstring("ssh-connection"); /* service requested */
- ssh2_pkt_addstring("keyboard-interactive"); /* method */
- ssh2_pkt_addstring(""); /* lang */
- ssh2_pkt_addstring("");
- ssh2_pkt_send();
-
- crWaitUntilV(ispkt);
- if (pktin.type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
- if (pktin.type == SSH2_MSG_USERAUTH_FAILURE)
- gotit = TRUE;
- logevent("Keyboard-interactive authentication refused");
- type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
- continue;
- }
-
- kbd_inter_running = TRUE;
- }
-
- if (kbd_inter_running) {
- method = AUTH_KEYBOARD_INTERACTIVE;
- type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
- tried_keyb_inter = TRUE;
-
- /* We've got packet with that "interactive" info
- dump banners, and set its prompt as ours */
- {
- char *name, *inst, *lang, *prompt;
- int name_len, inst_len, lang_len, prompt_len;
- ssh2_pkt_getstring(&name, &name_len);
- ssh2_pkt_getstring(&inst, &inst_len);
- ssh2_pkt_getstring(&lang, &lang_len);
- if (name_len > 0)
- c_write_untrusted(name, name_len);
- if (inst_len > 0)
- c_write_untrusted(inst, inst_len);
- num_prompts = ssh2_pkt_getuint32();
-
- ssh2_pkt_getstring(&prompt, &prompt_len);
- strncpy(pwprompt, prompt, sizeof(pwprompt));
- need_pw = TRUE;
-
- echo = ssh2_pkt_getbool();
- }
- }
-
if (!method && can_pubkey && agent_exists() && !tried_agent) {
/*
* Attempt public-key authentication using Pageant.
}
}
+ if (!method && can_keyb_inter && !tried_keyb_inter) {
+ method = AUTH_KEYBOARD_INTERACTIVE;
+ type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
+ tried_keyb_inter = TRUE;
+
+ ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
+ ssh2_pkt_addstring(username);
+ ssh2_pkt_addstring("ssh-connection"); /* service requested */
+ ssh2_pkt_addstring("keyboard-interactive"); /* method */
+ ssh2_pkt_addstring(""); /* lang */
+ ssh2_pkt_addstring("");
+ ssh2_pkt_send();
+
+ crWaitUntilV(ispkt);
+ if (pktin.type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
+ if (pktin.type == SSH2_MSG_USERAUTH_FAILURE)
+ gotit = TRUE;
+ logevent("Keyboard-interactive authentication refused");
+ type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
+ continue;
+ }
+
+ kbd_inter_running = TRUE;
+ }
+
+ if (kbd_inter_running) {
+ method = AUTH_KEYBOARD_INTERACTIVE;
+ type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
+ tried_keyb_inter = TRUE;
+
+ /* We've got packet with that "interactive" info
+ dump banners, and set its prompt as ours */
+ {
+ char *name, *inst, *lang, *prompt;
+ int name_len, inst_len, lang_len, prompt_len;
+ ssh2_pkt_getstring(&name, &name_len);
+ ssh2_pkt_getstring(&inst, &inst_len);
+ ssh2_pkt_getstring(&lang, &lang_len);
+ if (name_len > 0)
+ c_write_untrusted(name, name_len);
+ if (inst_len > 0)
+ c_write_untrusted(inst, inst_len);
+ num_prompts = ssh2_pkt_getuint32();
+
+ ssh2_pkt_getstring(&prompt, &prompt_len);
+ strncpy(pwprompt, prompt, sizeof(pwprompt));
+ need_pw = TRUE;
+
+ echo = ssh2_pkt_getbool();
+ }
+ }
+
if (!method && can_passwd) {
method = AUTH_PASSWORD;
sprintf(pwprompt, "%.90s@%.90s's password: ", username,
c = find234(ssh_channels, &i, ssh_channelfind);
if (!c)
continue; /* nonexistent channel */
- if (c->closes == 0) {
- ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
- ssh2_pkt_adduint32(c->remoteid);
- ssh2_pkt_send();
- }
/* Do pre-close processing on the channel. */
switch (c->type) {
case CHAN_MAINSESSION:
break; /* nothing to see here, move along */
case CHAN_X11:
+ if (c->u.x11.s != NULL)
+ x11_close(c->u.x11.s);
+ sshfwd_close(c);
break;
case CHAN_AGENT:
+ sshfwd_close(c);
break;
case CHAN_SOCKDATA:
+ if (c->u.pfd.s != NULL)
+ pfd_close(c->u.pfd.s);
+ sshfwd_close(c);
break;
}
+ if (c->closes == 0) {
+ ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
+ ssh2_pkt_adduint32(c->remoteid);
+ ssh2_pkt_send();
+ }
del234(ssh_channels, c);
bufchain_clear(&c->v.v2.outbuffer);
sfree(c);
void ssh_unthrottle(int bufsize)
{
if (ssh_version == 1) {
- if (bufsize < SSH1_BUFFER_LIMIT) {
+ if (ssh1_stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
ssh1_stdout_throttling = 0;
ssh1_throttle(-1);
}