]> asedeno.scripts.mit.edu Git - PuTTY_svn.git/blob - ssh.c
Add AES support in SSH2. Not yet complete: there's no way to select
[PuTTY_svn.git] / ssh.c
1 #include <windows.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <stdarg.h>
5 #include <assert.h>
6
7 #include "putty.h"
8 #include "tree234.h"
9 #include "ssh.h"
10
11 #ifndef FALSE
12 #define FALSE 0
13 #endif
14 #ifndef TRUE
15 #define TRUE 1
16 #endif
17
18 #define logevent(s) { logevent(s); \
19                       if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) \
20                       fprintf(stderr, "%s\n", s); }
21
22 #define bombout(msg) ( ssh_state = SSH_STATE_CLOSED, \
23                           (s ? sk_close(s), s = NULL : 0), \
24                           connection_fatal msg )
25
26 #define SSH1_MSG_DISCONNECT                       1    /* 0x1 */
27 #define SSH1_SMSG_PUBLIC_KEY                      2    /* 0x2 */
28 #define SSH1_CMSG_SESSION_KEY                     3    /* 0x3 */
29 #define SSH1_CMSG_USER                            4    /* 0x4 */
30 #define SSH1_CMSG_AUTH_RSA                        6    /* 0x6 */
31 #define SSH1_SMSG_AUTH_RSA_CHALLENGE              7    /* 0x7 */
32 #define SSH1_CMSG_AUTH_RSA_RESPONSE               8    /* 0x8 */
33 #define SSH1_CMSG_AUTH_PASSWORD                   9    /* 0x9 */
34 #define SSH1_CMSG_REQUEST_PTY                     10   /* 0xa */
35 #define SSH1_CMSG_WINDOW_SIZE                     11   /* 0xb */
36 #define SSH1_CMSG_EXEC_SHELL                      12   /* 0xc */
37 #define SSH1_CMSG_EXEC_CMD                        13   /* 0xd */
38 #define SSH1_SMSG_SUCCESS                         14   /* 0xe */
39 #define SSH1_SMSG_FAILURE                         15   /* 0xf */
40 #define SSH1_CMSG_STDIN_DATA                      16   /* 0x10 */
41 #define SSH1_SMSG_STDOUT_DATA                     17   /* 0x11 */
42 #define SSH1_SMSG_STDERR_DATA                     18   /* 0x12 */
43 #define SSH1_CMSG_EOF                             19   /* 0x13 */
44 #define SSH1_SMSG_EXIT_STATUS                     20   /* 0x14 */
45 #define SSH1_MSG_CHANNEL_OPEN_CONFIRMATION        21   /* 0x15 */
46 #define SSH1_MSG_CHANNEL_OPEN_FAILURE             22   /* 0x16 */
47 #define SSH1_MSG_CHANNEL_DATA                     23   /* 0x17 */
48 #define SSH1_MSG_CHANNEL_CLOSE                    24   /* 0x18 */
49 #define SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION       25   /* 0x19 */
50 #define SSH1_SMSG_X11_OPEN                        27   /* 0x1b */
51 #define SSH1_CMSG_PORT_FORWARD_REQUEST            28   /* 0x1c */
52 #define SSH1_MSG_PORT_OPEN                        29   /* 0x1d */
53 #define SSH1_CMSG_AGENT_REQUEST_FORWARDING        30   /* 0x1e */
54 #define SSH1_SMSG_AGENT_OPEN                      31   /* 0x1f */
55 #define SSH1_MSG_IGNORE                           32   /* 0x20 */
56 #define SSH1_CMSG_EXIT_CONFIRMATION               33   /* 0x21 */
57 #define SSH1_CMSG_X11_REQUEST_FORWARDING          34   /* 0x22 */
58 #define SSH1_CMSG_AUTH_RHOSTS_RSA                 35   /* 0x23 */
59 #define SSH1_MSG_DEBUG                            36   /* 0x24 */
60 #define SSH1_CMSG_REQUEST_COMPRESSION             37   /* 0x25 */
61 #define SSH1_CMSG_AUTH_TIS                        39   /* 0x27 */
62 #define SSH1_SMSG_AUTH_TIS_CHALLENGE              40   /* 0x28 */
63 #define SSH1_CMSG_AUTH_TIS_RESPONSE               41   /* 0x29 */
64 #define SSH1_CMSG_AUTH_CCARD                      70   /* 0x46 */
65 #define SSH1_SMSG_AUTH_CCARD_CHALLENGE            71   /* 0x47 */
66 #define SSH1_CMSG_AUTH_CCARD_RESPONSE             72   /* 0x48 */
67
68 #define SSH1_AUTH_TIS                             5    /* 0x5 */
69 #define SSH1_AUTH_CCARD                           16   /* 0x10 */
70
71 #define SSH_AGENTC_REQUEST_RSA_IDENTITIES         1    /* 0x1 */
72 #define SSH_AGENT_RSA_IDENTITIES_ANSWER           2    /* 0x2 */
73 #define SSH_AGENTC_RSA_CHALLENGE                  3    /* 0x3 */
74 #define SSH_AGENT_RSA_RESPONSE                    4    /* 0x4 */
75 #define SSH_AGENT_FAILURE                         5    /* 0x5 */
76 #define SSH_AGENT_SUCCESS                         6    /* 0x6 */
77 #define SSH_AGENTC_ADD_RSA_IDENTITY               7    /* 0x7 */
78 #define SSH_AGENTC_REMOVE_RSA_IDENTITY            8    /* 0x8 */
79
80 #define SSH2_MSG_DISCONNECT                       1    /* 0x1 */
81 #define SSH2_MSG_IGNORE                           2    /* 0x2 */
82 #define SSH2_MSG_UNIMPLEMENTED                    3    /* 0x3 */
83 #define SSH2_MSG_DEBUG                            4    /* 0x4 */
84 #define SSH2_MSG_SERVICE_REQUEST                  5    /* 0x5 */
85 #define SSH2_MSG_SERVICE_ACCEPT                   6    /* 0x6 */
86 #define SSH2_MSG_KEXINIT                          20   /* 0x14 */
87 #define SSH2_MSG_NEWKEYS                          21   /* 0x15 */
88 #define SSH2_MSG_KEXDH_INIT                       30   /* 0x1e */
89 #define SSH2_MSG_KEXDH_REPLY                      31   /* 0x1f */
90 #define SSH2_MSG_KEX_DH_GEX_REQUEST               30   /* 0x1e */
91 #define SSH2_MSG_KEX_DH_GEX_GROUP                 31   /* 0x1f */
92 #define SSH2_MSG_KEX_DH_GEX_INIT                  32   /* 0x20 */
93 #define SSH2_MSG_KEX_DH_GEX_REPLY                 33   /* 0x21 */
94 #define SSH2_MSG_USERAUTH_REQUEST                 50   /* 0x32 */
95 #define SSH2_MSG_USERAUTH_FAILURE                 51   /* 0x33 */
96 #define SSH2_MSG_USERAUTH_SUCCESS                 52   /* 0x34 */
97 #define SSH2_MSG_USERAUTH_BANNER                  53   /* 0x35 */
98 #define SSH2_MSG_USERAUTH_PK_OK                   60   /* 0x3c */
99 #define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ        60   /* 0x3c */
100 #define SSH2_MSG_GLOBAL_REQUEST                   80   /* 0x50 */
101 #define SSH2_MSG_REQUEST_SUCCESS                  81   /* 0x51 */
102 #define SSH2_MSG_REQUEST_FAILURE                  82   /* 0x52 */
103 #define SSH2_MSG_CHANNEL_OPEN                     90   /* 0x5a */
104 #define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION        91   /* 0x5b */
105 #define SSH2_MSG_CHANNEL_OPEN_FAILURE             92   /* 0x5c */
106 #define SSH2_MSG_CHANNEL_WINDOW_ADJUST            93   /* 0x5d */
107 #define SSH2_MSG_CHANNEL_DATA                     94   /* 0x5e */
108 #define SSH2_MSG_CHANNEL_EXTENDED_DATA            95   /* 0x5f */
109 #define SSH2_MSG_CHANNEL_EOF                      96   /* 0x60 */
110 #define SSH2_MSG_CHANNEL_CLOSE                    97   /* 0x61 */
111 #define SSH2_MSG_CHANNEL_REQUEST                  98   /* 0x62 */
112 #define SSH2_MSG_CHANNEL_SUCCESS                  99   /* 0x63 */
113 #define SSH2_MSG_CHANNEL_FAILURE                  100  /* 0x64 */
114
115 #define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1  /* 0x1 */
116 #define SSH2_DISCONNECT_PROTOCOL_ERROR            2    /* 0x2 */
117 #define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED       3    /* 0x3 */
118 #define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4   /* 0x4 */
119 #define SSH2_DISCONNECT_MAC_ERROR                 5    /* 0x5 */
120 #define SSH2_DISCONNECT_COMPRESSION_ERROR         6    /* 0x6 */
121 #define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE     7    /* 0x7 */
122 #define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 /* 0x8 */
123 #define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE   9    /* 0x9 */
124 #define SSH2_DISCONNECT_CONNECTION_LOST           10   /* 0xa */
125 #define SSH2_DISCONNECT_BY_APPLICATION            11   /* 0xb */
126
127 #define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED     1    /* 0x1 */
128 #define SSH2_OPEN_CONNECT_FAILED                  2    /* 0x2 */
129 #define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE            3    /* 0x3 */
130 #define SSH2_OPEN_RESOURCE_SHORTAGE               4    /* 0x4 */
131
132 #define SSH2_EXTENDED_DATA_STDERR                 1    /* 0x1 */
133
134 #define GET_32BIT(cp) \
135     (((unsigned long)(unsigned char)(cp)[0] << 24) | \
136     ((unsigned long)(unsigned char)(cp)[1] << 16) | \
137     ((unsigned long)(unsigned char)(cp)[2] << 8) | \
138     ((unsigned long)(unsigned char)(cp)[3]))
139
140 #define PUT_32BIT(cp, value) { \
141     (cp)[0] = (unsigned char)((value) >> 24); \
142     (cp)[1] = (unsigned char)((value) >> 16); \
143     (cp)[2] = (unsigned char)((value) >> 8); \
144     (cp)[3] = (unsigned char)(value); }
145
146 enum { PKT_END, PKT_INT, PKT_CHAR, PKT_DATA, PKT_STR, PKT_BIGNUM };
147
148 /* Coroutine mechanics for the sillier bits of the code */
149 #define crBegin1        static int crLine = 0;
150 #define crBegin2        switch(crLine) { case 0:;
151 #define crBegin         crBegin1; crBegin2;
152 #define crFinish(z)     } crLine = 0; return (z)
153 #define crFinishV       } crLine = 0; return
154 #define crReturn(z)     \
155         do {\
156             crLine=__LINE__; return (z); case __LINE__:;\
157         } while (0)
158 #define crReturnV       \
159         do {\
160             crLine=__LINE__; return; case __LINE__:;\
161         } while (0)
162 #define crStop(z)       do{ crLine = 0; return (z); }while(0)
163 #define crStopV         do{ crLine = 0; return; }while(0)
164 #define crWaitUntil(c)  do { crReturn(0); } while (!(c))
165 #define crWaitUntilV(c) do { crReturnV; } while (!(c))
166
167 extern const struct ssh_cipher ssh_3des;
168 extern const struct ssh_cipher ssh_3des_ssh2;
169 extern const struct ssh_cipher ssh_des;
170 extern const struct ssh_cipher ssh_aes128_ssh2;
171 extern const struct ssh_cipher ssh_aes192_ssh2;
172 extern const struct ssh_cipher ssh_aes256_ssh2;
173 extern const struct ssh_cipher ssh_blowfish_ssh1;
174 extern const struct ssh_cipher ssh_blowfish_ssh2;
175
176 extern char *x11_init (Socket *, char *, void *);
177 extern void x11_close (Socket);
178 extern void x11_send  (Socket , char *, int);
179 extern void x11_invent_auth(char *, int, char *, int);
180
181 /*
182  * Ciphers for SSH2. We miss out single-DES because it isn't
183  * supported; also 3DES and Blowfish are both done differently from
184  * SSH1. (3DES uses outer chaining; Blowfish has the opposite
185  * endianness and different-sized keys.)
186  */
187 const static struct ssh_cipher *ciphers[] = {
188     &ssh_aes256_ssh2,
189     &ssh_aes192_ssh2,
190     &ssh_aes128_ssh2,
191     &ssh_blowfish_ssh2,
192     &ssh_3des_ssh2
193 };
194
195 extern const struct ssh_kex ssh_diffiehellman;
196 extern const struct ssh_kex ssh_diffiehellman_gex;
197 const static struct ssh_kex *kex_algs[] = {
198 #ifdef DO_DIFFIE_HELLMAN_GEX
199     &ssh_diffiehellman_gex,
200 #endif
201     &ssh_diffiehellman };
202
203 extern const struct ssh_signkey ssh_dss;
204 const static struct ssh_signkey *hostkey_algs[] = { &ssh_dss };
205
206 extern const struct ssh_mac ssh_md5, ssh_sha1, ssh_sha1_buggy;
207
208 static void nullmac_key(unsigned char *key) { }
209 static void nullmac_generate(unsigned char *blk, int len, unsigned long seq) { }
210 static int nullmac_verify(unsigned char *blk, int len, unsigned long seq) { return 1; }
211 const static struct ssh_mac ssh_mac_none = {
212     nullmac_key, nullmac_key, nullmac_generate, nullmac_verify, "none", 0
213 };
214 const static struct ssh_mac *macs[] = {
215     &ssh_sha1, &ssh_md5, &ssh_mac_none };
216 const static struct ssh_mac *buggymacs[] = {
217     &ssh_sha1_buggy, &ssh_md5, &ssh_mac_none };
218
219 static void ssh_comp_none_init(void) { }
220 static int ssh_comp_none_block(unsigned char *block, int len,
221                                unsigned char **outblock, int *outlen) {
222     return 0;
223 }
224 const static struct ssh_compress ssh_comp_none = {
225     "none",
226     ssh_comp_none_init, ssh_comp_none_block,
227     ssh_comp_none_init, ssh_comp_none_block
228 };
229 extern const struct ssh_compress ssh_zlib;
230 const static struct ssh_compress *compressions[] = {
231     &ssh_zlib, &ssh_comp_none };
232
233 enum {                                 /* channel types */
234     CHAN_MAINSESSION,
235     CHAN_X11,
236     CHAN_AGENT,
237 };
238
239 /*
240  * 2-3-4 tree storing channels.
241  */
242 struct ssh_channel {
243     unsigned remoteid, localid;
244     int type;
245     int closes;
246     struct ssh2_data_channel {
247         unsigned char *outbuffer;
248         unsigned outbuflen, outbufsize;
249         unsigned remwindow, remmaxpkt;
250     } v2;
251     union {
252         struct ssh_agent_channel {
253             unsigned char *message;
254             unsigned char msglen[4];
255             int lensofar, totallen;
256         } a;
257         struct ssh_x11_channel {
258             Socket s;
259         } x11;
260     } u;
261 };
262
263 struct Packet {
264     long length;
265     int type;
266     unsigned char *data;
267     unsigned char *body;
268     long savedpos;
269     long maxlen;
270 };
271
272 static SHA_State exhash, exhashbase;
273
274 static Socket s = NULL;
275
276 static unsigned char session_key[32];
277 static int ssh1_compressing;
278 static int ssh_agentfwd_enabled;
279 static int ssh_X11_fwd_enabled;
280 static const struct ssh_cipher *cipher = NULL;
281 static const struct ssh_cipher *cscipher = NULL;
282 static const struct ssh_cipher *sccipher = NULL;
283 static const struct ssh_mac *csmac = NULL;
284 static const struct ssh_mac *scmac = NULL;
285 static const struct ssh_compress *cscomp = NULL;
286 static const struct ssh_compress *sccomp = NULL;
287 static const struct ssh_kex *kex = NULL;
288 static const struct ssh_signkey *hostkey = NULL;
289 int (*ssh_get_password)(const char *prompt, char *str, int maxlen) = NULL;
290
291 static char *savedhost;
292 static int savedport;
293 static int ssh_send_ok;
294 static int ssh_echoing, ssh_editing;
295
296 static tree234 *ssh_channels;           /* indexed by local id */
297 static struct ssh_channel *mainchan;   /* primary session channel */
298
299 static enum {
300     SSH_STATE_PREPACKET,
301     SSH_STATE_BEFORE_SIZE,
302     SSH_STATE_INTERMED,
303     SSH_STATE_SESSION,
304     SSH_STATE_CLOSED
305 } ssh_state = SSH_STATE_PREPACKET;
306
307 static int size_needed = FALSE, eof_needed = FALSE;
308
309 static struct Packet pktin = { 0, 0, NULL, NULL, 0 };
310 static struct Packet pktout = { 0, 0, NULL, NULL, 0 };
311 static unsigned char *deferred_send_data = NULL;
312 static int deferred_len = 0, deferred_size = 0;
313
314 static int ssh_version;
315 static void (*ssh_protocol)(unsigned char *in, int inlen, int ispkt);
316 static void ssh1_protocol(unsigned char *in, int inlen, int ispkt);
317 static void ssh2_protocol(unsigned char *in, int inlen, int ispkt);
318 static void ssh_size(void);
319 static void ssh_special (Telnet_Special);
320 static void ssh2_try_send(struct ssh_channel *c);
321 static void ssh2_add_channel_data(struct ssh_channel *c, char *buf, int len);
322
323 static int (*s_rdpkt)(unsigned char **data, int *datalen);
324
325 static struct rdpkt1_state_tag {
326     long len, pad, biglen, to_read;
327     unsigned long realcrc, gotcrc;
328     unsigned char *p;
329     int i;
330     int chunk;
331 } rdpkt1_state;
332
333 static struct rdpkt2_state_tag {
334     long len, pad, payload, packetlen, maclen;
335     int i;
336     int cipherblk;
337     unsigned long incoming_sequence;
338 } rdpkt2_state;
339
340 static int ssh_channelcmp(void *av, void *bv) {
341     struct ssh_channel *a = (struct ssh_channel *)av;
342     struct ssh_channel *b = (struct ssh_channel *)bv;
343     if (a->localid < b->localid) return -1;
344     if (a->localid > b->localid) return +1;
345     return 0;
346 }
347 static int ssh_channelfind(void *av, void *bv) {
348     unsigned *a = (unsigned *)av;
349     struct ssh_channel *b = (struct ssh_channel *)bv;
350     if (*a < b->localid) return -1;
351     if (*a > b->localid) return +1;
352     return 0;
353 }
354
355 static void c_write (char *buf, int len) {
356     if ((flags & FLAG_STDERR)) {
357         int i;
358         for (i = 0; i < len; i++)
359             if (buf[i] != '\r')
360                 fputc(buf[i], stderr);
361         return;
362     }
363     from_backend(1, buf, len);
364 }
365
366 /*
367  * Collect incoming data in the incoming packet buffer.
368  * Decipher and verify the packet when it is completely read.
369  * Drop SSH1_MSG_DEBUG and SSH1_MSG_IGNORE packets.
370  * Update the *data and *datalen variables.
371  * Return the additional nr of bytes needed, or 0 when
372  * a complete packet is available.
373  */
374 static int ssh1_rdpkt(unsigned char **data, int *datalen)
375 {
376     struct rdpkt1_state_tag *st = &rdpkt1_state;
377
378     crBegin;
379
380 next_packet:
381
382     pktin.type = 0;
383     pktin.length = 0;
384
385     for (st->i = st->len = 0; st->i < 4; st->i++) {
386         while ((*datalen) == 0)
387             crReturn(4-st->i);
388         st->len = (st->len << 8) + **data;
389         (*data)++, (*datalen)--;
390     }
391
392 #ifdef FWHACK
393     if (st->len == 0x52656d6f) {        /* "Remo"te server has closed ... */
394         st->len = 0x300;                /* big enough to carry to end */
395     }
396 #endif
397
398     st->pad = 8 - (st->len % 8);
399     st->biglen = st->len + st->pad;
400     pktin.length = st->len - 5;
401
402     if (pktin.maxlen < st->biglen) {
403         pktin.maxlen = st->biglen;
404         pktin.data = (pktin.data == NULL ? smalloc(st->biglen+APIEXTRA) :
405                       srealloc(pktin.data, st->biglen+APIEXTRA));
406         if (!pktin.data)
407             fatalbox("Out of memory");
408     }
409
410     st->to_read = st->biglen;
411     st->p = pktin.data;
412     while (st->to_read > 0) {
413         st->chunk = st->to_read;
414         while ((*datalen) == 0)
415             crReturn(st->to_read);
416         if (st->chunk > (*datalen))
417             st->chunk = (*datalen);
418         memcpy(st->p, *data, st->chunk);
419         *data += st->chunk;
420         *datalen -= st->chunk;
421         st->p += st->chunk;
422         st->to_read -= st->chunk;
423     }
424
425     if (cipher)
426         cipher->decrypt(pktin.data, st->biglen);
427 #if 0
428     debug(("Got packet len=%d pad=%d\r\n", st->len, st->pad));
429     for (st->i = 0; st->i < st->biglen; st->i++)
430         debug(("  %02x", (unsigned char)pktin.data[st->i]));
431     debug(("\r\n"));
432 #endif
433
434     st->realcrc = crc32(pktin.data, st->biglen-4);
435     st->gotcrc = GET_32BIT(pktin.data+st->biglen-4);
436     if (st->gotcrc != st->realcrc) {
437         bombout(("Incorrect CRC received on packet"));
438         crReturn(0);
439     }
440
441     pktin.body = pktin.data + st->pad + 1;
442
443     if (ssh1_compressing) {
444         unsigned char *decompblk;
445         int decomplen;
446 #if 0
447         int i;
448         debug(("Packet payload pre-decompression:\n"));
449         for (i = -1; i < pktin.length; i++)
450             debug(("  %02x", (unsigned char)pktin.body[i]));
451         debug(("\r\n"));
452 #endif
453         zlib_decompress_block(pktin.body-1, pktin.length+1,
454                               &decompblk, &decomplen);
455
456         if (pktin.maxlen < st->pad + decomplen) {
457             pktin.maxlen = st->pad + decomplen;
458             pktin.data = srealloc(pktin.data, pktin.maxlen+APIEXTRA);
459             pktin.body = pktin.data + st->pad + 1;
460             if (!pktin.data)
461                 fatalbox("Out of memory");
462         }
463
464         memcpy(pktin.body-1, decompblk, decomplen);
465         sfree(decompblk);
466         pktin.length = decomplen-1;
467 #if 0
468         debug(("Packet payload post-decompression:\n"));
469         for (i = -1; i < pktin.length; i++)
470             debug(("  %02x", (unsigned char)pktin.body[i]));
471         debug(("\r\n"));
472 #endif
473     }
474
475     if (pktin.type == SSH1_SMSG_STDOUT_DATA ||
476         pktin.type == SSH1_SMSG_STDERR_DATA ||
477         pktin.type == SSH1_MSG_DEBUG ||
478         pktin.type == SSH1_SMSG_AUTH_TIS_CHALLENGE ||
479         pktin.type == SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
480         long strlen = GET_32BIT(pktin.body);
481         if (strlen + 4 != pktin.length) {
482             bombout(("Received data packet with bogus string length"));
483             crReturn(0);
484         }
485     }
486
487     pktin.type = pktin.body[-1];
488
489     if (pktin.type == SSH1_MSG_DEBUG) {
490         /* log debug message */
491         char buf[80];
492         int strlen = GET_32BIT(pktin.body);
493         strcpy(buf, "Remote: ");
494         if (strlen > 70) strlen = 70;
495         memcpy(buf+8, pktin.body+4, strlen);
496         buf[8+strlen] = '\0';
497         logevent(buf);
498         goto next_packet;
499     } else if (pktin.type == SSH1_MSG_IGNORE) {
500         /* do nothing */
501         goto next_packet;
502     }
503
504     crFinish(0);
505 }
506
507 static int ssh2_rdpkt(unsigned char **data, int *datalen)
508 {
509     struct rdpkt2_state_tag *st = &rdpkt2_state;
510
511     crBegin;
512
513 next_packet:
514     pktin.type = 0;
515     pktin.length = 0;
516     if (sccipher)
517         st->cipherblk = sccipher->blksize;
518     else
519         st->cipherblk = 8;
520     if (st->cipherblk < 8)
521         st->cipherblk = 8;
522
523     if (pktin.maxlen < st->cipherblk) {
524         pktin.maxlen = st->cipherblk;
525         pktin.data = (pktin.data == NULL ? smalloc(st->cipherblk+APIEXTRA) :
526                       srealloc(pktin.data, st->cipherblk+APIEXTRA));
527         if (!pktin.data)
528             fatalbox("Out of memory");
529     }
530
531     /*
532      * Acquire and decrypt the first block of the packet. This will
533      * contain the length and padding details.
534      */
535      for (st->i = st->len = 0; st->i < st->cipherblk; st->i++) {
536         while ((*datalen) == 0)
537             crReturn(st->cipherblk-st->i);
538         pktin.data[st->i] = *(*data)++;
539         (*datalen)--;
540     }
541 #ifdef FWHACK
542     if (!memcmp(pktin.data, "Remo", 4)) {/* "Remo"te server has closed ... */
543         /* FIXME */
544     }
545 #endif
546     if (sccipher)
547         sccipher->decrypt(pktin.data, st->cipherblk);
548
549     /*
550      * Now get the length and padding figures.
551      */
552     st->len = GET_32BIT(pktin.data);
553     st->pad = pktin.data[4];
554
555     /*
556      * This enables us to deduce the payload length.
557      */
558     st->payload = st->len - st->pad - 1;
559
560     pktin.length = st->payload + 5;
561
562     /*
563      * So now we can work out the total packet length.
564      */
565     st->packetlen = st->len + 4;
566     st->maclen = scmac ? scmac->len : 0;
567
568     /*
569      * Adjust memory allocation if packet is too big.
570      */
571     if (pktin.maxlen < st->packetlen+st->maclen) {
572         pktin.maxlen = st->packetlen+st->maclen;
573         pktin.data = (pktin.data == NULL ? smalloc(pktin.maxlen+APIEXTRA) :
574                       srealloc(pktin.data, pktin.maxlen+APIEXTRA));
575         if (!pktin.data)
576             fatalbox("Out of memory");
577     }
578
579     /*
580      * Read and decrypt the remainder of the packet.
581      */
582     for (st->i = st->cipherblk; st->i < st->packetlen + st->maclen; st->i++) {
583         while ((*datalen) == 0)
584             crReturn(st->packetlen + st->maclen - st->i);
585         pktin.data[st->i] = *(*data)++;
586         (*datalen)--;
587     }
588     /* Decrypt everything _except_ the MAC. */
589     if (sccipher)
590         sccipher->decrypt(pktin.data + st->cipherblk,
591                           st->packetlen - st->cipherblk);
592
593 #if 0
594     debug(("Got packet len=%d pad=%d\r\n", st->len, st->pad));
595     for (st->i = 0; st->i < st->packetlen; st->i++)
596         debug(("  %02x", (unsigned char)pktin.data[st->i]));
597     debug(("\r\n"));
598 #endif
599
600     /*
601      * Check the MAC.
602      */
603     if (scmac && !scmac->verify(pktin.data, st->len+4, st->incoming_sequence)) {
604         bombout(("Incorrect MAC received on packet"));
605         crReturn(0);
606     }
607     st->incoming_sequence++;               /* whether or not we MACed */
608
609     /*
610      * Decompress packet payload.
611      */
612     {
613         unsigned char *newpayload;
614         int newlen;
615         if (sccomp && sccomp->decompress(pktin.data+5, pktin.length-5,
616                                          &newpayload, &newlen)) {
617             if (pktin.maxlen < newlen+5) {
618                 pktin.maxlen = newlen+5;
619                 pktin.data = (pktin.data == NULL ? smalloc(pktin.maxlen+APIEXTRA) :
620                               srealloc(pktin.data, pktin.maxlen+APIEXTRA));
621                 if (!pktin.data)
622                     fatalbox("Out of memory");
623             }
624             pktin.length = 5 + newlen;
625             memcpy(pktin.data+5, newpayload, newlen);
626 #if 0
627             debug(("Post-decompression payload:\r\n"));
628             for (st->i = 0; st->i < newlen; st->i++)
629                 debug(("  %02x", (unsigned char)pktin.data[5+st->i]));
630             debug(("\r\n"));
631 #endif
632
633             sfree(newpayload);
634         }
635     }
636
637     pktin.savedpos = 6;
638     pktin.type = pktin.data[5];
639
640     if (pktin.type == SSH2_MSG_IGNORE || pktin.type == SSH2_MSG_DEBUG)
641         goto next_packet;              /* FIXME: print DEBUG message */
642
643     crFinish(0);
644 }
645
646 static void ssh1_pktout_size(int len) {
647     int pad, biglen;
648
649     len += 5;                          /* type and CRC */
650     pad = 8 - (len%8);
651     biglen = len + pad;
652
653     pktout.length = len-5;
654     if (pktout.maxlen < biglen) {
655         pktout.maxlen = biglen;
656 #ifdef MSCRYPTOAPI
657         /* Allocate enough buffer space for extra block
658          * for MS CryptEncrypt() */
659         pktout.data = (pktout.data == NULL ? smalloc(biglen+12) :
660                        srealloc(pktout.data, biglen+12));
661 #else
662         pktout.data = (pktout.data == NULL ? smalloc(biglen+4) :
663                        srealloc(pktout.data, biglen+4));
664 #endif
665         if (!pktout.data)
666             fatalbox("Out of memory");
667     }
668     pktout.body = pktout.data+4+pad+1;
669 }
670
671 static void s_wrpkt_start(int type, int len) {
672     ssh1_pktout_size(len);
673     pktout.type = type;
674 }
675
676 static void s_wrpkt(void) {
677     int pad, len, biglen, i;
678     unsigned long crc;
679
680     pktout.body[-1] = pktout.type;
681
682     if (ssh1_compressing) {
683         unsigned char *compblk;
684         int complen;
685 #if 0
686         debug(("Packet payload pre-compression:\n"));
687         for (i = -1; i < pktout.length; i++)
688             debug(("  %02x", (unsigned char)pktout.body[i]));
689         debug(("\r\n"));
690 #endif
691         zlib_compress_block(pktout.body-1, pktout.length+1,
692                             &compblk, &complen);
693         ssh1_pktout_size(complen-1);
694         memcpy(pktout.body-1, compblk, complen);
695         sfree(compblk);
696 #if 0
697         debug(("Packet payload post-compression:\n"));
698         for (i = -1; i < pktout.length; i++)
699             debug(("  %02x", (unsigned char)pktout.body[i]));
700         debug(("\r\n"));
701 #endif
702     }
703
704     len = pktout.length + 5;           /* type and CRC */
705     pad = 8 - (len%8);
706     biglen = len + pad;
707
708     for (i=0; i<pad; i++)
709         pktout.data[i+4] = random_byte();
710     crc = crc32(pktout.data+4, biglen-4);
711     PUT_32BIT(pktout.data+biglen, crc);
712     PUT_32BIT(pktout.data, len);
713
714 #if 0
715     debug(("Sending packet len=%d\r\n", biglen+4));
716     for (i = 0; i < biglen+4; i++)
717         debug(("  %02x", (unsigned char)pktout.data[i]));
718     debug(("\r\n"));
719 #endif
720     if (cipher)
721         cipher->encrypt(pktout.data+4, biglen);
722
723     sk_write(s, pktout.data, biglen+4);
724 }
725
726 /*
727  * Construct a packet with the specified contents and
728  * send it to the server.
729  */
730 static void send_packet(int pkttype, ...)
731 {
732     va_list args;
733     unsigned char *p, *argp, argchar;
734     unsigned long argint;
735     int pktlen, argtype, arglen;
736     Bignum bn;
737
738     pktlen = 0;
739     va_start(args, pkttype);
740     while ((argtype = va_arg(args, int)) != PKT_END) {
741         switch (argtype) {
742           case PKT_INT:
743             (void) va_arg(args, int);
744             pktlen += 4;
745             break;
746           case PKT_CHAR:
747             (void) va_arg(args, char);
748             pktlen++;
749             break;
750           case PKT_DATA:
751             (void) va_arg(args, unsigned char *);
752             arglen = va_arg(args, int);
753             pktlen += arglen;
754             break;
755           case PKT_STR:
756             argp = va_arg(args, unsigned char *);
757             arglen = strlen(argp);
758             pktlen += 4 + arglen;
759             break;
760           case PKT_BIGNUM:
761             bn = va_arg(args, Bignum);
762             pktlen += ssh1_bignum_length(bn);
763             break;
764           default:
765             assert(0);
766         }
767     }
768     va_end(args);
769
770     s_wrpkt_start(pkttype, pktlen);
771     p = pktout.body;
772
773     va_start(args, pkttype);
774     while ((argtype = va_arg(args, int)) != PKT_END) {
775         switch (argtype) {
776           case PKT_INT:
777             argint = va_arg(args, int);
778             PUT_32BIT(p, argint);
779             p += 4;
780             break;
781           case PKT_CHAR:
782             argchar = va_arg(args, unsigned char);
783             *p = argchar;
784             p++;
785             break;
786           case PKT_DATA:
787             argp = va_arg(args, unsigned char *);
788             arglen = va_arg(args, int);
789             memcpy(p, argp, arglen);
790             p += arglen;
791             break;
792           case PKT_STR:
793             argp = va_arg(args, unsigned char *);
794             arglen = strlen(argp);
795             PUT_32BIT(p, arglen);
796             memcpy(p + 4, argp, arglen);
797             p += 4 + arglen;
798             break;
799           case PKT_BIGNUM:
800             bn = va_arg(args, Bignum);
801             p += ssh1_write_bignum(p, bn);
802             break;
803         }
804     }
805     va_end(args);
806
807     s_wrpkt();
808 }
809
810 static int ssh_versioncmp(char *a, char *b) {
811     char *ae, *be;
812     unsigned long av, bv;
813
814     av = strtoul(a, &ae, 10);
815     bv = strtoul(b, &be, 10);
816     if (av != bv) return (av < bv ? -1 : +1);
817     if (*ae == '.') ae++;
818     if (*be == '.') be++;
819     av = strtoul(ae, &ae, 10);
820     bv = strtoul(be, &be, 10);
821     if (av != bv) return (av < bv ? -1 : +1);
822     return 0;
823 }
824
825
826 /*
827  * Utility routines for putting an SSH-protocol `string' and
828  * `uint32' into a SHA state.
829  */
830 #include <stdio.h>
831 static void sha_string(SHA_State *s, void *str, int len) {
832     unsigned char lenblk[4];
833     PUT_32BIT(lenblk, len);
834     SHA_Bytes(s, lenblk, 4);
835     SHA_Bytes(s, str, len);
836 }
837
838 static void sha_uint32(SHA_State *s, unsigned i) {
839     unsigned char intblk[4];
840     PUT_32BIT(intblk, i);
841     SHA_Bytes(s, intblk, 4);
842 }
843
844 /*
845  * SSH2 packet construction functions.
846  */
847 static void ssh2_pkt_ensure(int length) {
848     if (pktout.maxlen < length) {
849         pktout.maxlen = length + 256;
850         pktout.data = (pktout.data == NULL ? smalloc(pktout.maxlen+APIEXTRA) :
851                        srealloc(pktout.data, pktout.maxlen+APIEXTRA));
852         if (!pktout.data)
853             fatalbox("Out of memory");
854     }
855 }
856 static void ssh2_pkt_adddata(void *data, int len) {
857     pktout.length += len;
858     ssh2_pkt_ensure(pktout.length);
859     memcpy(pktout.data+pktout.length-len, data, len);
860 }
861 static void ssh2_pkt_addbyte(unsigned char byte) {
862     ssh2_pkt_adddata(&byte, 1);
863 }
864 static void ssh2_pkt_init(int pkt_type) {
865     pktout.length = 5;
866     ssh2_pkt_addbyte((unsigned char)pkt_type);
867 }
868 static void ssh2_pkt_addbool(unsigned char value) {
869     ssh2_pkt_adddata(&value, 1);
870 }
871 static void ssh2_pkt_adduint32(unsigned long value) {
872     unsigned char x[4];
873     PUT_32BIT(x, value);
874     ssh2_pkt_adddata(x, 4);
875 }
876 static void ssh2_pkt_addstring_start(void) {
877     ssh2_pkt_adduint32(0);
878     pktout.savedpos = pktout.length;
879 }
880 static void ssh2_pkt_addstring_str(char *data) {
881     ssh2_pkt_adddata(data, strlen(data));
882     PUT_32BIT(pktout.data + pktout.savedpos - 4,
883               pktout.length - pktout.savedpos);
884 }
885 static void ssh2_pkt_addstring_data(char *data, int len) {
886     ssh2_pkt_adddata(data, len);
887     PUT_32BIT(pktout.data + pktout.savedpos - 4,
888               pktout.length - pktout.savedpos);
889 }
890 static void ssh2_pkt_addstring(char *data) {
891     ssh2_pkt_addstring_start();
892     ssh2_pkt_addstring_str(data);
893 }
894 static char *ssh2_mpint_fmt(Bignum b, int *len) {
895     unsigned char *p;
896     int i, n = (ssh1_bignum_bitcount(b)+7)/8;
897     p = smalloc(n + 1);
898     if (!p)
899         fatalbox("out of memory");
900     p[0] = 0;
901     for (i = 1; i <= n; i++)
902         p[i] = bignum_byte(b, n-i);
903     i = 0;
904     while (i <= n && p[i] == 0 && (p[i+1] & 0x80) == 0)
905         i++;
906     memmove(p, p+i, n+1-i);
907     *len = n+1-i;
908     return p;
909 }
910 static void ssh2_pkt_addmp(Bignum b) {
911     unsigned char *p;
912     int len;
913     p = ssh2_mpint_fmt(b, &len);
914     ssh2_pkt_addstring_start();
915     ssh2_pkt_addstring_data(p, len);
916     sfree(p);
917 }
918
919 /*
920  * Construct an SSH2 final-form packet: compress it, encrypt it,
921  * put the MAC on it. Final packet, ready to be sent, is stored in
922  * pktout.data. Total length is returned.
923  */
924 static int ssh2_pkt_construct(void) {
925     int cipherblk, maclen, padding, i;
926     static unsigned long outgoing_sequence = 0;
927
928     /*
929      * Compress packet payload.
930      */
931 #if 0
932     debug(("Pre-compression payload:\r\n"));
933     for (i = 5; i < pktout.length; i++)
934         debug(("  %02x", (unsigned char)pktout.data[i]));
935     debug(("\r\n"));
936 #endif
937     {
938         unsigned char *newpayload;
939         int newlen;
940         if (cscomp && cscomp->compress(pktout.data+5, pktout.length-5,
941                                        &newpayload, &newlen)) {
942             pktout.length = 5;
943             ssh2_pkt_adddata(newpayload, newlen);
944             sfree(newpayload);
945         }
946     }
947
948     /*
949      * Add padding. At least four bytes, and must also bring total
950      * length (minus MAC) up to a multiple of the block size.
951      */
952     cipherblk = cscipher ? cscipher->blksize : 8;   /* block size */
953     cipherblk = cipherblk < 8 ? 8 : cipherblk;   /* or 8 if blksize < 8 */
954     padding = 4;
955     padding += (cipherblk - (pktout.length + padding) % cipherblk) % cipherblk;
956     maclen = csmac ? csmac->len : 0;
957     ssh2_pkt_ensure(pktout.length + padding + maclen);
958     pktout.data[4] = padding;
959     for (i = 0; i < padding; i++)
960         pktout.data[pktout.length + i] = random_byte();
961     PUT_32BIT(pktout.data, pktout.length + padding - 4);
962     if (csmac)
963         csmac->generate(pktout.data, pktout.length + padding,
964                         outgoing_sequence);
965     outgoing_sequence++;               /* whether or not we MACed */
966
967 #if 0
968     debug(("Sending packet len=%d\r\n", pktout.length+padding));
969     for (i = 0; i < pktout.length+padding; i++)
970         debug(("  %02x", (unsigned char)pktout.data[i]));
971     debug(("\r\n"));
972 #endif
973
974     if (cscipher)
975         cscipher->encrypt(pktout.data, pktout.length + padding);
976
977     /* Ready-to-send packet starts at pktout.data. We return length. */
978     return pktout.length + padding + maclen;
979 }
980
981 /*
982  * Construct and send an SSH2 packet immediately.
983  */
984 static void ssh2_pkt_send(void) {
985     int len = ssh2_pkt_construct();
986     sk_write(s, pktout.data, len);
987 }
988
989 /*
990  * Construct an SSH2 packet and add it to a deferred data block.
991  * Useful for sending multiple packets in a single sk_write() call,
992  * to prevent a traffic-analysing listener from being able to work
993  * out the length of any particular packet (such as the password
994  * packet).
995  * 
996  * Note that because SSH2 sequence-numbers its packets, this can
997  * NOT be used as an m4-style `defer' allowing packets to be
998  * constructed in one order and sent in another.
999  */
1000 static void ssh2_pkt_defer(void) {
1001     int len = ssh2_pkt_construct();
1002     if (deferred_len + len > deferred_size) {
1003         deferred_size = deferred_len + len + 128;
1004         deferred_send_data = srealloc(deferred_send_data, deferred_size);
1005     }
1006     memcpy(deferred_send_data+deferred_len, pktout.data, len);
1007     deferred_len += len;
1008 }
1009
1010 /*
1011  * Send the whole deferred data block constructed by
1012  * ssh2_pkt_defer().
1013  */
1014 static void ssh2_pkt_defersend(void) {
1015     sk_write(s, deferred_send_data, deferred_len);
1016     deferred_len = deferred_size = 0;
1017     sfree(deferred_send_data);
1018     deferred_send_data = NULL;
1019 }
1020
1021 #if 0
1022 void bndebug(char *string, Bignum b) {
1023     unsigned char *p;
1024     int i, len;
1025     p = ssh2_mpint_fmt(b, &len);
1026     debug(("%s", string));
1027     for (i = 0; i < len; i++)
1028         debug((" %02x", p[i]));
1029     debug(("\r\n"));
1030     sfree(p);
1031 }
1032 #endif
1033
1034 static void sha_mpint(SHA_State *s, Bignum b) {
1035     unsigned char *p;
1036     int len;
1037     p = ssh2_mpint_fmt(b, &len);
1038     sha_string(s, p, len);
1039     sfree(p);
1040 }
1041
1042 /*
1043  * SSH2 packet decode functions.
1044  */
1045 static unsigned long ssh2_pkt_getuint32(void) {
1046     unsigned long value;
1047     if (pktin.length - pktin.savedpos < 4)
1048         return 0;                      /* arrgh, no way to decline (FIXME?) */
1049     value = GET_32BIT(pktin.data+pktin.savedpos);
1050     pktin.savedpos += 4;
1051     return value;
1052 }
1053 static void ssh2_pkt_getstring(char **p, int *length) {
1054     *p = NULL;
1055     if (pktin.length - pktin.savedpos < 4)
1056         return;
1057     *length = GET_32BIT(pktin.data+pktin.savedpos);
1058     pktin.savedpos += 4;
1059     if (pktin.length - pktin.savedpos < *length)
1060         return;
1061     *p = pktin.data+pktin.savedpos;
1062     pktin.savedpos += *length;
1063 }
1064 static Bignum ssh2_pkt_getmp(void) {
1065     char *p;
1066     int length;
1067     Bignum b;
1068
1069     ssh2_pkt_getstring(&p, &length);
1070     if (!p)
1071         return NULL;
1072     if (p[0] & 0x80) {
1073         bombout(("internal error: Can't handle negative mpints"));
1074         return NULL;
1075     }
1076     b = bignum_from_bytes(p, length);
1077     return b;
1078 }
1079
1080 static int do_ssh_init(unsigned char c) {
1081     static char *vsp;
1082     static char version[10];
1083     static char vstring[80];
1084     static char vlog[sizeof(vstring)+20];
1085     static int i;
1086
1087     crBegin;
1088
1089     /* Search for the string "SSH-" in the input. */
1090     i = 0;
1091     while (1) {
1092         static const int transS[] = { 1, 2, 2, 1 };
1093         static const int transH[] = { 0, 0, 3, 0 };
1094         static const int transminus[] = { 0, 0, 0, -1 };
1095         if (c == 'S') i = transS[i];
1096         else if (c == 'H') i = transH[i];
1097         else if (c == '-') i = transminus[i];
1098         else i = 0;
1099         if (i < 0)
1100             break;
1101         crReturn(1);                   /* get another character */
1102     }
1103
1104     strcpy(vstring, "SSH-");
1105     vsp = vstring+4;
1106     i = 0;
1107     while (1) {
1108         crReturn(1);                   /* get another char */
1109         if (vsp < vstring+sizeof(vstring)-1)
1110             *vsp++ = c;
1111         if (i >= 0) {
1112             if (c == '-') {
1113                 version[i] = '\0';
1114                 i = -1;
1115             } else if (i < sizeof(version)-1)
1116                 version[i++] = c;
1117         }
1118         else if (c == '\n')
1119             break;
1120     }
1121
1122     ssh_agentfwd_enabled = FALSE;
1123     rdpkt2_state.incoming_sequence = 0;
1124
1125     *vsp = 0;
1126     sprintf(vlog, "Server version: %s", vstring);
1127     vlog[strcspn(vlog, "\r\n")] = '\0';
1128     logevent(vlog);
1129
1130     /*
1131      * Server version "1.99" means we can choose whether we use v1
1132      * or v2 protocol. Choice is based on cfg.sshprot.
1133      */
1134     if (ssh_versioncmp(version, cfg.sshprot == 1 ? "2.0" : "1.99") >= 0) {
1135         /*
1136          * This is a v2 server. Begin v2 protocol.
1137          */
1138         char *verstring = "SSH-2.0-PuTTY";
1139         SHA_Init(&exhashbase);
1140         /*
1141          * Hash our version string and their version string.
1142          */
1143         sha_string(&exhashbase, verstring, strlen(verstring));
1144         sha_string(&exhashbase, vstring, strcspn(vstring, "\r\n"));
1145         sprintf(vstring, "%s\n", verstring);
1146         sprintf(vlog, "We claim version: %s", verstring);
1147         logevent(vlog);
1148         logevent("Using SSH protocol version 2");
1149         sk_write(s, vstring, strlen(vstring));
1150         ssh_protocol = ssh2_protocol;
1151         ssh_version = 2;
1152         s_rdpkt = ssh2_rdpkt;
1153     } else {
1154         /*
1155          * This is a v1 server. Begin v1 protocol.
1156          */
1157         sprintf(vstring, "SSH-%s-PuTTY\n",
1158                 (ssh_versioncmp(version, "1.5") <= 0 ? version : "1.5"));
1159         sprintf(vlog, "We claim version: %s", vstring);
1160         vlog[strcspn(vlog, "\r\n")] = '\0';
1161         logevent(vlog);
1162         logevent("Using SSH protocol version 1");
1163         sk_write(s, vstring, strlen(vstring));
1164         ssh_protocol = ssh1_protocol;
1165         ssh_version = 1;
1166         s_rdpkt = ssh1_rdpkt;
1167     }
1168     ssh_state = SSH_STATE_BEFORE_SIZE;
1169
1170     crFinish(0);
1171 }
1172
1173 static void ssh_gotdata(unsigned char *data, int datalen)
1174 {
1175     crBegin;
1176
1177     /*
1178      * To begin with, feed the characters one by one to the
1179      * protocol initialisation / selection function do_ssh_init().
1180      * When that returns 0, we're done with the initial greeting
1181      * exchange and can move on to packet discipline.
1182      */
1183     while (1) {
1184         int ret;
1185         if (datalen == 0)
1186             crReturnV;                 /* more data please */
1187         ret = do_ssh_init(*data);
1188         data++; datalen--;
1189         if (ret == 0)
1190             break;
1191     }
1192
1193     /*
1194      * We emerge from that loop when the initial negotiation is
1195      * over and we have selected an s_rdpkt function. Now pass
1196      * everything to s_rdpkt, and then pass the resulting packets
1197      * to the proper protocol handler.
1198      */
1199     if (datalen == 0)
1200         crReturnV;
1201     while (1) {
1202         while (datalen > 0) {
1203             if ( s_rdpkt(&data, &datalen) == 0 ) {
1204                 ssh_protocol(NULL, 0, 1);
1205                 if (ssh_state == SSH_STATE_CLOSED) {
1206                     return;
1207                 }
1208             }
1209         }
1210         crReturnV;
1211     }
1212     crFinishV;
1213 }
1214
1215 static int ssh_receive(Socket skt, int urgent, char *data, int len) {
1216     if (urgent==3) {
1217         /* A socket error has occurred. */
1218         ssh_state = SSH_STATE_CLOSED;
1219         sk_close(s);
1220         s = NULL;
1221         connection_fatal(data);
1222         return 0;
1223     } else if (!len) {
1224         /* Connection has closed. */
1225         ssh_state = SSH_STATE_CLOSED;
1226         sk_close(s);
1227         s = NULL;
1228         return 0;
1229     }
1230     ssh_gotdata (data, len);
1231     if (ssh_state == SSH_STATE_CLOSED) {
1232         if (s) {
1233             sk_close(s);
1234             s = NULL;
1235         }
1236         return 0;
1237     }
1238     return 1;
1239 }
1240
1241 /*
1242  * Connect to specified host and port.
1243  * Returns an error message, or NULL on success.
1244  * Also places the canonical host name into `realhost'.
1245  */
1246 static char *connect_to_host(char *host, int port, char **realhost)
1247 {
1248     SockAddr addr;
1249     char *err;
1250 #ifdef FWHACK
1251     char *FWhost;
1252     int FWport;
1253 #endif
1254
1255     savedhost = smalloc(1+strlen(host));
1256     if (!savedhost)
1257         fatalbox("Out of memory");
1258     strcpy(savedhost, host);
1259
1260     if (port < 0)
1261         port = 22;                     /* default ssh port */
1262     savedport = port;
1263
1264 #ifdef FWHACK
1265     FWhost = host;
1266     FWport = port;
1267     host = FWSTR;
1268     port = 23;
1269 #endif
1270
1271     /*
1272      * Try to find host.
1273      */
1274     addr = sk_namelookup(host, realhost);
1275     if ( (err = sk_addr_error(addr)) )
1276         return err;
1277
1278 #ifdef FWHACK
1279     *realhost = FWhost;
1280 #endif
1281
1282     /*
1283      * Open socket.
1284      */
1285     s = sk_new(addr, port, 0, 1, ssh_receive);
1286     if ( (err = sk_socket_error(s)) )
1287         return err;
1288
1289 #ifdef FWHACK
1290     sk_write(s, "connect ", 8);
1291     sk_write(s, FWhost, strlen(FWhost));
1292     {
1293         char buf[20];
1294         sprintf(buf, " %d\n", FWport);
1295         sk_write(s, buf, strlen(buf));
1296     }
1297 #endif
1298
1299     return NULL;
1300 }
1301
1302 /*
1303  * Handle the key exchange and user authentication phases.
1304  */
1305 static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
1306 {
1307     int i, j, len;
1308     unsigned char *rsabuf, *keystr1, *keystr2;
1309     unsigned char cookie[8];
1310     struct RSAKey servkey, hostkey;
1311     struct MD5Context md5c;
1312     static unsigned long supported_ciphers_mask, supported_auths_mask;
1313     static int tried_publickey;
1314     static unsigned char session_id[16];
1315     int cipher_type;
1316     static char username[100];
1317
1318     crBegin;
1319
1320     if (!ispkt) crWaitUntil(ispkt);
1321
1322     if (pktin.type != SSH1_SMSG_PUBLIC_KEY) {
1323         bombout(("Public key packet not received"));
1324         crReturn(0);
1325     }
1326
1327     logevent("Received public keys");
1328
1329     memcpy(cookie, pktin.body, 8);
1330
1331     i = makekey(pktin.body+8, &servkey, &keystr1, 0);
1332     j = makekey(pktin.body+8+i, &hostkey, &keystr2, 0);
1333
1334     /*
1335      * Log the host key fingerprint.
1336      */
1337     {
1338         char logmsg[80];
1339         logevent("Host key fingerprint is:");
1340         strcpy(logmsg, "      ");
1341         hostkey.comment = NULL;
1342         rsa_fingerprint(logmsg+strlen(logmsg), sizeof(logmsg)-strlen(logmsg),
1343                         &hostkey);
1344         logevent(logmsg);
1345     }
1346
1347     supported_ciphers_mask = GET_32BIT(pktin.body+12+i+j);
1348     supported_auths_mask = GET_32BIT(pktin.body+16+i+j);
1349
1350     MD5Init(&md5c);
1351     MD5Update(&md5c, keystr2, hostkey.bytes);
1352     MD5Update(&md5c, keystr1, servkey.bytes);
1353     MD5Update(&md5c, pktin.body, 8);
1354     MD5Final(session_id, &md5c);
1355
1356     for (i=0; i<32; i++)
1357         session_key[i] = random_byte();
1358
1359     len = (hostkey.bytes > servkey.bytes ? hostkey.bytes : servkey.bytes);
1360
1361     rsabuf = smalloc(len);
1362     if (!rsabuf)
1363         fatalbox("Out of memory");
1364
1365     /*
1366      * Verify the host key.
1367      */
1368     {
1369         /*
1370          * First format the key into a string.
1371          */
1372         int len = rsastr_len(&hostkey);
1373         char fingerprint[100];
1374         char *keystr = smalloc(len);
1375         if (!keystr)
1376             fatalbox("Out of memory");
1377         rsastr_fmt(keystr, &hostkey);
1378         rsa_fingerprint(fingerprint, sizeof(fingerprint), &hostkey);
1379         verify_ssh_host_key(savedhost, savedport, "rsa", keystr, fingerprint);
1380         sfree(keystr);
1381     }
1382
1383     for (i=0; i<32; i++) {
1384         rsabuf[i] = session_key[i];
1385         if (i < 16)
1386             rsabuf[i] ^= session_id[i];
1387     }
1388
1389     if (hostkey.bytes > servkey.bytes) {
1390         rsaencrypt(rsabuf, 32, &servkey);
1391         rsaencrypt(rsabuf, servkey.bytes, &hostkey);
1392     } else {
1393         rsaencrypt(rsabuf, 32, &hostkey);
1394         rsaencrypt(rsabuf, hostkey.bytes, &servkey);
1395     }
1396
1397     logevent("Encrypted session key");
1398
1399     cipher_type = cfg.cipher == CIPHER_BLOWFISH ? SSH_CIPHER_BLOWFISH :
1400                   cfg.cipher == CIPHER_DES ? SSH_CIPHER_DES : 
1401                   SSH_CIPHER_3DES;
1402     if ((supported_ciphers_mask & (1 << cipher_type)) == 0) {
1403         c_write("Selected cipher not supported, falling back to 3DES\r\n", 53);
1404         cipher_type = SSH_CIPHER_3DES;
1405     }
1406     switch (cipher_type) {
1407       case SSH_CIPHER_3DES: logevent("Using 3DES encryption"); break;
1408       case SSH_CIPHER_DES: logevent("Using single-DES encryption"); break;
1409       case SSH_CIPHER_BLOWFISH: logevent("Using Blowfish encryption"); break;
1410     }
1411
1412     send_packet(SSH1_CMSG_SESSION_KEY,
1413                 PKT_CHAR, cipher_type,
1414                 PKT_DATA, cookie, 8,
1415                 PKT_CHAR, (len*8) >> 8, PKT_CHAR, (len*8) & 0xFF,
1416                 PKT_DATA, rsabuf, len,
1417                 PKT_INT, 0,
1418                 PKT_END);
1419
1420     logevent("Trying to enable encryption...");
1421
1422     sfree(rsabuf);
1423
1424     cipher = cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
1425              cipher_type == SSH_CIPHER_DES ? &ssh_des :
1426              &ssh_3des;
1427     cipher->sesskey(session_key);
1428
1429     crWaitUntil(ispkt);
1430
1431     if (pktin.type != SSH1_SMSG_SUCCESS) {
1432         bombout(("Encryption not successfully enabled"));
1433         crReturn(0);
1434     }
1435
1436     logevent("Successfully started encryption");
1437
1438     fflush(stdout);
1439     {
1440         static int pos = 0;
1441         static char c;
1442         if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
1443             c_write("login as: ", 10);
1444             ssh_send_ok = 1;
1445             while (pos >= 0) {
1446                 crWaitUntil(!ispkt);
1447                 while (inlen--) switch (c = *in++) {
1448                   case 10: case 13:
1449                     username[pos] = 0;
1450                     pos = -1;
1451                     break;
1452                   case 8: case 127:
1453                     if (pos > 0) {
1454                         c_write("\b \b", 3);
1455                         pos--;
1456                     }
1457                     break;
1458                   case 21: case 27:
1459                     while (pos > 0) {
1460                         c_write("\b \b", 3);
1461                         pos--;
1462                     }
1463                     break;
1464                   case 3: case 4:
1465                     random_save_seed();
1466                     exit(0);
1467                     break;
1468                   default:
1469                     if (((c >= ' ' && c <= '~') ||
1470                          ((unsigned char)c >= 160)) && pos < 40) {
1471                         username[pos++] = c;
1472                         c_write(&c, 1);
1473                     }
1474                     break;
1475                 }
1476             }
1477             c_write("\r\n", 2);
1478             username[strcspn(username, "\n\r")] = '\0';
1479         } else {
1480             strncpy(username, cfg.username, 99);
1481             username[99] = '\0';
1482         }
1483
1484         send_packet(SSH1_CMSG_USER, PKT_STR, username, PKT_END);
1485         {
1486             char userlog[22+sizeof(username)];
1487             sprintf(userlog, "Sent username \"%s\"", username);
1488             logevent(userlog);
1489             if (flags & FLAG_INTERACTIVE &&
1490                 (!((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)))) {
1491                 strcat(userlog, "\r\n");
1492                 c_write(userlog, strlen(userlog));
1493             }
1494         }
1495     }
1496
1497     crWaitUntil(ispkt);
1498
1499     tried_publickey = 0;
1500
1501     while (pktin.type == SSH1_SMSG_FAILURE) {
1502         static char password[100];
1503         static char prompt[200];
1504         static int pos;
1505         static char c;
1506         static int pwpkt_type;
1507         /*
1508          * Show password prompt, having first obtained it via a TIS
1509          * or CryptoCard exchange if we're doing TIS or CryptoCard
1510          * authentication.
1511          */
1512         pwpkt_type = SSH1_CMSG_AUTH_PASSWORD;
1513         if (agent_exists()) {
1514             /*
1515              * Attempt RSA authentication using Pageant.
1516              */
1517             static unsigned char request[5], *response, *p;
1518             static int responselen;
1519             static int i, nkeys;
1520             static int authed = FALSE;
1521             void *r;
1522
1523             logevent("Pageant is running. Requesting keys.");
1524
1525             /* Request the keys held by the agent. */
1526             PUT_32BIT(request, 1);
1527             request[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
1528             agent_query(request, 5, &r, &responselen);
1529             response = (unsigned char *)r;
1530             if (response) {
1531                 p = response + 5;
1532                 nkeys = GET_32BIT(p); p += 4;
1533                 { char buf[64]; sprintf(buf, "Pageant has %d keys", nkeys);
1534                     logevent(buf); }
1535                 for (i = 0; i < nkeys; i++) {
1536                     static struct RSAKey key;
1537                     static Bignum challenge;
1538                     static char *commentp;
1539                     static int commentlen;
1540
1541                     { char buf[64]; sprintf(buf, "Trying Pageant key #%d", i);
1542                         logevent(buf); }
1543                     p += 4;
1544                     p += ssh1_read_bignum(p, &key.exponent);
1545                     p += ssh1_read_bignum(p, &key.modulus);
1546                     commentlen = GET_32BIT(p); p += 4;
1547                     commentp = p; p += commentlen;
1548                     send_packet(SSH1_CMSG_AUTH_RSA,
1549                                 PKT_BIGNUM, key.modulus, PKT_END);
1550                     crWaitUntil(ispkt);
1551                     if (pktin.type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
1552                         logevent("Key refused");
1553                         continue;
1554                     }
1555                     logevent("Received RSA challenge");
1556                     ssh1_read_bignum(pktin.body, &challenge);
1557                     {
1558                         char *agentreq, *q, *ret;
1559                         int len, retlen;
1560                         len = 1 + 4;   /* message type, bit count */
1561                         len += ssh1_bignum_length(key.exponent);
1562                         len += ssh1_bignum_length(key.modulus);
1563                         len += ssh1_bignum_length(challenge);
1564                         len += 16;     /* session id */
1565                         len += 4;      /* response format */
1566                         agentreq = smalloc(4 + len);
1567                         PUT_32BIT(agentreq, len);
1568                         q = agentreq + 4;
1569                         *q++ = SSH_AGENTC_RSA_CHALLENGE;
1570                         PUT_32BIT(q, ssh1_bignum_bitcount(key.modulus));
1571                         q += 4;
1572                         q += ssh1_write_bignum(q, key.exponent);
1573                         q += ssh1_write_bignum(q, key.modulus);
1574                         q += ssh1_write_bignum(q, challenge);
1575                         memcpy(q, session_id, 16); q += 16;
1576                         PUT_32BIT(q, 1);   /* response format */
1577                         agent_query(agentreq, len+4, &ret, &retlen);
1578                         sfree(agentreq);
1579                         if (ret) {
1580                             if (ret[4] == SSH_AGENT_RSA_RESPONSE) {
1581                                 logevent("Sending Pageant's response");
1582                                 send_packet(SSH1_CMSG_AUTH_RSA_RESPONSE,
1583                                             PKT_DATA, ret+5, 16, PKT_END);
1584                                 sfree(ret);
1585                                 crWaitUntil(ispkt);
1586                                 if (pktin.type == SSH1_SMSG_SUCCESS) {
1587                                     logevent("Pageant's response accepted");
1588                                     if (flags & FLAG_VERBOSE) {
1589                                         c_write("Authenticated using RSA key \"",
1590                                                 29);
1591                                         c_write(commentp, commentlen);
1592                                         c_write("\" from agent\r\n", 14);
1593                                     }
1594                                     authed = TRUE;
1595                                 } else
1596                                     logevent("Pageant's response not accepted");
1597                             } else {
1598                                 logevent("Pageant failed to answer challenge");
1599                                 sfree(ret);
1600                             }
1601                         } else {
1602                             logevent("No reply received from Pageant");
1603                         }
1604                     }
1605                     freebn(key.exponent);
1606                     freebn(key.modulus);
1607                     freebn(challenge);
1608                     if (authed)
1609                         break;
1610                 }
1611             }
1612             if (authed)
1613                 break;
1614         }
1615         if (*cfg.keyfile && !tried_publickey)
1616             pwpkt_type = SSH1_CMSG_AUTH_RSA;
1617
1618         if (pktin.type == SSH1_SMSG_FAILURE &&
1619             cfg.try_tis_auth &&
1620             (supported_auths_mask & (1<<SSH1_AUTH_TIS))) {
1621             pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
1622             logevent("Requested TIS authentication");
1623             send_packet(SSH1_CMSG_AUTH_TIS, PKT_END);
1624             crWaitUntil(ispkt);
1625             if (pktin.type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
1626                 logevent("TIS authentication declined");
1627                 if (flags & FLAG_INTERACTIVE)
1628                     c_write("TIS authentication refused.\r\n", 29);
1629             } else {
1630                 int challengelen = ((pktin.body[0] << 24) |
1631                                     (pktin.body[1] << 16) |
1632                                     (pktin.body[2] << 8) |
1633                                     (pktin.body[3]));
1634                 logevent("Received TIS challenge");
1635                 if (challengelen > sizeof(prompt)-1)
1636                     challengelen = sizeof(prompt)-1;   /* prevent overrun */
1637                 memcpy(prompt, pktin.body+4, challengelen);
1638                 prompt[challengelen] = '\0';
1639             }
1640         }
1641         if (pktin.type == SSH1_SMSG_FAILURE &&
1642             cfg.try_tis_auth &&
1643             (supported_auths_mask & (1<<SSH1_AUTH_CCARD))) {
1644             pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
1645             logevent("Requested CryptoCard authentication");
1646             send_packet(SSH1_CMSG_AUTH_CCARD, PKT_END);
1647             crWaitUntil(ispkt);
1648             if (pktin.type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
1649                 logevent("CryptoCard authentication declined");
1650                 c_write("CryptoCard authentication refused.\r\n", 29);
1651             } else {
1652                 int challengelen = ((pktin.body[0] << 24) |
1653                                     (pktin.body[1] << 16) |
1654                                     (pktin.body[2] << 8) |
1655                                     (pktin.body[3]));
1656                 logevent("Received CryptoCard challenge");
1657                 if (challengelen > sizeof(prompt)-1)
1658                     challengelen = sizeof(prompt)-1;   /* prevent overrun */
1659                 memcpy(prompt, pktin.body+4, challengelen);
1660                 strncpy(prompt + challengelen, "\r\nResponse : ",
1661                         sizeof(prompt)-challengelen);
1662                 prompt[sizeof(prompt)-1] = '\0';
1663             }
1664         }
1665         if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
1666             sprintf(prompt, "%.90s@%.90s's password: ",
1667                     username, savedhost);
1668         }
1669         if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
1670             char *comment = NULL;
1671             if (flags & FLAG_VERBOSE)
1672                 c_write("Trying public key authentication.\r\n", 35);
1673             if (!rsakey_encrypted(cfg.keyfile, &comment)) {
1674                 if (flags & FLAG_VERBOSE)
1675                     c_write("No passphrase required.\r\n", 25);
1676                 goto tryauth;
1677             }
1678             sprintf(prompt, "Passphrase for key \"%.100s\": ", comment);
1679             sfree(comment);
1680         }
1681
1682         if (ssh_get_password) {
1683             if (!ssh_get_password(prompt, password, sizeof(password))) {
1684                 /*
1685                  * get_password failed to get a password (for
1686                  * example because one was supplied on the command
1687                  * line which has already failed to work).
1688                  * Terminate.
1689                  */
1690                 logevent("No more passwords to try");
1691                 ssh_state = SSH_STATE_CLOSED;
1692                 crReturn(1);
1693             }
1694         } else {
1695             c_write(prompt, strlen(prompt));
1696             pos = 0;
1697             ssh_send_ok = 1;
1698             while (pos >= 0) {
1699                 crWaitUntil(!ispkt);
1700                 while (inlen--) switch (c = *in++) {
1701                   case 10: case 13:
1702                     password[pos] = 0;
1703                     pos = -1;
1704                     break;
1705                   case 8: case 127:
1706                     if (pos > 0)
1707                         pos--;
1708                     break;
1709                   case 21: case 27:
1710                     pos = 0;
1711                     break;
1712                   case 3: case 4:
1713                     random_save_seed();
1714                     exit(0);
1715                     break;
1716                   default:
1717                     if (((c >= ' ' && c <= '~') ||
1718                          ((unsigned char)c >= 160)) && pos < sizeof(password))
1719                         password[pos++] = c;
1720                     break;
1721                 }
1722             }
1723             c_write("\r\n", 2);
1724         }
1725
1726         tryauth:
1727         if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
1728             /*
1729              * Try public key authentication with the specified
1730              * key file.
1731              */
1732             static struct RSAKey pubkey;
1733             static Bignum challenge, response;
1734             static int i;
1735             static unsigned char buffer[32];
1736
1737             tried_publickey = 1;
1738             i = loadrsakey(cfg.keyfile, &pubkey, NULL, password);
1739             if (i == 0) {
1740                 c_write("Couldn't load public key from ", 30);
1741                 c_write(cfg.keyfile, strlen(cfg.keyfile));
1742                 c_write(".\r\n", 3);
1743                 continue;              /* go and try password */
1744             }
1745             if (i == -1) {
1746                 c_write("Wrong passphrase.\r\n", 19);
1747                 tried_publickey = 0;
1748                 continue;              /* try again */
1749             }
1750
1751             /*
1752              * Send a public key attempt.
1753              */
1754             send_packet(SSH1_CMSG_AUTH_RSA,
1755                         PKT_BIGNUM, pubkey.modulus, PKT_END);
1756
1757             crWaitUntil(ispkt);
1758             if (pktin.type == SSH1_SMSG_FAILURE) {
1759                 c_write("Server refused our public key.\r\n", 32);
1760                 continue;              /* go and try password */
1761             }
1762             if (pktin.type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
1763                 bombout(("Bizarre response to offer of public key"));
1764                 crReturn(0);
1765             }
1766             ssh1_read_bignum(pktin.body, &challenge);
1767             response = rsadecrypt(challenge, &pubkey);
1768             freebn(pubkey.private_exponent);   /* burn the evidence */
1769
1770             for (i = 0; i < 32; i++) {
1771                 buffer[i] = bignum_byte(response, 31-i);
1772             }
1773
1774             MD5Init(&md5c);
1775             MD5Update(&md5c, buffer, 32);
1776             MD5Update(&md5c, session_id, 16);
1777             MD5Final(buffer, &md5c);
1778
1779             send_packet(SSH1_CMSG_AUTH_RSA_RESPONSE,
1780                         PKT_DATA, buffer, 16, PKT_END);
1781
1782             crWaitUntil(ispkt);
1783             if (pktin.type == SSH1_SMSG_FAILURE) {
1784                 if (flags & FLAG_VERBOSE)
1785                     c_write("Failed to authenticate with our public key.\r\n",
1786                             45);
1787                 continue;              /* go and try password */
1788             } else if (pktin.type != SSH1_SMSG_SUCCESS) {
1789                 bombout(("Bizarre response to RSA authentication response"));
1790                 crReturn(0);
1791             }
1792
1793             break;                     /* we're through! */
1794         } else {
1795             send_packet(pwpkt_type, PKT_STR, password, PKT_END);
1796         }
1797         logevent("Sent password");
1798         memset(password, 0, strlen(password));
1799         crWaitUntil(ispkt);
1800         if (pktin.type == SSH1_SMSG_FAILURE) {
1801             if (flags & FLAG_VERBOSE)
1802                 c_write("Access denied\r\n", 15);
1803             logevent("Authentication refused");
1804         } else if (pktin.type == SSH1_MSG_DISCONNECT) {
1805             logevent("Received disconnect request");
1806             ssh_state = SSH_STATE_CLOSED;
1807             crReturn(1);
1808         } else if (pktin.type != SSH1_SMSG_SUCCESS) {
1809             bombout(("Strange packet received, type %d", pktin.type));
1810             crReturn(0);
1811         }
1812     }
1813
1814     logevent("Authentication successful");
1815
1816     crFinish(1);
1817 }
1818
1819 void sshfwd_close(struct ssh_channel *c) {
1820     if (c) {
1821         if (ssh_version == 1) {
1822             send_packet(SSH1_MSG_CHANNEL_CLOSE, PKT_INT, c->remoteid, PKT_END);
1823         } else {
1824             ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
1825             ssh2_pkt_adduint32(c->remoteid);
1826             ssh2_pkt_send();
1827         }
1828         c->closes = 1;
1829         if (c->type == CHAN_X11) {
1830             c->u.x11.s = NULL;
1831             logevent("X11 connection terminated");
1832         }
1833     }
1834 }
1835
1836 void sshfwd_write(struct ssh_channel *c, char *buf, int len) {
1837     if (ssh_version == 1) {
1838         send_packet(SSH1_MSG_CHANNEL_DATA,
1839                     PKT_INT, c->remoteid,
1840                     PKT_INT, len,
1841                     PKT_DATA, buf, len,
1842                     PKT_END);
1843     } else {
1844         ssh2_add_channel_data(c, buf, len);
1845         ssh2_try_send(c);
1846     }
1847 }
1848
1849 static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) {
1850     crBegin;
1851
1852     random_init();
1853
1854     while (!do_ssh1_login(in, inlen, ispkt)) {
1855         crReturnV;
1856     }
1857     if (ssh_state == SSH_STATE_CLOSED)
1858         crReturnV;
1859
1860     if (cfg.agentfwd && agent_exists()) {
1861         logevent("Requesting agent forwarding");
1862         send_packet(SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END);
1863         do { crReturnV; } while (!ispkt);
1864         if (pktin.type != SSH1_SMSG_SUCCESS && pktin.type != SSH1_SMSG_FAILURE) {
1865             bombout(("Protocol confusion"));
1866             crReturnV;
1867         } else if (pktin.type == SSH1_SMSG_FAILURE) {
1868             logevent("Agent forwarding refused");
1869         } else {
1870             logevent("Agent forwarding enabled");
1871             ssh_agentfwd_enabled = TRUE;
1872         }
1873     }
1874
1875     if (cfg.x11_forward) {
1876         char proto[20], data[64];
1877         logevent("Requesting X11 forwarding");
1878         x11_invent_auth(proto, sizeof(proto), data, sizeof(data));
1879         send_packet(SSH1_CMSG_X11_REQUEST_FORWARDING, 
1880                     PKT_STR, proto, PKT_STR, data,
1881                     PKT_INT, 0,
1882                     PKT_END);
1883         do { crReturnV; } while (!ispkt);
1884         if (pktin.type != SSH1_SMSG_SUCCESS && pktin.type != SSH1_SMSG_FAILURE) {
1885             bombout(("Protocol confusion"));
1886             crReturnV;
1887         } else if (pktin.type == SSH1_SMSG_FAILURE) {
1888             logevent("X11 forwarding refused");
1889         } else {
1890             logevent("X11 forwarding enabled");
1891             ssh_X11_fwd_enabled = TRUE;
1892         }
1893     }
1894
1895     if (!cfg.nopty) {
1896         send_packet(SSH1_CMSG_REQUEST_PTY,
1897                     PKT_STR, cfg.termtype,
1898                     PKT_INT, rows, PKT_INT, cols,
1899                     PKT_INT, 0, PKT_INT, 0,
1900                     PKT_CHAR, 0,
1901                     PKT_END);
1902         ssh_state = SSH_STATE_INTERMED;
1903         do { crReturnV; } while (!ispkt);
1904         if (pktin.type != SSH1_SMSG_SUCCESS && pktin.type != SSH1_SMSG_FAILURE) {
1905             bombout(("Protocol confusion"));
1906             crReturnV;
1907         } else if (pktin.type == SSH1_SMSG_FAILURE) {
1908             c_write("Server refused to allocate pty\r\n", 32);
1909             ssh_editing = ssh_echoing = 1;
1910         }
1911         logevent("Allocated pty");
1912     } else {
1913         ssh_editing = ssh_echoing = 1;
1914     }
1915
1916     if (cfg.compression) {
1917         send_packet(SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);
1918         do { crReturnV; } while (!ispkt);
1919         if (pktin.type != SSH1_SMSG_SUCCESS && pktin.type != SSH1_SMSG_FAILURE) {
1920             bombout(("Protocol confusion"));
1921             crReturnV;
1922         } else if (pktin.type == SSH1_SMSG_FAILURE) {
1923             c_write("Server refused to compress\r\n", 32);
1924         }
1925         logevent("Started compression");
1926         ssh1_compressing = TRUE;
1927         zlib_compress_init();
1928         zlib_decompress_init();
1929     }
1930
1931     if (*cfg.remote_cmd)
1932         send_packet(SSH1_CMSG_EXEC_CMD, PKT_STR, cfg.remote_cmd, PKT_END);
1933     else
1934         send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END);
1935     logevent("Started session");
1936
1937     ssh_state = SSH_STATE_SESSION;
1938     if (size_needed)
1939         ssh_size();
1940     if (eof_needed)
1941         ssh_special(TS_EOF);
1942
1943     ldisc_send(NULL, 0);               /* cause ldisc to notice changes */
1944     ssh_send_ok = 1;
1945     ssh_channels = newtree234(ssh_channelcmp);
1946     while (1) {
1947         crReturnV;
1948         if (ispkt) {
1949             if (pktin.type == SSH1_SMSG_STDOUT_DATA ||
1950                 pktin.type == SSH1_SMSG_STDERR_DATA) {
1951                 long len = GET_32BIT(pktin.body);
1952                 from_backend(pktin.type == SSH1_SMSG_STDERR_DATA,
1953                              pktin.body+4, len);
1954             } else if (pktin.type == SSH1_MSG_DISCONNECT) {
1955                 ssh_state = SSH_STATE_CLOSED;
1956                 logevent("Received disconnect request");
1957                 crReturnV;
1958             } else if (pktin.type == SSH1_SMSG_X11_OPEN) {
1959                 /* Remote side is trying to open a channel to talk to our
1960                  * X-Server. Give them back a local channel number. */
1961                 unsigned i;
1962                 struct ssh_channel *c, *d;
1963                 enum234 e;
1964
1965                 logevent("Received X11 connect request");
1966                 /* Refuse if X11 forwarding is disabled. */
1967                 if (!ssh_X11_fwd_enabled) {
1968                     send_packet(SSH1_MSG_CHANNEL_OPEN_FAILURE,
1969                                 PKT_INT, GET_32BIT(pktin.body),
1970                                 PKT_END);
1971                     logevent("Rejected X11 connect request");
1972                 } else {
1973                     c = smalloc(sizeof(struct ssh_channel));
1974
1975                     if ( x11_init(&c->u.x11.s, cfg.x11_display, c) != NULL ) {
1976                       logevent("opening X11 forward connection failed");
1977                       sfree(c);
1978                       send_packet(SSH1_MSG_CHANNEL_OPEN_FAILURE,
1979                                   PKT_INT, GET_32BIT(pktin.body),
1980                                   PKT_END);
1981                     } else {
1982                       logevent("opening X11 forward connection succeeded");
1983                       for (i=1, d = first234(ssh_channels, &e); d; d = next234(&e)) {
1984                           if (d->localid > i)
1985                               break;     /* found a free number */
1986                           i = d->localid + 1;
1987                       }
1988                       c->remoteid = GET_32BIT(pktin.body);
1989                       c->localid = i;
1990                       c->closes = 0;
1991                       c->type = CHAN_X11;   /* identify channel type */
1992                       add234(ssh_channels, c);
1993                       send_packet(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
1994                                   PKT_INT, c->remoteid, PKT_INT, c->localid,
1995                                   PKT_END);
1996                       logevent("Opened X11 forward channel");
1997                     }
1998                 }
1999             } else if (pktin.type == SSH1_SMSG_AGENT_OPEN) {
2000                 /* Remote side is trying to open a channel to talk to our
2001                  * agent. Give them back a local channel number. */
2002                 unsigned i;
2003                 struct ssh_channel *c;
2004                 enum234 e;
2005
2006                 /* Refuse if agent forwarding is disabled. */
2007                 if (!ssh_agentfwd_enabled) {
2008                     send_packet(SSH1_MSG_CHANNEL_OPEN_FAILURE,
2009                                 PKT_INT, GET_32BIT(pktin.body),
2010                                 PKT_END);
2011                 } else {
2012                     i = 1;
2013                     for (c = first234(ssh_channels, &e); c; c = next234(&e)) {
2014                         if (c->localid > i)
2015                             break;     /* found a free number */
2016                         i = c->localid + 1;
2017                     }
2018                     c = smalloc(sizeof(struct ssh_channel));
2019                     c->remoteid = GET_32BIT(pktin.body);
2020                     c->localid = i;
2021                     c->closes = 0;
2022                     c->type = CHAN_AGENT;   /* identify channel type */
2023                     c->u.a.lensofar = 0;
2024                     add234(ssh_channels, c);
2025                     send_packet(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
2026                                 PKT_INT, c->remoteid, PKT_INT, c->localid,
2027                                 PKT_END);
2028                 }
2029             } else if (pktin.type == SSH1_MSG_CHANNEL_CLOSE ||
2030                        pktin.type == SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION) {
2031                 /* Remote side closes a channel. */
2032                 unsigned i = GET_32BIT(pktin.body);
2033                 struct ssh_channel *c;
2034                 c = find234(ssh_channels, &i, ssh_channelfind);
2035                 if (c) {
2036                     int closetype;
2037                     closetype = (pktin.type == SSH1_MSG_CHANNEL_CLOSE ? 1 : 2);
2038                     send_packet(pktin.type, PKT_INT, c->remoteid, PKT_END);
2039                     if ((c->closes == 0) && (c->type == CHAN_X11)) {
2040                         logevent("X11 connection closed");
2041                         assert(c->u.x11.s != NULL);
2042                         x11_close(c->u.x11.s);
2043                         c->u.x11.s = NULL;
2044                     }
2045                     c->closes |= closetype;
2046                     if (c->closes == 3) {
2047                         del234(ssh_channels, c);
2048                         sfree(c);
2049                     }
2050                 }
2051             } else if (pktin.type == SSH1_MSG_CHANNEL_DATA) {
2052                 /* Data sent down one of our channels. */
2053                 int i = GET_32BIT(pktin.body);
2054                 int len = GET_32BIT(pktin.body+4);
2055                 unsigned char *p = pktin.body+8;
2056                 struct ssh_channel *c;
2057                 c = find234(ssh_channels, &i, ssh_channelfind);
2058                 if (c) {
2059                     switch(c->type) {
2060                       case CHAN_X11:
2061                         x11_send(c->u.x11.s, p, len);
2062                         break;
2063                       case CHAN_AGENT:
2064                         /* Data for an agent message. Buffer it. */
2065                         while (len > 0) {
2066                             if (c->u.a.lensofar < 4) {
2067                                 int l = min(4 - c->u.a.lensofar, len);
2068                                 memcpy(c->u.a.msglen + c->u.a.lensofar, p, l);
2069                                 p += l; len -= l; c->u.a.lensofar += l;
2070                             }
2071                             if (c->u.a.lensofar == 4) {
2072                                 c->u.a.totallen = 4 + GET_32BIT(c->u.a.msglen);
2073                                 c->u.a.message = smalloc(c->u.a.totallen);
2074                                 memcpy(c->u.a.message, c->u.a.msglen, 4);
2075                             }
2076                             if (c->u.a.lensofar >= 4 && len > 0) {
2077                                 int l = min(c->u.a.totallen - c->u.a.lensofar, len);
2078                                 memcpy(c->u.a.message + c->u.a.lensofar, p, l);
2079                                 p += l; len -= l; c->u.a.lensofar += l;
2080                             }
2081                             if (c->u.a.lensofar == c->u.a.totallen) {
2082                                 void *reply, *sentreply;
2083                                 int replylen;
2084                                 agent_query(c->u.a.message, c->u.a.totallen,
2085                                             &reply, &replylen);
2086                                 if (reply)
2087                                     sentreply = reply;
2088                                 else {
2089                                     /* Fake SSH_AGENT_FAILURE. */
2090                                     sentreply = "\0\0\0\1\5";
2091                                     replylen = 5;
2092                                 }
2093                                 send_packet(SSH1_MSG_CHANNEL_DATA,
2094                                             PKT_INT, c->remoteid,
2095                                             PKT_INT, replylen,
2096                                             PKT_DATA, sentreply, replylen,
2097                                             PKT_END);
2098                                 if (reply)
2099                                     sfree(reply);
2100                                 sfree(c->u.a.message);
2101                                 c->u.a.lensofar = 0;
2102                             }
2103                         }
2104                         break;
2105                     }
2106                 }                
2107             } else if (pktin.type == SSH1_SMSG_SUCCESS) {
2108                 /* may be from EXEC_SHELL on some servers */
2109             } else if (pktin.type == SSH1_SMSG_FAILURE) {
2110                 /* may be from EXEC_SHELL on some servers
2111                  * if no pty is available or in other odd cases. Ignore */
2112             } else if (pktin.type == SSH1_SMSG_EXIT_STATUS) {
2113                 send_packet(SSH1_CMSG_EXIT_CONFIRMATION, PKT_END);
2114             } else {
2115                 bombout(("Strange packet received: type %d", pktin.type));
2116                 crReturnV;
2117             }
2118         } else {
2119             while (inlen > 0) {
2120                 int len = min(inlen, 512);
2121                 send_packet(SSH1_CMSG_STDIN_DATA,
2122                             PKT_INT, len, PKT_DATA, in, len, PKT_END);
2123                 in += len;
2124                 inlen -= len;
2125             }
2126         }
2127     }
2128
2129     crFinishV;
2130 }
2131
2132 /*
2133  * Utility routine for decoding comma-separated strings in KEXINIT.
2134  */
2135 static int in_commasep_string(char *needle, char *haystack, int haylen) {
2136     int needlen = strlen(needle);
2137     while (1) {
2138         /*
2139          * Is it at the start of the string?
2140          */
2141         if (haylen >= needlen &&       /* haystack is long enough */
2142             !memcmp(needle, haystack, needlen) &&    /* initial match */
2143             (haylen == needlen || haystack[needlen] == ',')
2144                                        /* either , or EOS follows */
2145             )
2146             return 1;
2147         /*
2148          * If not, search for the next comma and resume after that.
2149          * If no comma found, terminate.
2150          */
2151         while (haylen > 0 && *haystack != ',')
2152             haylen--, haystack++;
2153         if (haylen == 0)
2154             return 0;
2155         haylen--, haystack++;          /* skip over comma itself */
2156     }
2157 }
2158
2159 /*
2160  * SSH2 key creation method.
2161  */
2162 static void ssh2_mkkey(Bignum K, char *H, char *sessid, char chr, char *keyspace) {
2163     SHA_State s;
2164     /* First 20 bytes. */
2165     SHA_Init(&s);
2166     sha_mpint(&s, K);
2167     SHA_Bytes(&s, H, 20);
2168     SHA_Bytes(&s, &chr, 1);
2169     SHA_Bytes(&s, sessid, 20);
2170     SHA_Final(&s, keyspace);
2171     /* Next 20 bytes. */
2172     SHA_Init(&s);
2173     sha_mpint(&s, K);
2174     SHA_Bytes(&s, H, 20);
2175     SHA_Bytes(&s, keyspace, 20);
2176     SHA_Final(&s, keyspace+20);
2177 }
2178
2179 /*
2180  * Handle the SSH2 transport layer.
2181  */
2182 static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
2183 {
2184     static int i, len, nbits;
2185     static char *str;
2186     static Bignum p, g, e, f, K;
2187     static int kex_init_value, kex_reply_value;
2188     static const struct ssh_mac **maclist;
2189     static int nmacs;
2190     static const struct ssh_cipher *cscipher_tobe = NULL;
2191     static const struct ssh_cipher *sccipher_tobe = NULL;
2192     static const struct ssh_mac *csmac_tobe = NULL;
2193     static const struct ssh_mac *scmac_tobe = NULL;
2194     static const struct ssh_compress *cscomp_tobe = NULL;
2195     static const struct ssh_compress *sccomp_tobe = NULL;
2196     static char *hostkeydata, *sigdata, *keystr, *fingerprint;
2197     static int hostkeylen, siglen;
2198     static void *hkey;                 /* actual host key */
2199     static unsigned char exchange_hash[20];
2200     static unsigned char first_exchange_hash[20];
2201     static unsigned char keyspace[40];
2202     static const struct ssh_cipher *preferred_cipher;
2203     static const struct ssh_compress *preferred_comp;
2204     static int first_kex;
2205
2206     crBegin;
2207     random_init();
2208     first_kex = 1;
2209
2210     /*
2211      * Set up the preferred cipher and compression.
2212      */
2213     if (cfg.cipher == CIPHER_BLOWFISH) {
2214         preferred_cipher = &ssh_blowfish_ssh2;
2215     } else if (cfg.cipher == CIPHER_DES) {
2216         logevent("Single DES not supported in SSH2; using 3DES");
2217         preferred_cipher = &ssh_3des_ssh2;
2218     } else if (cfg.cipher == CIPHER_3DES) {
2219         preferred_cipher = &ssh_3des_ssh2;
2220     } else {
2221         /* Shouldn't happen, but we do want to initialise to _something_. */
2222         preferred_cipher = &ssh_3des_ssh2;
2223     }
2224     if (cfg.compression)
2225         preferred_comp = &ssh_zlib;
2226     else
2227         preferred_comp = &ssh_comp_none;
2228
2229     /*
2230      * Be prepared to work around the buggy MAC problem.
2231      */
2232     if (cfg.buggymac)
2233         maclist = buggymacs, nmacs = lenof(buggymacs);
2234     else
2235         maclist = macs, nmacs = lenof(macs);
2236
2237     begin_key_exchange:
2238     /*
2239      * Construct and send our key exchange packet.
2240      */
2241     ssh2_pkt_init(SSH2_MSG_KEXINIT);
2242     for (i = 0; i < 16; i++)
2243         ssh2_pkt_addbyte((unsigned char)random_byte());
2244     /* List key exchange algorithms. */
2245     ssh2_pkt_addstring_start();
2246     for (i = 0; i < lenof(kex_algs); i++) {
2247         ssh2_pkt_addstring_str(kex_algs[i]->name);
2248         if (i < lenof(kex_algs)-1)
2249             ssh2_pkt_addstring_str(",");
2250     }
2251     /* List server host key algorithms. */
2252     ssh2_pkt_addstring_start();
2253     for (i = 0; i < lenof(hostkey_algs); i++) {
2254         ssh2_pkt_addstring_str(hostkey_algs[i]->name);
2255         if (i < lenof(hostkey_algs)-1)
2256             ssh2_pkt_addstring_str(",");
2257     }
2258     /* List client->server encryption algorithms. */
2259     ssh2_pkt_addstring_start();
2260     for (i = 0; i < lenof(ciphers)+1; i++) {
2261         const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1];
2262         ssh2_pkt_addstring_str(c->name);
2263         if (i < lenof(ciphers))
2264             ssh2_pkt_addstring_str(",");
2265     }
2266     /* List server->client encryption algorithms. */
2267     ssh2_pkt_addstring_start();
2268     for (i = 0; i < lenof(ciphers)+1; i++) {
2269         const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1];
2270         ssh2_pkt_addstring_str(c->name);
2271         if (i < lenof(ciphers))
2272             ssh2_pkt_addstring_str(",");
2273     }
2274     /* List client->server MAC algorithms. */
2275     ssh2_pkt_addstring_start();
2276     for (i = 0; i < nmacs; i++) {
2277         ssh2_pkt_addstring_str(maclist[i]->name);
2278         if (i < nmacs-1)
2279             ssh2_pkt_addstring_str(",");
2280     }
2281     /* List server->client MAC algorithms. */
2282     ssh2_pkt_addstring_start();
2283     for (i = 0; i < nmacs; i++) {
2284         ssh2_pkt_addstring_str(maclist[i]->name);
2285         if (i < nmacs-1)
2286             ssh2_pkt_addstring_str(",");
2287     }
2288     /* List client->server compression algorithms. */
2289     ssh2_pkt_addstring_start();
2290     for (i = 0; i < lenof(compressions)+1; i++) {
2291         const struct ssh_compress *c = i==0 ? preferred_comp : compressions[i-1];
2292         ssh2_pkt_addstring_str(c->name);
2293         if (i < lenof(compressions))
2294             ssh2_pkt_addstring_str(",");
2295     }
2296     /* List server->client compression algorithms. */
2297     ssh2_pkt_addstring_start();
2298     for (i = 0; i < lenof(compressions)+1; i++) {
2299         const struct ssh_compress *c = i==0 ? preferred_comp : compressions[i-1];
2300         ssh2_pkt_addstring_str(c->name);
2301         if (i < lenof(compressions))
2302             ssh2_pkt_addstring_str(",");
2303     }
2304     /* List client->server languages. Empty list. */
2305     ssh2_pkt_addstring_start();
2306     /* List server->client languages. Empty list. */
2307     ssh2_pkt_addstring_start();
2308     /* First KEX packet does _not_ follow, because we're not that brave. */
2309     ssh2_pkt_addbool(FALSE);
2310     /* Reserved. */
2311     ssh2_pkt_adduint32(0);
2312
2313     exhash = exhashbase;
2314     sha_string(&exhash, pktout.data+5, pktout.length-5);
2315
2316     ssh2_pkt_send();
2317
2318     if (!ispkt) crWaitUntil(ispkt);
2319     sha_string(&exhash, pktin.data+5, pktin.length-5);
2320
2321     /*
2322      * Now examine the other side's KEXINIT to see what we're up
2323      * to.
2324      */
2325     if (pktin.type != SSH2_MSG_KEXINIT) {
2326         bombout(("expected key exchange packet from server"));
2327         crReturn(0);
2328     }
2329     kex = NULL; hostkey = NULL; cscipher_tobe = NULL; sccipher_tobe = NULL;
2330     csmac_tobe = NULL; scmac_tobe = NULL; cscomp_tobe = NULL; sccomp_tobe = NULL;
2331     pktin.savedpos += 16;              /* skip garbage cookie */
2332     ssh2_pkt_getstring(&str, &len);    /* key exchange algorithms */
2333     for (i = 0; i < lenof(kex_algs); i++) {
2334         if (in_commasep_string(kex_algs[i]->name, str, len)) {
2335             kex = kex_algs[i];
2336             break;
2337         }
2338     }
2339     ssh2_pkt_getstring(&str, &len);    /* host key algorithms */
2340     for (i = 0; i < lenof(hostkey_algs); i++) {
2341         if (in_commasep_string(hostkey_algs[i]->name, str, len)) {
2342             hostkey = hostkey_algs[i];
2343             break;
2344         }
2345     }
2346     ssh2_pkt_getstring(&str, &len);    /* client->server cipher */
2347     for (i = 0; i < lenof(ciphers)+1; i++) {
2348         const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1];
2349         if (in_commasep_string(c->name, str, len)) {
2350             cscipher_tobe = c;
2351             break;
2352         }
2353     }
2354     ssh2_pkt_getstring(&str, &len);    /* server->client cipher */
2355     for (i = 0; i < lenof(ciphers)+1; i++) {
2356         const struct ssh_cipher *c = i==0 ? preferred_cipher : ciphers[i-1];
2357         if (in_commasep_string(c->name, str, len)) {
2358             sccipher_tobe = c;
2359             break;
2360         }
2361     }
2362     ssh2_pkt_getstring(&str, &len);    /* client->server mac */
2363     for (i = 0; i < nmacs; i++) {
2364         if (in_commasep_string(maclist[i]->name, str, len)) {
2365             csmac_tobe = maclist[i];
2366             break;
2367         }
2368     }
2369     ssh2_pkt_getstring(&str, &len);    /* server->client mac */
2370     for (i = 0; i < nmacs; i++) {
2371         if (in_commasep_string(maclist[i]->name, str, len)) {
2372             scmac_tobe = maclist[i];
2373             break;
2374         }
2375     }
2376     ssh2_pkt_getstring(&str, &len);    /* client->server compression */
2377     for (i = 0; i < lenof(compressions)+1; i++) {
2378         const struct ssh_compress *c = i==0 ? preferred_comp : compressions[i-1];
2379         if (in_commasep_string(c->name, str, len)) {
2380             cscomp_tobe = c;
2381             break;
2382         }
2383     }
2384     ssh2_pkt_getstring(&str, &len);    /* server->client compression */
2385     for (i = 0; i < lenof(compressions)+1; i++) {
2386         const struct ssh_compress *c = i==0 ? preferred_comp : compressions[i-1];
2387         if (in_commasep_string(c->name, str, len)) {
2388             sccomp_tobe = c;
2389             break;
2390         }
2391     }
2392
2393     /*
2394      * If we're doing Diffie-Hellman group exchange, start by
2395      * requesting a group.
2396      */
2397     if (kex == &ssh_diffiehellman_gex) {
2398         int csbits, scbits;
2399
2400         logevent("Doing Diffie-Hellman group exchange");
2401         /*
2402          * Work out number of bits. We start with the maximum key
2403          * length of either cipher...
2404          */
2405         csbits = cscipher_tobe->keylen;
2406         scbits = sccipher_tobe->keylen;
2407         nbits = (csbits > scbits ? csbits : scbits);
2408         /* The keys only have 160-bit entropy, since they're based on
2409          * a SHA-1 hash. So cap the key size at 160 bits. */
2410         if (nbits > 160) nbits = 160;
2411         /*
2412          * ... and then work out how big a DH group we will need to
2413          * allow that much data.
2414          */
2415         nbits = 512 << ((nbits-1) / 64);
2416         ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
2417         ssh2_pkt_adduint32(nbits);
2418         ssh2_pkt_send();
2419
2420         crWaitUntil(ispkt);
2421         if (pktin.type != SSH2_MSG_KEX_DH_GEX_GROUP) {
2422             bombout(("expected key exchange group packet from server"));
2423             crReturn(0);
2424         }
2425         p = ssh2_pkt_getmp();
2426         g = ssh2_pkt_getmp();
2427         dh_setup_group(p, g);
2428         kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
2429         kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
2430     } else {
2431         dh_setup_group1();
2432         kex_init_value = SSH2_MSG_KEXDH_INIT;
2433         kex_reply_value = SSH2_MSG_KEXDH_REPLY;
2434     }
2435
2436     logevent("Doing Diffie-Hellman key exchange");
2437     /*
2438      * Now generate and send e for Diffie-Hellman.
2439      */
2440     e = dh_create_e();
2441     ssh2_pkt_init(kex_init_value);
2442     ssh2_pkt_addmp(e);
2443     ssh2_pkt_send();
2444
2445     crWaitUntil(ispkt);
2446     if (pktin.type != kex_reply_value) {
2447         bombout(("expected key exchange reply packet from server"));
2448         crReturn(0);
2449     }
2450     ssh2_pkt_getstring(&hostkeydata, &hostkeylen);
2451     f = ssh2_pkt_getmp();
2452     ssh2_pkt_getstring(&sigdata, &siglen);
2453
2454     K = dh_find_K(f);
2455
2456     sha_string(&exhash, hostkeydata, hostkeylen);
2457     if (kex == &ssh_diffiehellman_gex) {
2458         sha_uint32(&exhash, nbits);
2459         sha_mpint(&exhash, p);
2460         sha_mpint(&exhash, g);
2461     }
2462     sha_mpint(&exhash, e);
2463     sha_mpint(&exhash, f);
2464     sha_mpint(&exhash, K);
2465     SHA_Final(&exhash, exchange_hash);
2466
2467     dh_cleanup();
2468
2469 #if 0
2470     debug(("Exchange hash is:\r\n"));
2471     for (i = 0; i < 20; i++)
2472         debug((" %02x", exchange_hash[i]));
2473     debug(("\r\n"));
2474 #endif
2475
2476     hkey = hostkey->newkey(hostkeydata, hostkeylen);
2477     if (!hostkey->verifysig(hkey, sigdata, siglen, exchange_hash, 20)) {
2478         bombout(("Server failed host key check"));
2479         crReturn(0);
2480     }
2481
2482     /*
2483      * Expect SSH2_MSG_NEWKEYS from server.
2484      */
2485     crWaitUntil(ispkt);
2486     if (pktin.type != SSH2_MSG_NEWKEYS) {
2487         bombout(("expected new-keys packet from server"));
2488         crReturn(0);
2489     }
2490
2491     /*
2492      * Authenticate remote host: verify host key. (We've already
2493      * checked the signature of the exchange hash.)
2494      */
2495     keystr = hostkey->fmtkey(hkey);
2496     fingerprint = hostkey->fingerprint(hkey);
2497     verify_ssh_host_key(savedhost, savedport, hostkey->keytype,
2498                         keystr, fingerprint);
2499     if (first_kex) {                /* don't bother logging this in rekeys */
2500         logevent("Host key fingerprint is:");
2501         logevent(fingerprint);
2502     }
2503     sfree(fingerprint);
2504     sfree(keystr);
2505     hostkey->freekey(hkey);
2506
2507     /*
2508      * Send SSH2_MSG_NEWKEYS.
2509      */
2510     ssh2_pkt_init(SSH2_MSG_NEWKEYS);
2511     ssh2_pkt_send();
2512
2513     /*
2514      * Create and initialise session keys.
2515      */
2516     cscipher = cscipher_tobe;
2517     sccipher = sccipher_tobe;
2518     csmac = csmac_tobe;
2519     scmac = scmac_tobe;
2520     cscomp = cscomp_tobe;
2521     sccomp = sccomp_tobe;
2522     cscomp->compress_init();
2523     sccomp->decompress_init();
2524     /*
2525      * Set IVs after keys. Here we use the exchange hash from the
2526      * _first_ key exchange.
2527      */
2528     if (first_kex)
2529         memcpy(first_exchange_hash, exchange_hash, sizeof(exchange_hash));
2530     ssh2_mkkey(K, exchange_hash, first_exchange_hash, 'C', keyspace);
2531     cscipher->setcskey(keyspace);
2532     ssh2_mkkey(K, exchange_hash, first_exchange_hash, 'D', keyspace);
2533     sccipher->setsckey(keyspace);
2534     ssh2_mkkey(K, exchange_hash, first_exchange_hash, 'A', keyspace);
2535     cscipher->setcsiv(keyspace);
2536     ssh2_mkkey(K, exchange_hash, first_exchange_hash, 'B', keyspace);
2537     sccipher->setsciv(keyspace);
2538     ssh2_mkkey(K, exchange_hash, first_exchange_hash, 'E', keyspace);
2539     csmac->setcskey(keyspace);
2540     ssh2_mkkey(K, exchange_hash, first_exchange_hash, 'F', keyspace);
2541     scmac->setsckey(keyspace);
2542
2543     /*
2544      * If this is the first key exchange phase, we must pass the
2545      * SSH2_MSG_NEWKEYS packet to the next layer, not because it
2546      * wants to see it but because it will need time to initialise
2547      * itself before it sees an actual packet. In subsequent key
2548      * exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
2549      * it would only confuse the layer above.
2550      */
2551     if (!first_kex) {
2552         crReturn(0);
2553     }
2554     first_kex = 0;
2555
2556     /*
2557      * Now we're encrypting. Begin returning 1 to the protocol main
2558      * function so that other things can run on top of the
2559      * transport. If we ever see a KEXINIT, we must go back to the
2560      * start.
2561      */
2562     while (!(ispkt && pktin.type == SSH2_MSG_KEXINIT)) {
2563         crReturn(1);
2564     }
2565     logevent("Server initiated key re-exchange");
2566     goto begin_key_exchange;
2567
2568     crFinish(1);
2569 }
2570
2571 /*
2572  * Add data to an SSH2 channel output buffer.
2573  */
2574 static void ssh2_add_channel_data(struct ssh_channel *c, char *buf, int len) {
2575     if (c->v2.outbufsize <
2576         c->v2.outbuflen + len) {
2577         c->v2.outbufsize =
2578             c->v2.outbuflen + len + 1024;
2579         c->v2.outbuffer = srealloc(c->v2.outbuffer,
2580                                    c->v2.outbufsize);
2581     }
2582     memcpy(c->v2.outbuffer + c->v2.outbuflen,
2583            buf, len);
2584     c->v2.outbuflen += len;
2585 }
2586
2587 /*
2588  * Attempt to send data on an SSH2 channel.
2589  */
2590 static void ssh2_try_send(struct ssh_channel *c) {
2591     while (c->v2.remwindow > 0 &&
2592            c->v2.outbuflen > 0) {
2593         unsigned len = c->v2.remwindow;
2594         if (len > c->v2.outbuflen)
2595             len = c->v2.outbuflen;
2596         if (len > c->v2.remmaxpkt)
2597             len = c->v2.remmaxpkt;
2598         ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
2599         ssh2_pkt_adduint32(c->remoteid);
2600         ssh2_pkt_addstring_start();
2601         ssh2_pkt_addstring_data(c->v2.outbuffer, len);
2602         ssh2_pkt_send();
2603         c->v2.outbuflen -= len;
2604         memmove(c->v2.outbuffer, c->v2.outbuffer+len,
2605                 c->v2.outbuflen);
2606         c->v2.remwindow -= len;
2607     }
2608 }
2609
2610 /*
2611  * Handle the SSH2 userauth and connection layers.
2612  */
2613 static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
2614 {
2615     static unsigned long remote_winsize;
2616     static unsigned long remote_maxpkt;
2617
2618     crBegin;
2619
2620     /*
2621      * Request userauth protocol, and await a response to it.
2622      */
2623     ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
2624     ssh2_pkt_addstring("ssh-userauth");
2625     ssh2_pkt_send();
2626     crWaitUntilV(ispkt);
2627     if (pktin.type != SSH2_MSG_SERVICE_ACCEPT) {
2628         bombout(("Server refused user authentication protocol"));
2629         crReturnV;
2630     }
2631
2632     /*
2633      * FIXME: currently we support only password authentication.
2634      * (This places us technically in violation of the SSH2 spec.
2635      * We must fix this.)
2636      */
2637     while (1) {
2638         /*
2639          * Get a username and a password.
2640          */
2641         static char username[100];
2642         static char password[100];
2643         static int pos = 0;
2644         static char c;
2645
2646         if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
2647             c_write("login as: ", 10);
2648             ssh_send_ok = 1;
2649             while (pos >= 0) {
2650                 crWaitUntilV(!ispkt);
2651                 while (inlen--) switch (c = *in++) {
2652                   case 10: case 13:
2653                     username[pos] = 0;
2654                     pos = -1;
2655                     break;
2656                   case 8: case 127:
2657                     if (pos > 0) {
2658                         c_write("\b \b", 3);
2659                         pos--;
2660                     }
2661                     break;
2662                   case 21: case 27:
2663                     while (pos > 0) {
2664                         c_write("\b \b", 3);
2665                         pos--;
2666                     }
2667                     break;
2668                   case 3: case 4:
2669                     random_save_seed();
2670                     exit(0);
2671                     break;
2672                   default:
2673                     if (((c >= ' ' && c <= '~') ||
2674                          ((unsigned char)c >= 160)) && pos < 40) {
2675                         username[pos++] = c;
2676                         c_write(&c, 1);
2677                     }
2678                     break;
2679                 }
2680             }
2681             c_write("\r\n", 2);
2682             username[strcspn(username, "\n\r")] = '\0';
2683         } else {
2684             char stuff[200];
2685             strncpy(username, cfg.username, 99);
2686             username[99] = '\0';
2687             if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
2688                 sprintf(stuff, "Using username \"%s\".\r\n", username);
2689                 c_write(stuff, strlen(stuff));
2690             }
2691         }
2692
2693         if (ssh_get_password) {
2694             char prompt[200];
2695             sprintf(prompt, "%.90s@%.90s's password: ", username, savedhost);
2696             if (!ssh_get_password(prompt, password, sizeof(password))) {
2697                 /*
2698                  * get_password failed to get a password (for
2699                  * example because one was supplied on the command
2700                  * line which has already failed to work).
2701                  * Terminate.
2702                  */
2703                 logevent("No more passwords to try");
2704                 ssh_state = SSH_STATE_CLOSED;
2705                 crReturnV;
2706             }
2707         } else {
2708             c_write("password: ", 10);
2709             ssh_send_ok = 1;
2710
2711             pos = 0;
2712             while (pos >= 0) {
2713                 crWaitUntilV(!ispkt);
2714                 while (inlen--) switch (c = *in++) {
2715                   case 10: case 13:
2716                     password[pos] = 0;
2717                     pos = -1;
2718                     break;
2719                   case 8: case 127:
2720                     if (pos > 0)
2721                         pos--;
2722                     break;
2723                   case 21: case 27:
2724                     pos = 0;
2725                     break;
2726                   case 3: case 4:
2727                     random_save_seed();
2728                     exit(0);
2729                     break;
2730                   default:
2731                     if (((c >= ' ' && c <= '~') ||
2732                          ((unsigned char)c >= 160)) && pos < 40)
2733                         password[pos++] = c;
2734                     break;
2735                 }
2736             }
2737             c_write("\r\n", 2);
2738         }
2739
2740         /*
2741          * We send the password packet lumped tightly together with
2742          * an SSH_MSG_IGNORE packet. The IGNORE packet contains a
2743          * string long enough to make the total length of the two
2744          * packets constant. This should ensure that a passive
2745          * listener doing traffic analyis can't work out the length
2746          * of the password.
2747          * 
2748          * For this to work, we need an assumption about the
2749          * maximum length of the password packet. I think 256 is
2750          * pretty conservative. Anyone using a password longer than
2751          * that probably doesn't have much to worry about from
2752          * people who find out how long their password is!
2753          */
2754         ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
2755         ssh2_pkt_addstring(username);
2756         ssh2_pkt_addstring("ssh-connection");   /* service requested */
2757         ssh2_pkt_addstring("password");
2758         ssh2_pkt_addbool(FALSE);
2759         ssh2_pkt_addstring(password);
2760         ssh2_pkt_defer();
2761         /*
2762          * We'll include a string that's an exact multiple of the
2763          * cipher block size. If the cipher is NULL for some
2764          * reason, we don't do this trick at all because we gain
2765          * nothing by it.
2766          */
2767         if (cscipher) {
2768             int i, j;
2769             ssh2_pkt_init(SSH2_MSG_IGNORE);
2770             ssh2_pkt_addstring_start();
2771             for (i = deferred_len; i <= 256; i += cscipher->blksize) {
2772                 for (j = 0; j < cscipher->blksize; j++) {
2773                     char c = (char)random_byte();
2774                     ssh2_pkt_addstring_data(&c, 1);
2775                 }
2776             }
2777             ssh2_pkt_defer();
2778         }
2779         ssh2_pkt_defersend();
2780
2781         crWaitUntilV(ispkt);
2782         if (pktin.type != SSH2_MSG_USERAUTH_SUCCESS) {
2783             c_write("Access denied\r\n", 15);
2784             logevent("Authentication refused");
2785         } else
2786             break;
2787     }
2788
2789     /*
2790      * Now we're authenticated for the connection protocol. The
2791      * connection protocol will automatically have started at this
2792      * point; there's no need to send SERVICE_REQUEST.
2793      */
2794
2795     /*
2796      * So now create a channel with a session in it.
2797      */
2798     mainchan = smalloc(sizeof(struct ssh_channel));
2799     mainchan->localid = 100;           /* as good as any */
2800     ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
2801     ssh2_pkt_addstring("session");
2802     ssh2_pkt_adduint32(mainchan->localid);
2803     ssh2_pkt_adduint32(0x8000UL);  /* our window size */
2804     ssh2_pkt_adduint32(0x4000UL);  /* our max pkt size */
2805     ssh2_pkt_send();
2806     crWaitUntilV(ispkt);
2807     if (pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
2808         bombout(("Server refused to open a session"));
2809         crReturnV;
2810         /* FIXME: error data comes back in FAILURE packet */
2811     }
2812     if (ssh2_pkt_getuint32() != mainchan->localid) {
2813         bombout(("Server's channel confirmation cited wrong channel"));
2814         crReturnV;
2815     }
2816     mainchan->remoteid = ssh2_pkt_getuint32();
2817     mainchan->type = CHAN_MAINSESSION;
2818     mainchan->closes = 0;
2819     mainchan->v2.remwindow = ssh2_pkt_getuint32();
2820     mainchan->v2.remmaxpkt = ssh2_pkt_getuint32();
2821     mainchan->v2.outbuffer = NULL;
2822     mainchan->v2.outbuflen = mainchan->v2.outbufsize = 0;
2823     ssh_channels = newtree234(ssh_channelcmp);
2824     add234(ssh_channels, mainchan);
2825     logevent("Opened channel for session");
2826
2827     /*
2828      * Potentially enable X11 forwarding.
2829      */
2830     if (cfg.x11_forward) {
2831         char proto[20], data[64];
2832         logevent("Requesting X11 forwarding");
2833         x11_invent_auth(proto, sizeof(proto), data, sizeof(data));
2834         ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
2835         ssh2_pkt_adduint32(mainchan->remoteid);
2836         ssh2_pkt_addstring("x11-req");
2837         ssh2_pkt_addbool(1);           /* want reply */
2838         ssh2_pkt_addbool(0);           /* many connections */
2839         ssh2_pkt_addstring(proto);
2840         ssh2_pkt_addstring(data);
2841         ssh2_pkt_adduint32(0);         /* screen number */
2842         ssh2_pkt_send();
2843
2844         do {
2845             crWaitUntilV(ispkt);
2846             if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
2847                 unsigned i = ssh2_pkt_getuint32();
2848                 struct ssh_channel *c;
2849                 c = find234(ssh_channels, &i, ssh_channelfind);
2850                 if (!c)
2851                     continue;          /* nonexistent channel */
2852                 c->v2.remwindow += ssh2_pkt_getuint32();
2853             }
2854         } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
2855
2856         if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
2857             if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
2858                 bombout(("Server got confused by X11 forwarding request"));
2859                 crReturnV;
2860             }
2861             logevent("X11 forwarding refused");
2862         } else {
2863             logevent("X11 forwarding enabled");
2864             ssh_X11_fwd_enabled = TRUE;
2865         }
2866     }
2867
2868     /*
2869      * Now allocate a pty for the session.
2870      */
2871     if (!cfg.nopty) {
2872         ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
2873         ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */
2874         ssh2_pkt_addstring("pty-req");
2875         ssh2_pkt_addbool(1);           /* want reply */
2876         ssh2_pkt_addstring(cfg.termtype);
2877         ssh2_pkt_adduint32(cols);
2878         ssh2_pkt_adduint32(rows);
2879         ssh2_pkt_adduint32(0);         /* pixel width */
2880         ssh2_pkt_adduint32(0);         /* pixel height */
2881         ssh2_pkt_addstring_start();
2882         ssh2_pkt_addstring_data("\0", 1);/* TTY_OP_END, no special options */
2883         ssh2_pkt_send();
2884         ssh_state = SSH_STATE_INTERMED;
2885
2886         do {
2887             crWaitUntilV(ispkt);
2888             if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
2889                 unsigned i = ssh2_pkt_getuint32();
2890                 struct ssh_channel *c;
2891                 c = find234(ssh_channels, &i, ssh_channelfind);
2892                 if (!c)
2893                     continue;          /* nonexistent channel */
2894                 c->v2.remwindow += ssh2_pkt_getuint32();
2895             }
2896         } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
2897
2898         if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
2899             if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
2900                 bombout(("Server got confused by pty request"));
2901                 crReturnV;
2902             }
2903             c_write("Server refused to allocate pty\r\n", 32);
2904             ssh_editing = ssh_echoing = 1;
2905         } else {
2906             logevent("Allocated pty");
2907         }
2908     } else {
2909         ssh_editing = ssh_echoing = 1;
2910     }
2911
2912     /*
2913      * Start a shell or a remote command.
2914      */
2915     ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
2916     ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */
2917     if (cfg.ssh_subsys) {
2918         ssh2_pkt_addstring("subsystem");
2919         ssh2_pkt_addbool(1);           /* want reply */
2920         ssh2_pkt_addstring(cfg.remote_cmd);
2921     } else if (*cfg.remote_cmd) {
2922         ssh2_pkt_addstring("exec");
2923         ssh2_pkt_addbool(1);           /* want reply */
2924         ssh2_pkt_addstring(cfg.remote_cmd);
2925     } else {
2926         ssh2_pkt_addstring("shell");
2927         ssh2_pkt_addbool(1);           /* want reply */
2928     }
2929     ssh2_pkt_send();
2930     do {
2931         crWaitUntilV(ispkt);
2932         if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
2933             unsigned i = ssh2_pkt_getuint32();
2934             struct ssh_channel *c;
2935             c = find234(ssh_channels, &i, ssh_channelfind);
2936             if (!c)
2937                 continue;              /* nonexistent channel */
2938             c->v2.remwindow += ssh2_pkt_getuint32();
2939         }
2940     } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
2941     if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
2942         if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
2943             bombout(("Server got confused by shell/command request"));
2944             crReturnV;
2945         }
2946         bombout(("Server refused to start a shell/command"));
2947         crReturnV;
2948     } else {
2949         logevent("Started a shell/command");
2950     }
2951
2952     ssh_state = SSH_STATE_SESSION;
2953     if (size_needed)
2954         ssh_size();
2955     if (eof_needed)
2956         ssh_special(TS_EOF);
2957
2958     /*
2959      * Transfer data!
2960      */
2961     ldisc_send(NULL, 0);               /* cause ldisc to notice changes */
2962     ssh_send_ok = 1;
2963     while (1) {
2964         static int try_send;
2965         crReturnV;
2966         try_send = FALSE;
2967         if (ispkt) {
2968             if (pktin.type == SSH2_MSG_CHANNEL_DATA ||
2969                 pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
2970                 char *data;
2971                 int length;
2972                 unsigned i = ssh2_pkt_getuint32();
2973                 struct ssh_channel *c;
2974                 c = find234(ssh_channels, &i, ssh_channelfind);
2975                 if (!c)
2976                     continue;          /* nonexistent channel */
2977                 if (pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
2978                     ssh2_pkt_getuint32() != SSH2_EXTENDED_DATA_STDERR)
2979                     continue;          /* extended but not stderr */
2980                 ssh2_pkt_getstring(&data, &length);
2981                 if (data) {
2982                     switch (c->type) {
2983                       case CHAN_MAINSESSION:
2984                         from_backend(pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA,
2985                                      data, length);
2986                         break;
2987                       case CHAN_X11:
2988                         x11_send(c->u.x11.s, data, length);
2989                         break;
2990                     }
2991                     /*
2992                      * Enlarge the window again at the remote
2993                      * side, just in case it ever runs down and
2994                      * they fail to send us any more data.
2995                      */
2996                     ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
2997                     ssh2_pkt_adduint32(c->remoteid);
2998                     ssh2_pkt_adduint32(length);
2999                     ssh2_pkt_send();
3000                 }
3001             } else if (pktin.type == SSH2_MSG_DISCONNECT) {
3002                 ssh_state = SSH_STATE_CLOSED;
3003                 logevent("Received disconnect message");
3004                 crReturnV;
3005             } else if (pktin.type == SSH2_MSG_CHANNEL_REQUEST) {
3006                 continue;              /* exit status et al; ignore (FIXME?) */
3007             } else if (pktin.type == SSH2_MSG_CHANNEL_EOF) {
3008                 unsigned i = ssh2_pkt_getuint32();
3009                 struct ssh_channel *c;
3010
3011                 c = find234(ssh_channels, &i, ssh_channelfind);
3012                 if (!c)
3013                     continue;          /* nonexistent channel */
3014                 
3015                 if (c->type == CHAN_X11) {
3016                     /*
3017                      * Remote EOF on an X11 channel means we should
3018                      * wrap up and close the channel ourselves.
3019                      */
3020                     x11_close(c->u.x11.s);
3021                     sshfwd_close(c);
3022                 }
3023             } else if (pktin.type == SSH2_MSG_CHANNEL_CLOSE) {
3024                 unsigned i = ssh2_pkt_getuint32();
3025                 struct ssh_channel *c;
3026                 enum234 e;
3027
3028                 c = find234(ssh_channels, &i, ssh_channelfind);
3029                 if (!c)
3030                     continue;          /* nonexistent channel */
3031                 if (c->closes == 0) {
3032                     ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
3033                     ssh2_pkt_adduint32(c->remoteid);
3034                     ssh2_pkt_send();
3035                 }
3036                 /* Do pre-close processing on the channel. */
3037                 switch (c->type) {
3038                   case CHAN_MAINSESSION:
3039                     break;             /* nothing to see here, move along */
3040                   case CHAN_X11:
3041                     break;
3042                 }
3043                 del234(ssh_channels, c);
3044                 sfree(c->v2.outbuffer);
3045                 sfree(c);
3046
3047                 /*
3048                  * See if that was the last channel left open.
3049                  */
3050                 c = first234(ssh_channels, &e);
3051                 if (!c) {
3052                     logevent("All channels closed. Disconnecting");
3053                     ssh2_pkt_init(SSH2_MSG_DISCONNECT);
3054                     ssh2_pkt_adduint32(SSH2_DISCONNECT_BY_APPLICATION);
3055                     ssh2_pkt_addstring("All open channels closed");
3056                     ssh2_pkt_addstring("en");   /* language tag */
3057                     ssh2_pkt_send();
3058                     ssh_state = SSH_STATE_CLOSED;
3059                     crReturnV;
3060                 }
3061                 continue;              /* remote sends close; ignore (FIXME) */
3062             } else if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
3063                 unsigned i = ssh2_pkt_getuint32();
3064                 struct ssh_channel *c;
3065                 c = find234(ssh_channels, &i, ssh_channelfind);
3066                 if (!c)
3067                     continue;          /* nonexistent channel */
3068                 mainchan->v2.remwindow += ssh2_pkt_getuint32();
3069                 try_send = TRUE;
3070             } else if (pktin.type == SSH2_MSG_CHANNEL_OPEN) {
3071                 char *type;
3072                 int typelen;
3073                 char *error = NULL;
3074                 struct ssh_channel *c;
3075                 ssh2_pkt_getstring(&type, &typelen);
3076                 c = smalloc(sizeof(struct ssh_channel));
3077
3078                 if (typelen == 3 && !memcmp(type, "x11", 3)) {
3079                     if (!ssh_X11_fwd_enabled)
3080                         error = "X11 forwarding is not enabled";
3081                     else if ( x11_init(&c->u.x11.s, cfg.x11_display, c) != NULL ) {
3082                         error = "Unable to open an X11 connection";
3083                     } else {
3084                         c->type = CHAN_X11;
3085                     }
3086                 } else {
3087                     error = "Unsupported channel type requested";
3088                 }
3089
3090                 c->remoteid = ssh2_pkt_getuint32();
3091                 if (error) {
3092                     ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_FAILURE);
3093                     ssh2_pkt_adduint32(c->remoteid);
3094                     ssh2_pkt_adduint32(SSH2_OPEN_CONNECT_FAILED);
3095                     ssh2_pkt_addstring(error);
3096                     ssh2_pkt_addstring("en");   /* language tag */
3097                     ssh2_pkt_send();
3098                     sfree(c);
3099                 } else {
3100                     struct ssh_channel *d;
3101                     unsigned i;
3102                     enum234 e;
3103
3104                     for (i=1, d = first234(ssh_channels, &e); d;
3105                          d = next234(&e)) {
3106                         if (d->localid > i)
3107                             break;     /* found a free number */
3108                         i = d->localid + 1;
3109                     }
3110                     c->localid = i;
3111                     c->closes = 0;
3112                     c->v2.remwindow = ssh2_pkt_getuint32();
3113                     c->v2.remmaxpkt = ssh2_pkt_getuint32();
3114                     c->v2.outbuffer = NULL;
3115                     c->v2.outbuflen = c->v2.outbufsize = 0;
3116                     add234(ssh_channels, c);
3117                     ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
3118                     ssh2_pkt_adduint32(c->remoteid);
3119                     ssh2_pkt_adduint32(c->localid);
3120                     ssh2_pkt_adduint32(0x8000UL);  /* our window size */
3121                     ssh2_pkt_adduint32(0x4000UL);  /* our max pkt size */
3122                     ssh2_pkt_send();
3123                 }
3124             } else {
3125                 bombout(("Strange packet received: type %d", pktin.type));
3126                 crReturnV;
3127             }
3128         } else {
3129             /*
3130              * We have spare data. Add it to the channel buffer.
3131              */
3132             ssh2_add_channel_data(mainchan, in, inlen);
3133             try_send = TRUE;
3134         }
3135         if (try_send) {
3136             enum234 e;
3137             struct ssh_channel *c;
3138             /*
3139              * Try to send data on all channels if we can.
3140              */
3141             for (c = first234(ssh_channels, &e); c; c = next234(&e))
3142                 ssh2_try_send(c);
3143         }
3144     }
3145
3146     crFinishV;
3147 }
3148
3149 /*
3150  * Handle the top-level SSH2 protocol.
3151  */
3152 static void ssh2_protocol(unsigned char *in, int inlen, int ispkt)
3153 {
3154     if (do_ssh2_transport(in, inlen, ispkt) == 0)
3155         return;
3156     do_ssh2_authconn(in, inlen, ispkt);
3157 }
3158
3159 /*
3160  * Called to set up the connection.
3161  *
3162  * Returns an error message, or NULL on success.
3163  */
3164 static char *ssh_init (char *host, int port, char **realhost) {
3165     char *p;
3166         
3167 #ifdef MSCRYPTOAPI
3168     if(crypto_startup() == 0)
3169         return "Microsoft high encryption pack not installed!";
3170 #endif
3171
3172     ssh_send_ok = 0;
3173     ssh_editing = 0;
3174     ssh_echoing = 0;
3175
3176     p = connect_to_host(host, port, realhost);
3177     if (p != NULL)
3178         return p;
3179
3180     return NULL;
3181 }
3182
3183 /*
3184  * Called to send data down the Telnet connection.
3185  */
3186 static void ssh_send (char *buf, int len) {
3187     if (s == NULL || ssh_protocol == NULL)
3188         return;
3189
3190     ssh_protocol(buf, len, 0);
3191 }
3192
3193 /*
3194  * Called to set the size of the window from SSH's POV.
3195  */
3196 static void ssh_size(void) {
3197     switch (ssh_state) {
3198       case SSH_STATE_BEFORE_SIZE:
3199       case SSH_STATE_PREPACKET:
3200       case SSH_STATE_CLOSED:
3201         break;                         /* do nothing */
3202       case SSH_STATE_INTERMED:
3203         size_needed = TRUE;            /* buffer for later */
3204         break;
3205       case SSH_STATE_SESSION:
3206         if (!cfg.nopty) {
3207             if (ssh_version == 1) {
3208                 send_packet(SSH1_CMSG_WINDOW_SIZE,
3209                             PKT_INT, rows, PKT_INT, cols,
3210                             PKT_INT, 0, PKT_INT, 0, PKT_END);
3211             } else {
3212                 ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
3213                 ssh2_pkt_adduint32(mainchan->remoteid);
3214                 ssh2_pkt_addstring("window-change");
3215                 ssh2_pkt_addbool(0);
3216                 ssh2_pkt_adduint32(cols);
3217                 ssh2_pkt_adduint32(rows);
3218                 ssh2_pkt_adduint32(0);
3219                 ssh2_pkt_adduint32(0);
3220                 ssh2_pkt_send();
3221             }
3222         }
3223         break;
3224     }
3225 }
3226
3227 /*
3228  * Send Telnet special codes. TS_EOF is useful for `plink', so you
3229  * can send an EOF and collect resulting output (e.g. `plink
3230  * hostname sort').
3231  */
3232 static void ssh_special (Telnet_Special code) {
3233     if (code == TS_EOF) {
3234         if (ssh_state != SSH_STATE_SESSION) {
3235             /*
3236              * Buffer the EOF in case we are pre-SESSION, so we can
3237              * send it as soon as we reach SESSION.
3238              */
3239             if (code == TS_EOF)
3240                 eof_needed = TRUE;
3241             return;
3242         }
3243         if (ssh_version == 1) {
3244             send_packet(SSH1_CMSG_EOF, PKT_END);
3245         } else {
3246             ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
3247             ssh2_pkt_adduint32(mainchan->remoteid);
3248             ssh2_pkt_send();
3249         }
3250         logevent("Sent EOF message");
3251     } else if (code == TS_PING) {
3252         if (ssh_state == SSH_STATE_CLOSED || ssh_state == SSH_STATE_PREPACKET)
3253             return;
3254         if (ssh_version == 1) {
3255             send_packet(SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
3256         } else {
3257             ssh2_pkt_init(SSH2_MSG_IGNORE);
3258             ssh2_pkt_addstring_start();
3259             ssh2_pkt_send();
3260         }
3261     } else {
3262         /* do nothing */
3263     }
3264 }
3265
3266 static Socket ssh_socket(void) { return s; }
3267
3268 static int ssh_sendok(void) { return ssh_send_ok; }
3269
3270 static int ssh_ldisc(int option) {
3271     if (option == LD_ECHO) return ssh_echoing;
3272     if (option == LD_EDIT) return ssh_editing;
3273     return FALSE;
3274 }
3275
3276 Backend ssh_backend = {
3277     ssh_init,
3278     ssh_send,
3279     ssh_size,
3280     ssh_special,
3281     ssh_socket,
3282     ssh_sendok,
3283     ssh_ldisc,
3284     22
3285 };