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