]> asedeno.scripts.mit.edu Git - PuTTY_svn.git/blob - ssh.c
cbcf439fe69876c7c6aaef85d65afb69e39ad0a2
[PuTTY_svn.git] / ssh.c
1 #include <windows.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <stdarg.h>
5 #include <assert.h>
6
7 #include "putty.h"
8 #include "tree234.h"
9 #include "ssh.h"
10
11 #ifndef FALSE
12 #define FALSE 0
13 #endif
14 #ifndef TRUE
15 #define TRUE 1
16 #endif
17
18 /* uncomment this for packet level debugging */
19 /* #define DUMP_PACKETS */
20
21 #define logevent(s) { logevent(s); \
22                       if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) \
23                       { fprintf(stderr, "%s\n", s); fflush(stderr); } }
24
25 #define bombout(msg) ( ssh_state = SSH_STATE_CLOSED, \
26                           (s ? sk_close(s), s = NULL : 0), \
27                           connection_fatal msg )
28
29 #define SSH1_MSG_DISCONNECT                       1     /* 0x1 */
30 #define SSH1_SMSG_PUBLIC_KEY                      2     /* 0x2 */
31 #define SSH1_CMSG_SESSION_KEY                     3     /* 0x3 */
32 #define SSH1_CMSG_USER                            4     /* 0x4 */
33 #define SSH1_CMSG_AUTH_RSA                        6     /* 0x6 */
34 #define SSH1_SMSG_AUTH_RSA_CHALLENGE              7     /* 0x7 */
35 #define SSH1_CMSG_AUTH_RSA_RESPONSE               8     /* 0x8 */
36 #define SSH1_CMSG_AUTH_PASSWORD                   9     /* 0x9 */
37 #define SSH1_CMSG_REQUEST_PTY                     10    /* 0xa */
38 #define SSH1_CMSG_WINDOW_SIZE                     11    /* 0xb */
39 #define SSH1_CMSG_EXEC_SHELL                      12    /* 0xc */
40 #define SSH1_CMSG_EXEC_CMD                        13    /* 0xd */
41 #define SSH1_SMSG_SUCCESS                         14    /* 0xe */
42 #define SSH1_SMSG_FAILURE                         15    /* 0xf */
43 #define SSH1_CMSG_STDIN_DATA                      16    /* 0x10 */
44 #define SSH1_SMSG_STDOUT_DATA                     17    /* 0x11 */
45 #define SSH1_SMSG_STDERR_DATA                     18    /* 0x12 */
46 #define SSH1_CMSG_EOF                             19    /* 0x13 */
47 #define SSH1_SMSG_EXIT_STATUS                     20    /* 0x14 */
48 #define SSH1_MSG_CHANNEL_OPEN_CONFIRMATION        21    /* 0x15 */
49 #define SSH1_MSG_CHANNEL_OPEN_FAILURE             22    /* 0x16 */
50 #define SSH1_MSG_CHANNEL_DATA                     23    /* 0x17 */
51 #define SSH1_MSG_CHANNEL_CLOSE                    24    /* 0x18 */
52 #define SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION       25    /* 0x19 */
53 #define SSH1_SMSG_X11_OPEN                        27    /* 0x1b */
54 #define SSH1_CMSG_PORT_FORWARD_REQUEST            28    /* 0x1c */
55 #define SSH1_MSG_PORT_OPEN                        29    /* 0x1d */
56 #define SSH1_CMSG_AGENT_REQUEST_FORWARDING        30    /* 0x1e */
57 #define SSH1_SMSG_AGENT_OPEN                      31    /* 0x1f */
58 #define SSH1_MSG_IGNORE                           32    /* 0x20 */
59 #define SSH1_CMSG_EXIT_CONFIRMATION               33    /* 0x21 */
60 #define SSH1_CMSG_X11_REQUEST_FORWARDING          34    /* 0x22 */
61 #define SSH1_CMSG_AUTH_RHOSTS_RSA                 35    /* 0x23 */
62 #define SSH1_MSG_DEBUG                            36    /* 0x24 */
63 #define SSH1_CMSG_REQUEST_COMPRESSION             37    /* 0x25 */
64 #define SSH1_CMSG_AUTH_TIS                        39    /* 0x27 */
65 #define SSH1_SMSG_AUTH_TIS_CHALLENGE              40    /* 0x28 */
66 #define SSH1_CMSG_AUTH_TIS_RESPONSE               41    /* 0x29 */
67 #define SSH1_CMSG_AUTH_CCARD                      70    /* 0x46 */
68 #define SSH1_SMSG_AUTH_CCARD_CHALLENGE            71    /* 0x47 */
69 #define SSH1_CMSG_AUTH_CCARD_RESPONSE             72    /* 0x48 */
70
71 #define SSH1_AUTH_TIS                             5     /* 0x5 */
72 #define SSH1_AUTH_CCARD                           16    /* 0x10 */
73
74 #define SSH1_PROTOFLAG_SCREEN_NUMBER              1     /* 0x1 */
75 /* Mask for protoflags we will echo back to server if seen */
76 #define SSH1_PROTOFLAGS_SUPPORTED                 0     /* 0x1 */
77
78 #define SSH2_MSG_DISCONNECT                       1     /* 0x1 */
79 #define SSH2_MSG_IGNORE                           2     /* 0x2 */
80 #define SSH2_MSG_UNIMPLEMENTED                    3     /* 0x3 */
81 #define SSH2_MSG_DEBUG                            4     /* 0x4 */
82 #define SSH2_MSG_SERVICE_REQUEST                  5     /* 0x5 */
83 #define SSH2_MSG_SERVICE_ACCEPT                   6     /* 0x6 */
84 #define SSH2_MSG_KEXINIT                          20    /* 0x14 */
85 #define SSH2_MSG_NEWKEYS                          21    /* 0x15 */
86 #define SSH2_MSG_KEXDH_INIT                       30    /* 0x1e */
87 #define SSH2_MSG_KEXDH_REPLY                      31    /* 0x1f */
88 #define SSH2_MSG_KEX_DH_GEX_REQUEST               30    /* 0x1e */
89 #define SSH2_MSG_KEX_DH_GEX_GROUP                 31    /* 0x1f */
90 #define SSH2_MSG_KEX_DH_GEX_INIT                  32    /* 0x20 */
91 #define SSH2_MSG_KEX_DH_GEX_REPLY                 33    /* 0x21 */
92 #define SSH2_MSG_USERAUTH_REQUEST                 50    /* 0x32 */
93 #define SSH2_MSG_USERAUTH_FAILURE                 51    /* 0x33 */
94 #define SSH2_MSG_USERAUTH_SUCCESS                 52    /* 0x34 */
95 #define SSH2_MSG_USERAUTH_BANNER                  53    /* 0x35 */
96 #define SSH2_MSG_USERAUTH_PK_OK                   60    /* 0x3c */
97 #define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ        60    /* 0x3c */
98 #define SSH2_MSG_GLOBAL_REQUEST                   80    /* 0x50 */
99 #define SSH2_MSG_REQUEST_SUCCESS                  81    /* 0x51 */
100 #define SSH2_MSG_REQUEST_FAILURE                  82    /* 0x52 */
101 #define SSH2_MSG_CHANNEL_OPEN                     90    /* 0x5a */
102 #define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION        91    /* 0x5b */
103 #define SSH2_MSG_CHANNEL_OPEN_FAILURE             92    /* 0x5c */
104 #define SSH2_MSG_CHANNEL_WINDOW_ADJUST            93    /* 0x5d */
105 #define SSH2_MSG_CHANNEL_DATA                     94    /* 0x5e */
106 #define SSH2_MSG_CHANNEL_EXTENDED_DATA            95    /* 0x5f */
107 #define SSH2_MSG_CHANNEL_EOF                      96    /* 0x60 */
108 #define SSH2_MSG_CHANNEL_CLOSE                    97    /* 0x61 */
109 #define SSH2_MSG_CHANNEL_REQUEST                  98    /* 0x62 */
110 #define SSH2_MSG_CHANNEL_SUCCESS                  99    /* 0x63 */
111 #define SSH2_MSG_CHANNEL_FAILURE                  100   /* 0x64 */
112
113 #define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1   /* 0x1 */
114 #define SSH2_DISCONNECT_PROTOCOL_ERROR            2     /* 0x2 */
115 #define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED       3     /* 0x3 */
116 #define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4    /* 0x4 */
117 #define SSH2_DISCONNECT_MAC_ERROR                 5     /* 0x5 */
118 #define SSH2_DISCONNECT_COMPRESSION_ERROR         6     /* 0x6 */
119 #define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE     7     /* 0x7 */
120 #define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8        /* 0x8 */
121 #define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE   9     /* 0x9 */
122 #define SSH2_DISCONNECT_CONNECTION_LOST           10    /* 0xa */
123 #define SSH2_DISCONNECT_BY_APPLICATION            11    /* 0xb */
124 #define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS      12    /* 0xc */
125 #define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER    13    /* 0xd */
126 #define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14       /* 0xe */
127 #define SSH2_DISCONNECT_ILLEGAL_USER_NAME         15    /* 0xf */
128
129 static const char *const ssh2_disconnect_reasons[] = {
130     NULL,
131     "SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT",
132     "SSH_DISCONNECT_PROTOCOL_ERROR",
133     "SSH_DISCONNECT_KEY_EXCHANGE_FAILED",
134     "SSH_DISCONNECT_HOST_AUTHENTICATION_FAILED",
135     "SSH_DISCONNECT_MAC_ERROR",
136     "SSH_DISCONNECT_COMPRESSION_ERROR",
137     "SSH_DISCONNECT_SERVICE_NOT_AVAILABLE",
138     "SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED",
139     "SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE",
140     "SSH_DISCONNECT_CONNECTION_LOST",
141     "SSH_DISCONNECT_BY_APPLICATION",
142     "SSH_DISCONNECT_TOO_MANY_CONNECTIONS",
143     "SSH_DISCONNECT_AUTH_CANCELLED_BY_USER",
144     "SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE",
145     "SSH_DISCONNECT_ILLEGAL_USER_NAME",
146 };
147
148 #define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED     1     /* 0x1 */
149 #define SSH2_OPEN_CONNECT_FAILED                  2     /* 0x2 */
150 #define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE            3     /* 0x3 */
151 #define SSH2_OPEN_RESOURCE_SHORTAGE               4     /* 0x4 */
152
153 #define SSH2_EXTENDED_DATA_STDERR                 1     /* 0x1 */
154
155 /*
156  * Various remote-bug flags.
157  */
158 #define BUG_CHOKES_ON_SSH1_IGNORE                 1
159 #define BUG_SSH2_HMAC                             2
160
161 #define GET_32BIT(cp) \
162     (((unsigned long)(unsigned char)(cp)[0] << 24) | \
163     ((unsigned long)(unsigned char)(cp)[1] << 16) | \
164     ((unsigned long)(unsigned char)(cp)[2] << 8) | \
165     ((unsigned long)(unsigned char)(cp)[3]))
166
167 #define PUT_32BIT(cp, value) { \
168     (cp)[0] = (unsigned char)((value) >> 24); \
169     (cp)[1] = (unsigned char)((value) >> 16); \
170     (cp)[2] = (unsigned char)((value) >> 8); \
171     (cp)[3] = (unsigned char)(value); }
172
173 enum { PKT_END, PKT_INT, PKT_CHAR, PKT_DATA, PKT_STR, PKT_BIGNUM };
174
175 /* Coroutine mechanics for the sillier bits of the code */
176 #define crBegin1        static int crLine = 0;
177 #define crBegin2        switch(crLine) { case 0:;
178 #define crBegin         crBegin1; crBegin2;
179 #define crFinish(z)     } crLine = 0; return (z)
180 #define crFinishV       } crLine = 0; return
181 #define crReturn(z)     \
182         do {\
183             crLine=__LINE__; return (z); case __LINE__:;\
184         } while (0)
185 #define crReturnV       \
186         do {\
187             crLine=__LINE__; return; case __LINE__:;\
188         } while (0)
189 #define crStop(z)       do{ crLine = 0; return (z); }while(0)
190 #define crStopV         do{ crLine = 0; return; }while(0)
191 #define crWaitUntil(c)  do { crReturn(0); } while (!(c))
192 #define crWaitUntilV(c) do { crReturnV; } while (!(c))
193
194 extern char *x11_init(Socket *, char *, void *);
195 extern void x11_close(Socket);
196 extern void x11_send(Socket, char *, int);
197 extern void x11_invent_auth(char *, int, char *, int);
198
199 extern char *pfd_newconnect(Socket * s, char *hostname, int port, void *c);
200 extern char *pfd_addforward(char *desthost, int destport, int port);
201 extern void pfd_close(Socket s);
202 extern void pfd_send(Socket s, char *data, int len);
203 extern void pfd_confirm(Socket s);
204
205 /*
206  * Ciphers for SSH2. We miss out single-DES because it isn't
207  * supported; also 3DES and Blowfish are both done differently from
208  * SSH1. (3DES uses outer chaining; Blowfish has the opposite
209  * endianness and different-sized keys.)
210  */
211 const static struct ssh2_ciphers *ciphers[] = {
212     &ssh2_aes,
213     &ssh2_blowfish,
214     &ssh2_3des,
215 };
216
217 const static struct ssh_kex *kex_algs[] = {
218     &ssh_diffiehellman_gex,
219     &ssh_diffiehellman
220 };
221
222 const static struct ssh_signkey *hostkey_algs[] = { &ssh_rsa, &ssh_dss };
223
224 static void nullmac_key(unsigned char *key)
225 {
226 }
227 static void nullmac_generate(unsigned char *blk, int len,
228                              unsigned long seq)
229 {
230 }
231 static int nullmac_verify(unsigned char *blk, int len, unsigned long seq)
232 {
233     return 1;
234 }
235 const static struct ssh_mac ssh_mac_none = {
236     nullmac_key, nullmac_key, nullmac_generate, nullmac_verify, "none", 0
237 };
238 const static struct ssh_mac *macs[] = {
239     &ssh_sha1, &ssh_md5, &ssh_mac_none
240 };
241 const static struct ssh_mac *buggymacs[] = {
242     &ssh_sha1_buggy, &ssh_md5, &ssh_mac_none
243 };
244
245 static void ssh_comp_none_init(void)
246 {
247 }
248 static int ssh_comp_none_block(unsigned char *block, int len,
249                                unsigned char **outblock, int *outlen)
250 {
251     return 0;
252 }
253 static int ssh_comp_none_disable(void)
254 {
255     return 0;
256 }
257 const static struct ssh_compress ssh_comp_none = {
258     "none",
259     ssh_comp_none_init, ssh_comp_none_block,
260     ssh_comp_none_init, ssh_comp_none_block,
261     ssh_comp_none_disable
262 };
263 extern const struct ssh_compress ssh_zlib;
264 const static struct ssh_compress *compressions[] = {
265     &ssh_zlib, &ssh_comp_none
266 };
267
268 enum {                                 /* channel types */
269     CHAN_MAINSESSION,
270     CHAN_X11,
271     CHAN_AGENT,
272     CHAN_SOCKDATA
273 };
274
275 /*
276  * 2-3-4 tree storing channels.
277  */
278 struct ssh_channel {
279     unsigned remoteid, localid;
280     int type;
281     int closes;
282     struct ssh2_data_channel {
283         unsigned char *outbuffer;
284         unsigned outbuflen, outbufsize;
285         unsigned remwindow, remmaxpkt;
286     } v2;
287     union {
288         struct ssh_agent_channel {
289             unsigned char *message;
290             unsigned char msglen[4];
291             int lensofar, totallen;
292         } a;
293         struct ssh_x11_channel {
294             Socket s;
295         } x11;
296         struct ssh_pfd_channel {
297             Socket s;
298         } pfd;
299     } u;
300 };
301
302 /*
303  * 2-3-4 tree storing remote->local port forwardings (so we can
304  * reject any attempt to open a port we didn't explicitly ask to
305  * have forwarded).
306  */
307 struct ssh_rportfwd {
308     unsigned port;
309     char host[256];
310 };
311
312 struct Packet {
313     long length;
314     int type;
315     unsigned char *data;
316     unsigned char *body;
317     long savedpos;
318     long maxlen;
319 };
320
321 static SHA_State exhash, exhashbase;
322
323 static Socket s = NULL;
324
325 static unsigned char session_key[32];
326 static int ssh1_compressing;
327 static int ssh1_remote_protoflags;
328 static int ssh1_local_protoflags;
329 static int ssh_agentfwd_enabled;
330 static int ssh_X11_fwd_enabled;
331 static int ssh_remote_bugs;
332 static const struct ssh_cipher *cipher = NULL;
333 static const struct ssh2_cipher *cscipher = NULL;
334 static const struct ssh2_cipher *sccipher = NULL;
335 static const struct ssh_mac *csmac = NULL;
336 static const struct ssh_mac *scmac = NULL;
337 static const struct ssh_compress *cscomp = NULL;
338 static const struct ssh_compress *sccomp = NULL;
339 static const struct ssh_kex *kex = NULL;
340 static const struct ssh_signkey *hostkey = NULL;
341 static unsigned char ssh2_session_id[20];
342 int (*ssh_get_line) (const char *prompt, char *str, int maxlen,
343                      int is_pw) = NULL;
344
345 static char *savedhost;
346 static int savedport;
347 static int ssh_send_ok;
348 static int ssh_echoing, ssh_editing;
349
350 static tree234 *ssh_channels;          /* indexed by local id */
351 static struct ssh_channel *mainchan;   /* primary session channel */
352
353 static tree234 *ssh_rportfwds;
354
355 static enum {
356     SSH_STATE_PREPACKET,
357     SSH_STATE_BEFORE_SIZE,
358     SSH_STATE_INTERMED,
359     SSH_STATE_SESSION,
360     SSH_STATE_CLOSED
361 } ssh_state = SSH_STATE_PREPACKET;
362
363 static int size_needed = FALSE, eof_needed = FALSE;
364
365 static struct Packet pktin = { 0, 0, NULL, NULL, 0 };
366 static struct Packet pktout = { 0, 0, NULL, NULL, 0 };
367 static unsigned char *deferred_send_data = NULL;
368 static int deferred_len = 0, deferred_size = 0;
369
370 static int ssh_version;
371 static void (*ssh_protocol) (unsigned char *in, int inlen, int ispkt);
372 static void ssh1_protocol(unsigned char *in, int inlen, int ispkt);
373 static void ssh2_protocol(unsigned char *in, int inlen, int ispkt);
374 static void ssh_size(void);
375 static void ssh_special(Telnet_Special);
376 static void ssh2_try_send(struct ssh_channel *c);
377 static void ssh2_add_channel_data(struct ssh_channel *c, char *buf,
378                                   int len);
379
380 static int (*s_rdpkt) (unsigned char **data, int *datalen);
381
382 static struct rdpkt1_state_tag {
383     long len, pad, biglen, to_read;
384     unsigned long realcrc, gotcrc;
385     unsigned char *p;
386     int i;
387     int chunk;
388 } rdpkt1_state;
389
390 static struct rdpkt2_state_tag {
391     long len, pad, payload, packetlen, maclen;
392     int i;
393     int cipherblk;
394     unsigned long incoming_sequence;
395 } rdpkt2_state;
396
397 static int ssh_channelcmp(void *av, void *bv)
398 {
399     struct ssh_channel *a = (struct ssh_channel *) av;
400     struct ssh_channel *b = (struct ssh_channel *) bv;
401     if (a->localid < b->localid)
402         return -1;
403     if (a->localid > b->localid)
404         return +1;
405     return 0;
406 }
407 static int ssh_channelfind(void *av, void *bv)
408 {
409     unsigned *a = (unsigned *) av;
410     struct ssh_channel *b = (struct ssh_channel *) bv;
411     if (*a < b->localid)
412         return -1;
413     if (*a > b->localid)
414         return +1;
415     return 0;
416 }
417
418 static int ssh_rportcmp(void *av, void *bv)
419 {
420     struct ssh_rportfwd *a = (struct ssh_rportfwd *) av;
421     struct ssh_rportfwd *b = (struct ssh_rportfwd *) bv;
422     int i;
423     if ( (i = strcmp(a->host, b->host)) != 0)
424         return i < 0 ? -1 : +1;
425     if (a->port > b->port)
426         return +1;
427     return 0;
428 }
429
430 static int alloc_channel_id(void)
431 {
432     const unsigned CHANNEL_NUMBER_OFFSET = 256;
433     unsigned low, high, mid;
434     int tsize;
435     struct ssh_channel *c;
436
437     /*
438      * First-fit allocation of channel numbers: always pick the
439      * lowest unused one. To do this, binary-search using the
440      * counted B-tree to find the largest channel ID which is in a
441      * contiguous sequence from the beginning. (Precisely
442      * everything in that sequence must have ID equal to its tree
443      * index plus CHANNEL_NUMBER_OFFSET.)
444      */
445     tsize = count234(ssh_channels);
446
447     low = -1;
448     high = tsize;
449     while (high - low > 1) {
450         mid = (high + low) / 2;
451         c = index234(ssh_channels, mid);
452         if (c->localid == mid + CHANNEL_NUMBER_OFFSET)
453             low = mid;                 /* this one is fine */
454         else
455             high = mid;                /* this one is past it */
456     }
457     /*
458      * Now low points to either -1, or the tree index of the
459      * largest ID in the initial sequence.
460      */
461     {
462         unsigned i = low + 1 + CHANNEL_NUMBER_OFFSET;
463         assert(NULL == find234(ssh_channels, &i, ssh_channelfind));
464     }
465     return low + 1 + CHANNEL_NUMBER_OFFSET;
466 }
467
468 static void c_write(char *buf, int len)
469 {
470     if ((flags & FLAG_STDERR)) {
471         int i;
472         for (i = 0; i < len; i++)
473             if (buf[i] != '\r')
474                 fputc(buf[i], stderr);
475         return;
476     }
477     from_backend(1, buf, len);
478 }
479
480 static void c_write_untrusted(char *buf, int len)
481 {
482     int i;
483     for (i = 0; i < len; i++) {
484         if (buf[i] == '\n')
485             c_write("\r\n", 2);
486         else if ((buf[i] & 0x60) || (buf[i] == '\r'))
487             c_write(buf + i, 1);
488     }
489 }
490
491 static void c_write_str(char *buf)
492 {
493     c_write(buf, strlen(buf));
494 }
495
496 /*
497  * Collect incoming data in the incoming packet buffer.
498  * Decipher and verify the packet when it is completely read.
499  * Drop SSH1_MSG_DEBUG and SSH1_MSG_IGNORE packets.
500  * Update the *data and *datalen variables.
501  * Return the additional nr of bytes needed, or 0 when
502  * a complete packet is available.
503  */
504 static int ssh1_rdpkt(unsigned char **data, int *datalen)
505 {
506     struct rdpkt1_state_tag *st = &rdpkt1_state;
507
508     crBegin;
509
510   next_packet:
511
512     pktin.type = 0;
513     pktin.length = 0;
514
515     for (st->i = st->len = 0; st->i < 4; st->i++) {
516         while ((*datalen) == 0)
517             crReturn(4 - st->i);
518         st->len = (st->len << 8) + **data;
519         (*data)++, (*datalen)--;
520     }
521
522 #ifdef FWHACK
523     if (st->len == 0x52656d6f) {       /* "Remo"te server has closed ... */
524         st->len = 0x300;               /* big enough to carry to end */
525     }
526 #endif
527
528     st->pad = 8 - (st->len % 8);
529     st->biglen = st->len + st->pad;
530     pktin.length = st->len - 5;
531
532     if (pktin.maxlen < st->biglen) {
533         pktin.maxlen = st->biglen;
534         pktin.data = (pktin.data == NULL ? smalloc(st->biglen + APIEXTRA) :
535                       srealloc(pktin.data, st->biglen + APIEXTRA));
536         if (!pktin.data)
537             fatalbox("Out of memory");
538     }
539
540     st->to_read = st->biglen;
541     st->p = pktin.data;
542     while (st->to_read > 0) {
543         st->chunk = st->to_read;
544         while ((*datalen) == 0)
545             crReturn(st->to_read);
546         if (st->chunk > (*datalen))
547             st->chunk = (*datalen);
548         memcpy(st->p, *data, st->chunk);
549         *data += st->chunk;
550         *datalen -= st->chunk;
551         st->p += st->chunk;
552         st->to_read -= st->chunk;
553     }
554
555     if (cipher)
556         cipher->decrypt(pktin.data, st->biglen);
557 #ifdef DUMP_PACKETS
558     debug(("Got packet len=%d pad=%d\n", st->len, st->pad));
559     dmemdump(pktin.data, st->biglen);
560 #endif
561
562     st->realcrc = crc32(pktin.data, st->biglen - 4);
563     st->gotcrc = GET_32BIT(pktin.data + st->biglen - 4);
564     if (st->gotcrc != st->realcrc) {
565         bombout(("Incorrect CRC received on packet"));
566         crReturn(0);
567     }
568
569     pktin.body = pktin.data + st->pad + 1;
570
571     if (ssh1_compressing) {
572         unsigned char *decompblk;
573         int decomplen;
574 #ifdef DUMP_PACKETS
575         debug(("Packet payload pre-decompression:\n"));
576         dmemdump(pktin.body - 1, pktin.length + 1);
577 #endif
578         zlib_decompress_block(pktin.body - 1, pktin.length + 1,
579                               &decompblk, &decomplen);
580
581         if (pktin.maxlen < st->pad + decomplen) {
582             pktin.maxlen = st->pad + decomplen;
583             pktin.data = srealloc(pktin.data, pktin.maxlen + APIEXTRA);
584             pktin.body = pktin.data + st->pad + 1;
585             if (!pktin.data)
586                 fatalbox("Out of memory");
587         }
588
589         memcpy(pktin.body - 1, decompblk, decomplen);
590         sfree(decompblk);
591         pktin.length = decomplen - 1;
592 #ifdef DUMP_PACKETS
593         debug(("Packet payload post-decompression:\n"));
594         dmemdump(pktin.body - 1, pktin.length + 1);
595 #endif
596     }
597
598     if (pktin.type == SSH1_SMSG_STDOUT_DATA ||
599         pktin.type == SSH1_SMSG_STDERR_DATA ||
600         pktin.type == SSH1_MSG_DEBUG ||
601         pktin.type == SSH1_SMSG_AUTH_TIS_CHALLENGE ||
602         pktin.type == SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
603         long strlen = GET_32BIT(pktin.body);
604         if (strlen + 4 != pktin.length) {
605             bombout(("Received data packet with bogus string length"));
606             crReturn(0);
607         }
608     }
609
610     pktin.type = pktin.body[-1];
611
612     if (pktin.type == SSH1_MSG_DEBUG) {
613         /* log debug message */
614         char buf[80];
615         int strlen = GET_32BIT(pktin.body);
616         strcpy(buf, "Remote: ");
617         if (strlen > 70)
618             strlen = 70;
619         memcpy(buf + 8, pktin.body + 4, strlen);
620         buf[8 + strlen] = '\0';
621         logevent(buf);
622         goto next_packet;
623     } else if (pktin.type == SSH1_MSG_IGNORE) {
624         /* do nothing */
625         goto next_packet;
626     }
627
628     if (pktin.type == SSH1_MSG_DISCONNECT) {
629         /* log reason code in disconnect message */
630         char buf[256];
631         unsigned msglen = GET_32BIT(pktin.body);
632         unsigned nowlen;
633         strcpy(buf, "Remote sent disconnect: ");
634         nowlen = strlen(buf);
635         if (msglen > sizeof(buf) - nowlen - 1)
636             msglen = sizeof(buf) - nowlen - 1;
637         memcpy(buf + nowlen, pktin.body + 4, msglen);
638         buf[nowlen + msglen] = '\0';
639         logevent(buf);
640     }
641
642     crFinish(0);
643 }
644
645 static int ssh2_rdpkt(unsigned char **data, int *datalen)
646 {
647     struct rdpkt2_state_tag *st = &rdpkt2_state;
648
649     crBegin;
650
651   next_packet:
652     pktin.type = 0;
653     pktin.length = 0;
654     if (sccipher)
655         st->cipherblk = sccipher->blksize;
656     else
657         st->cipherblk = 8;
658     if (st->cipherblk < 8)
659         st->cipherblk = 8;
660
661     if (pktin.maxlen < st->cipherblk) {
662         pktin.maxlen = st->cipherblk;
663         pktin.data =
664             (pktin.data ==
665              NULL ? smalloc(st->cipherblk +
666                             APIEXTRA) : srealloc(pktin.data,
667                                                  st->cipherblk +
668                                                  APIEXTRA));
669         if (!pktin.data)
670             fatalbox("Out of memory");
671     }
672
673     /*
674      * Acquire and decrypt the first block of the packet. This will
675      * contain the length and padding details.
676      */
677     for (st->i = st->len = 0; st->i < st->cipherblk; st->i++) {
678         while ((*datalen) == 0)
679             crReturn(st->cipherblk - st->i);
680         pktin.data[st->i] = *(*data)++;
681         (*datalen)--;
682     }
683 #ifdef FWHACK
684     if (!memcmp(pktin.data, "Remo", 4)) {       /* "Remo"te server has closed ... */
685         /* FIXME */
686     }
687 #endif
688     if (sccipher)
689         sccipher->decrypt(pktin.data, st->cipherblk);
690
691     /*
692      * Now get the length and padding figures.
693      */
694     st->len = GET_32BIT(pktin.data);
695     st->pad = pktin.data[4];
696
697     /*
698      * This enables us to deduce the payload length.
699      */
700     st->payload = st->len - st->pad - 1;
701
702     pktin.length = st->payload + 5;
703
704     /*
705      * So now we can work out the total packet length.
706      */
707     st->packetlen = st->len + 4;
708     st->maclen = scmac ? scmac->len : 0;
709
710     /*
711      * Adjust memory allocation if packet is too big.
712      */
713     if (pktin.maxlen < st->packetlen + st->maclen) {
714         pktin.maxlen = st->packetlen + st->maclen;
715         pktin.data =
716             (pktin.data ==
717              NULL ? smalloc(pktin.maxlen + APIEXTRA) : srealloc(pktin.data,
718                                                                 pktin.maxlen
719                                                                 +
720                                                                 APIEXTRA));
721         if (!pktin.data)
722             fatalbox("Out of memory");
723     }
724
725     /*
726      * Read and decrypt the remainder of the packet.
727      */
728     for (st->i = st->cipherblk; st->i < st->packetlen + st->maclen;
729          st->i++) {
730         while ((*datalen) == 0)
731             crReturn(st->packetlen + st->maclen - st->i);
732         pktin.data[st->i] = *(*data)++;
733         (*datalen)--;
734     }
735     /* Decrypt everything _except_ the MAC. */
736     if (sccipher)
737         sccipher->decrypt(pktin.data + st->cipherblk,
738                           st->packetlen - st->cipherblk);
739
740 #ifdef DUMP_PACKETS
741     debug(("Got packet len=%d pad=%d\n", st->len, st->pad));
742     dmemdump(pktin.data, st->packetlen);
743 #endif
744
745     /*
746      * Check the MAC.
747      */
748     if (scmac
749         && !scmac->verify(pktin.data, st->len + 4,
750                           st->incoming_sequence)) {
751         bombout(("Incorrect MAC received on packet"));
752         crReturn(0);
753     }
754     st->incoming_sequence++;           /* whether or not we MACed */
755
756     /*
757      * Decompress packet payload.
758      */
759     {
760         unsigned char *newpayload;
761         int newlen;
762         if (sccomp && sccomp->decompress(pktin.data + 5, pktin.length - 5,
763                                          &newpayload, &newlen)) {
764             if (pktin.maxlen < newlen + 5) {
765                 pktin.maxlen = newlen + 5;
766                 pktin.data =
767                     (pktin.data ==
768                      NULL ? smalloc(pktin.maxlen +
769                                     APIEXTRA) : srealloc(pktin.data,
770                                                          pktin.maxlen +
771                                                          APIEXTRA));
772                 if (!pktin.data)
773                     fatalbox("Out of memory");
774             }
775             pktin.length = 5 + newlen;
776             memcpy(pktin.data + 5, newpayload, newlen);
777 #ifdef DUMP_PACKETS
778             debug(("Post-decompression payload:\n"));
779             dmemdump(pktin.data + 5, newlen);
780 #endif
781
782             sfree(newpayload);
783         }
784     }
785
786     pktin.savedpos = 6;
787     pktin.type = pktin.data[5];
788
789     if (pktin.type == SSH2_MSG_IGNORE || pktin.type == SSH2_MSG_DEBUG)
790         goto next_packet;              /* FIXME: print DEBUG message */
791
792     if (pktin.type == SSH2_MSG_DISCONNECT) {
793         /* log reason code in disconnect message */
794         char buf[256];
795         int reason = GET_32BIT(pktin.data + 6);
796         unsigned msglen = GET_32BIT(pktin.data + 10);
797         unsigned nowlen;
798         if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {
799             sprintf(buf, "Received disconnect message (%s)",
800                     ssh2_disconnect_reasons[reason]);
801         } else {
802             sprintf(buf, "Received disconnect message (unknown type %d)",
803                     reason);
804         }
805         logevent(buf);
806         strcpy(buf, "Disconnection message text: ");
807         nowlen = strlen(buf);
808         if (msglen > sizeof(buf) - nowlen - 1)
809             msglen = sizeof(buf) - nowlen - 1;
810         memcpy(buf + nowlen, pktin.data + 14, msglen);
811         buf[nowlen + msglen] = '\0';
812         logevent(buf);
813     }
814
815     crFinish(0);
816 }
817
818 static void ssh1_pktout_size(int len)
819 {
820     int pad, biglen;
821
822     len += 5;                          /* type and CRC */
823     pad = 8 - (len % 8);
824     biglen = len + pad;
825
826     pktout.length = len - 5;
827     if (pktout.maxlen < biglen) {
828         pktout.maxlen = biglen;
829 #ifdef MSCRYPTOAPI
830         /* Allocate enough buffer space for extra block
831          * for MS CryptEncrypt() */
832         pktout.data = (pktout.data == NULL ? smalloc(biglen + 12) :
833                        srealloc(pktout.data, biglen + 12));
834 #else
835         pktout.data = (pktout.data == NULL ? smalloc(biglen + 4) :
836                        srealloc(pktout.data, biglen + 4));
837 #endif
838         if (!pktout.data)
839             fatalbox("Out of memory");
840     }
841     pktout.body = pktout.data + 4 + pad + 1;
842 }
843
844 static void s_wrpkt_start(int type, int len)
845 {
846     ssh1_pktout_size(len);
847     pktout.type = type;
848 }
849
850 static int s_wrpkt_prepare(void)
851 {
852     int pad, len, biglen, i;
853     unsigned long crc;
854
855     pktout.body[-1] = pktout.type;
856
857 #ifdef DUMP_PACKETS
858     debug(("Packet payload pre-compression:\n"));
859     dmemdump(pktout.body - 1, pktout.length + 1);
860 #endif
861
862     if (ssh1_compressing) {
863         unsigned char *compblk;
864         int complen;
865         zlib_compress_block(pktout.body - 1, pktout.length + 1,
866                             &compblk, &complen);
867         ssh1_pktout_size(complen - 1);
868         memcpy(pktout.body - 1, compblk, complen);
869         sfree(compblk);
870 #ifdef DUMP_PACKETS
871         debug(("Packet payload post-compression:\n"));
872         dmemdump(pktout.body - 1, pktout.length + 1);
873 #endif
874     }
875
876     len = pktout.length + 5;           /* type and CRC */
877     pad = 8 - (len % 8);
878     biglen = len + pad;
879
880     for (i = 0; i < pad; i++)
881         pktout.data[i + 4] = random_byte();
882     crc = crc32(pktout.data + 4, biglen - 4);
883     PUT_32BIT(pktout.data + biglen, crc);
884     PUT_32BIT(pktout.data, len);
885
886 #ifdef DUMP_PACKETS
887     debug(("Sending packet len=%d\n", biglen + 4));
888     dmemdump(pktout.data, biglen + 4);
889 #endif
890     if (cipher)
891         cipher->encrypt(pktout.data + 4, biglen);
892
893     return biglen + 4;
894 }
895
896 static void s_wrpkt(void)
897 {
898     int len;
899     len = s_wrpkt_prepare();
900     sk_write(s, pktout.data, len);
901 }
902
903 static void s_wrpkt_defer(void)
904 {
905     int len;
906     len = s_wrpkt_prepare();
907     if (deferred_len + len > deferred_size) {
908         deferred_size = deferred_len + len + 128;
909         deferred_send_data = srealloc(deferred_send_data, deferred_size);
910     }
911     memcpy(deferred_send_data + deferred_len, pktout.data, len);
912     deferred_len += len;
913 }
914
915 /*
916  * Construct a packet with the specified contents.
917  */
918 static void construct_packet(int pkttype, va_list ap1, va_list ap2)
919 {
920     unsigned char *p, *argp, argchar;
921     unsigned long argint;
922     int pktlen, argtype, arglen;
923     Bignum bn;
924
925     pktlen = 0;
926     while ((argtype = va_arg(ap1, int)) != PKT_END) {
927         switch (argtype) {
928           case PKT_INT:
929             (void) va_arg(ap1, int);
930             pktlen += 4;
931             break;
932           case PKT_CHAR:
933             (void) va_arg(ap1, char);
934             pktlen++;
935             break;
936           case PKT_DATA:
937             (void) va_arg(ap1, unsigned char *);
938             arglen = va_arg(ap1, int);
939             pktlen += arglen;
940             break;
941           case PKT_STR:
942             argp = va_arg(ap1, unsigned char *);
943             arglen = strlen(argp);
944             pktlen += 4 + arglen;
945             break;
946           case PKT_BIGNUM:
947             bn = va_arg(ap1, Bignum);
948             pktlen += ssh1_bignum_length(bn);
949             break;
950           default:
951             assert(0);
952         }
953     }
954
955     s_wrpkt_start(pkttype, pktlen);
956     p = pktout.body;
957
958     while ((argtype = va_arg(ap2, int)) != PKT_END) {
959         switch (argtype) {
960           case PKT_INT:
961             argint = va_arg(ap2, int);
962             PUT_32BIT(p, argint);
963             p += 4;
964             break;
965           case PKT_CHAR:
966             argchar = va_arg(ap2, unsigned char);
967             *p = argchar;
968             p++;
969             break;
970           case PKT_DATA:
971             argp = va_arg(ap2, unsigned char *);
972             arglen = va_arg(ap2, int);
973             memcpy(p, argp, arglen);
974             p += arglen;
975             break;
976           case PKT_STR:
977             argp = va_arg(ap2, unsigned char *);
978             arglen = strlen(argp);
979             PUT_32BIT(p, arglen);
980             memcpy(p + 4, argp, arglen);
981             p += 4 + arglen;
982             break;
983           case PKT_BIGNUM:
984             bn = va_arg(ap2, Bignum);
985             p += ssh1_write_bignum(p, bn);
986             break;
987         }
988     }
989 }
990
991 static void send_packet(int pkttype, ...)
992 {
993     va_list ap1, ap2;
994     va_start(ap1, pkttype);
995     va_start(ap2, pkttype);
996     construct_packet(pkttype, ap1, ap2);
997     s_wrpkt();
998 }
999
1000 static void defer_packet(int pkttype, ...)
1001 {
1002     va_list ap1, ap2;
1003     va_start(ap1, pkttype);
1004     va_start(ap2, pkttype);
1005     construct_packet(pkttype, ap1, ap2);
1006     s_wrpkt_defer();
1007 }
1008
1009 static int ssh_versioncmp(char *a, char *b)
1010 {
1011     char *ae, *be;
1012     unsigned long av, bv;
1013
1014     av = strtoul(a, &ae, 10);
1015     bv = strtoul(b, &be, 10);
1016     if (av != bv)
1017         return (av < bv ? -1 : +1);
1018     if (*ae == '.')
1019         ae++;
1020     if (*be == '.')
1021         be++;
1022     av = strtoul(ae, &ae, 10);
1023     bv = strtoul(be, &be, 10);
1024     if (av != bv)
1025         return (av < bv ? -1 : +1);
1026     return 0;
1027 }
1028
1029
1030 /*
1031  * Utility routines for putting an SSH-protocol `string' and
1032  * `uint32' into a SHA state.
1033  */
1034 #include <stdio.h>
1035 static void sha_string(SHA_State * s, void *str, int len)
1036 {
1037     unsigned char lenblk[4];
1038     PUT_32BIT(lenblk, len);
1039     SHA_Bytes(s, lenblk, 4);
1040     SHA_Bytes(s, str, len);
1041 }
1042
1043 static void sha_uint32(SHA_State * s, unsigned i)
1044 {
1045     unsigned char intblk[4];
1046     PUT_32BIT(intblk, i);
1047     SHA_Bytes(s, intblk, 4);
1048 }
1049
1050 /*
1051  * SSH2 packet construction functions.
1052  */
1053 static void ssh2_pkt_ensure(int length)
1054 {
1055     if (pktout.maxlen < length) {
1056         pktout.maxlen = length + 256;
1057         pktout.data =
1058             (pktout.data ==
1059              NULL ? smalloc(pktout.maxlen +
1060                             APIEXTRA) : srealloc(pktout.data,
1061                                                  pktout.maxlen +
1062                                                  APIEXTRA));
1063         if (!pktout.data)
1064             fatalbox("Out of memory");
1065     }
1066 }
1067 static void ssh2_pkt_adddata(void *data, int len)
1068 {
1069     pktout.length += len;
1070     ssh2_pkt_ensure(pktout.length);
1071     memcpy(pktout.data + pktout.length - len, data, len);
1072 }
1073 static void ssh2_pkt_addbyte(unsigned char byte)
1074 {
1075     ssh2_pkt_adddata(&byte, 1);
1076 }
1077 static void ssh2_pkt_init(int pkt_type)
1078 {
1079     pktout.length = 5;
1080     ssh2_pkt_addbyte((unsigned char) pkt_type);
1081 }
1082 static void ssh2_pkt_addbool(unsigned char value)
1083 {
1084     ssh2_pkt_adddata(&value, 1);
1085 }
1086 static void ssh2_pkt_adduint32(unsigned long value)
1087 {
1088     unsigned char x[4];
1089     PUT_32BIT(x, value);
1090     ssh2_pkt_adddata(x, 4);
1091 }
1092 static void ssh2_pkt_addstring_start(void)
1093 {
1094     ssh2_pkt_adduint32(0);
1095     pktout.savedpos = pktout.length;
1096 }
1097 static void ssh2_pkt_addstring_str(char *data)
1098 {
1099     ssh2_pkt_adddata(data, strlen(data));
1100     PUT_32BIT(pktout.data + pktout.savedpos - 4,
1101               pktout.length - pktout.savedpos);
1102 }
1103 static void ssh2_pkt_addstring_data(char *data, int len)
1104 {
1105     ssh2_pkt_adddata(data, len);
1106     PUT_32BIT(pktout.data + pktout.savedpos - 4,
1107               pktout.length - pktout.savedpos);
1108 }
1109 static void ssh2_pkt_addstring(char *data)
1110 {
1111     ssh2_pkt_addstring_start();
1112     ssh2_pkt_addstring_str(data);
1113 }
1114 static char *ssh2_mpint_fmt(Bignum b, int *len)
1115 {
1116     unsigned char *p;
1117     int i, n = (bignum_bitcount(b) + 7) / 8;
1118     p = smalloc(n + 1);
1119     if (!p)
1120         fatalbox("out of memory");
1121     p[0] = 0;
1122     for (i = 1; i <= n; i++)
1123         p[i] = bignum_byte(b, n - i);
1124     i = 0;
1125     while (i <= n && p[i] == 0 && (p[i + 1] & 0x80) == 0)
1126         i++;
1127     memmove(p, p + i, n + 1 - i);
1128     *len = n + 1 - i;
1129     return p;
1130 }
1131 static void ssh2_pkt_addmp(Bignum b)
1132 {
1133     unsigned char *p;
1134     int len;
1135     p = ssh2_mpint_fmt(b, &len);
1136     ssh2_pkt_addstring_start();
1137     ssh2_pkt_addstring_data(p, len);
1138     sfree(p);
1139 }
1140
1141 /*
1142  * Construct an SSH2 final-form packet: compress it, encrypt it,
1143  * put the MAC on it. Final packet, ready to be sent, is stored in
1144  * pktout.data. Total length is returned.
1145  */
1146 static int ssh2_pkt_construct(void)
1147 {
1148     int cipherblk, maclen, padding, i;
1149     static unsigned long outgoing_sequence = 0;
1150
1151     /*
1152      * Compress packet payload.
1153      */
1154 #ifdef DUMP_PACKETS
1155     debug(("Pre-compression payload:\n"));
1156     dmemdump(pktout.data + 5, pktout.length - 5);
1157 #endif
1158     {
1159         unsigned char *newpayload;
1160         int newlen;
1161         if (cscomp && cscomp->compress(pktout.data + 5, pktout.length - 5,
1162                                        &newpayload, &newlen)) {
1163             pktout.length = 5;
1164             ssh2_pkt_adddata(newpayload, newlen);
1165             sfree(newpayload);
1166         }
1167     }
1168
1169     /*
1170      * Add padding. At least four bytes, and must also bring total
1171      * length (minus MAC) up to a multiple of the block size.
1172      */
1173     cipherblk = cscipher ? cscipher->blksize : 8;       /* block size */
1174     cipherblk = cipherblk < 8 ? 8 : cipherblk;  /* or 8 if blksize < 8 */
1175     padding = 4;
1176     padding +=
1177         (cipherblk - (pktout.length + padding) % cipherblk) % cipherblk;
1178     maclen = csmac ? csmac->len : 0;
1179     ssh2_pkt_ensure(pktout.length + padding + maclen);
1180     pktout.data[4] = padding;
1181     for (i = 0; i < padding; i++)
1182         pktout.data[pktout.length + i] = random_byte();
1183     PUT_32BIT(pktout.data, pktout.length + padding - 4);
1184     if (csmac)
1185         csmac->generate(pktout.data, pktout.length + padding,
1186                         outgoing_sequence);
1187     outgoing_sequence++;               /* whether or not we MACed */
1188
1189 #ifdef DUMP_PACKETS
1190     debug(("Sending packet len=%d\n", pktout.length + padding));
1191     dmemdump(pktout.data, pktout.length + padding);
1192 #endif
1193
1194     if (cscipher)
1195         cscipher->encrypt(pktout.data, pktout.length + padding);
1196
1197     /* Ready-to-send packet starts at pktout.data. We return length. */
1198     return pktout.length + padding + maclen;
1199 }
1200
1201 /*
1202  * Construct and send an SSH2 packet immediately.
1203  */
1204 static void ssh2_pkt_send(void)
1205 {
1206     int len = ssh2_pkt_construct();
1207     sk_write(s, pktout.data, len);
1208 }
1209
1210 /*
1211  * Construct an SSH2 packet and add it to a deferred data block.
1212  * Useful for sending multiple packets in a single sk_write() call,
1213  * to prevent a traffic-analysing listener from being able to work
1214  * out the length of any particular packet (such as the password
1215  * packet).
1216  * 
1217  * Note that because SSH2 sequence-numbers its packets, this can
1218  * NOT be used as an m4-style `defer' allowing packets to be
1219  * constructed in one order and sent in another.
1220  */
1221 static void ssh2_pkt_defer(void)
1222 {
1223     int len = ssh2_pkt_construct();
1224     if (deferred_len + len > deferred_size) {
1225         deferred_size = deferred_len + len + 128;
1226         deferred_send_data = srealloc(deferred_send_data, deferred_size);
1227     }
1228     memcpy(deferred_send_data + deferred_len, pktout.data, len);
1229     deferred_len += len;
1230 }
1231
1232 /*
1233  * Send the whole deferred data block constructed by
1234  * ssh2_pkt_defer() or SSH1's defer_packet().
1235  */
1236 static void ssh_pkt_defersend(void)
1237 {
1238     sk_write(s, deferred_send_data, deferred_len);
1239     deferred_len = deferred_size = 0;
1240     sfree(deferred_send_data);
1241     deferred_send_data = NULL;
1242 }
1243
1244 #if 0
1245 void bndebug(char *string, Bignum b)
1246 {
1247     unsigned char *p;
1248     int i, len;
1249     p = ssh2_mpint_fmt(b, &len);
1250     debug(("%s", string));
1251     for (i = 0; i < len; i++)
1252         debug((" %02x", p[i]));
1253     debug(("\n"));
1254     sfree(p);
1255 }
1256 #endif
1257
1258 static void sha_mpint(SHA_State * s, Bignum b)
1259 {
1260     unsigned char *p;
1261     int len;
1262     p = ssh2_mpint_fmt(b, &len);
1263     sha_string(s, p, len);
1264     sfree(p);
1265 }
1266
1267 /*
1268  * SSH2 packet decode functions.
1269  */
1270 static unsigned long ssh2_pkt_getuint32(void)
1271 {
1272     unsigned long value;
1273     if (pktin.length - pktin.savedpos < 4)
1274         return 0;                      /* arrgh, no way to decline (FIXME?) */
1275     value = GET_32BIT(pktin.data + pktin.savedpos);
1276     pktin.savedpos += 4;
1277     return value;
1278 }
1279 static int ssh2_pkt_getbool(void)
1280 {
1281     unsigned long value;
1282     if (pktin.length - pktin.savedpos < 1)
1283         return 0;                      /* arrgh, no way to decline (FIXME?) */
1284     value = pktin.data[pktin.savedpos] != 0;
1285     pktin.savedpos++;
1286     return value;
1287 }
1288 static void ssh2_pkt_getstring(char **p, int *length)
1289 {
1290     *p = NULL;
1291     if (pktin.length - pktin.savedpos < 4)
1292         return;
1293     *length = GET_32BIT(pktin.data + pktin.savedpos);
1294     pktin.savedpos += 4;
1295     if (pktin.length - pktin.savedpos < *length)
1296         return;
1297     *p = pktin.data + pktin.savedpos;
1298     pktin.savedpos += *length;
1299 }
1300 static Bignum ssh2_pkt_getmp(void)
1301 {
1302     char *p;
1303     int length;
1304     Bignum b;
1305
1306     ssh2_pkt_getstring(&p, &length);
1307     if (!p)
1308         return NULL;
1309     if (p[0] & 0x80) {
1310         bombout(("internal error: Can't handle negative mpints"));
1311         return NULL;
1312     }
1313     b = bignum_from_bytes(p, length);
1314     return b;
1315 }
1316
1317 /*
1318  * Examine the remote side's version string and compare it against
1319  * a list of known buggy implementations.
1320  */
1321 static void ssh_detect_bugs(char *vstring)
1322 {
1323     char *imp;                         /* pointer to implementation part */
1324     imp = vstring;
1325     imp += strcspn(imp, "-");
1326     if (*imp)
1327         imp++;
1328     imp += strcspn(imp, "-");
1329     if (*imp)
1330         imp++;
1331
1332     ssh_remote_bugs = 0;
1333
1334     if (!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") ||
1335         !strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") ||
1336         !strcmp(imp, "1.2.22")) {
1337         /*
1338          * These versions don't support SSH1_MSG_IGNORE, so we have
1339          * to use a different defence against password length
1340          * sniffing.
1341          */
1342         ssh_remote_bugs |= BUG_CHOKES_ON_SSH1_IGNORE;
1343         logevent("We believe remote version has SSH1 ignore bug");
1344     }
1345
1346     if (!strncmp(imp, "2.1.0", 5) || !strncmp(imp, "2.0.", 4) ||
1347         !strncmp(imp, "2.2.0", 5) || !strncmp(imp, "2.3.0", 5) ||
1348         !strncmp(imp, "2.1 ", 4)) {
1349         /*
1350          * These versions have the HMAC bug.
1351          */
1352         ssh_remote_bugs |= BUG_SSH2_HMAC;
1353         logevent("We believe remote version has SSH2 HMAC bug");
1354     }
1355 }
1356
1357 static int do_ssh_init(unsigned char c)
1358 {
1359     static int vslen;
1360     static char version[10];
1361     static char *vstring;
1362     static int vstrsize;
1363     static char *vlog;
1364     static int i;
1365
1366     crBegin;
1367
1368     /* Search for the string "SSH-" in the input. */
1369     i = 0;
1370     while (1) {
1371         static const int transS[] = { 1, 2, 2, 1 };
1372         static const int transH[] = { 0, 0, 3, 0 };
1373         static const int transminus[] = { 0, 0, 0, -1 };
1374         if (c == 'S')
1375             i = transS[i];
1376         else if (c == 'H')
1377             i = transH[i];
1378         else if (c == '-')
1379             i = transminus[i];
1380         else
1381             i = 0;
1382         if (i < 0)
1383             break;
1384         crReturn(1);                   /* get another character */
1385     }
1386
1387     vstring = smalloc(16);
1388     vstrsize = 16;
1389     strcpy(vstring, "SSH-");
1390     vslen = 4;
1391     i = 0;
1392     while (1) {
1393         crReturn(1);                   /* get another char */
1394         if (vslen >= vstrsize - 1) {
1395             vstrsize += 16;
1396             vstring = srealloc(vstring, vstrsize);
1397         }
1398         vstring[vslen++] = c;
1399         if (i >= 0) {
1400             if (c == '-') {
1401                 version[i] = '\0';
1402                 i = -1;
1403             } else if (i < sizeof(version) - 1)
1404                 version[i++] = c;
1405         } else if (c == '\n')
1406             break;
1407     }
1408
1409     ssh_agentfwd_enabled = FALSE;
1410     rdpkt2_state.incoming_sequence = 0;
1411
1412     vstring[vslen] = 0;
1413     vlog = smalloc(20 + vslen);
1414     sprintf(vlog, "Server version: %s", vstring);
1415     ssh_detect_bugs(vstring);
1416     vlog[strcspn(vlog, "\r\n")] = '\0';
1417     logevent(vlog);
1418     sfree(vlog);
1419
1420     /*
1421      * Server version "1.99" means we can choose whether we use v1
1422      * or v2 protocol. Choice is based on cfg.sshprot.
1423      */
1424     if (ssh_versioncmp(version, cfg.sshprot == 1 ? "2.0" : "1.99") >= 0) {
1425         /*
1426          * This is a v2 server. Begin v2 protocol.
1427          */
1428         char verstring[80], vlog[100];
1429         sprintf(verstring, "SSH-2.0-%s", sshver);
1430         SHA_Init(&exhashbase);
1431         /*
1432          * Hash our version string and their version string.
1433          */
1434         sha_string(&exhashbase, verstring, strlen(verstring));
1435         sha_string(&exhashbase, vstring, strcspn(vstring, "\r\n"));
1436         sprintf(vlog, "We claim version: %s", verstring);
1437         logevent(vlog);
1438         strcat(verstring, "\n");
1439         logevent("Using SSH protocol version 2");
1440         sk_write(s, verstring, strlen(verstring));
1441         ssh_protocol = ssh2_protocol;
1442         ssh_version = 2;
1443         s_rdpkt = ssh2_rdpkt;
1444     } else {
1445         /*
1446          * This is a v1 server. Begin v1 protocol.
1447          */
1448         char verstring[80], vlog[100];
1449         sprintf(verstring, "SSH-%s-%s",
1450                 (ssh_versioncmp(version, "1.5") <= 0 ? version : "1.5"),
1451                 sshver);
1452         sprintf(vlog, "We claim version: %s", verstring);
1453         logevent(vlog);
1454         strcat(verstring, "\n");
1455         logevent("Using SSH protocol version 1");
1456         sk_write(s, verstring, strlen(verstring));
1457         ssh_protocol = ssh1_protocol;
1458         ssh_version = 1;
1459         s_rdpkt = ssh1_rdpkt;
1460     }
1461     ssh_state = SSH_STATE_BEFORE_SIZE;
1462
1463     sfree(vstring);
1464
1465     crFinish(0);
1466 }
1467
1468 static void ssh_gotdata(unsigned char *data, int datalen)
1469 {
1470     crBegin;
1471
1472     /*
1473      * To begin with, feed the characters one by one to the
1474      * protocol initialisation / selection function do_ssh_init().
1475      * When that returns 0, we're done with the initial greeting
1476      * exchange and can move on to packet discipline.
1477      */
1478     while (1) {
1479         int ret;
1480         if (datalen == 0)
1481             crReturnV;                 /* more data please */
1482         ret = do_ssh_init(*data);
1483         data++;
1484         datalen--;
1485         if (ret == 0)
1486             break;
1487     }
1488
1489     /*
1490      * We emerge from that loop when the initial negotiation is
1491      * over and we have selected an s_rdpkt function. Now pass
1492      * everything to s_rdpkt, and then pass the resulting packets
1493      * to the proper protocol handler.
1494      */
1495     if (datalen == 0)
1496         crReturnV;
1497     while (1) {
1498         while (datalen > 0) {
1499             if (s_rdpkt(&data, &datalen) == 0) {
1500                 ssh_protocol(NULL, 0, 1);
1501                 if (ssh_state == SSH_STATE_CLOSED) {
1502                     return;
1503                 }
1504             }
1505         }
1506         crReturnV;
1507     }
1508     crFinishV;
1509 }
1510
1511 static int ssh_closing(Plug plug, char *error_msg, int error_code,
1512                        int calling_back)
1513 {
1514     ssh_state = SSH_STATE_CLOSED;
1515     if (s) {
1516         sk_close(s);
1517         s = NULL;
1518     }
1519     if (error_msg) {
1520         /* A socket error has occurred. */
1521         connection_fatal(error_msg);
1522     } else {
1523         /* Otherwise, the remote side closed the connection normally. */
1524     }
1525     return 0;
1526 }
1527
1528 static int ssh_receive(Plug plug, int urgent, char *data, int len)
1529 {
1530     ssh_gotdata(data, len);
1531     if (ssh_state == SSH_STATE_CLOSED) {
1532         if (s) {
1533             sk_close(s);
1534             s = NULL;
1535         }
1536         return 0;
1537     }
1538     return 1;
1539 }
1540
1541 /*
1542  * Connect to specified host and port.
1543  * Returns an error message, or NULL on success.
1544  * Also places the canonical host name into `realhost'. It must be
1545  * freed by the caller.
1546  */
1547 static char *connect_to_host(char *host, int port, char **realhost)
1548 {
1549     static struct plug_function_table fn_table = {
1550         ssh_closing,
1551         ssh_receive
1552     }, *fn_table_ptr = &fn_table;
1553
1554     SockAddr addr;
1555     char *err;
1556 #ifdef FWHACK
1557     char *FWhost;
1558     int FWport;
1559 #endif
1560
1561     savedhost = smalloc(1 + strlen(host));
1562     if (!savedhost)
1563         fatalbox("Out of memory");
1564     strcpy(savedhost, host);
1565
1566     if (port < 0)
1567         port = 22;                     /* default ssh port */
1568     savedport = port;
1569
1570 #ifdef FWHACK
1571     FWhost = host;
1572     FWport = port;
1573     host = FWSTR;
1574     port = 23;
1575 #endif
1576
1577     /*
1578      * Try to find host.
1579      */
1580     addr = sk_namelookup(host, realhost);
1581     if ((err = sk_addr_error(addr)))
1582         return err;
1583
1584 #ifdef FWHACK
1585     *realhost = strdup(FWhost);
1586 #endif
1587
1588     /*
1589      * Open socket.
1590      */
1591     s = sk_new(addr, port, 0, 1, &fn_table_ptr);
1592     if ((err = sk_socket_error(s)))
1593         return err;
1594
1595 #ifdef FWHACK
1596     sk_write(s, "connect ", 8);
1597     sk_write(s, FWhost, strlen(FWhost));
1598     {
1599         char buf[20];
1600         sprintf(buf, " %d\n", FWport);
1601         sk_write(s, buf, strlen(buf));
1602     }
1603 #endif
1604
1605     return NULL;
1606 }
1607
1608 /*
1609  * Handle the key exchange and user authentication phases.
1610  */
1611 static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
1612 {
1613     int i, j;
1614     static int len;
1615     static unsigned char *rsabuf, *keystr1, *keystr2;
1616     unsigned char cookie[8];
1617     struct RSAKey servkey, hostkey;
1618     struct MD5Context md5c;
1619     static unsigned long supported_ciphers_mask, supported_auths_mask;
1620     static int tried_publickey;
1621     static unsigned char session_id[16];
1622     static int cipher_type;
1623     static char username[100];
1624
1625     crBegin;
1626
1627     if (!ispkt)
1628         crWaitUntil(ispkt);
1629
1630     if (pktin.type != SSH1_SMSG_PUBLIC_KEY) {
1631         bombout(("Public key packet not received"));
1632         crReturn(0);
1633     }
1634
1635     logevent("Received public keys");
1636
1637     memcpy(cookie, pktin.body, 8);
1638
1639     i = makekey(pktin.body + 8, &servkey, &keystr1, 0);
1640     j = makekey(pktin.body + 8 + i, &hostkey, &keystr2, 0);
1641
1642     /*
1643      * Log the host key fingerprint.
1644      */
1645     {
1646         char logmsg[80];
1647         logevent("Host key fingerprint is:");
1648         strcpy(logmsg, "      ");
1649         hostkey.comment = NULL;
1650         rsa_fingerprint(logmsg + strlen(logmsg),
1651                         sizeof(logmsg) - strlen(logmsg), &hostkey);
1652         logevent(logmsg);
1653     }
1654
1655     ssh1_remote_protoflags = GET_32BIT(pktin.body + 8 + i + j);
1656     supported_ciphers_mask = GET_32BIT(pktin.body + 12 + i + j);
1657     supported_auths_mask = GET_32BIT(pktin.body + 16 + i + j);
1658
1659     ssh1_local_protoflags =
1660         ssh1_remote_protoflags & SSH1_PROTOFLAGS_SUPPORTED;
1661     ssh1_local_protoflags |= SSH1_PROTOFLAG_SCREEN_NUMBER;
1662
1663     MD5Init(&md5c);
1664     MD5Update(&md5c, keystr2, hostkey.bytes);
1665     MD5Update(&md5c, keystr1, servkey.bytes);
1666     MD5Update(&md5c, pktin.body, 8);
1667     MD5Final(session_id, &md5c);
1668
1669     for (i = 0; i < 32; i++)
1670         session_key[i] = random_byte();
1671
1672     len = (hostkey.bytes > servkey.bytes ? hostkey.bytes : servkey.bytes);
1673
1674     rsabuf = smalloc(len);
1675     if (!rsabuf)
1676         fatalbox("Out of memory");
1677
1678     /*
1679      * Verify the host key.
1680      */
1681     {
1682         /*
1683          * First format the key into a string.
1684          */
1685         int len = rsastr_len(&hostkey);
1686         char fingerprint[100];
1687         char *keystr = smalloc(len);
1688         if (!keystr)
1689             fatalbox("Out of memory");
1690         rsastr_fmt(keystr, &hostkey);
1691         rsa_fingerprint(fingerprint, sizeof(fingerprint), &hostkey);
1692         verify_ssh_host_key(savedhost, savedport, "rsa", keystr,
1693                             fingerprint);
1694         sfree(keystr);
1695     }
1696
1697     for (i = 0; i < 32; i++) {
1698         rsabuf[i] = session_key[i];
1699         if (i < 16)
1700             rsabuf[i] ^= session_id[i];
1701     }
1702
1703     if (hostkey.bytes > servkey.bytes) {
1704         rsaencrypt(rsabuf, 32, &servkey);
1705         rsaencrypt(rsabuf, servkey.bytes, &hostkey);
1706     } else {
1707         rsaencrypt(rsabuf, 32, &hostkey);
1708         rsaencrypt(rsabuf, hostkey.bytes, &servkey);
1709     }
1710
1711     logevent("Encrypted session key");
1712
1713     switch (cfg.cipher) {
1714       case CIPHER_BLOWFISH:
1715         cipher_type = SSH_CIPHER_BLOWFISH;
1716         break;
1717       case CIPHER_DES:
1718         cipher_type = SSH_CIPHER_DES;
1719         break;
1720       case CIPHER_3DES:
1721         cipher_type = SSH_CIPHER_3DES;
1722         break;
1723       case CIPHER_AES:
1724         c_write_str("AES not supported in SSH1, falling back to 3DES\r\n");
1725         cipher_type = SSH_CIPHER_3DES;
1726         break;
1727     }
1728     if ((supported_ciphers_mask & (1 << cipher_type)) == 0) {
1729         c_write_str
1730             ("Selected cipher not supported, falling back to 3DES\r\n");
1731         cipher_type = SSH_CIPHER_3DES;
1732         if ((supported_ciphers_mask & (1 << cipher_type)) == 0) {
1733             bombout(("Server violates SSH 1 protocol by "
1734                      "not supporting 3DES encryption"));
1735             crReturn(0);
1736         }
1737     }
1738     switch (cipher_type) {
1739       case SSH_CIPHER_3DES:
1740         logevent("Using 3DES encryption");
1741         break;
1742       case SSH_CIPHER_DES:
1743         logevent("Using single-DES encryption");
1744         break;
1745       case SSH_CIPHER_BLOWFISH:
1746         logevent("Using Blowfish encryption");
1747         break;
1748     }
1749
1750     send_packet(SSH1_CMSG_SESSION_KEY,
1751                 PKT_CHAR, cipher_type,
1752                 PKT_DATA, cookie, 8,
1753                 PKT_CHAR, (len * 8) >> 8, PKT_CHAR, (len * 8) & 0xFF,
1754                 PKT_DATA, rsabuf, len,
1755                 PKT_INT, ssh1_local_protoflags, PKT_END);
1756
1757     logevent("Trying to enable encryption...");
1758
1759     sfree(rsabuf);
1760
1761     cipher = cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
1762         cipher_type == SSH_CIPHER_DES ? &ssh_des : &ssh_3des;
1763     cipher->sesskey(session_key);
1764
1765     crWaitUntil(ispkt);
1766
1767     if (pktin.type != SSH1_SMSG_SUCCESS) {
1768         bombout(("Encryption not successfully enabled"));
1769         crReturn(0);
1770     }
1771
1772     logevent("Successfully started encryption");
1773
1774     fflush(stdout);
1775     {
1776         static int pos = 0;
1777         static char c;
1778         if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
1779             if (ssh_get_line) {
1780                 if (!ssh_get_line("login as: ",
1781                                   username, sizeof(username), FALSE)) {
1782                     /*
1783                      * get_line failed to get a username.
1784                      * Terminate.
1785                      */
1786                     logevent("No username provided. Abandoning session.");
1787                     ssh_state = SSH_STATE_CLOSED;
1788                     crReturn(1);
1789                 }
1790             } else {
1791                 c_write_str("login as: ");
1792                 ssh_send_ok = 1;
1793                 while (pos >= 0) {
1794                     crWaitUntil(!ispkt);
1795                     while (inlen--)
1796                         switch (c = *in++) {
1797                           case 10:
1798                           case 13:
1799                             username[pos] = 0;
1800                             pos = -1;
1801                             break;
1802                           case 8:
1803                           case 127:
1804                             if (pos > 0) {
1805                                 c_write_str("\b \b");
1806                                 pos--;
1807                             }
1808                             break;
1809                           case 21:
1810                           case 27:
1811                             while (pos > 0) {
1812                                 c_write_str("\b \b");
1813                                 pos--;
1814                             }
1815                             break;
1816                           case 3:
1817                           case 4:
1818                             random_save_seed();
1819                             exit(0);
1820                             break;
1821                           default:
1822                             if (((c >= ' ' && c <= '~') ||
1823                                  ((unsigned char) c >= 160))
1824                                 && pos < sizeof(username)-1) {
1825                                 username[pos++] = c;
1826                                 c_write(&c, 1);
1827                             }
1828                             break;
1829                         }
1830                 }
1831                 c_write_str("\r\n");
1832                 username[strcspn(username, "\n\r")] = '\0';
1833             }
1834         } else {
1835             strncpy(username, cfg.username, 99);
1836             username[99] = '\0';
1837         }
1838
1839         send_packet(SSH1_CMSG_USER, PKT_STR, username, PKT_END);
1840         {
1841             char userlog[22 + sizeof(username)];
1842             sprintf(userlog, "Sent username \"%s\"", username);
1843             logevent(userlog);
1844             if (flags & FLAG_INTERACTIVE &&
1845                 (!((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)))) {
1846                 strcat(userlog, "\r\n");
1847                 c_write_str(userlog);
1848             }
1849         }
1850     }
1851
1852     crWaitUntil(ispkt);
1853
1854     tried_publickey = 0;
1855
1856     while (pktin.type == SSH1_SMSG_FAILURE) {
1857         static char password[100];
1858         static char prompt[200];
1859         static int pos;
1860         static char c;
1861         static int pwpkt_type;
1862         /*
1863          * Show password prompt, having first obtained it via a TIS
1864          * or CryptoCard exchange if we're doing TIS or CryptoCard
1865          * authentication.
1866          */
1867         pwpkt_type = SSH1_CMSG_AUTH_PASSWORD;
1868         if (agent_exists()) {
1869             /*
1870              * Attempt RSA authentication using Pageant.
1871              */
1872             static unsigned char request[5], *response, *p;
1873             static int responselen;
1874             static int i, nkeys;
1875             static int authed = FALSE;
1876             void *r;
1877
1878             logevent("Pageant is running. Requesting keys.");
1879
1880             /* Request the keys held by the agent. */
1881             PUT_32BIT(request, 1);
1882             request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;
1883             agent_query(request, 5, &r, &responselen);
1884             response = (unsigned char *) r;
1885             if (response && responselen >= 5 &&
1886                 response[4] == SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
1887                 p = response + 5;
1888                 nkeys = GET_32BIT(p);
1889                 p += 4;
1890                 {
1891                     char buf[64];
1892                     sprintf(buf, "Pageant has %d SSH1 keys", nkeys);
1893                     logevent(buf);
1894                 }
1895                 for (i = 0; i < nkeys; i++) {
1896                     static struct RSAKey key;
1897                     static Bignum challenge;
1898                     static char *commentp;
1899                     static int commentlen;
1900
1901                     {
1902                         char buf[64];
1903                         sprintf(buf, "Trying Pageant key #%d", i);
1904                         logevent(buf);
1905                     }
1906                     p += 4;
1907                     p += ssh1_read_bignum(p, &key.exponent);
1908                     p += ssh1_read_bignum(p, &key.modulus);
1909                     commentlen = GET_32BIT(p);
1910                     p += 4;
1911                     commentp = p;
1912                     p += commentlen;
1913                     send_packet(SSH1_CMSG_AUTH_RSA,
1914                                 PKT_BIGNUM, key.modulus, PKT_END);
1915                     crWaitUntil(ispkt);
1916                     if (pktin.type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
1917                         logevent("Key refused");
1918                         continue;
1919                     }
1920                     logevent("Received RSA challenge");
1921                     ssh1_read_bignum(pktin.body, &challenge);
1922                     {
1923                         char *agentreq, *q, *ret;
1924                         void *vret;
1925                         int len, retlen;
1926                         len = 1 + 4;   /* message type, bit count */
1927                         len += ssh1_bignum_length(key.exponent);
1928                         len += ssh1_bignum_length(key.modulus);
1929                         len += ssh1_bignum_length(challenge);
1930                         len += 16;     /* session id */
1931                         len += 4;      /* response format */
1932                         agentreq = smalloc(4 + len);
1933                         PUT_32BIT(agentreq, len);
1934                         q = agentreq + 4;
1935                         *q++ = SSH1_AGENTC_RSA_CHALLENGE;
1936                         PUT_32BIT(q, bignum_bitcount(key.modulus));
1937                         q += 4;
1938                         q += ssh1_write_bignum(q, key.exponent);
1939                         q += ssh1_write_bignum(q, key.modulus);
1940                         q += ssh1_write_bignum(q, challenge);
1941                         memcpy(q, session_id, 16);
1942                         q += 16;
1943                         PUT_32BIT(q, 1);        /* response format */
1944                         agent_query(agentreq, len + 4, &vret, &retlen);
1945                         ret = vret;
1946                         sfree(agentreq);
1947                         if (ret) {
1948                             if (ret[4] == SSH1_AGENT_RSA_RESPONSE) {
1949                                 logevent("Sending Pageant's response");
1950                                 send_packet(SSH1_CMSG_AUTH_RSA_RESPONSE,
1951                                             PKT_DATA, ret + 5, 16,
1952                                             PKT_END);
1953                                 sfree(ret);
1954                                 crWaitUntil(ispkt);
1955                                 if (pktin.type == SSH1_SMSG_SUCCESS) {
1956                                     logevent
1957                                         ("Pageant's response accepted");
1958                                     if (flags & FLAG_VERBOSE) {
1959                                         c_write_str
1960                                             ("Authenticated using RSA key \"");
1961                                         c_write(commentp, commentlen);
1962                                         c_write_str("\" from agent\r\n");
1963                                     }
1964                                     authed = TRUE;
1965                                 } else
1966                                     logevent
1967                                         ("Pageant's response not accepted");
1968                             } else {
1969                                 logevent
1970                                     ("Pageant failed to answer challenge");
1971                                 sfree(ret);
1972                             }
1973                         } else {
1974                             logevent("No reply received from Pageant");
1975                         }
1976                     }
1977                     freebn(key.exponent);
1978                     freebn(key.modulus);
1979                     freebn(challenge);
1980                     if (authed)
1981                         break;
1982                 }
1983             }
1984             if (authed)
1985                 break;
1986         }
1987         if (*cfg.keyfile && !tried_publickey)
1988             pwpkt_type = SSH1_CMSG_AUTH_RSA;
1989
1990         if (pktin.type == SSH1_SMSG_FAILURE &&
1991             cfg.try_tis_auth &&
1992             (supported_auths_mask & (1 << SSH1_AUTH_TIS))) {
1993             pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
1994             logevent("Requested TIS authentication");
1995             send_packet(SSH1_CMSG_AUTH_TIS, PKT_END);
1996             crWaitUntil(ispkt);
1997             if (pktin.type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
1998                 logevent("TIS authentication declined");
1999                 if (flags & FLAG_INTERACTIVE)
2000                     c_write_str("TIS authentication refused.\r\n");
2001             } else {
2002                 int challengelen = ((pktin.body[0] << 24) |
2003                                     (pktin.body[1] << 16) |
2004                                     (pktin.body[2] << 8) |
2005                                     (pktin.body[3]));
2006                 logevent("Received TIS challenge");
2007                 if (challengelen > sizeof(prompt) - 1)
2008                     challengelen = sizeof(prompt) - 1;  /* prevent overrun */
2009                 memcpy(prompt, pktin.body + 4, challengelen);
2010                 prompt[challengelen] = '\0';
2011             }
2012         }
2013         if (pktin.type == SSH1_SMSG_FAILURE &&
2014             cfg.try_tis_auth &&
2015             (supported_auths_mask & (1 << SSH1_AUTH_CCARD))) {
2016             pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
2017             logevent("Requested CryptoCard authentication");
2018             send_packet(SSH1_CMSG_AUTH_CCARD, PKT_END);
2019             crWaitUntil(ispkt);
2020             if (pktin.type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
2021                 logevent("CryptoCard authentication declined");
2022                 c_write_str("CryptoCard authentication refused.\r\n");
2023             } else {
2024                 int challengelen = ((pktin.body[0] << 24) |
2025                                     (pktin.body[1] << 16) |
2026                                     (pktin.body[2] << 8) |
2027                                     (pktin.body[3]));
2028                 logevent("Received CryptoCard challenge");
2029                 if (challengelen > sizeof(prompt) - 1)
2030                     challengelen = sizeof(prompt) - 1;  /* prevent overrun */
2031                 memcpy(prompt, pktin.body + 4, challengelen);
2032                 strncpy(prompt + challengelen, "\r\nResponse : ",
2033                         sizeof(prompt) - challengelen);
2034                 prompt[sizeof(prompt) - 1] = '\0';
2035             }
2036         }
2037         if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
2038             sprintf(prompt, "%.90s@%.90s's password: ",
2039                     username, savedhost);
2040         }
2041         if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
2042             char *comment = NULL;
2043             if (flags & FLAG_VERBOSE)
2044                 c_write_str("Trying public key authentication.\r\n");
2045             if (!rsakey_encrypted(cfg.keyfile, &comment)) {
2046                 if (flags & FLAG_VERBOSE)
2047                     c_write_str("No passphrase required.\r\n");
2048                 goto tryauth;
2049             }
2050             sprintf(prompt, "Passphrase for key \"%.100s\": ", comment);
2051             sfree(comment);
2052         }
2053
2054         if (ssh_get_line) {
2055             if (!ssh_get_line(prompt, password, sizeof(password), TRUE)) {
2056                 /*
2057                  * get_line failed to get a password (for example
2058                  * because one was supplied on the command line
2059                  * which has already failed to work). Terminate.
2060                  */
2061                 send_packet(SSH1_MSG_DISCONNECT,
2062                             PKT_STR, "No more passwords available to try",
2063                             PKT_END);
2064                 connection_fatal("Unable to authenticate");
2065                 ssh_state = SSH_STATE_CLOSED;
2066                 crReturn(1);
2067             }
2068         } else {
2069             c_write_str(prompt);
2070             pos = 0;
2071             ssh_send_ok = 1;
2072             while (pos >= 0) {
2073                 crWaitUntil(!ispkt);
2074                 while (inlen--)
2075                     switch (c = *in++) {
2076                       case 10:
2077                       case 13:
2078                         password[pos] = 0;
2079                         pos = -1;
2080                         break;
2081                       case 8:
2082                       case 127:
2083                         if (pos > 0)
2084                             pos--;
2085                         break;
2086                       case 21:
2087                       case 27:
2088                         pos = 0;
2089                         break;
2090                       case 3:
2091                       case 4:
2092                         random_save_seed();
2093                         exit(0);
2094                         break;
2095                       default:
2096                         if (pos < sizeof(password)-1)
2097                             password[pos++] = c;
2098                         break;
2099                     }
2100             }
2101             c_write_str("\r\n");
2102         }
2103
2104       tryauth:
2105         if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
2106             /*
2107              * Try public key authentication with the specified
2108              * key file.
2109              */
2110             static struct RSAKey pubkey;
2111             static Bignum challenge, response;
2112             static int i;
2113             static unsigned char buffer[32];
2114
2115             tried_publickey = 1;
2116             i = loadrsakey(cfg.keyfile, &pubkey, password);
2117             if (i == 0) {
2118                 c_write_str("Couldn't load public key from ");
2119                 c_write_str(cfg.keyfile);
2120                 c_write_str(".\r\n");
2121                 continue;              /* go and try password */
2122             }
2123             if (i == -1) {
2124                 c_write_str("Wrong passphrase.\r\n");
2125                 tried_publickey = 0;
2126                 continue;              /* try again */
2127             }
2128
2129             /*
2130              * Send a public key attempt.
2131              */
2132             send_packet(SSH1_CMSG_AUTH_RSA,
2133                         PKT_BIGNUM, pubkey.modulus, PKT_END);
2134
2135             crWaitUntil(ispkt);
2136             if (pktin.type == SSH1_SMSG_FAILURE) {
2137                 c_write_str("Server refused our public key.\r\n");
2138                 continue;              /* go and try password */
2139             }
2140             if (pktin.type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
2141                 bombout(("Bizarre response to offer of public key"));
2142                 crReturn(0);
2143             }
2144             ssh1_read_bignum(pktin.body, &challenge);
2145             response = rsadecrypt(challenge, &pubkey);
2146             freebn(pubkey.private_exponent);    /* burn the evidence */
2147
2148             for (i = 0; i < 32; i++) {
2149                 buffer[i] = bignum_byte(response, 31 - i);
2150             }
2151
2152             MD5Init(&md5c);
2153             MD5Update(&md5c, buffer, 32);
2154             MD5Update(&md5c, session_id, 16);
2155             MD5Final(buffer, &md5c);
2156
2157             send_packet(SSH1_CMSG_AUTH_RSA_RESPONSE,
2158                         PKT_DATA, buffer, 16, PKT_END);
2159
2160             crWaitUntil(ispkt);
2161             if (pktin.type == SSH1_SMSG_FAILURE) {
2162                 if (flags & FLAG_VERBOSE)
2163                     c_write_str
2164                         ("Failed to authenticate with our public key.\r\n");
2165                 continue;              /* go and try password */
2166             } else if (pktin.type != SSH1_SMSG_SUCCESS) {
2167                 bombout(
2168                         ("Bizarre response to RSA authentication response"));
2169                 crReturn(0);
2170             }
2171
2172             break;                     /* we're through! */
2173         } else {
2174             if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
2175                 /*
2176                  * Defence against traffic analysis: we send a
2177                  * whole bunch of packets containing strings of
2178                  * different lengths. One of these strings is the
2179                  * password, in a SSH1_CMSG_AUTH_PASSWORD packet.
2180                  * The others are all random data in
2181                  * SSH1_MSG_IGNORE packets. This way a passive
2182                  * listener can't tell which is the password, and
2183                  * hence can't deduce the password length.
2184                  * 
2185                  * Anybody with a password length greater than 16
2186                  * bytes is going to have enough entropy in their
2187                  * password that a listener won't find it _that_
2188                  * much help to know how long it is. So what we'll
2189                  * do is:
2190                  * 
2191                  *  - if password length < 16, we send 15 packets
2192                  *    containing string lengths 1 through 15
2193                  * 
2194                  *  - otherwise, we let N be the nearest multiple
2195                  *    of 8 below the password length, and send 8
2196                  *    packets containing string lengths N through
2197                  *    N+7. This won't obscure the order of
2198                  *    magnitude of the password length, but it will
2199                  *    introduce a bit of extra uncertainty.
2200                  * 
2201                  * A few servers (the old 1.2.18 through 1.2.22)
2202                  * can't deal with SSH1_MSG_IGNORE. For these
2203                  * servers, we need an alternative defence. We make
2204                  * use of the fact that the password is interpreted
2205                  * as a C string: so we can append a NUL, then some
2206                  * random data.
2207                  */
2208                 if (ssh_remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE) {
2209                     char string[64];
2210                     char *s;
2211                     int len;
2212
2213                     len = strlen(password);
2214                     if (len < sizeof(string)) {
2215                         s = string;
2216                         strcpy(string, password);
2217                         len++;         /* cover the zero byte */
2218                         while (len < sizeof(string)) {
2219                             string[len++] = (char) random_byte();
2220                         }
2221                     } else {
2222                         s = password;
2223                     }
2224                     send_packet(pwpkt_type, PKT_INT, len,
2225                                 PKT_DATA, s, len, PKT_END);
2226                 } else {
2227                     int bottom, top, pwlen, i;
2228                     char *randomstr;
2229
2230                     pwlen = strlen(password);
2231                     if (pwlen < 16) {
2232                         bottom = 0;    /* zero length passwords are OK! :-) */
2233                         top = 15;
2234                     } else {
2235                         bottom = pwlen & ~7;
2236                         top = bottom + 7;
2237                     }
2238
2239                     assert(pwlen >= bottom && pwlen <= top);
2240
2241                     randomstr = smalloc(top + 1);
2242
2243                     for (i = bottom; i <= top; i++) {
2244                         if (i == pwlen)
2245                             defer_packet(pwpkt_type, PKT_STR, password,
2246                                          PKT_END);
2247                         else {
2248                             for (j = 0; j < i; j++) {
2249                                 do {
2250                                     randomstr[j] = random_byte();
2251                                 } while (randomstr[j] == '\0');
2252                             }
2253                             randomstr[i] = '\0';
2254                             defer_packet(SSH1_MSG_IGNORE,
2255                                          PKT_STR, randomstr, PKT_END);
2256                         }
2257                     }
2258                     ssh_pkt_defersend();
2259                 }
2260             } else {
2261                 send_packet(pwpkt_type, PKT_STR, password, PKT_END);
2262             }
2263         }
2264         logevent("Sent password");
2265         memset(password, 0, strlen(password));
2266         crWaitUntil(ispkt);
2267         if (pktin.type == SSH1_SMSG_FAILURE) {
2268             if (flags & FLAG_VERBOSE)
2269                 c_write_str("Access denied\r\n");
2270             logevent("Authentication refused");
2271         } else if (pktin.type == SSH1_MSG_DISCONNECT) {
2272             logevent("Received disconnect request");
2273             ssh_state = SSH_STATE_CLOSED;
2274             crReturn(1);
2275         } else if (pktin.type != SSH1_SMSG_SUCCESS) {
2276             bombout(("Strange packet received, type %d", pktin.type));
2277             crReturn(0);
2278         }
2279     }
2280
2281     logevent("Authentication successful");
2282
2283     crFinish(1);
2284 }
2285
2286 void sshfwd_close(struct ssh_channel *c)
2287 {
2288     if (c && !c->closes) {
2289         if (ssh_version == 1) {
2290             send_packet(SSH1_MSG_CHANNEL_CLOSE, PKT_INT, c->remoteid,
2291                         PKT_END);
2292         } else {
2293             ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
2294             ssh2_pkt_adduint32(c->remoteid);
2295             ssh2_pkt_send();
2296         }
2297         c->closes = 1;
2298         if (c->type == CHAN_X11) {
2299             c->u.x11.s = NULL;
2300             logevent("Forwarded X11 connection terminated");
2301         } else if (c->type == CHAN_SOCKDATA) {
2302             c->u.pfd.s = NULL;
2303             logevent("Forwarded port closed");
2304         }
2305     }
2306 }
2307
2308 void sshfwd_write(struct ssh_channel *c, char *buf, int len)
2309 {
2310     if (ssh_version == 1) {
2311         send_packet(SSH1_MSG_CHANNEL_DATA,
2312                     PKT_INT, c->remoteid,
2313                     PKT_INT, len, PKT_DATA, buf, len, PKT_END);
2314     } else {
2315         ssh2_add_channel_data(c, buf, len);
2316         ssh2_try_send(c);
2317     }
2318 }
2319
2320 static void ssh1_protocol(unsigned char *in, int inlen, int ispkt)
2321 {
2322     crBegin;
2323
2324     random_init();
2325
2326     while (!do_ssh1_login(in, inlen, ispkt)) {
2327         crReturnV;
2328     }
2329     if (ssh_state == SSH_STATE_CLOSED)
2330         crReturnV;
2331
2332     if (cfg.agentfwd && agent_exists()) {
2333         logevent("Requesting agent forwarding");
2334         send_packet(SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END);
2335         do {
2336             crReturnV;
2337         } while (!ispkt);
2338         if (pktin.type != SSH1_SMSG_SUCCESS
2339             && pktin.type != SSH1_SMSG_FAILURE) {
2340             bombout(("Protocol confusion"));
2341             crReturnV;
2342         } else if (pktin.type == SSH1_SMSG_FAILURE) {
2343             logevent("Agent forwarding refused");
2344         } else {
2345             logevent("Agent forwarding enabled");
2346             ssh_agentfwd_enabled = TRUE;
2347         }
2348     }
2349
2350     if (cfg.x11_forward) {
2351         char proto[20], data[64];
2352         logevent("Requesting X11 forwarding");
2353         x11_invent_auth(proto, sizeof(proto), data, sizeof(data));
2354         if (ssh1_local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER) {
2355             send_packet(SSH1_CMSG_X11_REQUEST_FORWARDING,
2356                         PKT_STR, proto, PKT_STR, data,
2357                         PKT_INT, 0, PKT_END);
2358         } else {
2359             send_packet(SSH1_CMSG_X11_REQUEST_FORWARDING,
2360                         PKT_STR, proto, PKT_STR, data, PKT_END);
2361         }
2362         do {
2363             crReturnV;
2364         } while (!ispkt);
2365         if (pktin.type != SSH1_SMSG_SUCCESS
2366             && pktin.type != SSH1_SMSG_FAILURE) {
2367             bombout(("Protocol confusion"));
2368             crReturnV;
2369         } else if (pktin.type == SSH1_SMSG_FAILURE) {
2370             logevent("X11 forwarding refused");
2371         } else {
2372             logevent("X11 forwarding enabled");
2373             ssh_X11_fwd_enabled = TRUE;
2374         }
2375     }
2376
2377     {
2378         char type, *e;
2379         int n;
2380         int sport,dport;
2381         char sports[256], dports[256], host[256];
2382         char buf[1024];
2383
2384         ssh_rportfwds = newtree234(ssh_rportcmp);
2385         /* Add port forwardings. */
2386         e = cfg.portfwd;
2387         while (*e) {
2388             type = *e++;
2389             n = 0;
2390             while (*e && *e != '\t')
2391                 sports[n++] = *e++;
2392             sports[n] = 0;
2393             if (*e == '\t')
2394                 e++;
2395             n = 0;
2396             while (*e && *e != ':')
2397                 host[n++] = *e++;
2398             host[n] = 0;
2399             if (*e == ':')
2400                 e++;
2401             n = 0;
2402             while (*e)
2403                 dports[n++] = *e++;
2404             dports[n] = 0;
2405             e++;
2406             dport = atoi(dports);
2407             sport = atoi(sports);
2408             if (sport && dport) {
2409                 if (type == 'L') {
2410                     pfd_addforward(host, dport, sport);
2411                     sprintf(buf, "Local port %d forwarding to %s:%d",
2412                             sport, host, dport);
2413                     logevent(buf);
2414                 } else {
2415                     struct ssh_rportfwd *pf;
2416                     pf = smalloc(sizeof(*pf));
2417                     strcpy(pf->host, host);
2418                     pf->port = dport;
2419                     if (add234(ssh_rportfwds, pf) != pf) {
2420                         sprintf(buf, 
2421                                 "Duplicate remote port forwarding to %s:%s",
2422                                 host, dport);
2423                         logevent(buf);
2424                     } else {
2425                         sprintf(buf, "Requesting remote port %d forward to %s:%d",
2426                                 sport, host, dport);
2427                         logevent(buf);
2428                         send_packet(SSH1_CMSG_PORT_FORWARD_REQUEST,
2429                                     PKT_INT, sport,
2430                                     PKT_STR, host,
2431                                     PKT_INT, dport,
2432                                     PKT_END);
2433                     }
2434                 }
2435             }
2436         }
2437     }
2438
2439     if (!cfg.nopty) {
2440         send_packet(SSH1_CMSG_REQUEST_PTY,
2441                     PKT_STR, cfg.termtype,
2442                     PKT_INT, rows, PKT_INT, cols,
2443                     PKT_INT, 0, PKT_INT, 0, PKT_CHAR, 0, PKT_END);
2444         ssh_state = SSH_STATE_INTERMED;
2445         do {
2446             crReturnV;
2447         } while (!ispkt);
2448         if (pktin.type != SSH1_SMSG_SUCCESS
2449             && pktin.type != SSH1_SMSG_FAILURE) {
2450             bombout(("Protocol confusion"));
2451             crReturnV;
2452         } else if (pktin.type == SSH1_SMSG_FAILURE) {
2453             c_write_str("Server refused to allocate pty\r\n");
2454             ssh_editing = ssh_echoing = 1;
2455         }
2456         logevent("Allocated pty");
2457     } else {
2458         ssh_editing = ssh_echoing = 1;
2459     }
2460
2461     if (cfg.compression) {
2462         send_packet(SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);
2463         do {
2464             crReturnV;
2465         } while (!ispkt);
2466         if (pktin.type != SSH1_SMSG_SUCCESS
2467             && pktin.type != SSH1_SMSG_FAILURE) {
2468             bombout(("Protocol confusion"));
2469             crReturnV;
2470         } else if (pktin.type == SSH1_SMSG_FAILURE) {
2471             c_write_str("Server refused to compress\r\n");
2472         }
2473         logevent("Started compression");
2474         ssh1_compressing = TRUE;
2475         zlib_compress_init();
2476         zlib_decompress_init();
2477     }
2478
2479     if (*cfg.remote_cmd_ptr)
2480         send_packet(SSH1_CMSG_EXEC_CMD, PKT_STR, cfg.remote_cmd_ptr,
2481                     PKT_END);
2482     else
2483         send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END);
2484     logevent("Started session");
2485
2486     ssh_state = SSH_STATE_SESSION;
2487     if (size_needed)
2488         ssh_size();
2489     if (eof_needed)
2490         ssh_special(TS_EOF);
2491
2492     ldisc_send(NULL, 0);               /* cause ldisc to notice changes */
2493     ssh_send_ok = 1;
2494     ssh_channels = newtree234(ssh_channelcmp);
2495     while (1) {
2496         crReturnV;
2497         if (ispkt) {
2498             if (pktin.type == SSH1_SMSG_STDOUT_DATA ||
2499                 pktin.type == SSH1_SMSG_STDERR_DATA) {
2500                 long len = GET_32BIT(pktin.body);
2501                 from_backend(pktin.type == SSH1_SMSG_STDERR_DATA,
2502                              pktin.body + 4, len);
2503             } else if (pktin.type == SSH1_MSG_DISCONNECT) {
2504                 ssh_state = SSH_STATE_CLOSED;
2505                 logevent("Received disconnect request");
2506                 crReturnV;
2507             } else if (pktin.type == SSH1_SMSG_X11_OPEN) {
2508                 /* Remote side is trying to open a channel to talk to our
2509                  * X-Server. Give them back a local channel number. */
2510                 struct ssh_channel *c;
2511
2512                 logevent("Received X11 connect request");
2513                 /* Refuse if X11 forwarding is disabled. */
2514                 if (!ssh_X11_fwd_enabled) {
2515                     send_packet(SSH1_MSG_CHANNEL_OPEN_FAILURE,
2516                                 PKT_INT, GET_32BIT(pktin.body), PKT_END);
2517                     logevent("Rejected X11 connect request");
2518                 } else {
2519                     c = smalloc(sizeof(struct ssh_channel));
2520
2521                     if (x11_init(&c->u.x11.s, cfg.x11_display, c) != NULL) {
2522                         logevent("opening X11 forward connection failed");
2523                         sfree(c);
2524                         send_packet(SSH1_MSG_CHANNEL_OPEN_FAILURE,
2525                                     PKT_INT, GET_32BIT(pktin.body),
2526                                     PKT_END);
2527                     } else {
2528                         logevent
2529                             ("opening X11 forward connection succeeded");
2530                         c->remoteid = GET_32BIT(pktin.body);
2531                         c->localid = alloc_channel_id();
2532                         c->closes = 0;
2533                         c->type = CHAN_X11;     /* identify channel type */
2534                         add234(ssh_channels, c);
2535                         send_packet(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
2536                                     PKT_INT, c->remoteid, PKT_INT,
2537                                     c->localid, PKT_END);
2538                         logevent("Opened X11 forward channel");
2539                     }
2540                 }
2541             } else if (pktin.type == SSH1_SMSG_AGENT_OPEN) {
2542                 /* Remote side is trying to open a channel to talk to our
2543                  * agent. Give them back a local channel number. */
2544                 struct ssh_channel *c;
2545
2546                 /* Refuse if agent forwarding is disabled. */
2547                 if (!ssh_agentfwd_enabled) {
2548                     send_packet(SSH1_MSG_CHANNEL_OPEN_FAILURE,
2549                                 PKT_INT, GET_32BIT(pktin.body), PKT_END);
2550                 } else {
2551                     c = smalloc(sizeof(struct ssh_channel));
2552                     c->remoteid = GET_32BIT(pktin.body);
2553                     c->localid = alloc_channel_id();
2554                     c->closes = 0;
2555                     c->type = CHAN_AGENT;       /* identify channel type */
2556                     c->u.a.lensofar = 0;
2557                     add234(ssh_channels, c);
2558                     send_packet(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
2559                                 PKT_INT, c->remoteid, PKT_INT, c->localid,
2560                                 PKT_END);
2561                 }
2562             } else if (pktin.type == SSH1_MSG_PORT_OPEN) {
2563                 /* Remote side is trying to open a channel to talk to a
2564                  * forwarded port. Give them back a local channel number. */
2565                 struct ssh_channel *c;
2566                 struct ssh_rportfwd pf;
2567                 int hostsize, port;
2568                 char host[256], buf[1024];
2569                 char *p, *h, *e;
2570                 c = smalloc(sizeof(struct ssh_channel));
2571
2572                 hostsize = GET_32BIT(pktin.body+4);
2573                 for(h = host, p = pktin.body+8; hostsize != 0; hostsize--) {
2574                     if (h+1 < host+sizeof(host))
2575                         *h++ = *p;
2576                     *p++;
2577                 }
2578                 *h = 0;
2579                 port = GET_32BIT(p);
2580
2581                 strcpy(pf.host, host);
2582                 pf.port = port;
2583
2584                 if (find234(ssh_rportfwds, &pf, NULL) == NULL) {
2585                     sprintf(buf, "Rejected remote port open request for %s:%d",
2586                             host, port);
2587                     logevent(buf);
2588                     send_packet(SSH1_MSG_CHANNEL_OPEN_FAILURE,
2589                                 PKT_INT, GET_32BIT(pktin.body), PKT_END);
2590                 } else {
2591                     sprintf(buf, "Received remote port open request for %s:%d",
2592                             host, port);
2593                     logevent(buf);
2594                     e = pfd_newconnect(&c->u.pfd.s, host, port, c);
2595                     if (e != NULL) {
2596                         char buf[256];
2597                         sprintf(buf, "Port open failed: %s", e);
2598                         logevent(buf);
2599                         sfree(c);
2600                         send_packet(SSH1_MSG_CHANNEL_OPEN_FAILURE,
2601                                     PKT_INT, GET_32BIT(pktin.body),
2602                                     PKT_END);
2603                     } else {
2604                         c->remoteid = GET_32BIT(pktin.body);
2605                         c->localid = alloc_channel_id();
2606                         c->closes = 0;
2607                         c->type = CHAN_SOCKDATA;        /* identify channel type */
2608                         add234(ssh_channels, c);
2609                         send_packet(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
2610                                     PKT_INT, c->remoteid, PKT_INT,
2611                                     c->localid, PKT_END);
2612                         logevent("Forwarded port opened successfully");
2613                     }
2614                 }
2615
2616             } else if (pktin.type == SSH1_MSG_CHANNEL_OPEN_CONFIRMATION) {
2617                     unsigned int remoteid = GET_32BIT(pktin.body);
2618                     unsigned int localid = GET_32BIT(pktin.body+4);
2619                     struct ssh_channel *c;
2620                     
2621                     c = find234(ssh_channels, &remoteid, ssh_channelfind);
2622                     if (c) {
2623                         c->remoteid = localid;
2624                         pfd_confirm(c->u.pfd.s);
2625                     } else {
2626                         sshfwd_close(c);
2627                     }
2628
2629             } else if (pktin.type == SSH1_MSG_CHANNEL_CLOSE ||
2630                        pktin.type == SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION) {
2631                 /* Remote side closes a channel. */
2632                 unsigned i = GET_32BIT(pktin.body);
2633                 struct ssh_channel *c;
2634                 c = find234(ssh_channels, &i, ssh_channelfind);
2635                 if (c) {
2636                     int closetype;
2637                     closetype =
2638                         (pktin.type == SSH1_MSG_CHANNEL_CLOSE ? 1 : 2);
2639                     if (!(c->closes & closetype))
2640                         send_packet(pktin.type, PKT_INT, c->remoteid,
2641                                     PKT_END);
2642                     if ((c->closes == 0) && (c->type == CHAN_X11)) {
2643                         logevent("Forwarded X11 connection terminated");
2644                         assert(c->u.x11.s != NULL);
2645                         x11_close(c->u.x11.s);
2646                         c->u.x11.s = NULL;
2647                     }
2648                     if ((c->closes == 0) && (c->type == CHAN_SOCKDATA)) {
2649                         logevent("Forwarded port closed");
2650                         assert(c->u.pfd.s != NULL);
2651                         pfd_close(c->u.pfd.s);
2652                         c->u.pfd.s = NULL;
2653                     }
2654                     c->closes |= closetype;
2655                     if (c->closes == 3) {
2656                         del234(ssh_channels, c);
2657                         sfree(c);
2658                     }
2659                 }
2660             } else if (pktin.type == SSH1_MSG_CHANNEL_DATA) {
2661                 /* Data sent down one of our channels. */
2662                 int i = GET_32BIT(pktin.body);
2663                 int len = GET_32BIT(pktin.body + 4);
2664                 unsigned char *p = pktin.body + 8;
2665                 struct ssh_channel *c;
2666                 c = find234(ssh_channels, &i, ssh_channelfind);
2667                 if (c) {
2668                     switch (c->type) {
2669                       case CHAN_X11:
2670                         x11_send(c->u.x11.s, p, len);
2671                         break;
2672                       case CHAN_SOCKDATA:
2673                               pfd_send(c->u.pfd.s, p, len);
2674                               break;
2675                       case CHAN_AGENT:
2676                         /* Data for an agent message. Buffer it. */
2677                         while (len > 0) {
2678                             if (c->u.a.lensofar < 4) {
2679                                 int l = min(4 - c->u.a.lensofar, len);
2680                                 memcpy(c->u.a.msglen + c->u.a.lensofar, p,
2681                                        l);
2682                                 p += l;
2683                                 len -= l;
2684                                 c->u.a.lensofar += l;
2685                             }
2686                             if (c->u.a.lensofar == 4) {
2687                                 c->u.a.totallen =
2688                                     4 + GET_32BIT(c->u.a.msglen);
2689                                 c->u.a.message = smalloc(c->u.a.totallen);
2690                                 memcpy(c->u.a.message, c->u.a.msglen, 4);
2691                             }
2692                             if (c->u.a.lensofar >= 4 && len > 0) {
2693                                 int l =
2694                                     min(c->u.a.totallen - c->u.a.lensofar,
2695                                         len);
2696                                 memcpy(c->u.a.message + c->u.a.lensofar, p,
2697                                        l);
2698                                 p += l;
2699                                 len -= l;
2700                                 c->u.a.lensofar += l;
2701                             }
2702                             if (c->u.a.lensofar == c->u.a.totallen) {
2703                                 void *reply, *sentreply;
2704                                 int replylen;
2705                                 agent_query(c->u.a.message,
2706                                             c->u.a.totallen, &reply,
2707                                             &replylen);
2708                                 if (reply)
2709                                     sentreply = reply;
2710                                 else {
2711                                     /* Fake SSH_AGENT_FAILURE. */
2712                                     sentreply = "\0\0\0\1\5";
2713                                     replylen = 5;
2714                                 }
2715                                 send_packet(SSH1_MSG_CHANNEL_DATA,
2716                                             PKT_INT, c->remoteid,
2717                                             PKT_INT, replylen,
2718                                             PKT_DATA, sentreply, replylen,
2719                                             PKT_END);
2720                                 if (reply)
2721                                     sfree(reply);
2722                                 sfree(c->u.a.message);
2723                                 c->u.a.lensofar = 0;
2724                             }
2725                         }
2726                         break;
2727                     }
2728                 }
2729             } else if (pktin.type == SSH1_SMSG_SUCCESS) {
2730                 /* may be from EXEC_SHELL on some servers */
2731             } else if (pktin.type == SSH1_SMSG_FAILURE) {
2732                 /* may be from EXEC_SHELL on some servers
2733                  * if no pty is available or in other odd cases. Ignore */
2734             } else if (pktin.type == SSH1_SMSG_EXIT_STATUS) {
2735                 send_packet(SSH1_CMSG_EXIT_CONFIRMATION, PKT_END);
2736             } else {
2737                 bombout(("Strange packet received: type %d", pktin.type));
2738                 crReturnV;
2739             }
2740         } else {
2741             while (inlen > 0) {
2742                 int len = min(inlen, 512);
2743                 send_packet(SSH1_CMSG_STDIN_DATA,
2744                             PKT_INT, len, PKT_DATA, in, len, PKT_END);
2745                 in += len;
2746                 inlen -= len;
2747             }
2748         }
2749     }
2750
2751     crFinishV;
2752 }
2753
2754 /*
2755  * Utility routine for decoding comma-separated strings in KEXINIT.
2756  */
2757 static int in_commasep_string(char *needle, char *haystack, int haylen)
2758 {
2759     int needlen = strlen(needle);
2760     while (1) {
2761         /*
2762          * Is it at the start of the string?
2763          */
2764         if (haylen >= needlen &&       /* haystack is long enough */
2765             !memcmp(needle, haystack, needlen) &&       /* initial match */
2766             (haylen == needlen || haystack[needlen] == ',')
2767             /* either , or EOS follows */
2768             )
2769             return 1;
2770         /*
2771          * If not, search for the next comma and resume after that.
2772          * If no comma found, terminate.
2773          */
2774         while (haylen > 0 && *haystack != ',')
2775             haylen--, haystack++;
2776         if (haylen == 0)
2777             return 0;
2778         haylen--, haystack++;          /* skip over comma itself */
2779     }
2780 }
2781
2782 /*
2783  * SSH2 key creation method.
2784  */
2785 static void ssh2_mkkey(Bignum K, char *H, char *sessid, char chr,
2786                        char *keyspace)
2787 {
2788     SHA_State s;
2789     /* First 20 bytes. */
2790     SHA_Init(&s);
2791     sha_mpint(&s, K);
2792     SHA_Bytes(&s, H, 20);
2793     SHA_Bytes(&s, &chr, 1);
2794     SHA_Bytes(&s, sessid, 20);
2795     SHA_Final(&s, keyspace);
2796     /* Next 20 bytes. */
2797     SHA_Init(&s);
2798     sha_mpint(&s, K);
2799     SHA_Bytes(&s, H, 20);
2800     SHA_Bytes(&s, keyspace, 20);
2801     SHA_Final(&s, keyspace + 20);
2802 }
2803
2804 /*
2805  * Handle the SSH2 transport layer.
2806  */
2807 static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
2808 {
2809     static int i, j, len, nbits, pbits;
2810     static char *str;
2811     static Bignum p, g, e, f, K;
2812     static int kex_init_value, kex_reply_value;
2813     static const struct ssh_mac **maclist;
2814     static int nmacs;
2815     static const struct ssh2_cipher *cscipher_tobe = NULL;
2816     static const struct ssh2_cipher *sccipher_tobe = NULL;
2817     static const struct ssh_mac *csmac_tobe = NULL;
2818     static const struct ssh_mac *scmac_tobe = NULL;
2819     static const struct ssh_compress *cscomp_tobe = NULL;
2820     static const struct ssh_compress *sccomp_tobe = NULL;
2821     static char *hostkeydata, *sigdata, *keystr, *fingerprint;
2822     static int hostkeylen, siglen;
2823     static void *hkey;                 /* actual host key */
2824     static unsigned char exchange_hash[20];
2825     static unsigned char keyspace[40];
2826     static const struct ssh2_ciphers *preferred_cipher;
2827     static const struct ssh_compress *preferred_comp;
2828     static int first_kex;
2829
2830     crBegin;
2831     random_init();
2832     first_kex = 1;
2833
2834     /*
2835      * Set up the preferred cipher and compression.
2836      */
2837     if (cfg.cipher == CIPHER_BLOWFISH) {
2838         preferred_cipher = &ssh2_blowfish;
2839     } else if (cfg.cipher == CIPHER_DES) {
2840         logevent("Single DES not supported in SSH2; using 3DES");
2841         preferred_cipher = &ssh2_3des;
2842     } else if (cfg.cipher == CIPHER_3DES) {
2843         preferred_cipher = &ssh2_3des;
2844     } else if (cfg.cipher == CIPHER_AES) {
2845         preferred_cipher = &ssh2_aes;
2846     } else {
2847         /* Shouldn't happen, but we do want to initialise to _something_. */
2848         preferred_cipher = &ssh2_3des;
2849     }
2850     if (cfg.compression)
2851         preferred_comp = &ssh_zlib;
2852     else
2853         preferred_comp = &ssh_comp_none;
2854
2855     /*
2856      * Be prepared to work around the buggy MAC problem.
2857      */
2858     if (cfg.buggymac || (ssh_remote_bugs & BUG_SSH2_HMAC))
2859         maclist = buggymacs, nmacs = lenof(buggymacs);
2860     else
2861         maclist = macs, nmacs = lenof(macs);
2862
2863   begin_key_exchange:
2864     /*
2865      * Construct and send our key exchange packet.
2866      */
2867     ssh2_pkt_init(SSH2_MSG_KEXINIT);
2868     for (i = 0; i < 16; i++)
2869         ssh2_pkt_addbyte((unsigned char) random_byte());
2870     /* List key exchange algorithms. */
2871     ssh2_pkt_addstring_start();
2872     for (i = 0; i < lenof(kex_algs); i++) {
2873         ssh2_pkt_addstring_str(kex_algs[i]->name);
2874         if (i < lenof(kex_algs) - 1)
2875             ssh2_pkt_addstring_str(",");
2876     }
2877     /* List server host key algorithms. */
2878     ssh2_pkt_addstring_start();
2879     for (i = 0; i < lenof(hostkey_algs); i++) {
2880         ssh2_pkt_addstring_str(hostkey_algs[i]->name);
2881         if (i < lenof(hostkey_algs) - 1)
2882             ssh2_pkt_addstring_str(",");
2883     }
2884     /* List client->server encryption algorithms. */
2885     ssh2_pkt_addstring_start();
2886     for (i = 0; i < lenof(ciphers) + 1; i++) {
2887         const struct ssh2_ciphers *c =
2888             i == 0 ? preferred_cipher : ciphers[i - 1];
2889         for (j = 0; j < c->nciphers; j++) {
2890             ssh2_pkt_addstring_str(c->list[j]->name);
2891             if (i < lenof(ciphers) || j < c->nciphers - 1)
2892                 ssh2_pkt_addstring_str(",");
2893         }
2894     }
2895     /* List server->client encryption algorithms. */
2896     ssh2_pkt_addstring_start();
2897     for (i = 0; i < lenof(ciphers) + 1; i++) {
2898         const struct ssh2_ciphers *c =
2899             i == 0 ? preferred_cipher : ciphers[i - 1];
2900         for (j = 0; j < c->nciphers; j++) {
2901             ssh2_pkt_addstring_str(c->list[j]->name);
2902             if (i < lenof(ciphers) || j < c->nciphers - 1)
2903                 ssh2_pkt_addstring_str(",");
2904         }
2905     }
2906     /* List client->server MAC algorithms. */
2907     ssh2_pkt_addstring_start();
2908     for (i = 0; i < nmacs; i++) {
2909         ssh2_pkt_addstring_str(maclist[i]->name);
2910         if (i < nmacs - 1)
2911             ssh2_pkt_addstring_str(",");
2912     }
2913     /* List server->client MAC algorithms. */
2914     ssh2_pkt_addstring_start();
2915     for (i = 0; i < nmacs; i++) {
2916         ssh2_pkt_addstring_str(maclist[i]->name);
2917         if (i < nmacs - 1)
2918             ssh2_pkt_addstring_str(",");
2919     }
2920     /* List client->server compression algorithms. */
2921     ssh2_pkt_addstring_start();
2922     for (i = 0; i < lenof(compressions) + 1; i++) {
2923         const struct ssh_compress *c =
2924             i == 0 ? preferred_comp : compressions[i - 1];
2925         ssh2_pkt_addstring_str(c->name);
2926         if (i < lenof(compressions))
2927             ssh2_pkt_addstring_str(",");
2928     }
2929     /* List server->client compression algorithms. */
2930     ssh2_pkt_addstring_start();
2931     for (i = 0; i < lenof(compressions) + 1; i++) {
2932         const struct ssh_compress *c =
2933             i == 0 ? preferred_comp : compressions[i - 1];
2934         ssh2_pkt_addstring_str(c->name);
2935         if (i < lenof(compressions))
2936             ssh2_pkt_addstring_str(",");
2937     }
2938     /* List client->server languages. Empty list. */
2939     ssh2_pkt_addstring_start();
2940     /* List server->client languages. Empty list. */
2941     ssh2_pkt_addstring_start();
2942     /* First KEX packet does _not_ follow, because we're not that brave. */
2943     ssh2_pkt_addbool(FALSE);
2944     /* Reserved. */
2945     ssh2_pkt_adduint32(0);
2946
2947     exhash = exhashbase;
2948     sha_string(&exhash, pktout.data + 5, pktout.length - 5);
2949
2950     ssh2_pkt_send();
2951
2952     if (!ispkt)
2953         crWaitUntil(ispkt);
2954     sha_string(&exhash, pktin.data + 5, pktin.length - 5);
2955
2956     /*
2957      * Now examine the other side's KEXINIT to see what we're up
2958      * to.
2959      */
2960     if (pktin.type != SSH2_MSG_KEXINIT) {
2961         bombout(("expected key exchange packet from server"));
2962         crReturn(0);
2963     }
2964     kex = NULL;
2965     hostkey = NULL;
2966     cscipher_tobe = NULL;
2967     sccipher_tobe = NULL;
2968     csmac_tobe = NULL;
2969     scmac_tobe = NULL;
2970     cscomp_tobe = NULL;
2971     sccomp_tobe = NULL;
2972     pktin.savedpos += 16;              /* skip garbage cookie */
2973     ssh2_pkt_getstring(&str, &len);    /* key exchange algorithms */
2974     for (i = 0; i < lenof(kex_algs); i++) {
2975         if (in_commasep_string(kex_algs[i]->name, str, len)) {
2976             kex = kex_algs[i];
2977             break;
2978         }
2979     }
2980     ssh2_pkt_getstring(&str, &len);    /* host key algorithms */
2981     for (i = 0; i < lenof(hostkey_algs); i++) {
2982         if (in_commasep_string(hostkey_algs[i]->name, str, len)) {
2983             hostkey = hostkey_algs[i];
2984             break;
2985         }
2986     }
2987     ssh2_pkt_getstring(&str, &len);    /* client->server cipher */
2988     for (i = 0; i < lenof(ciphers) + 1; i++) {
2989         const struct ssh2_ciphers *c =
2990             i == 0 ? preferred_cipher : ciphers[i - 1];
2991         for (j = 0; j < c->nciphers; j++) {
2992             if (in_commasep_string(c->list[j]->name, str, len)) {
2993                 cscipher_tobe = c->list[j];
2994                 break;
2995             }
2996         }
2997         if (cscipher_tobe)
2998             break;
2999     }
3000     ssh2_pkt_getstring(&str, &len);    /* server->client cipher */
3001     for (i = 0; i < lenof(ciphers) + 1; i++) {
3002         const struct ssh2_ciphers *c =
3003             i == 0 ? preferred_cipher : ciphers[i - 1];
3004         for (j = 0; j < c->nciphers; j++) {
3005             if (in_commasep_string(c->list[j]->name, str, len)) {
3006                 sccipher_tobe = c->list[j];
3007                 break;
3008             }
3009         }
3010         if (sccipher_tobe)
3011             break;
3012     }
3013     ssh2_pkt_getstring(&str, &len);    /* client->server mac */
3014     for (i = 0; i < nmacs; i++) {
3015         if (in_commasep_string(maclist[i]->name, str, len)) {
3016             csmac_tobe = maclist[i];
3017             break;
3018         }
3019     }
3020     ssh2_pkt_getstring(&str, &len);    /* server->client mac */
3021     for (i = 0; i < nmacs; i++) {
3022         if (in_commasep_string(maclist[i]->name, str, len)) {
3023             scmac_tobe = maclist[i];
3024             break;
3025         }
3026     }
3027     ssh2_pkt_getstring(&str, &len);    /* client->server compression */
3028     for (i = 0; i < lenof(compressions) + 1; i++) {
3029         const struct ssh_compress *c =
3030             i == 0 ? preferred_comp : compressions[i - 1];
3031         if (in_commasep_string(c->name, str, len)) {
3032             cscomp_tobe = c;
3033             break;
3034         }
3035     }
3036     ssh2_pkt_getstring(&str, &len);    /* server->client compression */
3037     for (i = 0; i < lenof(compressions) + 1; i++) {
3038         const struct ssh_compress *c =
3039             i == 0 ? preferred_comp : compressions[i - 1];
3040         if (in_commasep_string(c->name, str, len)) {
3041             sccomp_tobe = c;
3042             break;
3043         }
3044     }
3045
3046     /*
3047      * Work out the number of bits of key we will need from the key
3048      * exchange. We start with the maximum key length of either
3049      * cipher...
3050      */
3051     {
3052         int csbits, scbits;
3053
3054         csbits = cscipher_tobe->keylen;
3055         scbits = sccipher_tobe->keylen;
3056         nbits = (csbits > scbits ? csbits : scbits);
3057     }
3058     /* The keys only have 160-bit entropy, since they're based on
3059      * a SHA-1 hash. So cap the key size at 160 bits. */
3060     if (nbits > 160)
3061         nbits = 160;
3062
3063     /*
3064      * If we're doing Diffie-Hellman group exchange, start by
3065      * requesting a group.
3066      */
3067     if (kex == &ssh_diffiehellman_gex) {
3068         logevent("Doing Diffie-Hellman group exchange");
3069         /*
3070          * Work out how big a DH group we will need to allow that
3071          * much data.
3072          */
3073         pbits = 512 << ((nbits - 1) / 64);
3074         ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
3075         ssh2_pkt_adduint32(pbits);
3076         ssh2_pkt_send();
3077
3078         crWaitUntil(ispkt);
3079         if (pktin.type != SSH2_MSG_KEX_DH_GEX_GROUP) {
3080             bombout(("expected key exchange group packet from server"));
3081             crReturn(0);
3082         }
3083         p = ssh2_pkt_getmp();
3084         g = ssh2_pkt_getmp();
3085         dh_setup_group(p, g);
3086         kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
3087         kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
3088     } else {
3089         dh_setup_group1();
3090         kex_init_value = SSH2_MSG_KEXDH_INIT;
3091         kex_reply_value = SSH2_MSG_KEXDH_REPLY;
3092     }
3093
3094     logevent("Doing Diffie-Hellman key exchange");
3095     /*
3096      * Now generate and send e for Diffie-Hellman.
3097      */
3098     e = dh_create_e(nbits * 2);
3099     ssh2_pkt_init(kex_init_value);
3100     ssh2_pkt_addmp(e);
3101     ssh2_pkt_send();
3102
3103     crWaitUntil(ispkt);
3104     if (pktin.type != kex_reply_value) {
3105         bombout(("expected key exchange reply packet from server"));
3106         crReturn(0);
3107     }
3108     ssh2_pkt_getstring(&hostkeydata, &hostkeylen);
3109     f = ssh2_pkt_getmp();
3110     ssh2_pkt_getstring(&sigdata, &siglen);
3111
3112     K = dh_find_K(f);
3113
3114     sha_string(&exhash, hostkeydata, hostkeylen);
3115     if (kex == &ssh_diffiehellman_gex) {
3116         sha_uint32(&exhash, pbits);
3117         sha_mpint(&exhash, p);
3118         sha_mpint(&exhash, g);
3119     }
3120     sha_mpint(&exhash, e);
3121     sha_mpint(&exhash, f);
3122     sha_mpint(&exhash, K);
3123     SHA_Final(&exhash, exchange_hash);
3124
3125     dh_cleanup();
3126
3127 #if 0
3128     debug(("Exchange hash is:\n"));
3129     dmemdump(exchange_hash, 20);
3130 #endif
3131
3132     hkey = hostkey->newkey(hostkeydata, hostkeylen);
3133     if (!hkey ||
3134         !hostkey->verifysig(hkey, sigdata, siglen, exchange_hash, 20)) {
3135         bombout(("Server's host key did not match the signature supplied"));
3136         crReturn(0);
3137     }
3138
3139     /*
3140      * Expect SSH2_MSG_NEWKEYS from server.
3141      */
3142     crWaitUntil(ispkt);
3143     if (pktin.type != SSH2_MSG_NEWKEYS) {
3144         bombout(("expected new-keys packet from server"));
3145         crReturn(0);
3146     }
3147
3148     /*
3149      * Authenticate remote host: verify host key. (We've already
3150      * checked the signature of the exchange hash.)
3151      */
3152     keystr = hostkey->fmtkey(hkey);
3153     fingerprint = hostkey->fingerprint(hkey);
3154     verify_ssh_host_key(savedhost, savedport, hostkey->keytype,
3155                         keystr, fingerprint);
3156     if (first_kex) {                   /* don't bother logging this in rekeys */
3157         logevent("Host key fingerprint is:");
3158         logevent(fingerprint);
3159     }
3160     sfree(fingerprint);
3161     sfree(keystr);
3162     hostkey->freekey(hkey);
3163
3164     /*
3165      * Send SSH2_MSG_NEWKEYS.
3166      */
3167     ssh2_pkt_init(SSH2_MSG_NEWKEYS);
3168     ssh2_pkt_send();
3169
3170     /*
3171      * Create and initialise session keys.
3172      */
3173     cscipher = cscipher_tobe;
3174     sccipher = sccipher_tobe;
3175     csmac = csmac_tobe;
3176     scmac = scmac_tobe;
3177     cscomp = cscomp_tobe;
3178     sccomp = sccomp_tobe;
3179     cscomp->compress_init();
3180     sccomp->decompress_init();
3181     /*
3182      * Set IVs after keys. Here we use the exchange hash from the
3183      * _first_ key exchange.
3184      */
3185     if (first_kex)
3186         memcpy(ssh2_session_id, exchange_hash, sizeof(exchange_hash));
3187     ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'C', keyspace);
3188     cscipher->setcskey(keyspace);
3189     ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'D', keyspace);
3190     sccipher->setsckey(keyspace);
3191     ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'A', keyspace);
3192     cscipher->setcsiv(keyspace);
3193     ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'B', keyspace);
3194     sccipher->setsciv(keyspace);
3195     ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'E', keyspace);
3196     csmac->setcskey(keyspace);
3197     ssh2_mkkey(K, exchange_hash, ssh2_session_id, 'F', keyspace);
3198     scmac->setsckey(keyspace);
3199
3200     /*
3201      * If this is the first key exchange phase, we must pass the
3202      * SSH2_MSG_NEWKEYS packet to the next layer, not because it
3203      * wants to see it but because it will need time to initialise
3204      * itself before it sees an actual packet. In subsequent key
3205      * exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
3206      * it would only confuse the layer above.
3207      */
3208     if (!first_kex) {
3209         crReturn(0);
3210     }
3211     first_kex = 0;
3212
3213     /*
3214      * Now we're encrypting. Begin returning 1 to the protocol main
3215      * function so that other things can run on top of the
3216      * transport. If we ever see a KEXINIT, we must go back to the
3217      * start.
3218      */
3219     while (!(ispkt && pktin.type == SSH2_MSG_KEXINIT)) {
3220         crReturn(1);
3221     }
3222     logevent("Server initiated key re-exchange");
3223     goto begin_key_exchange;
3224
3225     crFinish(1);
3226 }
3227
3228 /*
3229  * Add data to an SSH2 channel output buffer.
3230  */
3231 static void ssh2_add_channel_data(struct ssh_channel *c, char *buf,
3232                                   int len)
3233 {
3234     if (c->v2.outbufsize < c->v2.outbuflen + len) {
3235         c->v2.outbufsize = c->v2.outbuflen + len + 1024;
3236         c->v2.outbuffer = srealloc(c->v2.outbuffer, c->v2.outbufsize);
3237     }
3238     memcpy(c->v2.outbuffer + c->v2.outbuflen, buf, len);
3239     c->v2.outbuflen += len;
3240 }
3241
3242 /*
3243  * Attempt to send data on an SSH2 channel.
3244  */
3245 static void ssh2_try_send(struct ssh_channel *c)
3246 {
3247     while (c->v2.remwindow > 0 && c->v2.outbuflen > 0) {
3248         unsigned len = c->v2.remwindow;
3249         if (len > c->v2.outbuflen)
3250             len = c->v2.outbuflen;
3251         if (len > c->v2.remmaxpkt)
3252             len = c->v2.remmaxpkt;
3253         ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
3254         ssh2_pkt_adduint32(c->remoteid);
3255         ssh2_pkt_addstring_start();
3256         ssh2_pkt_addstring_data(c->v2.outbuffer, len);
3257         ssh2_pkt_send();
3258         c->v2.outbuflen -= len;
3259         memmove(c->v2.outbuffer, c->v2.outbuffer + len, c->v2.outbuflen);
3260         c->v2.remwindow -= len;
3261     }
3262 }
3263
3264 /*
3265  * Handle the SSH2 userauth and connection layers.
3266  */
3267 static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
3268 {
3269     static enum {
3270         AUTH_INVALID, AUTH_PUBLICKEY_AGENT, AUTH_PUBLICKEY_FILE,
3271         AUTH_PASSWORD
3272     } method;
3273     static enum {
3274         AUTH_TYPE_NONE,
3275         AUTH_TYPE_PUBLICKEY,
3276         AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
3277         AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
3278         AUTH_TYPE_PASSWORD
3279     } type;
3280     static int gotit, need_pw, can_pubkey, can_passwd;
3281     static int tried_pubkey_config, tried_agent;
3282     static int we_are_in;
3283     static char username[100];
3284     static char pwprompt[200];
3285     static char password[100];
3286
3287     crBegin;
3288
3289     /*
3290      * Request userauth protocol, and await a response to it.
3291      */
3292     ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
3293     ssh2_pkt_addstring("ssh-userauth");
3294     ssh2_pkt_send();
3295     crWaitUntilV(ispkt);
3296     if (pktin.type != SSH2_MSG_SERVICE_ACCEPT) {
3297         bombout(("Server refused user authentication protocol"));
3298         crReturnV;
3299     }
3300
3301     /*
3302      * We repeat this whole loop, including the username prompt,
3303      * until we manage a successful authentication. If the user
3304      * types the wrong _password_, they are sent back to the
3305      * beginning to try another username. (If they specify a
3306      * username in the config, they are never asked, even if they
3307      * do give a wrong password.)
3308      * 
3309      * I think this best serves the needs of
3310      * 
3311      *  - the people who have no configuration, no keys, and just
3312      *    want to try repeated (username,password) pairs until they
3313      *    type both correctly
3314      * 
3315      *  - people who have keys and configuration but occasionally
3316      *    need to fall back to passwords
3317      * 
3318      *  - people with a key held in Pageant, who might not have
3319      *    logged in to a particular machine before; so they want to
3320      *    type a username, and then _either_ their key will be
3321      *    accepted, _or_ they will type a password. If they mistype
3322      *    the username they will want to be able to get back and
3323      *    retype it!
3324      */
3325     do {
3326         static int pos;
3327         static char c;
3328
3329         /*
3330          * Get a username.
3331          */
3332         pos = 0;
3333         if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
3334             if (ssh_get_line) {
3335                 if (!ssh_get_line("login as: ",
3336                                   username, sizeof(username), FALSE)) {
3337                     /*
3338                      * get_line failed to get a username.
3339                      * Terminate.
3340                      */
3341                     logevent("No username provided. Abandoning session.");
3342                     ssh_state = SSH_STATE_CLOSED;
3343                     crReturnV;
3344                 }
3345             } else {
3346                 c_write_str("login as: ");
3347                 ssh_send_ok = 1;
3348                 while (pos >= 0) {
3349                     crWaitUntilV(!ispkt);
3350                     while (inlen--)
3351                         switch (c = *in++) {
3352                           case 10:
3353                           case 13:
3354                             username[pos] = 0;
3355                             pos = -1;
3356                             break;
3357                           case 8:
3358                           case 127:
3359                             if (pos > 0) {
3360                                 c_write_str("\b \b");
3361                                 pos--;
3362                             }
3363                             break;
3364                           case 21:
3365                           case 27:
3366                             while (pos > 0) {
3367                                 c_write_str("\b \b");
3368                                 pos--;
3369                             }
3370                             break;
3371                           case 3:
3372                           case 4:
3373                             random_save_seed();
3374                             exit(0);
3375                             break;
3376                           default:
3377                             if (((c >= ' ' && c <= '~') ||
3378                                  ((unsigned char) c >= 160))
3379                                 && pos < sizeof(username)-1) {
3380                                 username[pos++] = c;
3381                                 c_write(&c, 1);
3382                             }
3383                             break;
3384                         }
3385                 }
3386             }
3387             c_write_str("\r\n");
3388             username[strcspn(username, "\n\r")] = '\0';
3389         } else {
3390             char stuff[200];
3391             strncpy(username, cfg.username, 99);
3392             username[99] = '\0';
3393             if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
3394                 sprintf(stuff, "Using username \"%s\".\r\n", username);
3395                 c_write_str(stuff);
3396             }
3397         }
3398
3399         /*
3400          * Send an authentication request using method "none": (a)
3401          * just in case it succeeds, and (b) so that we know what
3402          * authentication methods we can usefully try next.
3403          */
3404         ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
3405         ssh2_pkt_addstring(username);
3406         ssh2_pkt_addstring("ssh-connection");   /* service requested */
3407         ssh2_pkt_addstring("none");    /* method */
3408         ssh2_pkt_send();
3409         type = AUTH_TYPE_NONE;
3410         gotit = FALSE;
3411         we_are_in = FALSE;
3412
3413         tried_pubkey_config = FALSE;
3414         tried_agent = FALSE;
3415
3416         while (1) {
3417             /*
3418              * Wait for the result of the last authentication request.
3419              */
3420             if (!gotit)
3421                 crWaitUntilV(ispkt);
3422             while (pktin.type == SSH2_MSG_USERAUTH_BANNER) {
3423                 char *banner;
3424                 int size;
3425                 /*
3426                  * Don't show the banner if we're operating in
3427                  * non-verbose non-interactive mode. (It's probably
3428                  * a script, which means nobody will read the
3429                  * banner _anyway_, and moreover the printing of
3430                  * the banner will screw up processing on the
3431                  * output of (say) plink.)
3432                  */
3433                 if (flags & (FLAG_VERBOSE | FLAG_INTERACTIVE)) {
3434                     ssh2_pkt_getstring(&banner, &size);
3435                     if (banner)
3436                         c_write_untrusted(banner, size);
3437                 }
3438                 crWaitUntilV(ispkt);
3439             }
3440             if (pktin.type == SSH2_MSG_USERAUTH_SUCCESS) {
3441                 logevent("Access granted");
3442                 we_are_in = TRUE;
3443                 break;
3444             }
3445
3446             if (pktin.type != SSH2_MSG_USERAUTH_FAILURE) {
3447                 bombout(
3448                         ("Strange packet received during authentication: type %d",
3449                          pktin.type));
3450                 crReturnV;
3451             }
3452
3453             gotit = FALSE;
3454
3455             /*
3456              * OK, we're now sitting on a USERAUTH_FAILURE message, so
3457              * we can look at the string in it and know what we can
3458              * helpfully try next.
3459              */
3460             {
3461                 char *methods;
3462                 int methlen;
3463                 ssh2_pkt_getstring(&methods, &methlen);
3464                 if (!ssh2_pkt_getbool()) {
3465                     /*
3466                      * We have received an unequivocal Access
3467                      * Denied. This can translate to a variety of
3468                      * messages:
3469                      * 
3470                      *  - if we'd just tried "none" authentication,
3471                      *    it's not worth printing anything at all
3472                      * 
3473                      *  - if we'd just tried a public key _offer_,
3474                      *    the message should be "Server refused our
3475                      *    key" (or no message at all if the key
3476                      *    came from Pageant)
3477                      * 
3478                      *  - if we'd just tried anything else, the
3479                      *    message really should be "Access denied".
3480                      * 
3481                      * Additionally, if we'd just tried password
3482                      * authentication, we should break out of this
3483                      * whole loop so as to go back to the username
3484                      * prompt.
3485                      */
3486                     if (type == AUTH_TYPE_NONE) {
3487                         /* do nothing */
3488                     } else if (type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
3489                                type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
3490                         if (type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
3491                             c_write_str("Server refused our key\r\n");
3492                         logevent("Server refused public key");
3493                     } else {
3494                         c_write_str("Access denied\r\n");
3495                         logevent("Access denied");
3496                         if (type == AUTH_TYPE_PASSWORD) {
3497                             we_are_in = FALSE;
3498                             break;
3499                         }
3500                     }
3501                 } else {
3502                     c_write_str("Further authentication required\r\n");
3503                     logevent("Further authentication required");
3504                 }
3505
3506                 can_pubkey =
3507                     in_commasep_string("publickey", methods, methlen);
3508                 can_passwd =
3509                     in_commasep_string("password", methods, methlen);
3510             }
3511
3512             method = 0;
3513
3514             if (!method && can_pubkey && agent_exists() && !tried_agent) {
3515                 /*
3516                  * Attempt public-key authentication using Pageant.
3517                  */
3518                 static unsigned char request[5], *response, *p;
3519                 static int responselen;
3520                 static int i, nkeys;
3521                 static int authed = FALSE;
3522                 void *r;
3523
3524                 tried_agent = TRUE;
3525
3526                 logevent("Pageant is running. Requesting keys.");
3527
3528                 /* Request the keys held by the agent. */
3529                 PUT_32BIT(request, 1);
3530                 request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
3531                 agent_query(request, 5, &r, &responselen);
3532                 response = (unsigned char *) r;
3533                 if (response && responselen >= 5 &&
3534                     response[4] == SSH2_AGENT_IDENTITIES_ANSWER) {
3535                     p = response + 5;
3536                     nkeys = GET_32BIT(p);
3537                     p += 4;
3538                     {
3539                         char buf[64];
3540                         sprintf(buf, "Pageant has %d SSH2 keys", nkeys);
3541                         logevent(buf);
3542                     }
3543                     for (i = 0; i < nkeys; i++) {
3544                         static char *pkblob, *alg, *commentp;
3545                         static int pklen, alglen, commentlen;
3546                         static int siglen, retlen, len;
3547                         static char *q, *agentreq, *ret;
3548                         void *vret;
3549
3550                         {
3551                             char buf[64];
3552                             sprintf(buf, "Trying Pageant key #%d", i);
3553                             logevent(buf);
3554                         }
3555                         pklen = GET_32BIT(p);
3556                         p += 4;
3557                         pkblob = p;
3558                         p += pklen;
3559                         alglen = GET_32BIT(pkblob);
3560                         alg = pkblob + 4;
3561                         commentlen = GET_32BIT(p);
3562                         p += 4;
3563                         commentp = p;
3564                         p += commentlen;
3565                         ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
3566                         ssh2_pkt_addstring(username);
3567                         ssh2_pkt_addstring("ssh-connection");   /* service requested */
3568                         ssh2_pkt_addstring("publickey");        /* method */
3569                         ssh2_pkt_addbool(FALSE);        /* no signature included */
3570                         ssh2_pkt_addstring_start();
3571                         ssh2_pkt_addstring_data(alg, alglen);
3572                         ssh2_pkt_addstring_start();
3573                         ssh2_pkt_addstring_data(pkblob, pklen);
3574                         ssh2_pkt_send();
3575
3576                         crWaitUntilV(ispkt);
3577                         if (pktin.type != SSH2_MSG_USERAUTH_PK_OK) {
3578                             logevent("Key refused");
3579                             continue;
3580                         }
3581
3582                         if (flags & FLAG_VERBOSE) {
3583                             c_write_str
3584                                 ("Authenticating with public key \"");
3585                             c_write(commentp, commentlen);
3586                             c_write_str("\" from agent\r\n");
3587                         }
3588
3589                         /*
3590                          * Server is willing to accept the key.
3591                          * Construct a SIGN_REQUEST.
3592                          */
3593                         ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
3594                         ssh2_pkt_addstring(username);
3595                         ssh2_pkt_addstring("ssh-connection");   /* service requested */
3596                         ssh2_pkt_addstring("publickey");        /* method */
3597                         ssh2_pkt_addbool(TRUE);
3598                         ssh2_pkt_addstring_start();
3599                         ssh2_pkt_addstring_data(alg, alglen);
3600                         ssh2_pkt_addstring_start();
3601                         ssh2_pkt_addstring_data(pkblob, pklen);
3602
3603                         siglen = pktout.length - 5 + 4 + 20;
3604                         len = 1;       /* message type */
3605                         len += 4 + pklen;       /* key blob */
3606                         len += 4 + siglen;      /* data to sign */
3607                         len += 4;      /* flags */
3608                         agentreq = smalloc(4 + len);
3609                         PUT_32BIT(agentreq, len);
3610                         q = agentreq + 4;
3611                         *q++ = SSH2_AGENTC_SIGN_REQUEST;
3612                         PUT_32BIT(q, pklen);
3613                         q += 4;
3614                         memcpy(q, pkblob, pklen);
3615                         q += pklen;
3616                         PUT_32BIT(q, siglen);
3617                         q += 4;
3618                         /* Now the data to be signed... */
3619                         PUT_32BIT(q, 20);
3620                         q += 4;
3621                         memcpy(q, ssh2_session_id, 20);
3622                         q += 20;
3623                         memcpy(q, pktout.data + 5, pktout.length - 5);
3624                         q += pktout.length - 5;
3625                         /* And finally the (zero) flags word. */
3626                         PUT_32BIT(q, 0);
3627                         agent_query(agentreq, len + 4, &vret, &retlen);
3628                         ret = vret;
3629                         sfree(agentreq);
3630                         if (ret) {
3631                             if (ret[4] == SSH2_AGENT_SIGN_RESPONSE) {
3632                                 logevent("Sending Pageant's response");
3633                                 ssh2_pkt_addstring_start();
3634                                 ssh2_pkt_addstring_data(ret + 9,
3635                                                         GET_32BIT(ret +
3636                                                                   5));
3637                                 ssh2_pkt_send();
3638                                 authed = TRUE;
3639                                 break;
3640                             } else {
3641                                 logevent
3642                                     ("Pageant failed to answer challenge");
3643                                 sfree(ret);
3644                             }
3645                         }
3646                     }
3647                     if (authed)
3648                         continue;
3649                 }
3650             }
3651
3652             if (!method && can_pubkey && *cfg.keyfile
3653                 && !tried_pubkey_config) {
3654                 unsigned char *pub_blob;
3655                 char *algorithm, *comment;
3656                 int pub_blob_len;
3657
3658                 tried_pubkey_config = TRUE;
3659
3660                 /*
3661                  * Try the public key supplied in the configuration.
3662                  *
3663                  * First, offer the public blob to see if the server is
3664                  * willing to accept it.
3665                  */
3666                 pub_blob = ssh2_userkey_loadpub(cfg.keyfile, &algorithm,
3667                                                 &pub_blob_len);
3668                 if (pub_blob) {
3669                     ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
3670                     ssh2_pkt_addstring(username);
3671                     ssh2_pkt_addstring("ssh-connection");       /* service requested */
3672                     ssh2_pkt_addstring("publickey");    /* method */
3673                     ssh2_pkt_addbool(FALSE);    /* no signature included */
3674                     ssh2_pkt_addstring(algorithm);
3675                     ssh2_pkt_addstring_start();
3676                     ssh2_pkt_addstring_data(pub_blob, pub_blob_len);
3677                     ssh2_pkt_send();
3678                     logevent("Offered public key");     /* FIXME */
3679
3680                     crWaitUntilV(ispkt);
3681                     if (pktin.type != SSH2_MSG_USERAUTH_PK_OK) {
3682                         gotit = TRUE;
3683                         type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
3684                         continue;      /* key refused; give up on it */
3685                     }
3686
3687                     logevent("Offer of public key accepted");
3688                     /*
3689                      * Actually attempt a serious authentication using
3690                      * the key.
3691                      */
3692                     if (ssh2_userkey_encrypted(cfg.keyfile, &comment)) {
3693                         sprintf(pwprompt,
3694                                 "Passphrase for key \"%.100s\": ",
3695                                 comment);
3696                         need_pw = TRUE;
3697                     } else {
3698                         need_pw = FALSE;
3699                     }
3700                     c_write_str("Authenticating with public key \"");
3701                     c_write_str(comment);
3702                     c_write_str("\"\r\n");
3703                     method = AUTH_PUBLICKEY_FILE;
3704                 }
3705             }
3706
3707             if (!method && can_passwd) {
3708                 method = AUTH_PASSWORD;
3709                 sprintf(pwprompt, "%.90s@%.90s's password: ", username,
3710                         savedhost);
3711                 need_pw = TRUE;
3712             }
3713
3714             if (need_pw) {
3715                 if (ssh_get_line) {
3716                     if (!ssh_get_line(pwprompt, password,
3717                                       sizeof(password), TRUE)) {
3718                         /*
3719                          * get_line failed to get a password (for
3720                          * example because one was supplied on the
3721                          * command line which has already failed to
3722                          * work). Terminate.
3723                          */
3724                         ssh2_pkt_init(SSH2_MSG_DISCONNECT);
3725                         ssh2_pkt_adduint32(SSH2_DISCONNECT_BY_APPLICATION);
3726                         ssh2_pkt_addstring
3727                             ("No more passwords available to try");
3728                         ssh2_pkt_addstring("en");       /* language tag */
3729                         ssh2_pkt_send();
3730                         connection_fatal("Unable to authenticate");
3731                         ssh_state = SSH_STATE_CLOSED;
3732                         crReturnV;
3733                     }
3734                 } else {
3735                     static int pos = 0;
3736                     static char c;
3737
3738                     c_write_str(pwprompt);
3739                     ssh_send_ok = 1;
3740
3741                     pos = 0;
3742                     while (pos >= 0) {
3743                         crWaitUntilV(!ispkt);
3744                         while (inlen--)
3745                             switch (c = *in++) {
3746                               case 10:
3747                               case 13:
3748                                 password[pos] = 0;
3749                                 pos = -1;
3750                                 break;
3751                               case 8:
3752                               case 127:
3753                                 if (pos > 0)
3754                                     pos--;
3755                                 break;
3756                               case 21:
3757                               case 27:
3758                                 pos = 0;
3759                                 break;
3760                               case 3:
3761                               case 4:
3762                                 random_save_seed();
3763                                 exit(0);
3764                                 break;
3765                               default:
3766                                 if (pos < sizeof(password)-1)
3767                                     password[pos++] = c;
3768                                 break;
3769                             }
3770                     }
3771                     c_write_str("\r\n");
3772                 }
3773             }
3774
3775             if (method == AUTH_PUBLICKEY_FILE) {
3776                 /*
3777                  * We have our passphrase. Now try the actual authentication.
3778                  */
3779                 struct ssh2_userkey *key;
3780
3781                 key = ssh2_load_userkey(cfg.keyfile, password);
3782                 if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
3783                     if (key == SSH2_WRONG_PASSPHRASE) {
3784                         c_write_str("Wrong passphrase\r\n");
3785                         tried_pubkey_config = FALSE;
3786                     } else {
3787                         c_write_str("Unable to load private key\r\n");
3788                         tried_pubkey_config = TRUE;
3789                     }
3790                     /* Send a spurious AUTH_NONE to return to the top. */
3791                     ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
3792                     ssh2_pkt_addstring(username);
3793                     ssh2_pkt_addstring("ssh-connection");       /* service requested */
3794                     ssh2_pkt_addstring("none"); /* method */
3795                     ssh2_pkt_send();
3796                     type = AUTH_TYPE_NONE;
3797                 } else {
3798                     unsigned char *blob, *sigdata;
3799                     int blob_len, sigdata_len;
3800
3801                     /*
3802                      * We have loaded the private key and the server
3803                      * has announced that it's willing to accept it.
3804                      * Hallelujah. Generate a signature and send it.
3805                      */
3806                     ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
3807                     ssh2_pkt_addstring(username);
3808                     ssh2_pkt_addstring("ssh-connection");       /* service requested */
3809                     ssh2_pkt_addstring("publickey");    /* method */
3810                     ssh2_pkt_addbool(TRUE);
3811                     ssh2_pkt_addstring(key->alg->name);
3812                     blob = key->alg->public_blob(key->data, &blob_len);
3813                     ssh2_pkt_addstring_start();
3814                     ssh2_pkt_addstring_data(blob, blob_len);
3815                     sfree(blob);
3816
3817                     /*
3818                      * The data to be signed is:
3819                      *
3820                      *   string  session-id
3821                      *
3822                      * followed by everything so far placed in the
3823                      * outgoing packet.
3824                      */
3825                     sigdata_len = pktout.length - 5 + 4 + 20;
3826                     sigdata = smalloc(sigdata_len);
3827                     PUT_32BIT(sigdata, 20);
3828                     memcpy(sigdata + 4, ssh2_session_id, 20);
3829                     memcpy(sigdata + 24, pktout.data + 5,
3830                            pktout.length - 5);
3831                     blob =
3832                         key->alg->sign(key->data, sigdata, sigdata_len,
3833                                        &blob_len);
3834                     ssh2_pkt_addstring_start();
3835                     ssh2_pkt_addstring_data(blob, blob_len);
3836                     sfree(blob);
3837                     sfree(sigdata);
3838
3839                     ssh2_pkt_send();
3840                     type = AUTH_TYPE_PUBLICKEY;
3841                 }
3842             } else if (method == AUTH_PASSWORD) {
3843                 /*
3844                  * We send the password packet lumped tightly together with
3845                  * an SSH_MSG_IGNORE packet. The IGNORE packet contains a
3846                  * string long enough to make the total length of the two
3847                  * packets constant. This should ensure that a passive
3848                  * listener doing traffic analyis can't work out the length
3849                  * of the password.
3850                  *
3851                  * For this to work, we need an assumption about the
3852                  * maximum length of the password packet. I think 256 is
3853                  * pretty conservative. Anyone using a password longer than
3854                  * that probably doesn't have much to worry about from
3855                  * people who find out how long their password is!
3856                  */
3857                 ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
3858                 ssh2_pkt_addstring(username);
3859                 ssh2_pkt_addstring("ssh-connection");   /* service requested */
3860                 ssh2_pkt_addstring("password");
3861                 ssh2_pkt_addbool(FALSE);
3862                 ssh2_pkt_addstring(password);
3863                 ssh2_pkt_defer();
3864                 /*
3865                  * We'll include a string that's an exact multiple of the
3866                  * cipher block size. If the cipher is NULL for some
3867                  * reason, we don't do this trick at all because we gain
3868                  * nothing by it.
3869                  */
3870                 if (cscipher) {
3871                     int stringlen, i;
3872
3873                     stringlen = (256 - deferred_len);
3874                     stringlen += cscipher->blksize - 1;
3875                     stringlen -= (stringlen % cscipher->blksize);
3876                     if (cscomp) {
3877                         /*
3878                          * Temporarily disable actual compression,
3879                          * so we can guarantee to get this string
3880                          * exactly the length we want it. The
3881                          * compression-disabling routine should
3882                          * return an integer indicating how many
3883                          * bytes we should adjust our string length
3884                          * by.
3885                          */
3886                         stringlen -= cscomp->disable_compression();
3887                     }
3888                     ssh2_pkt_init(SSH2_MSG_IGNORE);
3889                     ssh2_pkt_addstring_start();
3890                     for (i = 0; i < stringlen; i++) {
3891                         char c = (char) random_byte();
3892                         ssh2_pkt_addstring_data(&c, 1);
3893                     }
3894                     ssh2_pkt_defer();
3895                 }
3896                 ssh_pkt_defersend();
3897                 logevent("Sent password");
3898                 type = AUTH_TYPE_PASSWORD;
3899             } else {
3900                 c_write_str
3901                     ("No supported authentication methods left to try!\r\n");
3902                 logevent
3903                     ("No supported authentications offered. Disconnecting");
3904                 ssh2_pkt_init(SSH2_MSG_DISCONNECT);
3905                 ssh2_pkt_adduint32(SSH2_DISCONNECT_BY_APPLICATION);
3906                 ssh2_pkt_addstring
3907                     ("No supported authentication methods available");
3908                 ssh2_pkt_addstring("en");       /* language tag */
3909                 ssh2_pkt_send();
3910                 ssh_state = SSH_STATE_CLOSED;
3911                 crReturnV;
3912             }
3913         }
3914     } while (!we_are_in);
3915
3916     /*
3917      * Now we're authenticated for the connection protocol. The
3918      * connection protocol will automatically have started at this
3919      * point; there's no need to send SERVICE_REQUEST.
3920      */
3921
3922     /*
3923      * So now create a channel with a session in it.
3924      */
3925     ssh_channels = newtree234(ssh_channelcmp);
3926     mainchan = smalloc(sizeof(struct ssh_channel));
3927     mainchan->localid = alloc_channel_id();
3928     ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
3929     ssh2_pkt_addstring("session");
3930     ssh2_pkt_adduint32(mainchan->localid);
3931     ssh2_pkt_adduint32(0x8000UL);      /* our window size */
3932     ssh2_pkt_adduint32(0x4000UL);      /* our max pkt size */
3933     ssh2_pkt_send();
3934     crWaitUntilV(ispkt);
3935     if (pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
3936         bombout(("Server refused to open a session"));
3937         crReturnV;
3938         /* FIXME: error data comes back in FAILURE packet */
3939     }
3940     if (ssh2_pkt_getuint32() != mainchan->localid) {
3941         bombout(("Server's channel confirmation cited wrong channel"));
3942         crReturnV;
3943     }
3944     mainchan->remoteid = ssh2_pkt_getuint32();
3945     mainchan->type = CHAN_MAINSESSION;
3946     mainchan->closes = 0;
3947     mainchan->v2.remwindow = ssh2_pkt_getuint32();
3948     mainchan->v2.remmaxpkt = ssh2_pkt_getuint32();
3949     mainchan->v2.outbuffer = NULL;
3950     mainchan->v2.outbuflen = mainchan->v2.outbufsize = 0;
3951     add234(ssh_channels, mainchan);
3952     logevent("Opened channel for session");
3953
3954     /*
3955      * Potentially enable X11 forwarding.
3956      */
3957     if (cfg.x11_forward) {
3958         char proto[20], data[64];
3959         logevent("Requesting X11 forwarding");
3960         x11_invent_auth(proto, sizeof(proto), data, sizeof(data));
3961         ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
3962         ssh2_pkt_adduint32(mainchan->remoteid);
3963         ssh2_pkt_addstring("x11-req");
3964         ssh2_pkt_addbool(1);           /* want reply */
3965         ssh2_pkt_addbool(0);           /* many connections */
3966         ssh2_pkt_addstring(proto);
3967         ssh2_pkt_addstring(data);
3968         ssh2_pkt_adduint32(0);         /* screen number */
3969         ssh2_pkt_send();
3970
3971         do {
3972             crWaitUntilV(ispkt);
3973             if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
3974                 unsigned i = ssh2_pkt_getuint32();
3975                 struct ssh_channel *c;
3976                 c = find234(ssh_channels, &i, ssh_channelfind);
3977                 if (!c)
3978                     continue;          /* nonexistent channel */
3979                 c->v2.remwindow += ssh2_pkt_getuint32();
3980             }
3981         } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
3982
3983         if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
3984             if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
3985                 bombout(("Server got confused by X11 forwarding request"));
3986                 crReturnV;
3987             }
3988             logevent("X11 forwarding refused");
3989         } else {
3990             logevent("X11 forwarding enabled");
3991             ssh_X11_fwd_enabled = TRUE;
3992         }
3993     }
3994
3995     /*
3996      * Potentially enable agent forwarding.
3997      */
3998     if (cfg.agentfwd && agent_exists()) {
3999         logevent("Requesting OpenSSH-style agent forwarding");
4000         ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
4001         ssh2_pkt_adduint32(mainchan->remoteid);
4002         ssh2_pkt_addstring("auth-agent-req@openssh.com");
4003         ssh2_pkt_addbool(1);           /* want reply */
4004         ssh2_pkt_send();
4005
4006         do {
4007             crWaitUntilV(ispkt);
4008             if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
4009                 unsigned i = ssh2_pkt_getuint32();
4010                 struct ssh_channel *c;
4011                 c = find234(ssh_channels, &i, ssh_channelfind);
4012                 if (!c)
4013                     continue;          /* nonexistent channel */
4014                 c->v2.remwindow += ssh2_pkt_getuint32();
4015             }
4016         } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
4017
4018         if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
4019             if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
4020                 bombout(
4021                         ("Server got confused by agent forwarding request"));
4022                 crReturnV;
4023             }
4024             logevent("Agent forwarding refused");
4025         } else {
4026             logevent("Agent forwarding enabled");
4027             ssh_agentfwd_enabled = TRUE;
4028         }
4029     }
4030
4031     /*
4032      * Now allocate a pty for the session.
4033      */
4034     if (!cfg.nopty) {
4035         ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
4036         ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */
4037         ssh2_pkt_addstring("pty-req");
4038         ssh2_pkt_addbool(1);           /* want reply */
4039         ssh2_pkt_addstring(cfg.termtype);
4040         ssh2_pkt_adduint32(cols);
4041         ssh2_pkt_adduint32(rows);
4042         ssh2_pkt_adduint32(0);         /* pixel width */
4043         ssh2_pkt_adduint32(0);         /* pixel height */
4044         ssh2_pkt_addstring_start();
4045         ssh2_pkt_addstring_data("\0", 1);       /* TTY_OP_END, no special options */
4046         ssh2_pkt_send();
4047         ssh_state = SSH_STATE_INTERMED;
4048
4049         do {
4050             crWaitUntilV(ispkt);
4051             if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
4052                 unsigned i = ssh2_pkt_getuint32();
4053                 struct ssh_channel *c;
4054                 c = find234(ssh_channels, &i, ssh_channelfind);
4055                 if (!c)
4056                     continue;          /* nonexistent channel */
4057                 c->v2.remwindow += ssh2_pkt_getuint32();
4058             }
4059         } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
4060
4061         if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
4062             if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
4063                 bombout(("Server got confused by pty request"));
4064                 crReturnV;
4065             }
4066             c_write_str("Server refused to allocate pty\r\n");
4067             ssh_editing = ssh_echoing = 1;
4068         } else {
4069             logevent("Allocated pty");
4070         }
4071     } else {
4072         ssh_editing = ssh_echoing = 1;
4073     }
4074
4075     /*
4076      * Start a shell or a remote command.
4077      */
4078     ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
4079     ssh2_pkt_adduint32(mainchan->remoteid);     /* recipient channel */
4080     if (cfg.ssh_subsys) {
4081         ssh2_pkt_addstring("subsystem");
4082         ssh2_pkt_addbool(1);           /* want reply */
4083         ssh2_pkt_addstring(cfg.remote_cmd_ptr);
4084     } else if (*cfg.remote_cmd_ptr) {
4085         ssh2_pkt_addstring("exec");
4086         ssh2_pkt_addbool(1);           /* want reply */
4087         ssh2_pkt_addstring(cfg.remote_cmd_ptr);
4088     } else {
4089         ssh2_pkt_addstring("shell");
4090         ssh2_pkt_addbool(1);           /* want reply */
4091     }
4092     ssh2_pkt_send();
4093     do {
4094         crWaitUntilV(ispkt);
4095         if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
4096             unsigned i = ssh2_pkt_getuint32();
4097             struct ssh_channel *c;
4098             c = find234(ssh_channels, &i, ssh_channelfind);
4099             if (!c)
4100                 continue;              /* nonexistent channel */
4101             c->v2.remwindow += ssh2_pkt_getuint32();
4102         }
4103     } while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
4104     if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
4105         if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
4106             bombout(("Server got confused by shell/command request"));
4107             crReturnV;
4108         }
4109         bombout(("Server refused to start a shell/command"));
4110         crReturnV;
4111     } else {
4112         logevent("Started a shell/command");
4113     }
4114
4115     ssh_state = SSH_STATE_SESSION;
4116     if (size_needed)
4117         ssh_size();
4118     if (eof_needed)
4119         ssh_special(TS_EOF);
4120
4121     /*
4122      * Transfer data!
4123      */
4124     ldisc_send(NULL, 0);               /* cause ldisc to notice changes */
4125     ssh_send_ok = 1;
4126     while (1) {
4127         static int try_send;
4128         crReturnV;
4129         try_send = FALSE;
4130         if (ispkt) {
4131             if (pktin.type == SSH2_MSG_CHANNEL_DATA ||
4132                 pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
4133                 char *data;
4134                 int length;
4135                 unsigned i = ssh2_pkt_getuint32();
4136                 struct ssh_channel *c;
4137                 c = find234(ssh_channels, &i, ssh_channelfind);
4138                 if (!c)
4139                     continue;          /* nonexistent channel */
4140                 if (pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
4141                     ssh2_pkt_getuint32() != SSH2_EXTENDED_DATA_STDERR)
4142                     continue;          /* extended but not stderr */
4143                 ssh2_pkt_getstring(&data, &length);
4144                 if (data) {
4145                     switch (c->type) {
4146                       case CHAN_MAINSESSION:
4147                         from_backend(pktin.type ==
4148                                      SSH2_MSG_CHANNEL_EXTENDED_DATA, data,
4149                                      length);
4150                         break;
4151                       case CHAN_X11:
4152                         x11_send(c->u.x11.s, data, length);
4153                         break;
4154                       case CHAN_SOCKDATA:
4155                               pfd_send(c->u.pfd.s, data, length);
4156                               break;
4157                       case CHAN_AGENT:
4158                         while (length > 0) {
4159                             if (c->u.a.lensofar < 4) {
4160                                 int l = min(4 - c->u.a.lensofar, length);
4161                                 memcpy(c->u.a.msglen + c->u.a.lensofar,
4162                                        data, l);
4163                                 data += l;
4164                                 length -= l;
4165                                 c->u.a.lensofar += l;
4166                             }
4167                             if (c->u.a.lensofar == 4) {
4168                                 c->u.a.totallen =
4169                                     4 + GET_32BIT(c->u.a.msglen);
4170                                 c->u.a.message = smalloc(c->u.a.totallen);
4171                                 memcpy(c->u.a.message, c->u.a.msglen, 4);
4172                             }
4173                             if (c->u.a.lensofar >= 4 && length > 0) {
4174                                 int l =
4175                                     min(c->u.a.totallen - c->u.a.lensofar,
4176                                         length);
4177                                 memcpy(c->u.a.message + c->u.a.lensofar,
4178                                        data, l);
4179                                 data += l;
4180                                 length -= l;
4181                                 c->u.a.lensofar += l;
4182                             }
4183                             if (c->u.a.lensofar == c->u.a.totallen) {
4184                                 void *reply, *sentreply;
4185                                 int replylen;
4186                                 agent_query(c->u.a.message,
4187                                             c->u.a.totallen, &reply,
4188                                             &replylen);
4189                                 if (reply)
4190                                     sentreply = reply;
4191                                 else {
4192                                     /* Fake SSH_AGENT_FAILURE. */
4193                                     sentreply = "\0\0\0\1\5";
4194                                     replylen = 5;
4195                                 }
4196                                 ssh2_add_channel_data(c, sentreply,
4197                                                       replylen);
4198                                 try_send = TRUE;
4199                                 if (reply)
4200                                     sfree(reply);
4201                                 sfree(c->u.a.message);
4202                                 c->u.a.lensofar = 0;
4203                             }
4204                         }
4205                         break;
4206                     }
4207                     /*
4208                      * Enlarge the window again at the remote
4209                      * side, just in case it ever runs down and
4210                      * they fail to send us any more data.
4211                      */
4212                     ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
4213                     ssh2_pkt_adduint32(c->remoteid);
4214                     ssh2_pkt_adduint32(length);
4215                     ssh2_pkt_send();
4216                 }
4217             } else if (pktin.type == SSH2_MSG_DISCONNECT) {
4218                 ssh_state = SSH_STATE_CLOSED;
4219                 logevent("Received disconnect message");
4220                 crReturnV;
4221             } else if (pktin.type == SSH2_MSG_CHANNEL_REQUEST) {
4222                 continue;              /* exit status et al; ignore (FIXME?) */
4223             } else if (pktin.type == SSH2_MSG_CHANNEL_EOF) {
4224                 unsigned i = ssh2_pkt_getuint32();
4225                 struct ssh_channel *c;
4226
4227                 c = find234(ssh_channels, &i, ssh_channelfind);
4228                 if (!c)
4229                     continue;          /* nonexistent channel */
4230
4231                 if (c->type == CHAN_X11) {
4232                     /*
4233                      * Remote EOF on an X11 channel means we should
4234                      * wrap up and close the channel ourselves.
4235                      */
4236                     x11_close(c->u.x11.s);
4237                     sshfwd_close(c);
4238                 } else if (c->type == CHAN_AGENT) {
4239                     sshfwd_close(c);
4240                 } else if (c->type == CHAN_SOCKDATA) {
4241                         pfd_close(c->u.pfd.s);
4242                         sshfwd_close(c);
4243                 }
4244             } else if (pktin.type == SSH2_MSG_CHANNEL_CLOSE) {
4245                 unsigned i = ssh2_pkt_getuint32();
4246                 struct ssh_channel *c;
4247
4248                 c = find234(ssh_channels, &i, ssh_channelfind);
4249                 if (!c)
4250                     continue;          /* nonexistent channel */
4251                 if (c->closes == 0) {
4252                     ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
4253                     ssh2_pkt_adduint32(c->remoteid);
4254                     ssh2_pkt_send();
4255                 }
4256                 /* Do pre-close processing on the channel. */
4257                 switch (c->type) {
4258                   case CHAN_MAINSESSION:
4259                     break;             /* nothing to see here, move along */
4260                   case CHAN_X11:
4261                     break;
4262                   case CHAN_AGENT:
4263                     break;
4264                   case CHAN_SOCKDATA:
4265                           break;
4266                 }
4267                 del234(ssh_channels, c);
4268                 sfree(c->v2.outbuffer);
4269                 sfree(c);
4270
4271                 /*
4272                  * See if that was the last channel left open.
4273                  */
4274                 if (count234(ssh_channels) == 0) {
4275                     logevent("All channels closed. Disconnecting");
4276                     ssh2_pkt_init(SSH2_MSG_DISCONNECT);
4277                     ssh2_pkt_adduint32(SSH2_DISCONNECT_BY_APPLICATION);
4278                     ssh2_pkt_addstring("All open channels closed");
4279                     ssh2_pkt_addstring("en");   /* language tag */
4280                     ssh2_pkt_send();
4281                     ssh_state = SSH_STATE_CLOSED;
4282                     crReturnV;
4283                 }
4284                 continue;              /* remote sends close; ignore (FIXME) */
4285             } else if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
4286                 unsigned i = ssh2_pkt_getuint32();
4287                 struct ssh_channel *c;
4288                 c = find234(ssh_channels, &i, ssh_channelfind);
4289                 if (!c)
4290                     continue;          /* nonexistent channel */
4291                 c->v2.remwindow += ssh2_pkt_getuint32();
4292                 try_send = TRUE;
4293             } else if (pktin.type == SSH2_MSG_CHANNEL_OPEN) {
4294                 char *type;
4295                 int typelen;
4296                 char *error = NULL;
4297                 struct ssh_channel *c;
4298                 ssh2_pkt_getstring(&type, &typelen);
4299                 c = smalloc(sizeof(struct ssh_channel));
4300
4301                 if (typelen == 3 && !memcmp(type, "x11", 3)) {
4302                     if (!ssh_X11_fwd_enabled)
4303                         error = "X11 forwarding is not enabled";
4304                     else if (x11_init(&c->u.x11.s, cfg.x11_display, c) !=
4305                              NULL) {
4306                         error = "Unable to open an X11 connection";
4307                     } else {
4308                         c->type = CHAN_X11;
4309                     }
4310                 } else if (typelen == 22 &&
4311                            !memcmp(type, "auth-agent@openssh.com", 3)) {
4312                     if (!ssh_agentfwd_enabled)
4313                         error = "Agent forwarding is not enabled";
4314                     else {
4315                         c->type = CHAN_AGENT;   /* identify channel type */
4316                         c->u.a.lensofar = 0;
4317                     }
4318                 } else {
4319                     error = "Unsupported channel type requested";
4320                 }
4321
4322                 c->remoteid = ssh2_pkt_getuint32();
4323                 if (error) {
4324                     ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_FAILURE);
4325                     ssh2_pkt_adduint32(c->remoteid);
4326                     ssh2_pkt_adduint32(SSH2_OPEN_CONNECT_FAILED);
4327                     ssh2_pkt_addstring(error);
4328                     ssh2_pkt_addstring("en");   /* language tag */
4329                     ssh2_pkt_send();
4330                     sfree(c);
4331                 } else {
4332                     c->localid = alloc_channel_id();
4333                     c->closes = 0;
4334                     c->v2.remwindow = ssh2_pkt_getuint32();
4335                     c->v2.remmaxpkt = ssh2_pkt_getuint32();
4336                     c->v2.outbuffer = NULL;
4337                     c->v2.outbuflen = c->v2.outbufsize = 0;
4338                     add234(ssh_channels, c);
4339                     ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
4340                     ssh2_pkt_adduint32(c->remoteid);
4341                     ssh2_pkt_adduint32(c->localid);
4342                     ssh2_pkt_adduint32(0x8000UL);       /* our window size */
4343                     ssh2_pkt_adduint32(0x4000UL);       /* our max pkt size */
4344                     ssh2_pkt_send();
4345                 }
4346             } else {
4347                 bombout(("Strange packet received: type %d", pktin.type));
4348                 crReturnV;
4349             }
4350         } else {
4351             /*
4352              * We have spare data. Add it to the channel buffer.
4353              */
4354             ssh2_add_channel_data(mainchan, in, inlen);
4355             try_send = TRUE;
4356         }
4357         if (try_send) {
4358             int i;
4359             struct ssh_channel *c;
4360             /*
4361              * Try to send data on all channels if we can.
4362              */
4363             for (i = 0; NULL != (c = index234(ssh_channels, i)); i++)
4364                 ssh2_try_send(c);
4365         }
4366     }
4367
4368     crFinishV;
4369 }
4370
4371 /*
4372  * Handle the top-level SSH2 protocol.
4373  */
4374 static void ssh2_protocol(unsigned char *in, int inlen, int ispkt)
4375 {
4376     if (do_ssh2_transport(in, inlen, ispkt) == 0)
4377         return;
4378     do_ssh2_authconn(in, inlen, ispkt);
4379 }
4380
4381 /*
4382  * Called to set up the connection.
4383  *
4384  * Returns an error message, or NULL on success.
4385  */
4386 static char *ssh_init(char *host, int port, char **realhost)
4387 {
4388     char *p;
4389
4390 #ifdef MSCRYPTOAPI
4391     if (crypto_startup() == 0)
4392         return "Microsoft high encryption pack not installed!";
4393 #endif
4394
4395     ssh_send_ok = 0;
4396     ssh_editing = 0;
4397     ssh_echoing = 0;
4398
4399     p = connect_to_host(host, port, realhost);
4400     if (p != NULL)
4401         return p;
4402
4403     return NULL;
4404 }
4405
4406 /*
4407  * Called to send data down the Telnet connection.
4408  */
4409 static void ssh_send(char *buf, int len)
4410 {
4411     if (s == NULL || ssh_protocol == NULL)
4412         return;
4413
4414     ssh_protocol(buf, len, 0);
4415 }
4416
4417 /*
4418  * Called to set the size of the window from SSH's POV.
4419  */
4420 static void ssh_size(void)
4421 {
4422     switch (ssh_state) {
4423       case SSH_STATE_BEFORE_SIZE:
4424       case SSH_STATE_PREPACKET:
4425       case SSH_STATE_CLOSED:
4426         break;                         /* do nothing */
4427       case SSH_STATE_INTERMED:
4428         size_needed = TRUE;            /* buffer for later */
4429         break;
4430       case SSH_STATE_SESSION:
4431         if (!cfg.nopty) {
4432             if (ssh_version == 1) {
4433                 send_packet(SSH1_CMSG_WINDOW_SIZE,
4434                             PKT_INT, rows, PKT_INT, cols,
4435                             PKT_INT, 0, PKT_INT, 0, PKT_END);
4436             } else {
4437                 ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
4438                 ssh2_pkt_adduint32(mainchan->remoteid);
4439                 ssh2_pkt_addstring("window-change");
4440                 ssh2_pkt_addbool(0);
4441                 ssh2_pkt_adduint32(cols);
4442                 ssh2_pkt_adduint32(rows);
4443                 ssh2_pkt_adduint32(0);
4444                 ssh2_pkt_adduint32(0);
4445                 ssh2_pkt_send();
4446             }
4447         }
4448         break;
4449     }
4450 }
4451
4452 /*
4453  * Send Telnet special codes. TS_EOF is useful for `plink', so you
4454  * can send an EOF and collect resulting output (e.g. `plink
4455  * hostname sort').
4456  */
4457 static void ssh_special(Telnet_Special code)
4458 {
4459     if (code == TS_EOF) {
4460         if (ssh_state != SSH_STATE_SESSION) {
4461             /*
4462              * Buffer the EOF in case we are pre-SESSION, so we can
4463              * send it as soon as we reach SESSION.
4464              */
4465             if (code == TS_EOF)
4466                 eof_needed = TRUE;
4467             return;
4468         }
4469         if (ssh_version == 1) {
4470             send_packet(SSH1_CMSG_EOF, PKT_END);
4471         } else {
4472             ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
4473             ssh2_pkt_adduint32(mainchan->remoteid);
4474             ssh2_pkt_send();
4475         }
4476         logevent("Sent EOF message");
4477     } else if (code == TS_PING) {
4478         if (ssh_state == SSH_STATE_CLOSED
4479             || ssh_state == SSH_STATE_PREPACKET) return;
4480         if (ssh_version == 1) {
4481             send_packet(SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
4482         } else {
4483             ssh2_pkt_init(SSH2_MSG_IGNORE);
4484             ssh2_pkt_addstring_start();
4485             ssh2_pkt_send();
4486         }
4487     } else {
4488         /* do nothing */
4489     }
4490 }
4491
4492 void *new_sock_channel(Socket s)
4493 {
4494     struct ssh_channel *c;
4495     c = smalloc(sizeof(struct ssh_channel));
4496
4497     if (c) {
4498         c->remoteid = GET_32BIT(pktin.body);
4499         c->localid = alloc_channel_id();
4500         c->closes = 0;
4501         c->type = CHAN_SOCKDATA;        /* identify channel type */
4502         c->u.pfd.s = s;
4503         add234(ssh_channels, c);
4504     }
4505     return c;
4506 }
4507
4508 void ssh_send_port_open(void *channel, char *hostname, int port, char *org)
4509 {
4510     struct ssh_channel *c = (struct ssh_channel *)channel;
4511     char buf[1024];
4512
4513     sprintf(buf, "Opening forwarded connection to %.512s:%d", hostname, port);
4514     logevent(buf);
4515
4516     send_packet(SSH1_MSG_PORT_OPEN,
4517                 PKT_INT, c->localid,
4518                 PKT_STR, hostname,
4519                 PKT_INT, port,
4520                 //PKT_STR, org,
4521                 PKT_END);
4522 }
4523
4524
4525 static Socket ssh_socket(void)
4526 {
4527     return s;
4528 }
4529
4530 static int ssh_sendok(void)
4531 {
4532     return ssh_send_ok;
4533 }
4534
4535 static int ssh_ldisc(int option)
4536 {
4537     if (option == LD_ECHO)
4538         return ssh_echoing;
4539     if (option == LD_EDIT)
4540         return ssh_editing;
4541     return FALSE;
4542 }
4543
4544 Backend ssh_backend = {
4545     ssh_init,
4546     ssh_send,
4547     ssh_size,
4548     ssh_special,
4549     ssh_socket,
4550     ssh_sendok,
4551     ssh_ldisc,
4552     22
4553 };