#define OUR_V2_WINSIZE 16384
/*
- * Ciphers for SSH2. We miss out single-DES because it isn't
- * supported; also 3DES and Blowfish are both done differently from
- * SSH1. (3DES uses outer chaining; Blowfish has the opposite
- * endianness and different-sized keys.)
+ * Ciphers for SSH2.
*/
const static struct ssh2_ciphers *ciphers[] = {
&ssh2_aes,
&ssh2_blowfish,
&ssh2_3des,
+ &ssh2_des,
};
const static struct ssh_kex *kex_algs[] = {
n_preferred_ciphers++;
break;
case CIPHER_DES:
- /* Not supported in SSH2; silently drop */
+ preferred_ciphers[n_preferred_ciphers] = &ssh2_des;
+ n_preferred_ciphers++;
break;
case CIPHER_3DES:
preferred_ciphers[n_preferred_ciphers] = &ssh2_3des;
break;
}
}
+ if (!cscipher_tobe) {
+ bombout(("Couldn't agree a client-to-server cipher (available: %s)", str));
+ crReturn(0);
+ }
+
ssh2_pkt_getstring(&str, &len); /* server->client cipher */
warn = 0;
for (i = 0; i < n_preferred_ciphers; i++) {
break;
}
}
+ if (!sccipher_tobe) {
+ bombout(("Couldn't agree a server-to-client cipher (available: %s)", str));
+ crReturn(0);
+ }
+
ssh2_pkt_getstring(&str, &len); /* client->server mac */
for (i = 0; i < nmacs; i++) {
if (in_commasep_string(maclist[i]->name, str, len)) {
}
/*
- * Expect SSH2_MSG_NEWKEYS from server.
- */
- crWaitUntil(ispkt);
- if (pktin.type != SSH2_MSG_NEWKEYS) {
- bombout(("expected new-keys packet from server"));
- crReturn(0);
- }
-
- /*
* Authenticate remote host: verify host key. (We've already
* checked the signature of the exchange hash.)
*/
ssh2_pkt_send();
/*
+ * Expect SSH2_MSG_NEWKEYS from server.
+ */
+ crWaitUntil(ispkt);
+ if (pktin.type != SSH2_MSG_NEWKEYS) {
+ bombout(("expected new-keys packet from server"));
+ crReturn(0);
+ }
+
+ /*
* Create and initialise session keys.
*/
cscipher = cscipher_tobe;
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) {
unsigned i = ssh2_pkt_getuint32();
struct ssh_channel *c;
del234(ssh_channels, c);
sfree(c);
+ } else if (pktin.type == SSH2_MSG_CHANNEL_REQUEST) {
+ unsigned localid;
+ char *type;
+ int typelen, want_reply;
+ struct ssh_channel *c;
+
+ localid = ssh2_pkt_getuint32();
+ ssh2_pkt_getstring(&type, &typelen);
+ want_reply = ssh2_pkt_getbool();
+
+ /*
+ * First, check that the channel exists. Otherwise,
+ * we can instantly disconnect with a rude message.
+ */
+ c = find234(ssh_channels, &localid, ssh_channelfind);
+ if (!c) {
+ char buf[80];
+ sprintf(buf, "Received channel request for nonexistent"
+ " channel %d", localid);
+ logevent(buf);
+ ssh2_pkt_init(SSH2_MSG_DISCONNECT);
+ ssh2_pkt_adduint32(SSH2_DISCONNECT_BY_APPLICATION);
+ ssh2_pkt_addstring(buf);
+ ssh2_pkt_addstring("en"); /* language tag */
+ ssh2_pkt_send();
+ connection_fatal(buf);
+ ssh_state = SSH_STATE_CLOSED;
+ crReturnV;
+ }
+
+ /*
+ * We don't recognise any form of channel request,
+ * so we now either ignore the request or respond
+ * with CHANNEL_FAILURE, depending on want_reply.
+ */
+ if (want_reply) {
+ ssh2_pkt_init(SSH2_MSG_CHANNEL_FAILURE);
+ ssh2_pkt_adduint32(c->remoteid);
+ ssh2_pkt_send();
+ }
} else if (pktin.type == SSH2_MSG_CHANNEL_OPEN) {
char *type;
int typelen;