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