#define SSH2_MSG_CHANNEL_SUCCESS 99 /* 0x63 */
#define SSH2_MSG_CHANNEL_FAILURE 100 /* 0x64 */
+#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 /* 0x1 */
+#define SSH2_DISCONNECT_PROTOCOL_ERROR 2 /* 0x2 */
+#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3 /* 0x3 */
+#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4 /* 0x4 */
+#define SSH2_DISCONNECT_MAC_ERROR 5 /* 0x5 */
+#define SSH2_DISCONNECT_COMPRESSION_ERROR 6 /* 0x6 */
+#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7 /* 0x7 */
+#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 /* 0x8 */
+#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 /* 0x9 */
+#define SSH2_DISCONNECT_CONNECTION_LOST 10 /* 0xa */
+#define SSH2_DISCONNECT_BY_APPLICATION 11 /* 0xb */
+
#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 /* 0x1 */
#define SSH2_OPEN_CONNECT_FAILED 2 /* 0x2 */
#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 /* 0x3 */
else
b[j/2+1] |= ((unsigned char)p[i]);
}
+ while (b[0] > 1 && b[b[0]] == 0) b[0]--;
return b;
}
crFinishV;
}
-static int ssh_receive(Socket s, int urgent, char *data, int len) {
+static int ssh_receive(Socket skt, int urgent, char *data, int len) {
if (!len) {
/* Connection has closed. */
sk_close(s);
return 0;
}
ssh_gotdata (data, len);
+ if (ssh_state == SSH_STATE_CLOSED) {
+ if (s) {
+ sk_close(s);
+ s = NULL;
+ }
+ return 0;
+ }
return 1;
}
c_write("\r\n", 2);
username[strcspn(username, "\n\r")] = '\0';
} else {
- char stuff[200];
strncpy(username, cfg.username, 99);
username[99] = '\0';
- if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
- sprintf(stuff, "Sent username \"%s\".\r\n", username);
- c_write(stuff, strlen(stuff));
- }
}
send_packet(SSH1_CMSG_USER, PKT_STR, username, PKT_END);
{
- char userlog[20+sizeof(username)];
+ char userlog[22+sizeof(username)];
sprintf(userlog, "Sent username \"%s\"", username);
logevent(userlog);
+ if (flags & FLAG_INTERACTIVE &&
+ (!((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)))) {
+ strcat(userlog, "\r\n");
+ c_write(userlog, strlen(userlog));
+ }
}
}
} else if (pktin.type == SSH1_MSG_DISCONNECT) {
ssh_state = SSH_STATE_CLOSED;
logevent("Received disconnect request");
+ crReturnV;
} else if (pktin.type == SSH1_SMSG_AGENT_OPEN) {
/* Remote side is trying to open a channel to talk to our
* agent. Give them back a local channel number. */
ssh2_pkt_addstring_start();
ssh2_pkt_addstring_data("\0", 1);/* TTY_OP_END, no special options */
ssh2_pkt_send();
+ ssh_state = SSH_STATE_INTERMED;
do {
crWaitUntilV(ispkt);
logevent("Started a shell/command");
}
+ ssh_state = SSH_STATE_SESSION;
+ if (size_needed)
+ ssh_size();
+
/*
* Transfer data!
*/
} else if (pktin.type == SSH2_MSG_DISCONNECT) {
ssh_state = SSH_STATE_CLOSED;
logevent("Received disconnect message");
+ crReturnV;
} else if (pktin.type == SSH2_MSG_CHANNEL_REQUEST) {
continue; /* exit status et al; ignore (FIXME?) */
} else if (pktin.type == SSH2_MSG_CHANNEL_EOF) {
if (1 /* FIXME: "all channels are closed" */) {
logevent("All channels closed. Disconnecting");
ssh2_pkt_init(SSH2_MSG_DISCONNECT);
+ ssh2_pkt_adduint32(SSH2_DISCONNECT_BY_APPLICATION);
+ ssh2_pkt_addstring("All open channels closed");
+ ssh2_pkt_addstring("en"); /* language tag */
ssh2_pkt_send();
ssh_state = SSH_STATE_CLOSED;
- sk_close(s);
- s = NULL;
+ crReturnV;
}
continue; /* remote sends close; ignore (FIXME) */
} else if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
}
/*
- * Called to set the size of the window from Telnet's POV.
+ * Called to set the size of the window from SSH's POV.
*/
static void ssh_size(void) {
switch (ssh_state) {
break;
case SSH_STATE_SESSION:
if (!cfg.nopty) {
- send_packet(SSH1_CMSG_WINDOW_SIZE,
- PKT_INT, rows, PKT_INT, cols,
- PKT_INT, 0, PKT_INT, 0, PKT_END);
+ if (ssh_version == 1) {
+ send_packet(SSH1_CMSG_WINDOW_SIZE,
+ PKT_INT, rows, PKT_INT, cols,
+ PKT_INT, 0, PKT_INT, 0, PKT_END);
+ } else {
+ ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
+ ssh2_pkt_adduint32(mainchan->remoteid);
+ ssh2_pkt_addstring("window-change");
+ ssh2_pkt_addbool(0);
+ ssh2_pkt_adduint32(cols);
+ ssh2_pkt_adduint32(rows);
+ ssh2_pkt_adduint32(0);
+ ssh2_pkt_adduint32(0);
+ ssh2_pkt_send();
+ }
}
}
}