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