ssh->version = 1;
ssh->s_rdpkt = ssh1_rdpkt;
}
+ update_specials_menu(ssh->frontend);
ssh->state = SSH_STATE_BEFORE_SIZE;
sfree(s->vstring);
* Terminate.
*/
logevent("No username provided. Abandoning session.");
- ssh->state = SSH_STATE_CLOSED;
+ ssh_closing((Plug)ssh, NULL, 0, 0);
crReturn(1);
}
} else {
PKT_END);
logevent("Unable to authenticate");
connection_fatal(ssh->frontend, "Unable to authenticate");
- ssh->state = SSH_STATE_CLOSED;
+ ssh_closing((Plug)ssh, NULL, 0, 0);
crReturn(1);
}
} else {
ssh1_throttle(ssh, +1);
}
} else if (ssh->pktin.type == SSH1_MSG_DISCONNECT) {
- ssh->state = SSH_STATE_CLOSED;
+ ssh_closing((Plug)ssh, NULL, 0, 0);
logevent("Received disconnect request");
crReturnV;
} else if (ssh->pktin.type == SSH1_SMSG_X11_OPEN) {
* encrypted packet, we close the session once
* we've sent EXIT_CONFIRMATION.
*/
- ssh->state = SSH_STATE_CLOSED;
+ ssh_closing((Plug)ssh, NULL, 0, 0);
crReturnV;
} else {
bombout(("Strange packet received: type %d", ssh->pktin.type));
* Terminate.
*/
logevent("No username provided. Abandoning session.");
- ssh->state = SSH_STATE_CLOSED;
+ ssh_closing((Plug)ssh, NULL, 0, 0);
crReturnV;
}
} else {
logevent("Unable to authenticate");
connection_fatal(ssh->frontend,
"Unable to authenticate");
- ssh->state = SSH_STATE_CLOSED;
+ ssh_closing((Plug)ssh, NULL, 0, 0);
crReturnV;
}
} else {
" methods available");
ssh2_pkt_addstring(ssh, "en"); /* language tag */
ssh2_pkt_send(ssh);
- ssh->state = SSH_STATE_CLOSED;
+ ssh_closing((Plug)ssh, NULL, 0, 0);
crReturnV;
}
}
* See if that was the last channel left open.
*/
if (count234(ssh->channels) == 0) {
+ logevent("All channels closed. Disconnecting");
#if 0
/*
* We used to send SSH_MSG_DISCONNECT here,
* this is more polite than sending a
* DISCONNECT. So now we don't.
*/
- logevent("All channels closed. Disconnecting");
ssh2_pkt_init(ssh, SSH2_MSG_DISCONNECT);
ssh2_pkt_adduint32(ssh, SSH2_DISCONNECT_BY_APPLICATION);
ssh2_pkt_addstring(ssh, "All open channels closed");
ssh2_pkt_addstring(ssh, "en"); /* language tag */
ssh2_pkt_send(ssh);
#endif
- ssh->state = SSH_STATE_CLOSED;
+ ssh_closing((Plug)ssh, NULL, 0, 0);
crReturnV;
}
continue; /* remote sends close; ignore (FIXME) */
ssh2_pkt_addstring(ssh, "en"); /* language tag */
ssh2_pkt_send(ssh);
connection_fatal(ssh->frontend, "%s", buf);
- ssh->state = SSH_STATE_CLOSED;
+ ssh_closing((Plug)ssh, NULL, 0, 0);
crReturnV;
}
ssh = snew(struct ssh_tag);
ssh->cfg = *cfg; /* STRUCTURE COPY */
+ ssh->version = 0; /* when not ready yet */
ssh->s = NULL;
ssh->cipher = NULL;
ssh->v1_cipher_ctx = NULL;
}
/*
+ * Return a list of the special codes that make sense in this
+ * protocol.
+ */
+static const struct telnet_special *ssh_get_specials(void *handle)
+{
+ Ssh ssh = (Ssh) handle;
+
+ if (ssh->version == 1) {
+ static const struct telnet_special ssh1_specials[] = {
+ {"IGNORE message", TS_NOP},
+ {NULL, 0}
+ };
+ return ssh1_specials;
+ } else if (ssh->version == 2) {
+ static const struct telnet_special ssh2_specials[] = {
+ {"Break", TS_BRK},
+ {"IGNORE message", TS_NOP},
+ {NULL, 0}
+ };
+ return ssh2_specials;
+ } else
+ return NULL;
+}
+
+/*
* Send Telnet special codes. TS_EOF is useful for `plink', so you
* can send an EOF and collect resulting output (e.g. `plink
* hostname sort').
ssh2_pkt_send(ssh);
}
logevent("Sent EOF message");
- } else if (code == TS_PING) {
+ } else if (code == TS_PING || code == TS_NOP) {
if (ssh->state == SSH_STATE_CLOSED
|| ssh->state == SSH_STATE_PREPACKET) return;
if (ssh->version == 1) {
ssh2_pkt_addstring_start(ssh);
ssh2_pkt_send(ssh);
}
+ } else if (code == TS_BRK) {
+ if (ssh->state == SSH_STATE_CLOSED
+ || ssh->state == SSH_STATE_PREPACKET) return;
+ if (ssh->version == 1) {
+ logevent("Unable to send BREAK signal in SSH1");
+ } else {
+ ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
+ ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
+ ssh2_pkt_addstring(ssh, "break");
+ ssh2_pkt_addbool(ssh, 0);
+ ssh2_pkt_adduint32(ssh, 0); /* default break length */
+ ssh2_pkt_send(ssh);
+ }
} else {
/* do nothing */
}
static int ssh_return_exitcode(void *handle)
{
Ssh ssh = (Ssh) handle;
- return ssh->exitcode;
+ if (ssh->s != NULL)
+ return -1;
+ else
+ return (ssh->exitcode >= 0 ? ssh->exitcode : 0);
}
/*
ssh_sendbuffer,
ssh_size,
ssh_special,
+ ssh_get_specials,
ssh_socket,
ssh_return_exitcode,
ssh_sendok,