]> asedeno.scripts.mit.edu Git - PuTTY_svn.git/blob - ssh.c
5493191ec6279994fa0af619326abf1d736f69ed
[PuTTY_svn.git] / ssh.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <assert.h>
5
6 #include "putty.h"
7 #include "tree234.h"
8 #include "ssh.h"
9
10 #ifndef FALSE
11 #define FALSE 0
12 #endif
13 #ifndef TRUE
14 #define TRUE 1
15 #endif
16
17 #define SSH1_MSG_DISCONNECT                       1     /* 0x1 */
18 #define SSH1_SMSG_PUBLIC_KEY                      2     /* 0x2 */
19 #define SSH1_CMSG_SESSION_KEY                     3     /* 0x3 */
20 #define SSH1_CMSG_USER                            4     /* 0x4 */
21 #define SSH1_CMSG_AUTH_RSA                        6     /* 0x6 */
22 #define SSH1_SMSG_AUTH_RSA_CHALLENGE              7     /* 0x7 */
23 #define SSH1_CMSG_AUTH_RSA_RESPONSE               8     /* 0x8 */
24 #define SSH1_CMSG_AUTH_PASSWORD                   9     /* 0x9 */
25 #define SSH1_CMSG_REQUEST_PTY                     10    /* 0xa */
26 #define SSH1_CMSG_WINDOW_SIZE                     11    /* 0xb */
27 #define SSH1_CMSG_EXEC_SHELL                      12    /* 0xc */
28 #define SSH1_CMSG_EXEC_CMD                        13    /* 0xd */
29 #define SSH1_SMSG_SUCCESS                         14    /* 0xe */
30 #define SSH1_SMSG_FAILURE                         15    /* 0xf */
31 #define SSH1_CMSG_STDIN_DATA                      16    /* 0x10 */
32 #define SSH1_SMSG_STDOUT_DATA                     17    /* 0x11 */
33 #define SSH1_SMSG_STDERR_DATA                     18    /* 0x12 */
34 #define SSH1_CMSG_EOF                             19    /* 0x13 */
35 #define SSH1_SMSG_EXIT_STATUS                     20    /* 0x14 */
36 #define SSH1_MSG_CHANNEL_OPEN_CONFIRMATION        21    /* 0x15 */
37 #define SSH1_MSG_CHANNEL_OPEN_FAILURE             22    /* 0x16 */
38 #define SSH1_MSG_CHANNEL_DATA                     23    /* 0x17 */
39 #define SSH1_MSG_CHANNEL_CLOSE                    24    /* 0x18 */
40 #define SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION       25    /* 0x19 */
41 #define SSH1_SMSG_X11_OPEN                        27    /* 0x1b */
42 #define SSH1_CMSG_PORT_FORWARD_REQUEST            28    /* 0x1c */
43 #define SSH1_MSG_PORT_OPEN                        29    /* 0x1d */
44 #define SSH1_CMSG_AGENT_REQUEST_FORWARDING        30    /* 0x1e */
45 #define SSH1_SMSG_AGENT_OPEN                      31    /* 0x1f */
46 #define SSH1_MSG_IGNORE                           32    /* 0x20 */
47 #define SSH1_CMSG_EXIT_CONFIRMATION               33    /* 0x21 */
48 #define SSH1_CMSG_X11_REQUEST_FORWARDING          34    /* 0x22 */
49 #define SSH1_CMSG_AUTH_RHOSTS_RSA                 35    /* 0x23 */
50 #define SSH1_MSG_DEBUG                            36    /* 0x24 */
51 #define SSH1_CMSG_REQUEST_COMPRESSION             37    /* 0x25 */
52 #define SSH1_CMSG_AUTH_TIS                        39    /* 0x27 */
53 #define SSH1_SMSG_AUTH_TIS_CHALLENGE              40    /* 0x28 */
54 #define SSH1_CMSG_AUTH_TIS_RESPONSE               41    /* 0x29 */
55 #define SSH1_CMSG_AUTH_CCARD                      70    /* 0x46 */
56 #define SSH1_SMSG_AUTH_CCARD_CHALLENGE            71    /* 0x47 */
57 #define SSH1_CMSG_AUTH_CCARD_RESPONSE             72    /* 0x48 */
58
59 #define SSH1_AUTH_TIS                             5     /* 0x5 */
60 #define SSH1_AUTH_CCARD                           16    /* 0x10 */
61
62 #define SSH1_PROTOFLAG_SCREEN_NUMBER              1     /* 0x1 */
63 /* Mask for protoflags we will echo back to server if seen */
64 #define SSH1_PROTOFLAGS_SUPPORTED                 0     /* 0x1 */
65
66 #define SSH2_MSG_DISCONNECT                       1     /* 0x1 */
67 #define SSH2_MSG_IGNORE                           2     /* 0x2 */
68 #define SSH2_MSG_UNIMPLEMENTED                    3     /* 0x3 */
69 #define SSH2_MSG_DEBUG                            4     /* 0x4 */
70 #define SSH2_MSG_SERVICE_REQUEST                  5     /* 0x5 */
71 #define SSH2_MSG_SERVICE_ACCEPT                   6     /* 0x6 */
72 #define SSH2_MSG_KEXINIT                          20    /* 0x14 */
73 #define SSH2_MSG_NEWKEYS                          21    /* 0x15 */
74 #define SSH2_MSG_KEXDH_INIT                       30    /* 0x1e */
75 #define SSH2_MSG_KEXDH_REPLY                      31    /* 0x1f */
76 #define SSH2_MSG_KEX_DH_GEX_REQUEST               30    /* 0x1e */
77 #define SSH2_MSG_KEX_DH_GEX_GROUP                 31    /* 0x1f */
78 #define SSH2_MSG_KEX_DH_GEX_INIT                  32    /* 0x20 */
79 #define SSH2_MSG_KEX_DH_GEX_REPLY                 33    /* 0x21 */
80 #define SSH2_MSG_USERAUTH_REQUEST                 50    /* 0x32 */
81 #define SSH2_MSG_USERAUTH_FAILURE                 51    /* 0x33 */
82 #define SSH2_MSG_USERAUTH_SUCCESS                 52    /* 0x34 */
83 #define SSH2_MSG_USERAUTH_BANNER                  53    /* 0x35 */
84 #define SSH2_MSG_USERAUTH_PK_OK                   60    /* 0x3c */
85 #define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ        60    /* 0x3c */
86 #define SSH2_MSG_USERAUTH_INFO_REQUEST            60    /* 0x3c */
87 #define SSH2_MSG_USERAUTH_INFO_RESPONSE           61    /* 0x3d */
88 #define SSH2_MSG_GLOBAL_REQUEST                   80    /* 0x50 */
89 #define SSH2_MSG_REQUEST_SUCCESS                  81    /* 0x51 */
90 #define SSH2_MSG_REQUEST_FAILURE                  82    /* 0x52 */
91 #define SSH2_MSG_CHANNEL_OPEN                     90    /* 0x5a */
92 #define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION        91    /* 0x5b */
93 #define SSH2_MSG_CHANNEL_OPEN_FAILURE             92    /* 0x5c */
94 #define SSH2_MSG_CHANNEL_WINDOW_ADJUST            93    /* 0x5d */
95 #define SSH2_MSG_CHANNEL_DATA                     94    /* 0x5e */
96 #define SSH2_MSG_CHANNEL_EXTENDED_DATA            95    /* 0x5f */
97 #define SSH2_MSG_CHANNEL_EOF                      96    /* 0x60 */
98 #define SSH2_MSG_CHANNEL_CLOSE                    97    /* 0x61 */
99 #define SSH2_MSG_CHANNEL_REQUEST                  98    /* 0x62 */
100 #define SSH2_MSG_CHANNEL_SUCCESS                  99    /* 0x63 */
101 #define SSH2_MSG_CHANNEL_FAILURE                  100   /* 0x64 */
102
103 /*
104  * Packet type contexts, so that ssh2_pkt_type can correctly decode
105  * the ambiguous type numbers back into the correct type strings.
106  */
107 #define SSH2_PKTCTX_DHGROUP          0x0001
108 #define SSH2_PKTCTX_DHGEX            0x0002
109 #define SSH2_PKTCTX_KEX_MASK         0x000F
110 #define SSH2_PKTCTX_PUBLICKEY        0x0010
111 #define SSH2_PKTCTX_PASSWORD         0x0020
112 #define SSH2_PKTCTX_KBDINTER         0x0040
113 #define SSH2_PKTCTX_AUTH_MASK        0x00F0
114
115 #define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1   /* 0x1 */
116 #define SSH2_DISCONNECT_PROTOCOL_ERROR            2     /* 0x2 */
117 #define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED       3     /* 0x3 */
118 #define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4    /* 0x4 */
119 #define SSH2_DISCONNECT_MAC_ERROR                 5     /* 0x5 */
120 #define SSH2_DISCONNECT_COMPRESSION_ERROR         6     /* 0x6 */
121 #define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE     7     /* 0x7 */
122 #define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8        /* 0x8 */
123 #define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE   9     /* 0x9 */
124 #define SSH2_DISCONNECT_CONNECTION_LOST           10    /* 0xa */
125 #define SSH2_DISCONNECT_BY_APPLICATION            11    /* 0xb */
126 #define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS      12    /* 0xc */
127 #define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER    13    /* 0xd */
128 #define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14       /* 0xe */
129 #define SSH2_DISCONNECT_ILLEGAL_USER_NAME         15    /* 0xf */
130
131 static const char *const ssh2_disconnect_reasons[] = {
132     NULL,
133     "host not allowed to connect",
134     "protocol error",
135     "key exchange failed",
136     "host authentication failed",
137     "MAC error",
138     "compression error",
139     "service not available",
140     "protocol version not supported",
141     "host key not verifiable",
142     "connection lost",
143     "by application",
144     "too many connections",
145     "auth cancelled by user",
146     "no more auth methods available",
147     "illegal user name",
148 };
149
150 #define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED     1     /* 0x1 */
151 #define SSH2_OPEN_CONNECT_FAILED                  2     /* 0x2 */
152 #define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE            3     /* 0x3 */
153 #define SSH2_OPEN_RESOURCE_SHORTAGE               4     /* 0x4 */
154
155 #define SSH2_EXTENDED_DATA_STDERR                 1     /* 0x1 */
156
157 /*
158  * Various remote-bug flags.
159  */
160 #define BUG_CHOKES_ON_SSH1_IGNORE                 1
161 #define BUG_SSH2_HMAC                             2
162 #define BUG_NEEDS_SSH1_PLAIN_PASSWORD             4
163 #define BUG_CHOKES_ON_RSA                         8
164 #define BUG_SSH2_RSA_PADDING                     16
165 #define BUG_SSH2_DERIVEKEY                       32
166 #define BUG_SSH2_REKEY                           64
167 #define BUG_SSH2_PK_SESSIONID                   128
168
169 /*
170  * Codes for terminal modes.
171  * Most of these are the same in SSH-1 and SSH-2.
172  * This list is derived from draft-ietf-secsh-connect-25 and
173  * SSH-1 RFC-1.2.31.
174  */
175 static const struct {
176     const char* const mode;
177     int opcode;
178     enum { TTY_OP_CHAR, TTY_OP_BOOL } type;
179 } ssh_ttymodes[] = {
180     /* "V" prefix discarded for special characters relative to SSH specs */
181     { "INTR",         1, TTY_OP_CHAR },
182     { "QUIT",         2, TTY_OP_CHAR },
183     { "ERASE",        3, TTY_OP_CHAR },
184     { "KILL",         4, TTY_OP_CHAR },
185     { "EOF",          5, TTY_OP_CHAR },
186     { "EOL",          6, TTY_OP_CHAR },
187     { "EOL2",         7, TTY_OP_CHAR },
188     { "START",        8, TTY_OP_CHAR },
189     { "STOP",         9, TTY_OP_CHAR },
190     { "SUSP",        10, TTY_OP_CHAR },
191     { "DSUSP",       11, TTY_OP_CHAR },
192     { "REPRINT",     12, TTY_OP_CHAR },
193     { "WERASE",      13, TTY_OP_CHAR },
194     { "LNEXT",       14, TTY_OP_CHAR },
195     { "FLUSH",       15, TTY_OP_CHAR },
196     { "SWTCH",       16, TTY_OP_CHAR },
197     { "STATUS",      17, TTY_OP_CHAR },
198     { "DISCARD",     18, TTY_OP_CHAR },
199     { "IGNPAR",      30, TTY_OP_BOOL },
200     { "PARMRK",      31, TTY_OP_BOOL },
201     { "INPCK",       32, TTY_OP_BOOL },
202     { "ISTRIP",      33, TTY_OP_BOOL },
203     { "INLCR",       34, TTY_OP_BOOL },
204     { "IGNCR",       35, TTY_OP_BOOL },
205     { "ICRNL",       36, TTY_OP_BOOL },
206     { "IUCLC",       37, TTY_OP_BOOL },
207     { "IXON",        38, TTY_OP_BOOL },
208     { "IXANY",       39, TTY_OP_BOOL },
209     { "IXOFF",       40, TTY_OP_BOOL },
210     { "IMAXBEL",     41, TTY_OP_BOOL },
211     { "ISIG",        50, TTY_OP_BOOL },
212     { "ICANON",      51, TTY_OP_BOOL },
213     { "XCASE",       52, TTY_OP_BOOL },
214     { "ECHO",        53, TTY_OP_BOOL },
215     { "ECHOE",       54, TTY_OP_BOOL },
216     { "ECHOK",       55, TTY_OP_BOOL },
217     { "ECHONL",      56, TTY_OP_BOOL },
218     { "NOFLSH",      57, TTY_OP_BOOL },
219     { "TOSTOP",      58, TTY_OP_BOOL },
220     { "IEXTEN",      59, TTY_OP_BOOL },
221     { "ECHOCTL",     60, TTY_OP_BOOL },
222     { "ECHOKE",      61, TTY_OP_BOOL },
223     { "PENDIN",      62, TTY_OP_BOOL }, /* XXX is this a real mode? */
224     { "OPOST",       70, TTY_OP_BOOL },
225     { "OLCUC",       71, TTY_OP_BOOL },
226     { "ONLCR",       72, TTY_OP_BOOL },
227     { "OCRNL",       73, TTY_OP_BOOL },
228     { "ONOCR",       74, TTY_OP_BOOL },
229     { "ONLRET",      75, TTY_OP_BOOL },
230     { "CS7",         90, TTY_OP_BOOL },
231     { "CS8",         91, TTY_OP_BOOL },
232     { "PARENB",      92, TTY_OP_BOOL },
233     { "PARODD",      93, TTY_OP_BOOL }
234 };
235
236 /* Miscellaneous other tty-related constants. */
237 #define SSH_TTY_OP_END            0
238 /* The opcodes for ISPEED/OSPEED differ between SSH-1 and SSH-2. */
239 #define SSH1_TTY_OP_ISPEED      192
240 #define SSH1_TTY_OP_OSPEED      193
241 #define SSH2_TTY_OP_ISPEED      128
242 #define SSH2_TTY_OP_OSPEED      129
243
244 /* Helper functions for parsing tty-related config. */
245 static unsigned int ssh_tty_parse_specchar(char *s)
246 {
247     unsigned int ret;
248     if (*s) {
249         char *next = NULL;
250         ret = ctrlparse(s, &next);
251         if (!next) ret = s[0];
252     } else {
253         ret = 255; /* special value meaning "don't set" */
254     }
255     return ret;
256 }
257 static unsigned int ssh_tty_parse_boolean(char *s)
258 {
259     if (stricmp(s, "yes") == 0 ||
260         stricmp(s, "on") == 0 ||
261         stricmp(s, "true") == 0 ||
262         stricmp(s, "+") == 0)
263         return 1; /* true */
264     else if (stricmp(s, "no") == 0 ||
265              stricmp(s, "off") == 0 ||
266              stricmp(s, "false") == 0 ||
267              stricmp(s, "-") == 0)
268         return 0; /* false */
269     else
270         return (atoi(s) != 0);
271 }
272
273 #define translate(x) if (type == x) return #x
274 #define translatec(x,ctx) if (type == x && (pkt_ctx & ctx)) return #x
275 static char *ssh1_pkt_type(int type)
276 {
277     translate(SSH1_MSG_DISCONNECT);
278     translate(SSH1_SMSG_PUBLIC_KEY);
279     translate(SSH1_CMSG_SESSION_KEY);
280     translate(SSH1_CMSG_USER);
281     translate(SSH1_CMSG_AUTH_RSA);
282     translate(SSH1_SMSG_AUTH_RSA_CHALLENGE);
283     translate(SSH1_CMSG_AUTH_RSA_RESPONSE);
284     translate(SSH1_CMSG_AUTH_PASSWORD);
285     translate(SSH1_CMSG_REQUEST_PTY);
286     translate(SSH1_CMSG_WINDOW_SIZE);
287     translate(SSH1_CMSG_EXEC_SHELL);
288     translate(SSH1_CMSG_EXEC_CMD);
289     translate(SSH1_SMSG_SUCCESS);
290     translate(SSH1_SMSG_FAILURE);
291     translate(SSH1_CMSG_STDIN_DATA);
292     translate(SSH1_SMSG_STDOUT_DATA);
293     translate(SSH1_SMSG_STDERR_DATA);
294     translate(SSH1_CMSG_EOF);
295     translate(SSH1_SMSG_EXIT_STATUS);
296     translate(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION);
297     translate(SSH1_MSG_CHANNEL_OPEN_FAILURE);
298     translate(SSH1_MSG_CHANNEL_DATA);
299     translate(SSH1_MSG_CHANNEL_CLOSE);
300     translate(SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION);
301     translate(SSH1_SMSG_X11_OPEN);
302     translate(SSH1_CMSG_PORT_FORWARD_REQUEST);
303     translate(SSH1_MSG_PORT_OPEN);
304     translate(SSH1_CMSG_AGENT_REQUEST_FORWARDING);
305     translate(SSH1_SMSG_AGENT_OPEN);
306     translate(SSH1_MSG_IGNORE);
307     translate(SSH1_CMSG_EXIT_CONFIRMATION);
308     translate(SSH1_CMSG_X11_REQUEST_FORWARDING);
309     translate(SSH1_CMSG_AUTH_RHOSTS_RSA);
310     translate(SSH1_MSG_DEBUG);
311     translate(SSH1_CMSG_REQUEST_COMPRESSION);
312     translate(SSH1_CMSG_AUTH_TIS);
313     translate(SSH1_SMSG_AUTH_TIS_CHALLENGE);
314     translate(SSH1_CMSG_AUTH_TIS_RESPONSE);
315     translate(SSH1_CMSG_AUTH_CCARD);
316     translate(SSH1_SMSG_AUTH_CCARD_CHALLENGE);
317     translate(SSH1_CMSG_AUTH_CCARD_RESPONSE);
318     return "unknown";
319 }
320 static char *ssh2_pkt_type(int pkt_ctx, int type)
321 {
322     translate(SSH2_MSG_DISCONNECT);
323     translate(SSH2_MSG_IGNORE);
324     translate(SSH2_MSG_UNIMPLEMENTED);
325     translate(SSH2_MSG_DEBUG);
326     translate(SSH2_MSG_SERVICE_REQUEST);
327     translate(SSH2_MSG_SERVICE_ACCEPT);
328     translate(SSH2_MSG_KEXINIT);
329     translate(SSH2_MSG_NEWKEYS);
330     translatec(SSH2_MSG_KEXDH_INIT, SSH2_PKTCTX_DHGROUP);
331     translatec(SSH2_MSG_KEXDH_REPLY, SSH2_PKTCTX_DHGROUP);
332     translatec(SSH2_MSG_KEX_DH_GEX_REQUEST, SSH2_PKTCTX_DHGEX);
333     translatec(SSH2_MSG_KEX_DH_GEX_GROUP, SSH2_PKTCTX_DHGEX);
334     translatec(SSH2_MSG_KEX_DH_GEX_INIT, SSH2_PKTCTX_DHGEX);
335     translatec(SSH2_MSG_KEX_DH_GEX_REPLY, SSH2_PKTCTX_DHGEX);
336     translate(SSH2_MSG_USERAUTH_REQUEST);
337     translate(SSH2_MSG_USERAUTH_FAILURE);
338     translate(SSH2_MSG_USERAUTH_SUCCESS);
339     translate(SSH2_MSG_USERAUTH_BANNER);
340     translatec(SSH2_MSG_USERAUTH_PK_OK, SSH2_PKTCTX_PUBLICKEY);
341     translatec(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, SSH2_PKTCTX_PASSWORD);
342     translatec(SSH2_MSG_USERAUTH_INFO_REQUEST, SSH2_PKTCTX_KBDINTER);
343     translatec(SSH2_MSG_USERAUTH_INFO_RESPONSE, SSH2_PKTCTX_KBDINTER);
344     translate(SSH2_MSG_GLOBAL_REQUEST);
345     translate(SSH2_MSG_REQUEST_SUCCESS);
346     translate(SSH2_MSG_REQUEST_FAILURE);
347     translate(SSH2_MSG_CHANNEL_OPEN);
348     translate(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
349     translate(SSH2_MSG_CHANNEL_OPEN_FAILURE);
350     translate(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
351     translate(SSH2_MSG_CHANNEL_DATA);
352     translate(SSH2_MSG_CHANNEL_EXTENDED_DATA);
353     translate(SSH2_MSG_CHANNEL_EOF);
354     translate(SSH2_MSG_CHANNEL_CLOSE);
355     translate(SSH2_MSG_CHANNEL_REQUEST);
356     translate(SSH2_MSG_CHANNEL_SUCCESS);
357     translate(SSH2_MSG_CHANNEL_FAILURE);
358     return "unknown";
359 }
360 #undef translate
361 #undef translatec
362
363 /* Enumeration values for fields in SSH-1 packets */
364 enum {
365     PKT_END, PKT_INT, PKT_CHAR, PKT_DATA, PKT_STR, PKT_BIGNUM,
366     /* These values are for communicating relevant semantics of
367      * fields to the packet logging code. */
368     PKTT_OTHER, PKTT_PASSWORD, PKTT_DATA
369 };
370
371 /*
372  * Coroutine mechanics for the sillier bits of the code. If these
373  * macros look impenetrable to you, you might find it helpful to
374  * read
375  * 
376  *   http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
377  * 
378  * which explains the theory behind these macros.
379  * 
380  * In particular, if you are getting `case expression not constant'
381  * errors when building with MS Visual Studio, this is because MS's
382  * Edit and Continue debugging feature causes their compiler to
383  * violate ANSI C. To disable Edit and Continue debugging:
384  * 
385  *  - right-click ssh.c in the FileView
386  *  - click Settings
387  *  - select the C/C++ tab and the General category
388  *  - under `Debug info:', select anything _other_ than `Program
389  *    Database for Edit and Continue'.
390  */
391 #define crBegin(v)      { int *crLine = &v; switch(v) { case 0:;
392 #define crState(t) \
393     struct t *s; \
394     if (!ssh->t) ssh->t = snew(struct t); \
395     s = ssh->t;
396 #define crFinish(z)     } *crLine = 0; return (z); }
397 #define crFinishV       } *crLine = 0; return; }
398 #define crReturn(z)     \
399         do {\
400             *crLine =__LINE__; return (z); case __LINE__:;\
401         } while (0)
402 #define crReturnV       \
403         do {\
404             *crLine=__LINE__; return; case __LINE__:;\
405         } while (0)
406 #define crStop(z)       do{ *crLine = 0; return (z); }while(0)
407 #define crStopV         do{ *crLine = 0; return; }while(0)
408 #define crWaitUntil(c)  do { crReturn(0); } while (!(c))
409 #define crWaitUntilV(c) do { crReturnV; } while (!(c))
410
411 typedef struct ssh_tag *Ssh;
412 struct Packet;
413
414 static struct Packet *ssh1_pkt_init(int pkt_type);
415 static struct Packet *ssh2_pkt_init(int pkt_type);
416 static void ssh_pkt_ensure(struct Packet *, int length);
417 static void ssh_pkt_adddata(struct Packet *, void *data, int len);
418 static void ssh_pkt_addbyte(struct Packet *, unsigned char value);
419 static void ssh2_pkt_addbool(struct Packet *, unsigned char value);
420 static void ssh_pkt_adduint32(struct Packet *, unsigned long value);
421 static void ssh_pkt_addstring_start(struct Packet *);
422 static void ssh_pkt_addstring_str(struct Packet *, char *data);
423 static void ssh_pkt_addstring_data(struct Packet *, char *data, int len);
424 static void ssh_pkt_addstring(struct Packet *, char *data);
425 static unsigned char *ssh2_mpint_fmt(Bignum b, int *len);
426 static void ssh1_pkt_addmp(struct Packet *, Bignum b);
427 static void ssh2_pkt_addmp(struct Packet *, Bignum b);
428 static int ssh2_pkt_construct(Ssh, struct Packet *);
429 static void ssh2_pkt_send(Ssh, struct Packet *);
430 static void ssh2_pkt_send_noqueue(Ssh, struct Packet *);
431 static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
432                          struct Packet *pktin);
433 static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
434                              struct Packet *pktin);
435
436 /*
437  * Buffer management constants. There are several of these for
438  * various different purposes:
439  * 
440  *  - SSH1_BUFFER_LIMIT is the amount of backlog that must build up
441  *    on a local data stream before we throttle the whole SSH
442  *    connection (in SSH-1 only). Throttling the whole connection is
443  *    pretty drastic so we set this high in the hope it won't
444  *    happen very often.
445  * 
446  *  - SSH_MAX_BACKLOG is the amount of backlog that must build up
447  *    on the SSH connection itself before we defensively throttle
448  *    _all_ local data streams. This is pretty drastic too (though
449  *    thankfully unlikely in SSH-2 since the window mechanism should
450  *    ensure that the server never has any need to throttle its end
451  *    of the connection), so we set this high as well.
452  * 
453  *  - OUR_V2_WINSIZE is the maximum window size we present on SSH-2
454  *    channels.
455  */
456
457 #define SSH1_BUFFER_LIMIT 32768
458 #define SSH_MAX_BACKLOG 32768
459 #define OUR_V2_WINSIZE 16384
460 #define OUR_V2_MAXPKT 0x4000UL
461
462 const static struct ssh_signkey *hostkey_algs[] = { &ssh_rsa, &ssh_dss };
463
464 const static struct ssh_mac *macs[] = {
465     &ssh_hmac_sha1, &ssh_hmac_sha1_96, &ssh_hmac_md5
466 };
467 const static struct ssh_mac *buggymacs[] = {
468     &ssh_hmac_sha1_buggy, &ssh_hmac_sha1_96_buggy, &ssh_hmac_md5
469 };
470
471 static void *ssh_comp_none_init(void)
472 {
473     return NULL;
474 }
475 static void ssh_comp_none_cleanup(void *handle)
476 {
477 }
478 static int ssh_comp_none_block(void *handle, unsigned char *block, int len,
479                                unsigned char **outblock, int *outlen)
480 {
481     return 0;
482 }
483 static int ssh_comp_none_disable(void *handle)
484 {
485     return 0;
486 }
487 const static struct ssh_compress ssh_comp_none = {
488     "none",
489     ssh_comp_none_init, ssh_comp_none_cleanup, ssh_comp_none_block,
490     ssh_comp_none_init, ssh_comp_none_cleanup, ssh_comp_none_block,
491     ssh_comp_none_disable, NULL
492 };
493 extern const struct ssh_compress ssh_zlib;
494 const static struct ssh_compress *compressions[] = {
495     &ssh_zlib, &ssh_comp_none
496 };
497
498 enum {                                 /* channel types */
499     CHAN_MAINSESSION,
500     CHAN_X11,
501     CHAN_AGENT,
502     CHAN_SOCKDATA,
503     CHAN_SOCKDATA_DORMANT              /* one the remote hasn't confirmed */
504 };
505
506 /*
507  * 2-3-4 tree storing channels.
508  */
509 struct ssh_channel {
510     Ssh ssh;                           /* pointer back to main context */
511     unsigned remoteid, localid;
512     int type;
513     /* True if we opened this channel but server hasn't confirmed. */
514     int halfopen;
515     /*
516      * In SSH-1, this value contains four bits:
517      * 
518      *   1   We have sent SSH1_MSG_CHANNEL_CLOSE.
519      *   2   We have sent SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION.
520      *   4   We have received SSH1_MSG_CHANNEL_CLOSE.
521      *   8   We have received SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION.
522      * 
523      * A channel is completely finished with when all four bits are set.
524      */
525     int closes;
526     union {
527         struct ssh1_data_channel {
528             int throttling;
529         } v1;
530         struct ssh2_data_channel {
531             bufchain outbuffer;
532             unsigned remwindow, remmaxpkt;
533             unsigned locwindow;
534         } v2;
535     } v;
536     union {
537         struct ssh_agent_channel {
538             unsigned char *message;
539             unsigned char msglen[4];
540             unsigned lensofar, totallen;
541         } a;
542         struct ssh_x11_channel {
543             Socket s;
544         } x11;
545         struct ssh_pfd_channel {
546             Socket s;
547         } pfd;
548     } u;
549 };
550
551 /*
552  * 2-3-4 tree storing remote->local port forwardings. SSH-1 and SSH-2
553  * use this structure in different ways, reflecting SSH-2's
554  * altogether saner approach to port forwarding.
555  * 
556  * In SSH-1, you arrange a remote forwarding by sending the server
557  * the remote port number, and the local destination host:port.
558  * When a connection comes in, the server sends you back that
559  * host:port pair, and you connect to it. This is a ready-made
560  * security hole if you're not on the ball: a malicious server
561  * could send you back _any_ host:port pair, so if you trustingly
562  * connect to the address it gives you then you've just opened the
563  * entire inside of your corporate network just by connecting
564  * through it to a dodgy SSH server. Hence, we must store a list of
565  * host:port pairs we _are_ trying to forward to, and reject a
566  * connection request from the server if it's not in the list.
567  * 
568  * In SSH-2, each side of the connection minds its own business and
569  * doesn't send unnecessary information to the other. You arrange a
570  * remote forwarding by sending the server just the remote port
571  * number. When a connection comes in, the server tells you which
572  * of its ports was connected to; and _you_ have to remember what
573  * local host:port pair went with that port number.
574  * 
575  * Hence, in SSH-1 this structure is indexed by destination
576  * host:port pair, whereas in SSH-2 it is indexed by source port.
577  */
578 struct ssh_portfwd; /* forward declaration */
579
580 struct ssh_rportfwd {
581     unsigned sport, dport;
582     char dhost[256];
583     char *sportdesc;
584     struct ssh_portfwd *pfrec;
585 };
586 #define free_rportfwd(pf) ( \
587     ((pf) ? (sfree((pf)->sportdesc)) : (void)0 ), sfree(pf) )
588
589 /*
590  * Separately to the rportfwd tree (which is for looking up port
591  * open requests from the server), a tree of _these_ structures is
592  * used to keep track of all the currently open port forwardings,
593  * so that we can reconfigure in mid-session if the user requests
594  * it.
595  */
596 struct ssh_portfwd {
597     enum { DESTROY, KEEP, CREATE } status;
598     int type;
599     unsigned sport, dport;
600     char *saddr, *daddr;
601     char *sserv, *dserv;
602     struct ssh_rportfwd *remote;
603     int addressfamily;
604     void *local;
605 };
606 #define free_portfwd(pf) ( \
607     ((pf) ? (sfree((pf)->saddr), sfree((pf)->daddr), \
608              sfree((pf)->sserv), sfree((pf)->dserv)) : (void)0 ), sfree(pf) )
609
610 struct Packet {
611     long length;            /* length of `data' actually used */
612     long forcepad;          /* SSH-2: force padding to at least this length */
613     int type;               /* only used for incoming packets */
614     unsigned long sequence; /* SSH-2 incoming sequence number */
615     unsigned char *data;    /* allocated storage */
616     unsigned char *body;    /* offset of payload within `data' */
617     long savedpos;          /* temporary index into `data' (for strings) */
618     long maxlen;            /* amount of storage allocated for `data' */
619     long encrypted_len;     /* for SSH-2 total-size counting */
620
621     /*
622      * State associated with packet logging
623      */
624     int logmode;
625     int nblanks;
626     struct logblank_t *blanks;
627 };
628
629 static void ssh1_protocol(Ssh ssh, void *vin, int inlen,
630                           struct Packet *pktin);
631 static void ssh2_protocol(Ssh ssh, void *vin, int inlen,
632                           struct Packet *pktin);
633 static void ssh1_protocol_setup(Ssh ssh);
634 static void ssh2_protocol_setup(Ssh ssh);
635 static void ssh_size(void *handle, int width, int height);
636 static void ssh_special(void *handle, Telnet_Special);
637 static int ssh2_try_send(struct ssh_channel *c);
638 static void ssh2_add_channel_data(struct ssh_channel *c, char *buf, int len);
639 static void ssh_throttle_all(Ssh ssh, int enable, int bufsize);
640 static void ssh2_set_window(struct ssh_channel *c, unsigned newwin);
641 static int ssh_sendbuffer(void *handle);
642 static int ssh_do_close(Ssh ssh, int notify_exit);
643 static unsigned long ssh_pkt_getuint32(struct Packet *pkt);
644 static int ssh2_pkt_getbool(struct Packet *pkt);
645 static void ssh_pkt_getstring(struct Packet *pkt, char **p, int *length);
646 static void ssh2_timer(void *ctx, long now);
647 static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
648                              struct Packet *pktin);
649
650 struct rdpkt1_state_tag {
651     long len, pad, biglen, to_read;
652     unsigned long realcrc, gotcrc;
653     unsigned char *p;
654     int i;
655     int chunk;
656     struct Packet *pktin;
657 };
658
659 struct rdpkt2_state_tag {
660     long len, pad, payload, packetlen, maclen;
661     int i;
662     int cipherblk;
663     unsigned long incoming_sequence;
664     struct Packet *pktin;
665 };
666
667 typedef void (*handler_fn_t)(Ssh ssh, struct Packet *pktin);
668 typedef void (*chandler_fn_t)(Ssh ssh, struct Packet *pktin, void *ctx);
669
670 struct queued_handler;
671 struct queued_handler {
672     int msg1, msg2;
673     chandler_fn_t handler;
674     void *ctx;
675     struct queued_handler *next;
676 };
677
678 struct ssh_tag {
679     const struct plug_function_table *fn;
680     /* the above field _must_ be first in the structure */
681
682     char *v_c, *v_s;
683     void *exhash;
684
685     Socket s;
686
687     void *ldisc;
688     void *logctx;
689
690     unsigned char session_key[32];
691     int v1_compressing;
692     int v1_remote_protoflags;
693     int v1_local_protoflags;
694     int agentfwd_enabled;
695     int X11_fwd_enabled;
696     int remote_bugs;
697     const struct ssh_cipher *cipher;
698     void *v1_cipher_ctx;
699     void *crcda_ctx;
700     const struct ssh2_cipher *cscipher, *sccipher;
701     void *cs_cipher_ctx, *sc_cipher_ctx;
702     const struct ssh_mac *csmac, *scmac;
703     void *cs_mac_ctx, *sc_mac_ctx;
704     const struct ssh_compress *cscomp, *sccomp;
705     void *cs_comp_ctx, *sc_comp_ctx;
706     const struct ssh_kex *kex;
707     const struct ssh_signkey *hostkey;
708     unsigned char v2_session_id[32];
709     int v2_session_id_len;
710     void *kex_ctx;
711
712     char *savedhost;
713     int savedport;
714     int send_ok;
715     int echoing, editing;
716
717     void *frontend;
718
719     int ospeed, ispeed;                /* temporaries */
720     int term_width, term_height;
721
722     tree234 *channels;                 /* indexed by local id */
723     struct ssh_channel *mainchan;      /* primary session channel */
724     int exitcode;
725     int close_expected;
726     int clean_exit;
727
728     tree234 *rportfwds, *portfwds;
729
730     enum {
731         SSH_STATE_PREPACKET,
732         SSH_STATE_BEFORE_SIZE,
733         SSH_STATE_INTERMED,
734         SSH_STATE_SESSION,
735         SSH_STATE_CLOSED
736     } state;
737
738     int size_needed, eof_needed;
739
740     struct Packet **queue;
741     int queuelen, queuesize;
742     int queueing;
743     unsigned char *deferred_send_data;
744     int deferred_len, deferred_size;
745
746     /*
747      * Gross hack: pscp will try to start SFTP but fall back to
748      * scp1 if that fails. This variable is the means by which
749      * scp.c can reach into the SSH code and find out which one it
750      * got.
751      */
752     int fallback_cmd;
753
754     bufchain banner;    /* accumulates banners during do_ssh2_authconn */
755     /*
756      * Used for username and password input.
757      */
758     char *userpass_input_buffer;
759     int userpass_input_buflen;
760     int userpass_input_bufpos;
761     int userpass_input_echo;
762
763     int pkt_ctx;
764
765     void *x11auth;
766
767     int version;
768     int v1_throttle_count;
769     int overall_bufsize;
770     int throttled_all;
771     int v1_stdout_throttling;
772     unsigned long v2_outgoing_sequence;
773
774     int ssh1_rdpkt_crstate;
775     int ssh2_rdpkt_crstate;
776     int do_ssh_init_crstate;
777     int ssh_gotdata_crstate;
778     int do_ssh1_login_crstate;
779     int do_ssh1_connection_crstate;
780     int do_ssh2_transport_crstate;
781     int do_ssh2_authconn_crstate;
782
783     void *do_ssh_init_state;
784     void *do_ssh1_login_state;
785     void *do_ssh2_transport_state;
786     void *do_ssh2_authconn_state;
787
788     struct rdpkt1_state_tag rdpkt1_state;
789     struct rdpkt2_state_tag rdpkt2_state;
790
791     /* SSH-1 and SSH-2 use this for different things, but both use it */
792     int protocol_initial_phase_done;
793
794     void (*protocol) (Ssh ssh, void *vin, int inlen,
795                       struct Packet *pkt);
796     struct Packet *(*s_rdpkt) (Ssh ssh, unsigned char **data, int *datalen);
797
798     /*
799      * We maintain a full _copy_ of a Config structure here, not
800      * merely a pointer to it. That way, when we're passed a new
801      * one for reconfiguration, we can check the differences and
802      * potentially reconfigure port forwardings etc in mid-session.
803      */
804     Config cfg;
805
806     /*
807      * Used to transfer data back from async callbacks.
808      */
809     void *agent_response;
810     int agent_response_len;
811     int user_response;
812
813     /*
814      * The SSH connection can be set as `frozen', meaning we are
815      * not currently accepting incoming data from the network. This
816      * is slightly more serious than setting the _socket_ as
817      * frozen, because we may already have had data passed to us
818      * from the network which we need to delay processing until
819      * after the freeze is lifted, so we also need a bufchain to
820      * store that data.
821      */
822     int frozen;
823     bufchain queued_incoming_data;
824
825     /*
826      * Dispatch table for packet types that we may have to deal
827      * with at any time.
828      */
829     handler_fn_t packet_dispatch[256];
830
831     /*
832      * Queues of one-off handler functions for success/failure
833      * indications from a request.
834      */
835     struct queued_handler *qhead, *qtail;
836
837     /*
838      * This module deals with sending keepalives.
839      */
840     Pinger pinger;
841
842     /*
843      * Track incoming and outgoing data sizes and time, for
844      * size-based rekeys.
845      */
846     unsigned long incoming_data_size, outgoing_data_size, deferred_data_size;
847     unsigned long max_data_size;
848     int kex_in_progress;
849     long next_rekey, last_rekey;
850     char *deferred_rekey_reason;    /* points to STATIC string; don't free */
851 };
852
853 #define logevent(s) logevent(ssh->frontend, s)
854
855 /* logevent, only printf-formatted. */
856 static void logeventf(Ssh ssh, const char *fmt, ...)
857 {
858     va_list ap;
859     char *buf;
860
861     va_start(ap, fmt);
862     buf = dupvprintf(fmt, ap);
863     va_end(ap);
864     logevent(buf);
865     sfree(buf);
866 }
867
868 #define bombout(msg) \
869     do { \
870         char *text = dupprintf msg; \
871         ssh_do_close(ssh, FALSE); \
872         logevent(text); \
873         connection_fatal(ssh->frontend, "%s", text); \
874         sfree(text); \
875     } while (0)
876
877 /* Functions to leave bits out of the SSH packet log file. */
878
879 static void dont_log_password(Ssh ssh, struct Packet *pkt, int blanktype)
880 {
881     if (ssh->cfg.logomitpass)
882         pkt->logmode = blanktype;
883 }
884
885 static void dont_log_data(Ssh ssh, struct Packet *pkt, int blanktype)
886 {
887     if (ssh->cfg.logomitdata)
888         pkt->logmode = blanktype;
889 }
890
891 static void end_log_omission(Ssh ssh, struct Packet *pkt)
892 {
893     pkt->logmode = PKTLOG_EMIT;
894 }
895
896 /* Helper function for common bits of parsing cfg.ttymodes. */
897 static void parse_ttymodes(Ssh ssh, char *modes,
898                            void (*do_mode)(void *data, char *mode, char *val),
899                            void *data)
900 {
901     while (*modes) {
902         char *t = strchr(modes, '\t');
903         char *m = snewn(t-modes+1, char);
904         char *val;
905         strncpy(m, modes, t-modes);
906         m[t-modes] = '\0';
907         if (*(t+1) == 'A')
908             val = get_ttymode(ssh->frontend, m);
909         else
910             val = dupstr(t+2);
911         if (val)
912             do_mode(data, m, val);
913         sfree(m);
914         sfree(val);
915         modes += strlen(modes) + 1;
916     }
917 }
918
919 static int ssh_channelcmp(void *av, void *bv)
920 {
921     struct ssh_channel *a = (struct ssh_channel *) av;
922     struct ssh_channel *b = (struct ssh_channel *) bv;
923     if (a->localid < b->localid)
924         return -1;
925     if (a->localid > b->localid)
926         return +1;
927     return 0;
928 }
929 static int ssh_channelfind(void *av, void *bv)
930 {
931     unsigned *a = (unsigned *) av;
932     struct ssh_channel *b = (struct ssh_channel *) bv;
933     if (*a < b->localid)
934         return -1;
935     if (*a > b->localid)
936         return +1;
937     return 0;
938 }
939
940 static int ssh_rportcmp_ssh1(void *av, void *bv)
941 {
942     struct ssh_rportfwd *a = (struct ssh_rportfwd *) av;
943     struct ssh_rportfwd *b = (struct ssh_rportfwd *) bv;
944     int i;
945     if ( (i = strcmp(a->dhost, b->dhost)) != 0)
946         return i < 0 ? -1 : +1;
947     if (a->dport > b->dport)
948         return +1;
949     if (a->dport < b->dport)
950         return -1;
951     return 0;
952 }
953
954 static int ssh_rportcmp_ssh2(void *av, void *bv)
955 {
956     struct ssh_rportfwd *a = (struct ssh_rportfwd *) av;
957     struct ssh_rportfwd *b = (struct ssh_rportfwd *) bv;
958
959     if (a->sport > b->sport)
960         return +1;
961     if (a->sport < b->sport)
962         return -1;
963     return 0;
964 }
965
966 /*
967  * Special form of strcmp which can cope with NULL inputs. NULL is
968  * defined to sort before even the empty string.
969  */
970 static int nullstrcmp(const char *a, const char *b)
971 {
972     if (a == NULL && b == NULL)
973         return 0;
974     if (a == NULL)
975         return -1;
976     if (b == NULL)
977         return +1;
978     return strcmp(a, b);
979 }
980
981 static int ssh_portcmp(void *av, void *bv)
982 {
983     struct ssh_portfwd *a = (struct ssh_portfwd *) av;
984     struct ssh_portfwd *b = (struct ssh_portfwd *) bv;
985     int i;
986     if (a->type > b->type)
987         return +1;
988     if (a->type < b->type)
989         return -1;
990     if (a->addressfamily > b->addressfamily)
991         return +1;
992     if (a->addressfamily < b->addressfamily)
993         return -1;
994     if ( (i = nullstrcmp(a->saddr, b->saddr)) != 0)
995         return i < 0 ? -1 : +1;
996     if (a->sport > b->sport)
997         return +1;
998     if (a->sport < b->sport)
999         return -1;
1000     if (a->type != 'D') {
1001         if ( (i = nullstrcmp(a->daddr, b->daddr)) != 0)
1002             return i < 0 ? -1 : +1;
1003         if (a->dport > b->dport)
1004             return +1;
1005         if (a->dport < b->dport)
1006             return -1;
1007     }
1008     return 0;
1009 }
1010
1011 static int alloc_channel_id(Ssh ssh)
1012 {
1013     const unsigned CHANNEL_NUMBER_OFFSET = 256;
1014     unsigned low, high, mid;
1015     int tsize;
1016     struct ssh_channel *c;
1017
1018     /*
1019      * First-fit allocation of channel numbers: always pick the
1020      * lowest unused one. To do this, binary-search using the
1021      * counted B-tree to find the largest channel ID which is in a
1022      * contiguous sequence from the beginning. (Precisely
1023      * everything in that sequence must have ID equal to its tree
1024      * index plus CHANNEL_NUMBER_OFFSET.)
1025      */
1026     tsize = count234(ssh->channels);
1027
1028     low = -1;
1029     high = tsize;
1030     while (high - low > 1) {
1031         mid = (high + low) / 2;
1032         c = index234(ssh->channels, mid);
1033         if (c->localid == mid + CHANNEL_NUMBER_OFFSET)
1034             low = mid;                 /* this one is fine */
1035         else
1036             high = mid;                /* this one is past it */
1037     }
1038     /*
1039      * Now low points to either -1, or the tree index of the
1040      * largest ID in the initial sequence.
1041      */
1042     {
1043         unsigned i = low + 1 + CHANNEL_NUMBER_OFFSET;
1044         assert(NULL == find234(ssh->channels, &i, ssh_channelfind));
1045     }
1046     return low + 1 + CHANNEL_NUMBER_OFFSET;
1047 }
1048
1049 static void c_write(Ssh ssh, const char *buf, int len)
1050 {
1051     if ((flags & FLAG_STDERR)) {
1052         int i;
1053         for (i = 0; i < len; i++)
1054             if (buf[i] != '\r')
1055                 fputc(buf[i], stderr);
1056         return;
1057     }
1058     from_backend(ssh->frontend, 1, buf, len);
1059 }
1060
1061 static void c_write_untrusted(Ssh ssh, const char *buf, int len)
1062 {
1063     int i;
1064     for (i = 0; i < len; i++) {
1065         if (buf[i] == '\n')
1066             c_write(ssh, "\r\n", 2);
1067         else if ((buf[i] & 0x60) || (buf[i] == '\r'))
1068             c_write(ssh, buf + i, 1);
1069     }
1070 }
1071
1072 static void c_write_str(Ssh ssh, const char *buf)
1073 {
1074     c_write(ssh, buf, strlen(buf));
1075 }
1076
1077 static void ssh_free_packet(struct Packet *pkt)
1078 {
1079     sfree(pkt->data);
1080     sfree(pkt);
1081 }
1082 static struct Packet *ssh_new_packet(void)
1083 {
1084     struct Packet *pkt = snew(struct Packet);
1085
1086     pkt->body = pkt->data = NULL;
1087     pkt->maxlen = 0;
1088     pkt->logmode = PKTLOG_EMIT;
1089     pkt->nblanks = 0;
1090     pkt->blanks = NULL;
1091
1092     return pkt;
1093 }
1094
1095 /*
1096  * Collect incoming data in the incoming packet buffer.
1097  * Decipher and verify the packet when it is completely read.
1098  * Drop SSH1_MSG_DEBUG and SSH1_MSG_IGNORE packets.
1099  * Update the *data and *datalen variables.
1100  * Return a Packet structure when a packet is completed.
1101  */
1102 static struct Packet *ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen)
1103 {
1104     struct rdpkt1_state_tag *st = &ssh->rdpkt1_state;
1105
1106     crBegin(ssh->ssh1_rdpkt_crstate);
1107
1108     st->pktin = ssh_new_packet();
1109
1110     st->pktin->type = 0;
1111     st->pktin->length = 0;
1112
1113     for (st->i = st->len = 0; st->i < 4; st->i++) {
1114         while ((*datalen) == 0)
1115             crReturn(NULL);
1116         st->len = (st->len << 8) + **data;
1117         (*data)++, (*datalen)--;
1118     }
1119
1120     st->pad = 8 - (st->len % 8);
1121     st->biglen = st->len + st->pad;
1122     st->pktin->length = st->len - 5;
1123
1124     if (st->biglen < 0) {
1125         bombout(("Extremely large packet length from server suggests"
1126                  " data stream corruption"));
1127         ssh_free_packet(st->pktin);
1128         crStop(NULL);
1129     }
1130
1131     st->pktin->maxlen = st->biglen;
1132     st->pktin->data = snewn(st->biglen + APIEXTRA, unsigned char);
1133
1134     st->to_read = st->biglen;
1135     st->p = st->pktin->data;
1136     while (st->to_read > 0) {
1137         st->chunk = st->to_read;
1138         while ((*datalen) == 0)
1139             crReturn(NULL);
1140         if (st->chunk > (*datalen))
1141             st->chunk = (*datalen);
1142         memcpy(st->p, *data, st->chunk);
1143         *data += st->chunk;
1144         *datalen -= st->chunk;
1145         st->p += st->chunk;
1146         st->to_read -= st->chunk;
1147     }
1148
1149     if (ssh->cipher && detect_attack(ssh->crcda_ctx, st->pktin->data,
1150                                      st->biglen, NULL)) {
1151         bombout(("Network attack (CRC compensation) detected!"));
1152         ssh_free_packet(st->pktin);
1153         crStop(NULL);
1154     }
1155
1156     if (ssh->cipher)
1157         ssh->cipher->decrypt(ssh->v1_cipher_ctx, st->pktin->data, st->biglen);
1158
1159     st->realcrc = crc32_compute(st->pktin->data, st->biglen - 4);
1160     st->gotcrc = GET_32BIT(st->pktin->data + st->biglen - 4);
1161     if (st->gotcrc != st->realcrc) {
1162         bombout(("Incorrect CRC received on packet"));
1163         ssh_free_packet(st->pktin);
1164         crStop(NULL);
1165     }
1166
1167     st->pktin->body = st->pktin->data + st->pad + 1;
1168     st->pktin->savedpos = 0;
1169
1170     if (ssh->v1_compressing) {
1171         unsigned char *decompblk;
1172         int decomplen;
1173         if (!zlib_decompress_block(ssh->sc_comp_ctx,
1174                                    st->pktin->body - 1, st->pktin->length + 1,
1175                                    &decompblk, &decomplen)) {
1176             bombout(("Zlib decompression encountered invalid data"));
1177             ssh_free_packet(st->pktin);
1178             crStop(NULL);
1179         }
1180
1181         if (st->pktin->maxlen < st->pad + decomplen) {
1182             st->pktin->maxlen = st->pad + decomplen;
1183             st->pktin->data = sresize(st->pktin->data,
1184                                       st->pktin->maxlen + APIEXTRA,
1185                                       unsigned char);
1186             st->pktin->body = st->pktin->data + st->pad + 1;
1187         }
1188
1189         memcpy(st->pktin->body - 1, decompblk, decomplen);
1190         sfree(decompblk);
1191         st->pktin->length = decomplen - 1;
1192     }
1193
1194     st->pktin->type = st->pktin->body[-1];
1195
1196     /*
1197      * Log incoming packet, possibly omitting sensitive fields.
1198      */
1199     if (ssh->logctx) {
1200         int nblanks = 0;
1201         struct logblank_t blank;
1202         if (ssh->cfg.logomitdata) {
1203             int do_blank = FALSE, blank_prefix = 0;
1204             /* "Session data" packets - omit the data field */
1205             if ((st->pktin->type == SSH1_SMSG_STDOUT_DATA) ||
1206                 (st->pktin->type == SSH1_SMSG_STDERR_DATA)) {
1207                 do_blank = TRUE; blank_prefix = 0;
1208             } else if (st->pktin->type == SSH1_MSG_CHANNEL_DATA) {
1209                 do_blank = TRUE; blank_prefix = 4;
1210             }
1211             if (do_blank) {
1212                 blank.offset = blank_prefix;
1213                 blank.len = st->pktin->length;
1214                 blank.type = PKTLOG_OMIT;
1215                 nblanks = 1;
1216             }
1217         }
1218         log_packet(ssh->logctx,
1219                    PKT_INCOMING, st->pktin->type,
1220                    ssh1_pkt_type(st->pktin->type),
1221                    st->pktin->body, st->pktin->length,
1222                    nblanks, &blank);
1223     }
1224
1225     crFinish(st->pktin);
1226 }
1227
1228 static struct Packet *ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen)
1229 {
1230     struct rdpkt2_state_tag *st = &ssh->rdpkt2_state;
1231
1232     crBegin(ssh->ssh2_rdpkt_crstate);
1233
1234     st->pktin = ssh_new_packet();
1235
1236     st->pktin->type = 0;
1237     st->pktin->length = 0;
1238     if (ssh->sccipher)
1239         st->cipherblk = ssh->sccipher->blksize;
1240     else
1241         st->cipherblk = 8;
1242     if (st->cipherblk < 8)
1243         st->cipherblk = 8;
1244
1245     st->pktin->data = snewn(st->cipherblk + APIEXTRA, unsigned char);
1246
1247     /*
1248      * Acquire and decrypt the first block of the packet. This will
1249      * contain the length and padding details.
1250      */
1251     for (st->i = st->len = 0; st->i < st->cipherblk; st->i++) {
1252         while ((*datalen) == 0)
1253             crReturn(NULL);
1254         st->pktin->data[st->i] = *(*data)++;
1255         (*datalen)--;
1256     }
1257
1258     if (ssh->sccipher)
1259         ssh->sccipher->decrypt(ssh->sc_cipher_ctx,
1260                                st->pktin->data, st->cipherblk);
1261
1262     /*
1263      * Now get the length and padding figures.
1264      */
1265     st->len = GET_32BIT(st->pktin->data);
1266     st->pad = st->pktin->data[4];
1267
1268     /*
1269      * _Completely_ silly lengths should be stomped on before they
1270      * do us any more damage.
1271      */
1272     if (st->len < 0 || st->len > 35000 || st->pad < 4 ||
1273         st->len - st->pad < 1 || (st->len + 4) % st->cipherblk != 0) {
1274         bombout(("Incoming packet was garbled on decryption"));
1275         ssh_free_packet(st->pktin);
1276         crStop(NULL);
1277     }
1278
1279     /*
1280      * This enables us to deduce the payload length.
1281      */
1282     st->payload = st->len - st->pad - 1;
1283
1284     st->pktin->length = st->payload + 5;
1285
1286     /*
1287      * So now we can work out the total packet length.
1288      */
1289     st->packetlen = st->len + 4;
1290     st->maclen = ssh->scmac ? ssh->scmac->len : 0;
1291
1292     /*
1293      * Allocate memory for the rest of the packet.
1294      */
1295     st->pktin->maxlen = st->packetlen + st->maclen;
1296     st->pktin->data = sresize(st->pktin->data,
1297                               st->pktin->maxlen + APIEXTRA,
1298                               unsigned char);
1299
1300     /*
1301      * Read and decrypt the remainder of the packet.
1302      */
1303     for (st->i = st->cipherblk; st->i < st->packetlen + st->maclen;
1304          st->i++) {
1305         while ((*datalen) == 0)
1306             crReturn(NULL);
1307         st->pktin->data[st->i] = *(*data)++;
1308         (*datalen)--;
1309     }
1310     /* Decrypt everything _except_ the MAC. */
1311     if (ssh->sccipher)
1312         ssh->sccipher->decrypt(ssh->sc_cipher_ctx,
1313                                st->pktin->data + st->cipherblk,
1314                                st->packetlen - st->cipherblk);
1315
1316     st->pktin->encrypted_len = st->packetlen;
1317
1318     /*
1319      * Check the MAC.
1320      */
1321     if (ssh->scmac
1322         && !ssh->scmac->verify(ssh->sc_mac_ctx, st->pktin->data, st->len + 4,
1323                                st->incoming_sequence)) {
1324         bombout(("Incorrect MAC received on packet"));
1325         ssh_free_packet(st->pktin);
1326         crStop(NULL);
1327     }
1328
1329     st->pktin->sequence = st->incoming_sequence++;
1330
1331     /*
1332      * Decompress packet payload.
1333      */
1334     {
1335         unsigned char *newpayload;
1336         int newlen;
1337         if (ssh->sccomp &&
1338             ssh->sccomp->decompress(ssh->sc_comp_ctx,
1339                                     st->pktin->data + 5, st->pktin->length - 5,
1340                                     &newpayload, &newlen)) {
1341             if (st->pktin->maxlen < newlen + 5) {
1342                 st->pktin->maxlen = newlen + 5;
1343                 st->pktin->data = sresize(st->pktin->data,
1344                                           st->pktin->maxlen + APIEXTRA,
1345                                           unsigned char);
1346             }
1347             st->pktin->length = 5 + newlen;
1348             memcpy(st->pktin->data + 5, newpayload, newlen);
1349             sfree(newpayload);
1350         }
1351     }
1352
1353     st->pktin->savedpos = 6;
1354     st->pktin->body = st->pktin->data;
1355     st->pktin->type = st->pktin->data[5];
1356
1357     /*
1358      * Log incoming packet, possibly omitting sensitive fields.
1359      */
1360     if (ssh->logctx) {
1361         int nblanks = 0;
1362         struct logblank_t blank;
1363         if (ssh->cfg.logomitdata) {
1364             int do_blank = FALSE, blank_prefix = 0;
1365             /* "Session data" packets - omit the data field */
1366             if (st->pktin->type == SSH2_MSG_CHANNEL_DATA) {
1367                 do_blank = TRUE; blank_prefix = 4;
1368             } else if (st->pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
1369                 do_blank = TRUE; blank_prefix = 8;
1370             }
1371             if (do_blank) {
1372                 blank.offset = blank_prefix;
1373                 blank.len = (st->pktin->length-6) - blank_prefix;
1374                 blank.type = PKTLOG_OMIT;
1375                 nblanks = 1;
1376             }
1377         }
1378         log_packet(ssh->logctx, PKT_INCOMING, st->pktin->type,
1379                    ssh2_pkt_type(ssh->pkt_ctx, st->pktin->type),
1380                    st->pktin->data+6, st->pktin->length-6,
1381                    nblanks, &blank);
1382     }
1383
1384     crFinish(st->pktin);
1385 }
1386
1387 static int s_wrpkt_prepare(Ssh ssh, struct Packet *pkt, int *offset_p)
1388 {
1389     int pad, biglen, i, pktoffs;
1390     unsigned long crc;
1391 #ifdef __SC__
1392     /*
1393      * XXX various versions of SC (including 8.8.4) screw up the
1394      * register allocation in this function and use the same register
1395      * (D6) for len and as a temporary, with predictable results.  The
1396      * following sledgehammer prevents this.
1397      */
1398     volatile
1399 #endif
1400     int len;
1401
1402     if (ssh->logctx)
1403         log_packet(ssh->logctx, PKT_OUTGOING, pkt->data[12],
1404                    ssh1_pkt_type(pkt->data[12]),
1405                    pkt->body, pkt->length - (pkt->body - pkt->data),
1406                    pkt->nblanks, pkt->blanks);
1407     sfree(pkt->blanks); pkt->blanks = NULL;
1408     pkt->nblanks = 0;
1409
1410     if (ssh->v1_compressing) {
1411         unsigned char *compblk;
1412         int complen;
1413         zlib_compress_block(ssh->cs_comp_ctx,
1414                             pkt->data + 12, pkt->length - 12,
1415                             &compblk, &complen);
1416         memcpy(pkt->data + 12, compblk, complen);
1417         sfree(compblk);
1418         pkt->length = complen + 12;
1419     }
1420
1421     ssh_pkt_ensure(pkt, pkt->length + 4); /* space for CRC */
1422     pkt->length += 4;
1423     len = pkt->length - 4 - 8;  /* len(type+data+CRC) */
1424     pad = 8 - (len % 8);
1425     pktoffs = 8 - pad;
1426     biglen = len + pad;         /* len(padding+type+data+CRC) */
1427
1428     for (i = pktoffs; i < 4+8; i++)
1429         pkt->data[i] = random_byte();
1430     crc = crc32_compute(pkt->data + pktoffs + 4, biglen - 4); /* all ex len */
1431     PUT_32BIT(pkt->data + pktoffs + 4 + biglen - 4, crc);
1432     PUT_32BIT(pkt->data + pktoffs, len);
1433
1434     if (ssh->cipher)
1435         ssh->cipher->encrypt(ssh->v1_cipher_ctx,
1436                              pkt->data + pktoffs + 4, biglen);
1437
1438     if (offset_p) *offset_p = pktoffs;
1439     return biglen + 4;          /* len(length+padding+type+data+CRC) */
1440 }
1441
1442 static void s_wrpkt(Ssh ssh, struct Packet *pkt)
1443 {
1444     int len, backlog, offset;
1445     len = s_wrpkt_prepare(ssh, pkt, &offset);
1446     backlog = sk_write(ssh->s, (char *)pkt->data + offset, len);
1447     if (backlog > SSH_MAX_BACKLOG)
1448         ssh_throttle_all(ssh, 1, backlog);
1449     ssh_free_packet(pkt);
1450 }
1451
1452 static void s_wrpkt_defer(Ssh ssh, struct Packet *pkt)
1453 {
1454     int len, offset;
1455     len = s_wrpkt_prepare(ssh, pkt, &offset);
1456     if (ssh->deferred_len + len > ssh->deferred_size) {
1457         ssh->deferred_size = ssh->deferred_len + len + 128;
1458         ssh->deferred_send_data = sresize(ssh->deferred_send_data,
1459                                           ssh->deferred_size,
1460                                           unsigned char);
1461     }
1462     memcpy(ssh->deferred_send_data + ssh->deferred_len,
1463            pkt->data + offset, len);
1464     ssh->deferred_len += len;
1465     ssh_free_packet(pkt);
1466 }
1467
1468 /*
1469  * Construct a SSH-1 packet with the specified contents.
1470  * (This all-at-once interface used to be the only one, but now SSH-1
1471  * packets can also be constructed incrementally.)
1472  */
1473 static struct Packet *construct_packet(Ssh ssh, int pkttype, va_list ap)
1474 {
1475     int argtype;
1476     Bignum bn;
1477     struct Packet *pkt;
1478
1479     pkt = ssh1_pkt_init(pkttype);
1480
1481     while ((argtype = va_arg(ap, int)) != PKT_END) {
1482         unsigned char *argp, argchar;
1483         unsigned long argint;
1484         int arglen;
1485         switch (argtype) {
1486           /* Actual fields in the packet */
1487           case PKT_INT:
1488             argint = va_arg(ap, int);
1489             ssh_pkt_adduint32(pkt, argint);
1490             break;
1491           case PKT_CHAR:
1492             argchar = (unsigned char) va_arg(ap, int);
1493             ssh_pkt_addbyte(pkt, argchar);
1494             break;
1495           case PKT_DATA:
1496             argp = va_arg(ap, unsigned char *);
1497             arglen = va_arg(ap, int);
1498             ssh_pkt_adddata(pkt, argp, arglen);
1499             break;
1500           case PKT_STR:
1501             argp = va_arg(ap, unsigned char *);
1502             ssh_pkt_addstring(pkt, argp);
1503             break;
1504           case PKT_BIGNUM:
1505             bn = va_arg(ap, Bignum);
1506             ssh1_pkt_addmp(pkt, bn);
1507             break;
1508           /* Tokens for modifications to packet logging */
1509           case PKTT_PASSWORD:
1510             dont_log_password(ssh, pkt, PKTLOG_BLANK);
1511             break;
1512           case PKTT_DATA:
1513             dont_log_data(ssh, pkt, PKTLOG_OMIT);
1514             break;
1515           case PKTT_OTHER:
1516             end_log_omission(ssh, pkt);
1517             break;
1518         }
1519     }
1520
1521     return pkt;
1522 }
1523
1524 static void send_packet(Ssh ssh, int pkttype, ...)
1525 {
1526     struct Packet *pkt;
1527     va_list ap;
1528     va_start(ap, pkttype);
1529     pkt = construct_packet(ssh, pkttype, ap);
1530     va_end(ap);
1531     s_wrpkt(ssh, pkt);
1532 }
1533
1534 static void defer_packet(Ssh ssh, int pkttype, ...)
1535 {
1536     struct Packet *pkt;
1537     va_list ap;
1538     va_start(ap, pkttype);
1539     pkt = construct_packet(ssh, pkttype, ap);
1540     va_end(ap);
1541     s_wrpkt_defer(ssh, pkt);
1542 }
1543
1544 static int ssh_versioncmp(char *a, char *b)
1545 {
1546     char *ae, *be;
1547     unsigned long av, bv;
1548
1549     av = strtoul(a, &ae, 10);
1550     bv = strtoul(b, &be, 10);
1551     if (av != bv)
1552         return (av < bv ? -1 : +1);
1553     if (*ae == '.')
1554         ae++;
1555     if (*be == '.')
1556         be++;
1557     av = strtoul(ae, &ae, 10);
1558     bv = strtoul(be, &be, 10);
1559     if (av != bv)
1560         return (av < bv ? -1 : +1);
1561     return 0;
1562 }
1563
1564 /*
1565  * Utility routines for putting an SSH-protocol `string' and
1566  * `uint32' into a hash state.
1567  */
1568 static void hash_string(const struct ssh_hash *h, void *s, void *str, int len)
1569 {
1570     unsigned char lenblk[4];
1571     PUT_32BIT(lenblk, len);
1572     h->bytes(s, lenblk, 4);
1573     h->bytes(s, str, len);
1574 }
1575
1576 static void hash_uint32(const struct ssh_hash *h, void *s, unsigned i)
1577 {
1578     unsigned char intblk[4];
1579     PUT_32BIT(intblk, i);
1580     h->bytes(s, intblk, 4);
1581 }
1582
1583 /*
1584  * Packet construction functions. Mostly shared between SSH-1 and SSH-2.
1585  */
1586 static void ssh_pkt_ensure(struct Packet *pkt, int length)
1587 {
1588     if (pkt->maxlen < length) {
1589         unsigned char *body = pkt->body;
1590         int offset = body ? body - pkt->data : 0;
1591         pkt->maxlen = length + 256;
1592         pkt->data = sresize(pkt->data, pkt->maxlen + APIEXTRA, unsigned char);
1593         if (body) pkt->body = pkt->data + offset;
1594     }
1595 }
1596 static void ssh_pkt_adddata(struct Packet *pkt, void *data, int len)
1597 {
1598     if (pkt->logmode != PKTLOG_EMIT) {
1599         pkt->nblanks++;
1600         pkt->blanks = sresize(pkt->blanks, pkt->nblanks, struct logblank_t);
1601         assert(pkt->body);
1602         pkt->blanks[pkt->nblanks-1].offset = pkt->length -
1603                                              (pkt->body - pkt->data);
1604         pkt->blanks[pkt->nblanks-1].len = len;
1605         pkt->blanks[pkt->nblanks-1].type = pkt->logmode;
1606     }
1607     pkt->length += len;
1608     ssh_pkt_ensure(pkt, pkt->length);
1609     memcpy(pkt->data + pkt->length - len, data, len);
1610 }
1611 static void ssh_pkt_addbyte(struct Packet *pkt, unsigned char byte)
1612 {
1613     ssh_pkt_adddata(pkt, &byte, 1);
1614 }
1615 static void ssh2_pkt_addbool(struct Packet *pkt, unsigned char value)
1616 {
1617     ssh_pkt_adddata(pkt, &value, 1);
1618 }
1619 static void ssh_pkt_adduint32(struct Packet *pkt, unsigned long value)
1620 {
1621     unsigned char x[4];
1622     PUT_32BIT(x, value);
1623     ssh_pkt_adddata(pkt, x, 4);
1624 }
1625 static void ssh_pkt_addstring_start(struct Packet *pkt)
1626 {
1627     ssh_pkt_adduint32(pkt, 0);
1628     pkt->savedpos = pkt->length;
1629 }
1630 static void ssh_pkt_addstring_str(struct Packet *pkt, char *data)
1631 {
1632     ssh_pkt_adddata(pkt, data, strlen(data));
1633     PUT_32BIT(pkt->data + pkt->savedpos - 4, pkt->length - pkt->savedpos);
1634 }
1635 static void ssh_pkt_addstring_data(struct Packet *pkt, char *data, int len)
1636 {
1637     ssh_pkt_adddata(pkt, data, len);
1638     PUT_32BIT(pkt->data + pkt->savedpos - 4, pkt->length - pkt->savedpos);
1639 }
1640 static void ssh_pkt_addstring(struct Packet *pkt, char *data)
1641 {
1642     ssh_pkt_addstring_start(pkt);
1643     ssh_pkt_addstring_str(pkt, data);
1644 }
1645 static void ssh1_pkt_addmp(struct Packet *pkt, Bignum b)
1646 {
1647     int len = ssh1_bignum_length(b);
1648     unsigned char *data = snewn(len, char);
1649     (void) ssh1_write_bignum(data, b);
1650     ssh_pkt_adddata(pkt, data, len);
1651     sfree(data);
1652 }
1653 static unsigned char *ssh2_mpint_fmt(Bignum b, int *len)
1654 {
1655     unsigned char *p;
1656     int i, n = (bignum_bitcount(b) + 7) / 8;
1657     p = snewn(n + 1, unsigned char);
1658     p[0] = 0;
1659     for (i = 1; i <= n; i++)
1660         p[i] = bignum_byte(b, n - i);
1661     i = 0;
1662     while (i <= n && p[i] == 0 && (p[i + 1] & 0x80) == 0)
1663         i++;
1664     memmove(p, p + i, n + 1 - i);
1665     *len = n + 1 - i;
1666     return p;
1667 }
1668 static void ssh2_pkt_addmp(struct Packet *pkt, Bignum b)
1669 {
1670     unsigned char *p;
1671     int len;
1672     p = ssh2_mpint_fmt(b, &len);
1673     ssh_pkt_addstring_start(pkt);
1674     ssh_pkt_addstring_data(pkt, (char *)p, len);
1675     sfree(p);
1676 }
1677
1678 static struct Packet *ssh1_pkt_init(int pkt_type)
1679 {
1680     struct Packet *pkt = ssh_new_packet();
1681     pkt->length = 4 + 8;            /* space for length + max padding */
1682     ssh_pkt_addbyte(pkt, pkt_type);
1683     pkt->body = pkt->data + pkt->length;
1684     return pkt;
1685 }
1686
1687 /* For legacy code (SSH-1 and -2 packet construction used to be separate) */
1688 #define ssh2_pkt_ensure(pkt, length) ssh_pkt_ensure(pkt, length)
1689 #define ssh2_pkt_adddata(pkt, data, len) ssh_pkt_adddata(pkt, data, len)
1690 #define ssh2_pkt_addbyte(pkt, byte) ssh_pkt_addbyte(pkt, byte)
1691 #define ssh2_pkt_adduint32(pkt, value) ssh_pkt_adduint32(pkt, value)
1692 #define ssh2_pkt_addstring_start(pkt) ssh_pkt_addstring_start(pkt)
1693 #define ssh2_pkt_addstring_str(pkt, data) ssh_pkt_addstring_str(pkt, data)
1694 #define ssh2_pkt_addstring_data(pkt, data, len) ssh_pkt_addstring_data(pkt, data, len)
1695 #define ssh2_pkt_addstring(pkt, data) ssh_pkt_addstring(pkt, data)
1696
1697 static struct Packet *ssh2_pkt_init(int pkt_type)
1698 {
1699     struct Packet *pkt = ssh_new_packet();
1700     pkt->length = 5; /* space for packet length + padding length */
1701     pkt->forcepad = 0;
1702     ssh_pkt_addbyte(pkt, (unsigned char) pkt_type);
1703     pkt->body = pkt->data + pkt->length; /* after packet type */
1704     return pkt;
1705 }
1706
1707 /*
1708  * Construct an SSH-2 final-form packet: compress it, encrypt it,
1709  * put the MAC on it. Final packet, ready to be sent, is stored in
1710  * pkt->data. Total length is returned.
1711  */
1712 static int ssh2_pkt_construct(Ssh ssh, struct Packet *pkt)
1713 {
1714     int cipherblk, maclen, padding, i;
1715
1716     if (ssh->logctx)
1717         log_packet(ssh->logctx, PKT_OUTGOING, pkt->data[5],
1718                    ssh2_pkt_type(ssh->pkt_ctx, pkt->data[5]),
1719                    pkt->body, pkt->length - (pkt->body - pkt->data),
1720                    pkt->nblanks, pkt->blanks);
1721     sfree(pkt->blanks); pkt->blanks = NULL;
1722     pkt->nblanks = 0;
1723
1724     /*
1725      * Compress packet payload.
1726      */
1727     {
1728         unsigned char *newpayload;
1729         int newlen;
1730         if (ssh->cscomp &&
1731             ssh->cscomp->compress(ssh->cs_comp_ctx, pkt->data + 5,
1732                                   pkt->length - 5,
1733                                   &newpayload, &newlen)) {
1734             pkt->length = 5;
1735             ssh2_pkt_adddata(pkt, newpayload, newlen);
1736             sfree(newpayload);
1737         }
1738     }
1739
1740     /*
1741      * Add padding. At least four bytes, and must also bring total
1742      * length (minus MAC) up to a multiple of the block size.
1743      * If pkt->forcepad is set, make sure the packet is at least that size
1744      * after padding.
1745      */
1746     cipherblk = ssh->cscipher ? ssh->cscipher->blksize : 8;  /* block size */
1747     cipherblk = cipherblk < 8 ? 8 : cipherblk;  /* or 8 if blksize < 8 */
1748     padding = 4;
1749     if (pkt->length + padding < pkt->forcepad)
1750         padding = pkt->forcepad - pkt->length;
1751     padding +=
1752         (cipherblk - (pkt->length + padding) % cipherblk) % cipherblk;
1753     assert(padding <= 255);
1754     maclen = ssh->csmac ? ssh->csmac->len : 0;
1755     ssh2_pkt_ensure(pkt, pkt->length + padding + maclen);
1756     pkt->data[4] = padding;
1757     for (i = 0; i < padding; i++)
1758         pkt->data[pkt->length + i] = random_byte();
1759     PUT_32BIT(pkt->data, pkt->length + padding - 4);
1760     if (ssh->csmac)
1761         ssh->csmac->generate(ssh->cs_mac_ctx, pkt->data,
1762                              pkt->length + padding,
1763                              ssh->v2_outgoing_sequence);
1764     ssh->v2_outgoing_sequence++;       /* whether or not we MACed */
1765
1766     if (ssh->cscipher)
1767         ssh->cscipher->encrypt(ssh->cs_cipher_ctx,
1768                                pkt->data, pkt->length + padding);
1769
1770     pkt->encrypted_len = pkt->length + padding;
1771
1772     /* Ready-to-send packet starts at pkt->data. We return length. */
1773     return pkt->length + padding + maclen;
1774 }
1775
1776 /*
1777  * Routines called from the main SSH code to send packets. There
1778  * are quite a few of these, because we have two separate
1779  * mechanisms for delaying the sending of packets:
1780  * 
1781  *  - In order to send an IGNORE message and a password message in
1782  *    a single fixed-length blob, we require the ability to
1783  *    concatenate the encrypted forms of those two packets _into_ a
1784  *    single blob and then pass it to our <network.h> transport
1785  *    layer in one go. Hence, there's a deferment mechanism which
1786  *    works after packet encryption.
1787  * 
1788  *  - In order to avoid sending any connection-layer messages
1789  *    during repeat key exchange, we have to queue up any such
1790  *    outgoing messages _before_ they are encrypted (and in
1791  *    particular before they're allocated sequence numbers), and
1792  *    then send them once we've finished.
1793  * 
1794  * I call these mechanisms `defer' and `queue' respectively, so as
1795  * to distinguish them reasonably easily.
1796  * 
1797  * The functions send_noqueue() and defer_noqueue() free the packet
1798  * structure they are passed. Every outgoing packet goes through
1799  * precisely one of these functions in its life; packets passed to
1800  * ssh2_pkt_send() or ssh2_pkt_defer() either go straight to one of
1801  * these or get queued, and then when the queue is later emptied
1802  * the packets are all passed to defer_noqueue().
1803  *
1804  * When using a CBC-mode cipher, it's necessary to ensure that an
1805  * attacker can't provide data to be encrypted using an IV that they
1806  * know.  We ensure this by prefixing each packet that might contain
1807  * user data with an SSH_MSG_IGNORE.  This is done using the deferral
1808  * mechanism, so in this case send_noqueue() ends up redirecting to
1809  * defer_noqueue().  If you don't like this inefficiency, don't use
1810  * CBC.
1811  */
1812
1813 static void ssh2_pkt_defer_noqueue(Ssh, struct Packet *, int);
1814 static void ssh_pkt_defersend(Ssh);
1815
1816 /*
1817  * Send an SSH-2 packet immediately, without queuing or deferring.
1818  */
1819 static void ssh2_pkt_send_noqueue(Ssh ssh, struct Packet *pkt)
1820 {
1821     int len;
1822     int backlog;
1823     if (ssh->cscipher != NULL && (ssh->cscipher->flags & SSH_CIPHER_IS_CBC)) {
1824         /* We need to send two packets, so use the deferral mechanism. */
1825         ssh2_pkt_defer_noqueue(ssh, pkt, FALSE);
1826         ssh_pkt_defersend(ssh);
1827         return;
1828     }
1829     len = ssh2_pkt_construct(ssh, pkt);
1830     backlog = sk_write(ssh->s, (char *)pkt->data, len);
1831     if (backlog > SSH_MAX_BACKLOG)
1832         ssh_throttle_all(ssh, 1, backlog);
1833
1834     ssh->outgoing_data_size += pkt->encrypted_len;
1835     if (!ssh->kex_in_progress &&
1836         ssh->max_data_size != 0 &&
1837         ssh->outgoing_data_size > ssh->max_data_size)
1838         do_ssh2_transport(ssh, "too much data sent", -1, NULL);
1839
1840     ssh_free_packet(pkt);
1841 }
1842
1843 /*
1844  * Defer an SSH-2 packet.
1845  */
1846 static void ssh2_pkt_defer_noqueue(Ssh ssh, struct Packet *pkt, int noignore)
1847 {
1848     int len;
1849     if (ssh->cscipher != NULL && (ssh->cscipher->flags & SSH_CIPHER_IS_CBC) &&
1850         ssh->deferred_len == 0 && !noignore) {
1851         /*
1852          * Interpose an SSH_MSG_IGNORE to ensure that user data don't
1853          * get encrypted with a known IV.
1854          */
1855         struct Packet *ipkt = ssh2_pkt_init(SSH2_MSG_IGNORE);
1856         ssh2_pkt_defer_noqueue(ssh, ipkt, TRUE);
1857     }
1858     len = ssh2_pkt_construct(ssh, pkt);
1859     if (ssh->deferred_len + len > ssh->deferred_size) {
1860         ssh->deferred_size = ssh->deferred_len + len + 128;
1861         ssh->deferred_send_data = sresize(ssh->deferred_send_data,
1862                                           ssh->deferred_size,
1863                                           unsigned char);
1864     }
1865     memcpy(ssh->deferred_send_data + ssh->deferred_len, pkt->data, len);
1866     ssh->deferred_len += len;
1867     ssh->deferred_data_size += pkt->encrypted_len;
1868     ssh_free_packet(pkt);
1869 }
1870
1871 /*
1872  * Queue an SSH-2 packet.
1873  */
1874 static void ssh2_pkt_queue(Ssh ssh, struct Packet *pkt)
1875 {
1876     assert(ssh->queueing);
1877
1878     if (ssh->queuelen >= ssh->queuesize) {
1879         ssh->queuesize = ssh->queuelen + 32;
1880         ssh->queue = sresize(ssh->queue, ssh->queuesize, struct Packet *);
1881     }
1882
1883     ssh->queue[ssh->queuelen++] = pkt;
1884 }
1885
1886 /*
1887  * Either queue or send a packet, depending on whether queueing is
1888  * set.
1889  */
1890 static void ssh2_pkt_send(Ssh ssh, struct Packet *pkt)
1891 {
1892     if (ssh->queueing)
1893         ssh2_pkt_queue(ssh, pkt);
1894     else
1895         ssh2_pkt_send_noqueue(ssh, pkt);
1896 }
1897
1898 #if 0 /* disused */
1899 /*
1900  * Either queue or defer a packet, depending on whether queueing is
1901  * set.
1902  */
1903 static void ssh2_pkt_defer(Ssh ssh, struct Packet *pkt)
1904 {
1905     if (ssh->queueing)
1906         ssh2_pkt_queue(ssh, pkt);
1907     else
1908         ssh2_pkt_defer_noqueue(ssh, pkt, FALSE);
1909 }
1910 #endif
1911
1912 /*
1913  * Send the whole deferred data block constructed by
1914  * ssh2_pkt_defer() or SSH-1's defer_packet().
1915  * 
1916  * The expected use of the defer mechanism is that you call
1917  * ssh2_pkt_defer() a few times, then call ssh_pkt_defersend(). If
1918  * not currently queueing, this simply sets up deferred_send_data
1919  * and then sends it. If we _are_ currently queueing, the calls to
1920  * ssh2_pkt_defer() put the deferred packets on to the queue
1921  * instead, and therefore ssh_pkt_defersend() has no deferred data
1922  * to send. Hence, there's no need to make it conditional on
1923  * ssh->queueing.
1924  */
1925 static void ssh_pkt_defersend(Ssh ssh)
1926 {
1927     int backlog;
1928     backlog = sk_write(ssh->s, (char *)ssh->deferred_send_data,
1929                        ssh->deferred_len);
1930     ssh->deferred_len = ssh->deferred_size = 0;
1931     sfree(ssh->deferred_send_data);
1932     ssh->deferred_send_data = NULL;
1933     if (backlog > SSH_MAX_BACKLOG)
1934         ssh_throttle_all(ssh, 1, backlog);
1935
1936     ssh->outgoing_data_size += ssh->deferred_data_size;
1937     if (!ssh->kex_in_progress &&
1938         ssh->max_data_size != 0 &&
1939         ssh->outgoing_data_size > ssh->max_data_size)
1940         do_ssh2_transport(ssh, "too much data sent", -1, NULL);
1941     ssh->deferred_data_size = 0;
1942 }
1943
1944 /*
1945  * Send all queued SSH-2 packets. We send them by means of
1946  * ssh2_pkt_defer_noqueue(), in case they included a pair of
1947  * packets that needed to be lumped together.
1948  */
1949 static void ssh2_pkt_queuesend(Ssh ssh)
1950 {
1951     int i;
1952
1953     assert(!ssh->queueing);
1954
1955     for (i = 0; i < ssh->queuelen; i++)
1956         ssh2_pkt_defer_noqueue(ssh, ssh->queue[i], FALSE);
1957     ssh->queuelen = 0;
1958
1959     ssh_pkt_defersend(ssh);
1960 }
1961
1962 #if 0
1963 void bndebug(char *string, Bignum b)
1964 {
1965     unsigned char *p;
1966     int i, len;
1967     p = ssh2_mpint_fmt(b, &len);
1968     debug(("%s", string));
1969     for (i = 0; i < len; i++)
1970         debug((" %02x", p[i]));
1971     debug(("\n"));
1972     sfree(p);
1973 }
1974 #endif
1975
1976 static void hash_mpint(const struct ssh_hash *h, void *s, Bignum b)
1977 {
1978     unsigned char *p;
1979     int len;
1980     p = ssh2_mpint_fmt(b, &len);
1981     hash_string(h, s, p, len);
1982     sfree(p);
1983 }
1984
1985 /*
1986  * Packet decode functions for both SSH-1 and SSH-2.
1987  */
1988 static unsigned long ssh_pkt_getuint32(struct Packet *pkt)
1989 {
1990     unsigned long value;
1991     if (pkt->length - pkt->savedpos < 4)
1992         return 0;                      /* arrgh, no way to decline (FIXME?) */
1993     value = GET_32BIT(pkt->body + pkt->savedpos);
1994     pkt->savedpos += 4;
1995     return value;
1996 }
1997 static int ssh2_pkt_getbool(struct Packet *pkt)
1998 {
1999     unsigned long value;
2000     if (pkt->length - pkt->savedpos < 1)
2001         return 0;                      /* arrgh, no way to decline (FIXME?) */
2002     value = pkt->body[pkt->savedpos] != 0;
2003     pkt->savedpos++;
2004     return value;
2005 }
2006 static void ssh_pkt_getstring(struct Packet *pkt, char **p, int *length)
2007 {
2008     int len;
2009     *p = NULL;
2010     *length = 0;
2011     if (pkt->length - pkt->savedpos < 4)
2012         return;
2013     len = GET_32BIT(pkt->body + pkt->savedpos);
2014     if (len < 0)
2015         return;
2016     *length = len;
2017     pkt->savedpos += 4;
2018     if (pkt->length - pkt->savedpos < *length)
2019         return;
2020     *p = (char *)(pkt->body + pkt->savedpos);
2021     pkt->savedpos += *length;
2022 }
2023 static void *ssh_pkt_getdata(struct Packet *pkt, int length)
2024 {
2025     if (pkt->length - pkt->savedpos < length)
2026         return NULL;
2027     pkt->savedpos += length;
2028     return pkt->body + (pkt->savedpos - length);
2029 }
2030 static int ssh1_pkt_getrsakey(struct Packet *pkt, struct RSAKey *key,
2031                               unsigned char **keystr)
2032 {
2033     int j;
2034
2035     j = makekey(pkt->body + pkt->savedpos,
2036                 pkt->length - pkt->savedpos,
2037                 key, keystr, 0);
2038
2039     if (j < 0)
2040         return FALSE;
2041     
2042     pkt->savedpos += j;
2043     assert(pkt->savedpos < pkt->length);
2044
2045     return TRUE;
2046 }
2047 static Bignum ssh1_pkt_getmp(struct Packet *pkt)
2048 {
2049     int j;
2050     Bignum b;
2051
2052     j = ssh1_read_bignum(pkt->body + pkt->savedpos,
2053                          pkt->length - pkt->savedpos, &b);
2054
2055     if (j < 0)
2056         return NULL;
2057
2058     pkt->savedpos += j;
2059     return b;
2060 }
2061 static Bignum ssh2_pkt_getmp(struct Packet *pkt)
2062 {
2063     char *p;
2064     int length;
2065     Bignum b;
2066
2067     ssh_pkt_getstring(pkt, &p, &length);
2068     if (!p)
2069         return NULL;
2070     if (p[0] & 0x80)
2071         return NULL;
2072     b = bignum_from_bytes((unsigned char *)p, length);
2073     return b;
2074 }
2075
2076 /*
2077  * Helper function to add an SSH-2 signature blob to a packet.
2078  * Expects to be shown the public key blob as well as the signature
2079  * blob. Normally works just like ssh2_pkt_addstring, but will
2080  * fiddle with the signature packet if necessary for
2081  * BUG_SSH2_RSA_PADDING.
2082  */
2083 static void ssh2_add_sigblob(Ssh ssh, struct Packet *pkt,
2084                              void *pkblob_v, int pkblob_len,
2085                              void *sigblob_v, int sigblob_len)
2086 {
2087     unsigned char *pkblob = (unsigned char *)pkblob_v;
2088     unsigned char *sigblob = (unsigned char *)sigblob_v;
2089
2090     /* dmemdump(pkblob, pkblob_len); */
2091     /* dmemdump(sigblob, sigblob_len); */
2092
2093     /*
2094      * See if this is in fact an ssh-rsa signature and a buggy
2095      * server; otherwise we can just do this the easy way.
2096      */
2097     if ((ssh->remote_bugs & BUG_SSH2_RSA_PADDING) &&
2098         (GET_32BIT(pkblob) == 7 && !memcmp(pkblob+4, "ssh-rsa", 7))) {
2099         int pos, len, siglen;
2100
2101         /*
2102          * Find the byte length of the modulus.
2103          */
2104
2105         pos = 4+7;                     /* skip over "ssh-rsa" */
2106         pos += 4 + GET_32BIT(pkblob+pos);   /* skip over exponent */
2107         len = GET_32BIT(pkblob+pos);   /* find length of modulus */
2108         pos += 4;                      /* find modulus itself */
2109         while (len > 0 && pkblob[pos] == 0)
2110             len--, pos++;
2111         /* debug(("modulus length is %d\n", len)); */
2112
2113         /*
2114          * Now find the signature integer.
2115          */
2116         pos = 4+7;                     /* skip over "ssh-rsa" */
2117         siglen = GET_32BIT(sigblob+pos);
2118         /* debug(("signature length is %d\n", siglen)); */
2119
2120         if (len != siglen) {
2121             unsigned char newlen[4];
2122             ssh2_pkt_addstring_start(pkt);
2123             ssh2_pkt_addstring_data(pkt, (char *)sigblob, pos);
2124             /* dmemdump(sigblob, pos); */
2125             pos += 4;                  /* point to start of actual sig */
2126             PUT_32BIT(newlen, len);
2127             ssh2_pkt_addstring_data(pkt, (char *)newlen, 4);
2128             /* dmemdump(newlen, 4); */
2129             newlen[0] = 0;
2130             while (len-- > siglen) {
2131                 ssh2_pkt_addstring_data(pkt, (char *)newlen, 1);
2132                 /* dmemdump(newlen, 1); */
2133             }
2134             ssh2_pkt_addstring_data(pkt, (char *)(sigblob+pos), siglen);
2135             /* dmemdump(sigblob+pos, siglen); */
2136             return;
2137         }
2138
2139         /* Otherwise fall through and do it the easy way. */
2140     }
2141
2142     ssh2_pkt_addstring_start(pkt);
2143     ssh2_pkt_addstring_data(pkt, (char *)sigblob, sigblob_len);
2144 }
2145
2146 /*
2147  * Examine the remote side's version string and compare it against
2148  * a list of known buggy implementations.
2149  */
2150 static void ssh_detect_bugs(Ssh ssh, char *vstring)
2151 {
2152     char *imp;                         /* pointer to implementation part */
2153     imp = vstring;
2154     imp += strcspn(imp, "-");
2155     if (*imp) imp++;
2156     imp += strcspn(imp, "-");
2157     if (*imp) imp++;
2158
2159     ssh->remote_bugs = 0;
2160
2161     if (ssh->cfg.sshbug_ignore1 == FORCE_ON ||
2162         (ssh->cfg.sshbug_ignore1 == AUTO &&
2163          (!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") ||
2164           !strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") ||
2165           !strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25") ||
2166           !strcmp(imp, "OSU_1.4alpha3") || !strcmp(imp, "OSU_1.5alpha4")))) {
2167         /*
2168          * These versions don't support SSH1_MSG_IGNORE, so we have
2169          * to use a different defence against password length
2170          * sniffing.
2171          */
2172         ssh->remote_bugs |= BUG_CHOKES_ON_SSH1_IGNORE;
2173         logevent("We believe remote version has SSH-1 ignore bug");
2174     }
2175
2176     if (ssh->cfg.sshbug_plainpw1 == FORCE_ON ||
2177         (ssh->cfg.sshbug_plainpw1 == AUTO &&
2178          (!strcmp(imp, "Cisco-1.25") || !strcmp(imp, "OSU_1.4alpha3")))) {
2179         /*
2180          * These versions need a plain password sent; they can't
2181          * handle having a null and a random length of data after
2182          * the password.
2183          */
2184         ssh->remote_bugs |= BUG_NEEDS_SSH1_PLAIN_PASSWORD;
2185         logevent("We believe remote version needs a plain SSH-1 password");
2186     }
2187
2188     if (ssh->cfg.sshbug_rsa1 == FORCE_ON ||
2189         (ssh->cfg.sshbug_rsa1 == AUTO &&
2190          (!strcmp(imp, "Cisco-1.25")))) {
2191         /*
2192          * These versions apparently have no clue whatever about
2193          * RSA authentication and will panic and die if they see
2194          * an AUTH_RSA message.
2195          */
2196         ssh->remote_bugs |= BUG_CHOKES_ON_RSA;
2197         logevent("We believe remote version can't handle SSH-1 RSA authentication");
2198     }
2199
2200     if (ssh->cfg.sshbug_hmac2 == FORCE_ON ||
2201         (ssh->cfg.sshbug_hmac2 == AUTO &&
2202          !wc_match("* VShell", imp) &&
2203          (wc_match("2.1.0*", imp) || wc_match("2.0.*", imp) ||
2204           wc_match("2.2.0*", imp) || wc_match("2.3.0*", imp) ||
2205           wc_match("2.1 *", imp)))) {
2206         /*
2207          * These versions have the HMAC bug.
2208          */
2209         ssh->remote_bugs |= BUG_SSH2_HMAC;
2210         logevent("We believe remote version has SSH-2 HMAC bug");
2211     }
2212
2213     if (ssh->cfg.sshbug_derivekey2 == FORCE_ON ||
2214         (ssh->cfg.sshbug_derivekey2 == AUTO &&
2215          !wc_match("* VShell", imp) &&
2216          (wc_match("2.0.0*", imp) || wc_match("2.0.10*", imp) ))) {
2217         /*
2218          * These versions have the key-derivation bug (failing to
2219          * include the literal shared secret in the hashes that
2220          * generate the keys).
2221          */
2222         ssh->remote_bugs |= BUG_SSH2_DERIVEKEY;
2223         logevent("We believe remote version has SSH-2 key-derivation bug");
2224     }
2225
2226     if (ssh->cfg.sshbug_rsapad2 == FORCE_ON ||
2227         (ssh->cfg.sshbug_rsapad2 == AUTO &&
2228          (wc_match("OpenSSH_2.[5-9]*", imp) ||
2229           wc_match("OpenSSH_3.[0-2]*", imp)))) {
2230         /*
2231          * These versions have the SSH-2 RSA padding bug.
2232          */
2233         ssh->remote_bugs |= BUG_SSH2_RSA_PADDING;
2234         logevent("We believe remote version has SSH-2 RSA padding bug");
2235     }
2236
2237     if (ssh->cfg.sshbug_pksessid2 == FORCE_ON ||
2238         (ssh->cfg.sshbug_pksessid2 == AUTO &&
2239          wc_match("OpenSSH_2.[0-2]*", imp))) {
2240         /*
2241          * These versions have the SSH-2 session-ID bug in
2242          * public-key authentication.
2243          */
2244         ssh->remote_bugs |= BUG_SSH2_PK_SESSIONID;
2245         logevent("We believe remote version has SSH-2 public-key-session-ID bug");
2246     }
2247
2248     if (ssh->cfg.sshbug_rekey2 == FORCE_ON ||
2249         (ssh->cfg.sshbug_rekey2 == AUTO &&
2250          (wc_match("DigiSSH_2.0", imp) ||
2251           wc_match("OpenSSH_2.[0-4]*", imp) ||
2252           wc_match("OpenSSH_2.5.[0-3]*", imp) ||
2253           wc_match("Sun_SSH_1.0", imp) ||
2254           wc_match("Sun_SSH_1.0.1", imp) ||
2255           /* All versions <= 1.2.6 (they changed their format in 1.2.7) */
2256           wc_match("WeOnlyDo-*", imp)))) {
2257         /*
2258          * These versions have the SSH-2 rekey bug.
2259          */
2260         ssh->remote_bugs |= BUG_SSH2_REKEY;
2261         logevent("We believe remote version has SSH-2 rekey bug");
2262     }
2263 }
2264
2265 /*
2266  * The `software version' part of an SSH version string is required
2267  * to contain no spaces or minus signs.
2268  */
2269 static void ssh_fix_verstring(char *str)
2270 {
2271     /* Eat "SSH-<protoversion>-". */
2272     assert(*str == 'S'); str++;
2273     assert(*str == 'S'); str++;
2274     assert(*str == 'H'); str++;
2275     assert(*str == '-'); str++;
2276     while (*str && *str != '-') str++;
2277     assert(*str == '-'); str++;
2278
2279     /* Convert minus signs and spaces in the remaining string into
2280      * underscores. */
2281     while (*str) {
2282         if (*str == '-' || *str == ' ')
2283             *str = '_';
2284         str++;
2285     }
2286 }
2287
2288 static int do_ssh_init(Ssh ssh, unsigned char c)
2289 {
2290     struct do_ssh_init_state {
2291         int vslen;
2292         char version[10];
2293         char *vstring;
2294         int vstrsize;
2295         int i;
2296         int proto1, proto2;
2297     };
2298     crState(do_ssh_init_state);
2299
2300     crBegin(ssh->do_ssh_init_crstate);
2301
2302     /* Search for a line beginning with the string "SSH-" in the input. */
2303     for (;;) {
2304         if (c != 'S') goto no;
2305         crReturn(1);
2306         if (c != 'S') goto no;
2307         crReturn(1);
2308         if (c != 'H') goto no;
2309         crReturn(1);
2310         if (c != '-') goto no;
2311         break;
2312       no:
2313         while (c != '\012')
2314             crReturn(1);
2315         crReturn(1);
2316     }
2317
2318     s->vstrsize = 16;
2319     s->vstring = snewn(s->vstrsize, char);
2320     strcpy(s->vstring, "SSH-");
2321     s->vslen = 4;
2322     s->i = 0;
2323     while (1) {
2324         crReturn(1);                   /* get another char */
2325         if (s->vslen >= s->vstrsize - 1) {
2326             s->vstrsize += 16;
2327             s->vstring = sresize(s->vstring, s->vstrsize, char);
2328         }
2329         s->vstring[s->vslen++] = c;
2330         if (s->i >= 0) {
2331             if (c == '-') {
2332                 s->version[s->i] = '\0';
2333                 s->i = -1;
2334             } else if (s->i < sizeof(s->version) - 1)
2335                 s->version[s->i++] = c;
2336         } else if (c == '\012')
2337             break;
2338     }
2339
2340     ssh->agentfwd_enabled = FALSE;
2341     ssh->rdpkt2_state.incoming_sequence = 0;
2342
2343     s->vstring[s->vslen] = 0;
2344     s->vstring[strcspn(s->vstring, "\015\012")] = '\0';/* remove EOL chars */
2345     logeventf(ssh, "Server version: %s", s->vstring);
2346     ssh_detect_bugs(ssh, s->vstring);
2347
2348     /*
2349      * Decide which SSH protocol version to support.
2350      */
2351
2352     /* Anything strictly below "2.0" means protocol 1 is supported. */
2353     s->proto1 = ssh_versioncmp(s->version, "2.0") < 0;
2354     /* Anything greater or equal to "1.99" means protocol 2 is supported. */
2355     s->proto2 = ssh_versioncmp(s->version, "1.99") >= 0;
2356
2357     if (ssh->cfg.sshprot == 0 && !s->proto1) {
2358         bombout(("SSH protocol version 1 required by user but not provided by server"));
2359         crStop(0);
2360     }
2361     if (ssh->cfg.sshprot == 3 && !s->proto2) {
2362         bombout(("SSH protocol version 2 required by user but not provided by server"));
2363         crStop(0);
2364     }
2365
2366     {
2367         char *verstring;
2368
2369         if (s->proto2 && (ssh->cfg.sshprot >= 2 || !s->proto1)) {
2370             /*
2371              * Construct a v2 version string.
2372              */
2373             verstring = dupprintf("SSH-2.0-%s\015\012", sshver);
2374             ssh->version = 2;
2375         } else {
2376             /*
2377              * Construct a v1 version string.
2378              */
2379             verstring = dupprintf("SSH-%s-%s\012",
2380                                   (ssh_versioncmp(s->version, "1.5") <= 0 ?
2381                                    s->version : "1.5"),
2382                                   sshver);
2383             ssh->version = 1;
2384         }
2385
2386         ssh_fix_verstring(verstring);
2387
2388         if (ssh->version == 2) {
2389             size_t len;
2390             /*
2391              * Hash our version string and their version string.
2392              */
2393             len = strcspn(verstring, "\015\012");
2394             ssh->v_c = snewn(len + 1, char);
2395             memcpy(ssh->v_c, verstring, len);
2396             ssh->v_c[len] = 0;
2397             len = strcspn(s->vstring, "\015\012");
2398             ssh->v_s = snewn(len + 1, char);
2399             memcpy(ssh->v_s, s->vstring, len);
2400             ssh->v_s[len] = 0;
2401             
2402             /*
2403              * Initialise SSH-2 protocol.
2404              */
2405             ssh->protocol = ssh2_protocol;
2406             ssh2_protocol_setup(ssh);
2407             ssh->s_rdpkt = ssh2_rdpkt;
2408         } else {
2409             /*
2410              * Initialise SSH-1 protocol.
2411              */
2412             ssh->protocol = ssh1_protocol;
2413             ssh1_protocol_setup(ssh);
2414             ssh->s_rdpkt = ssh1_rdpkt;
2415         }
2416         logeventf(ssh, "We claim version: %.*s",
2417                   strcspn(verstring, "\015\012"), verstring);
2418         sk_write(ssh->s, verstring, strlen(verstring));
2419         sfree(verstring);
2420         if (ssh->version == 2)
2421             do_ssh2_transport(ssh, NULL, -1, NULL);
2422     }
2423
2424     logeventf(ssh, "Using SSH protocol version %d", ssh->version);
2425
2426     update_specials_menu(ssh->frontend);
2427     ssh->state = SSH_STATE_BEFORE_SIZE;
2428     ssh->pinger = pinger_new(&ssh->cfg, &ssh_backend, ssh);
2429
2430     sfree(s->vstring);
2431
2432     crFinish(0);
2433 }
2434
2435 static void ssh_process_incoming_data(Ssh ssh,
2436                                       unsigned char **data, int *datalen)
2437 {
2438     struct Packet *pktin = ssh->s_rdpkt(ssh, data, datalen);
2439     if (pktin) {
2440         ssh->protocol(ssh, NULL, 0, pktin);
2441         ssh_free_packet(pktin);
2442     }
2443 }
2444
2445 static void ssh_queue_incoming_data(Ssh ssh,
2446                                     unsigned char **data, int *datalen)
2447 {
2448     bufchain_add(&ssh->queued_incoming_data, *data, *datalen);
2449     *data += *datalen;
2450     *datalen = 0;
2451 }
2452
2453 static void ssh_process_queued_incoming_data(Ssh ssh)
2454 {
2455     void *vdata;
2456     unsigned char *data;
2457     int len, origlen;
2458
2459     while (!ssh->frozen && bufchain_size(&ssh->queued_incoming_data)) {
2460         bufchain_prefix(&ssh->queued_incoming_data, &vdata, &len);
2461         data = vdata;
2462         origlen = len;
2463
2464         while (!ssh->frozen && len > 0)
2465             ssh_process_incoming_data(ssh, &data, &len);
2466
2467         if (origlen > len)
2468             bufchain_consume(&ssh->queued_incoming_data, origlen - len);
2469     }
2470 }
2471
2472 static void ssh_set_frozen(Ssh ssh, int frozen)
2473 {
2474     if (ssh->s)
2475         sk_set_frozen(ssh->s, frozen);
2476     ssh->frozen = frozen;
2477 }
2478
2479 static void ssh_gotdata(Ssh ssh, unsigned char *data, int datalen)
2480 {
2481     crBegin(ssh->ssh_gotdata_crstate);
2482
2483     /*
2484      * To begin with, feed the characters one by one to the
2485      * protocol initialisation / selection function do_ssh_init().
2486      * When that returns 0, we're done with the initial greeting
2487      * exchange and can move on to packet discipline.
2488      */
2489     while (1) {
2490         int ret;                       /* need not be kept across crReturn */
2491         if (datalen == 0)
2492             crReturnV;                 /* more data please */
2493         ret = do_ssh_init(ssh, *data);
2494         data++;
2495         datalen--;
2496         if (ret == 0)
2497             break;
2498     }
2499
2500     /*
2501      * We emerge from that loop when the initial negotiation is
2502      * over and we have selected an s_rdpkt function. Now pass
2503      * everything to s_rdpkt, and then pass the resulting packets
2504      * to the proper protocol handler.
2505      */
2506
2507     while (1) {
2508         while (bufchain_size(&ssh->queued_incoming_data) > 0 || datalen > 0) {
2509             if (ssh->frozen) {
2510                 ssh_queue_incoming_data(ssh, &data, &datalen);
2511                 /* This uses up all data and cannot cause anything interesting
2512                  * to happen; indeed, for anything to happen at all, we must
2513                  * return, so break out. */
2514                 break;
2515             } else if (bufchain_size(&ssh->queued_incoming_data) > 0) {
2516                 /* This uses up some or all data, and may freeze the
2517                  * session. */
2518                 ssh_process_queued_incoming_data(ssh);
2519             } else {
2520                 /* This uses up some or all data, and may freeze the
2521                  * session. */
2522                 ssh_process_incoming_data(ssh, &data, &datalen);
2523             }
2524             /* FIXME this is probably EBW. */
2525             if (ssh->state == SSH_STATE_CLOSED)
2526                 return;
2527         }
2528         /* We're out of data. Go and get some more. */
2529         crReturnV;
2530     }
2531     crFinishV;
2532 }
2533
2534 static int ssh_do_close(Ssh ssh, int notify_exit)
2535 {
2536     int ret = 0;
2537     struct ssh_channel *c;
2538
2539     ssh->state = SSH_STATE_CLOSED;
2540     expire_timer_context(ssh);
2541     if (ssh->s) {
2542         sk_close(ssh->s);
2543         ssh->s = NULL;
2544         if (notify_exit)
2545             notify_remote_exit(ssh->frontend);
2546         else
2547             ret = 1;
2548     }
2549     /*
2550      * Now we must shut down any port- and X-forwarded channels going
2551      * through this connection.
2552      */
2553     if (ssh->channels) {
2554         while (NULL != (c = index234(ssh->channels, 0))) {
2555             switch (c->type) {
2556               case CHAN_X11:
2557                 x11_close(c->u.x11.s);
2558                 break;
2559               case CHAN_SOCKDATA:
2560                 pfd_close(c->u.pfd.s);
2561                 break;
2562             }
2563             del234(ssh->channels, c); /* moving next one to index 0 */
2564             if (ssh->version == 2)
2565                 bufchain_clear(&c->v.v2.outbuffer);
2566             sfree(c);
2567         }
2568     }
2569     /*
2570      * Go through port-forwardings, and close any associated
2571      * listening sockets.
2572      */
2573     if (ssh->portfwds) {
2574         struct ssh_portfwd *pf;
2575         while (NULL != (pf = index234(ssh->portfwds, 0))) {
2576             /* Dispose of any listening socket. */
2577             if (pf->local)
2578                 pfd_terminate(pf->local);
2579             del234(ssh->portfwds, pf); /* moving next one to index 0 */
2580             free_portfwd(pf);
2581         }
2582     }
2583
2584     return ret;
2585 }
2586
2587 static void ssh_log(Plug plug, int type, SockAddr addr, int port,
2588                     const char *error_msg, int error_code)
2589 {
2590     Ssh ssh = (Ssh) plug;
2591     char addrbuf[256], *msg;
2592
2593     sk_getaddr(addr, addrbuf, lenof(addrbuf));
2594
2595     if (type == 0)
2596         msg = dupprintf("Connecting to %s port %d", addrbuf, port);
2597     else
2598         msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg);
2599
2600     logevent(msg);
2601     sfree(msg);
2602 }
2603
2604 static int ssh_closing(Plug plug, const char *error_msg, int error_code,
2605                        int calling_back)
2606 {
2607     Ssh ssh = (Ssh) plug;
2608     int need_notify = ssh_do_close(ssh, FALSE);
2609
2610     if (!error_msg) {
2611         if (!ssh->close_expected)
2612             error_msg = "Server unexpectedly closed network connection";
2613         else
2614             error_msg = "Server closed network connection";
2615     }
2616
2617     if (need_notify)
2618         notify_remote_exit(ssh->frontend);
2619
2620     if (error_msg)
2621         logevent(error_msg);
2622     if (!ssh->close_expected || !ssh->clean_exit)
2623         connection_fatal(ssh->frontend, "%s", error_msg);
2624     return 0;
2625 }
2626
2627 static int ssh_receive(Plug plug, int urgent, char *data, int len)
2628 {
2629     Ssh ssh = (Ssh) plug;
2630     ssh_gotdata(ssh, (unsigned char *)data, len);
2631     if (ssh->state == SSH_STATE_CLOSED) {
2632         ssh_do_close(ssh, TRUE);
2633         return 0;
2634     }
2635     return 1;
2636 }
2637
2638 static void ssh_sent(Plug plug, int bufsize)
2639 {
2640     Ssh ssh = (Ssh) plug;
2641     /*
2642      * If the send backlog on the SSH socket itself clears, we
2643      * should unthrottle the whole world if it was throttled.
2644      */
2645     if (bufsize < SSH_MAX_BACKLOG)
2646         ssh_throttle_all(ssh, 0, bufsize);
2647 }
2648
2649 /*
2650  * Connect to specified host and port.
2651  * Returns an error message, or NULL on success.
2652  * Also places the canonical host name into `realhost'. It must be
2653  * freed by the caller.
2654  */
2655 static const char *connect_to_host(Ssh ssh, char *host, int port,
2656                                    char **realhost, int nodelay, int keepalive)
2657 {
2658     static const struct plug_function_table fn_table = {
2659         ssh_log,
2660         ssh_closing,
2661         ssh_receive,
2662         ssh_sent,
2663         NULL
2664     };
2665
2666     SockAddr addr;
2667     const char *err;
2668
2669     ssh->savedhost = snewn(1 + strlen(host), char);
2670     strcpy(ssh->savedhost, host);
2671
2672     if (port < 0)
2673         port = 22;                     /* default ssh port */
2674     ssh->savedport = port;
2675
2676     /*
2677      * Try to find host.
2678      */
2679     logeventf(ssh, "Looking up host \"%s\"%s", host,
2680               (ssh->cfg.addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
2681                (ssh->cfg.addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" : "")));
2682     addr = name_lookup(host, port, realhost, &ssh->cfg,
2683                        ssh->cfg.addressfamily);
2684     if ((err = sk_addr_error(addr)) != NULL) {
2685         sk_addr_free(addr);
2686         return err;
2687     }
2688
2689     /*
2690      * Open socket.
2691      */
2692     ssh->fn = &fn_table;
2693     ssh->s = new_connection(addr, *realhost, port,
2694                             0, 1, nodelay, keepalive, (Plug) ssh, &ssh->cfg);
2695     if ((err = sk_socket_error(ssh->s)) != NULL) {
2696         ssh->s = NULL;
2697         notify_remote_exit(ssh->frontend);
2698         return err;
2699     }
2700
2701     return NULL;
2702 }
2703
2704 /*
2705  * Throttle or unthrottle the SSH connection.
2706  */
2707 static void ssh1_throttle(Ssh ssh, int adjust)
2708 {
2709     int old_count = ssh->v1_throttle_count;
2710     ssh->v1_throttle_count += adjust;
2711     assert(ssh->v1_throttle_count >= 0);
2712     if (ssh->v1_throttle_count && !old_count) {
2713         ssh_set_frozen(ssh, 1);
2714     } else if (!ssh->v1_throttle_count && old_count) {
2715         ssh_set_frozen(ssh, 0);
2716     }
2717 }
2718
2719 /*
2720  * Throttle or unthrottle _all_ local data streams (for when sends
2721  * on the SSH connection itself back up).
2722  */
2723 static void ssh_throttle_all(Ssh ssh, int enable, int bufsize)
2724 {
2725     int i;
2726     struct ssh_channel *c;
2727
2728     if (enable == ssh->throttled_all)
2729         return;
2730     ssh->throttled_all = enable;
2731     ssh->overall_bufsize = bufsize;
2732     if (!ssh->channels)
2733         return;
2734     for (i = 0; NULL != (c = index234(ssh->channels, i)); i++) {
2735         switch (c->type) {
2736           case CHAN_MAINSESSION:
2737             /*
2738              * This is treated separately, outside the switch.
2739              */
2740             break;
2741           case CHAN_X11:
2742             x11_override_throttle(c->u.x11.s, enable);
2743             break;
2744           case CHAN_AGENT:
2745             /* Agent channels require no buffer management. */
2746             break;
2747           case CHAN_SOCKDATA:
2748             pfd_override_throttle(c->u.pfd.s, enable);
2749             break;
2750         }
2751     }
2752 }
2753
2754 /*
2755  * Username and password input, abstracted off into routines
2756  * reusable in several places - even between SSH-1 and SSH-2.
2757  */
2758
2759 /* Set up a username or password input loop on a given buffer. */
2760 static void setup_userpass_input(Ssh ssh, char *buffer, int buflen, int echo)
2761 {
2762     ssh->userpass_input_buffer = buffer;
2763     ssh->userpass_input_buflen = buflen;
2764     ssh->userpass_input_bufpos = 0;
2765     ssh->userpass_input_echo = echo;
2766 }
2767
2768 /*
2769  * Process some terminal data in the course of username/password
2770  * input. Returns >0 for success (line of input returned in
2771  * buffer), <0 for failure (user hit ^C/^D, bomb out and exit), 0
2772  * for inconclusive (keep waiting for more input please).
2773  */
2774 static int process_userpass_input(Ssh ssh, unsigned char *in, int inlen)
2775 {
2776     char c;
2777
2778     while (inlen--) {
2779         switch (c = *in++) {
2780           case 10:
2781           case 13:
2782             ssh->userpass_input_buffer[ssh->userpass_input_bufpos] = 0;
2783             ssh->userpass_input_buffer[ssh->userpass_input_buflen-1] = 0;
2784             return +1;
2785             break;
2786           case 8:
2787           case 127:
2788             if (ssh->userpass_input_bufpos > 0) {
2789                 if (ssh->userpass_input_echo)
2790                     c_write_str(ssh, "\b \b");
2791                 ssh->userpass_input_bufpos--;
2792             }
2793             break;
2794           case 21:
2795           case 27:
2796             while (ssh->userpass_input_bufpos > 0) {
2797                 if (ssh->userpass_input_echo)
2798                     c_write_str(ssh, "\b \b");
2799                 ssh->userpass_input_bufpos--;
2800             }
2801             break;
2802           case 3:
2803           case 4:
2804             return -1;
2805             break;
2806           default:
2807             /*
2808              * This simplistic check for printability is disabled
2809              * when we're doing password input, because some people
2810              * have control characters in their passwords.o
2811              */
2812             if ((!ssh->userpass_input_echo ||
2813                  (c >= ' ' && c <= '~') ||
2814                  ((unsigned char) c >= 160))
2815                 && ssh->userpass_input_bufpos < ssh->userpass_input_buflen-1) {
2816                 ssh->userpass_input_buffer[ssh->userpass_input_bufpos++] = c;
2817                 if (ssh->userpass_input_echo)
2818                     c_write(ssh, &c, 1);
2819             }
2820             break;
2821         }
2822     }
2823     return 0;
2824 }
2825
2826 static void ssh_agent_callback(void *sshv, void *reply, int replylen)
2827 {
2828     Ssh ssh = (Ssh) sshv;
2829
2830     ssh->agent_response = reply;
2831     ssh->agent_response_len = replylen;
2832
2833     if (ssh->version == 1)
2834         do_ssh1_login(ssh, NULL, -1, NULL);
2835     else
2836         do_ssh2_authconn(ssh, NULL, -1, NULL);
2837 }
2838
2839 static void ssh_dialog_callback(void *sshv, int ret)
2840 {
2841     Ssh ssh = (Ssh) sshv;
2842
2843     ssh->user_response = ret;
2844
2845     if (ssh->version == 1)
2846         do_ssh1_login(ssh, NULL, -1, NULL);
2847     else
2848         do_ssh2_transport(ssh, NULL, -1, NULL);
2849
2850     /*
2851      * This may have unfrozen the SSH connection, so do a
2852      * queued-data run.
2853      */
2854     ssh_process_queued_incoming_data(ssh);
2855 }
2856
2857 static void ssh_agentf_callback(void *cv, void *reply, int replylen)
2858 {
2859     struct ssh_channel *c = (struct ssh_channel *)cv;
2860     Ssh ssh = c->ssh;
2861     void *sentreply = reply;
2862
2863     if (!sentreply) {
2864         /* Fake SSH_AGENT_FAILURE. */
2865         sentreply = "\0\0\0\1\5";
2866         replylen = 5;
2867     }
2868     if (ssh->version == 2) {
2869         ssh2_add_channel_data(c, sentreply, replylen);
2870         ssh2_try_send(c);
2871     } else {
2872         send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
2873                     PKT_INT, c->remoteid,
2874                     PKTT_DATA,
2875                     PKT_INT, replylen,
2876                     PKT_DATA, sentreply, replylen,
2877                     PKTT_OTHER,
2878                     PKT_END);
2879     }
2880     if (reply)
2881         sfree(reply);
2882 }
2883
2884 /*
2885  * Client-initiated disconnection. Send a DISCONNECT if `wire_reason'
2886  * non-NULL, otherwise just close the connection. `client_reason' == NULL
2887  * => log `wire_reason'.
2888  */
2889 static void ssh_disconnect(Ssh ssh, char *client_reason, char *wire_reason,
2890                            int code, int clean_exit)
2891 {
2892     char *error;
2893     if (!client_reason)
2894         client_reason = wire_reason;
2895     if (client_reason)
2896         error = dupprintf("Disconnected: %s", client_reason);
2897     else
2898         error = dupstr("Disconnected");
2899     if (wire_reason) {
2900         if (ssh->version == 1) {
2901             send_packet(ssh, SSH1_MSG_DISCONNECT, PKT_STR, wire_reason,
2902                         PKT_END);
2903         } else if (ssh->version == 2) {
2904             struct Packet *pktout = ssh2_pkt_init(SSH2_MSG_DISCONNECT);
2905             ssh2_pkt_adduint32(pktout, code);
2906             ssh2_pkt_addstring(pktout, wire_reason);
2907             ssh2_pkt_addstring(pktout, "en");   /* language tag */
2908             ssh2_pkt_send_noqueue(ssh, pktout);
2909         }
2910     }
2911     ssh->close_expected = TRUE;
2912     ssh->clean_exit = clean_exit;
2913     ssh_closing((Plug)ssh, error, 0, 0);
2914     sfree(error);
2915 }
2916
2917 /*
2918  * Handle the key exchange and user authentication phases.
2919  */
2920 static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
2921                          struct Packet *pktin)
2922 {
2923     int i, j, ret;
2924     unsigned char cookie[8], *ptr;
2925     struct RSAKey servkey, hostkey;
2926     struct MD5Context md5c;
2927     struct do_ssh1_login_state {
2928         int len;
2929         unsigned char *rsabuf, *keystr1, *keystr2;
2930         unsigned long supported_ciphers_mask, supported_auths_mask;
2931         int tried_publickey, tried_agent;
2932         int tis_auth_refused, ccard_auth_refused;
2933         unsigned char session_id[16];
2934         int cipher_type;
2935         char username[100];
2936         void *publickey_blob;
2937         int publickey_bloblen;
2938         char password[100];
2939         char prompt[200];
2940         int pos;
2941         char c;
2942         int pwpkt_type;
2943         unsigned char request[5], *response, *p;
2944         int responselen;
2945         int keyi, nkeys;
2946         int authed;
2947         struct RSAKey key;
2948         Bignum challenge;
2949         char *commentp;
2950         int commentlen;
2951         int dlgret;
2952     };
2953     crState(do_ssh1_login_state);
2954
2955     crBegin(ssh->do_ssh1_login_crstate);
2956
2957     if (!pktin)
2958         crWaitUntil(pktin);
2959
2960     if (pktin->type != SSH1_SMSG_PUBLIC_KEY) {
2961         bombout(("Public key packet not received"));
2962         crStop(0);
2963     }
2964
2965     logevent("Received public keys");
2966
2967     ptr = ssh_pkt_getdata(pktin, 8);
2968     if (!ptr) {
2969         bombout(("SSH-1 public key packet stopped before random cookie"));
2970         crStop(0);
2971     }
2972     memcpy(cookie, ptr, 8);
2973
2974     if (!ssh1_pkt_getrsakey(pktin, &servkey, &s->keystr1) ||
2975         !ssh1_pkt_getrsakey(pktin, &hostkey, &s->keystr2)) {    
2976         bombout(("Failed to read SSH-1 public keys from public key packet"));
2977         crStop(0);
2978     }
2979
2980     /*
2981      * Log the host key fingerprint.
2982      */
2983     {
2984         char logmsg[80];
2985         logevent("Host key fingerprint is:");
2986         strcpy(logmsg, "      ");
2987         hostkey.comment = NULL;
2988         rsa_fingerprint(logmsg + strlen(logmsg),
2989                         sizeof(logmsg) - strlen(logmsg), &hostkey);
2990         logevent(logmsg);
2991     }
2992
2993     ssh->v1_remote_protoflags = ssh_pkt_getuint32(pktin);
2994     s->supported_ciphers_mask = ssh_pkt_getuint32(pktin);
2995     s->supported_auths_mask = ssh_pkt_getuint32(pktin);
2996
2997     ssh->v1_local_protoflags =
2998         ssh->v1_remote_protoflags & SSH1_PROTOFLAGS_SUPPORTED;
2999     ssh->v1_local_protoflags |= SSH1_PROTOFLAG_SCREEN_NUMBER;
3000
3001     MD5Init(&md5c);
3002     MD5Update(&md5c, s->keystr2, hostkey.bytes);
3003     MD5Update(&md5c, s->keystr1, servkey.bytes);
3004     MD5Update(&md5c, cookie, 8);
3005     MD5Final(s->session_id, &md5c);
3006
3007     for (i = 0; i < 32; i++)
3008         ssh->session_key[i] = random_byte();
3009
3010     /*
3011      * Verify that the `bits' and `bytes' parameters match.
3012      */
3013     if (hostkey.bits > hostkey.bytes * 8 ||
3014         servkey.bits > servkey.bytes * 8) {
3015         bombout(("SSH-1 public keys were badly formatted"));
3016         crStop(0);
3017     }
3018
3019     s->len = (hostkey.bytes > servkey.bytes ? hostkey.bytes : servkey.bytes);
3020
3021     s->rsabuf = snewn(s->len, unsigned char);
3022
3023     /*
3024      * Verify the host key.
3025      */
3026     {
3027         /*
3028          * First format the key into a string.
3029          */
3030         int len = rsastr_len(&hostkey);
3031         char fingerprint[100];
3032         char *keystr = snewn(len, char);
3033         rsastr_fmt(keystr, &hostkey);
3034         rsa_fingerprint(fingerprint, sizeof(fingerprint), &hostkey);
3035
3036         ssh_set_frozen(ssh, 1);
3037         s->dlgret = verify_ssh_host_key(ssh->frontend,
3038                                         ssh->savedhost, ssh->savedport,
3039                                         "rsa", keystr, fingerprint,
3040                                         ssh_dialog_callback, ssh);
3041         sfree(keystr);
3042         if (s->dlgret < 0) {
3043             do {
3044                 crReturn(0);
3045                 if (pktin) {
3046                     bombout(("Unexpected data from server while waiting"
3047                              " for user host key response"));
3048                     crStop(0);
3049                 }
3050             } while (pktin || inlen > 0);
3051             s->dlgret = ssh->user_response;
3052         }
3053         ssh_set_frozen(ssh, 0);
3054
3055         if (s->dlgret == 0) {
3056             ssh_disconnect(ssh, "User aborted at host key verification",
3057                            NULL, 0, TRUE);
3058             crStop(0);
3059         }
3060     }
3061
3062     for (i = 0; i < 32; i++) {
3063         s->rsabuf[i] = ssh->session_key[i];
3064         if (i < 16)
3065             s->rsabuf[i] ^= s->session_id[i];
3066     }
3067
3068     if (hostkey.bytes > servkey.bytes) {
3069         ret = rsaencrypt(s->rsabuf, 32, &servkey);
3070         if (ret)
3071             ret = rsaencrypt(s->rsabuf, servkey.bytes, &hostkey);
3072     } else {
3073         ret = rsaencrypt(s->rsabuf, 32, &hostkey);
3074         if (ret)
3075             ret = rsaencrypt(s->rsabuf, hostkey.bytes, &servkey);
3076     }
3077     if (!ret) {
3078         bombout(("SSH-1 public key encryptions failed due to bad formatting"));
3079         crStop(0);      
3080     }
3081
3082     logevent("Encrypted session key");
3083
3084     {
3085         int cipher_chosen = 0, warn = 0;
3086         char *cipher_string = NULL;
3087         int i;
3088         for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) {
3089             int next_cipher = ssh->cfg.ssh_cipherlist[i];
3090             if (next_cipher == CIPHER_WARN) {
3091                 /* If/when we choose a cipher, warn about it */
3092                 warn = 1;
3093             } else if (next_cipher == CIPHER_AES) {
3094                 /* XXX Probably don't need to mention this. */
3095                 logevent("AES not supported in SSH-1, skipping");
3096             } else {
3097                 switch (next_cipher) {
3098                   case CIPHER_3DES:     s->cipher_type = SSH_CIPHER_3DES;
3099                                         cipher_string = "3DES"; break;
3100                   case CIPHER_BLOWFISH: s->cipher_type = SSH_CIPHER_BLOWFISH;
3101                                         cipher_string = "Blowfish"; break;
3102                   case CIPHER_DES:      s->cipher_type = SSH_CIPHER_DES;
3103                                         cipher_string = "single-DES"; break;
3104                 }
3105                 if (s->supported_ciphers_mask & (1 << s->cipher_type))
3106                     cipher_chosen = 1;
3107             }
3108         }
3109         if (!cipher_chosen) {
3110             if ((s->supported_ciphers_mask & (1 << SSH_CIPHER_3DES)) == 0)
3111                 bombout(("Server violates SSH-1 protocol by not "
3112                          "supporting 3DES encryption"));
3113             else
3114                 /* shouldn't happen */
3115                 bombout(("No supported ciphers found"));
3116             crStop(0);
3117         }
3118
3119         /* Warn about chosen cipher if necessary. */
3120         if (warn) {
3121             ssh_set_frozen(ssh, 1);
3122             s->dlgret = askalg(ssh->frontend, "cipher", cipher_string,
3123                                ssh_dialog_callback, ssh);
3124             if (s->dlgret < 0) {
3125                 do {
3126                     crReturn(0);
3127                     if (pktin) {
3128                         bombout(("Unexpected data from server while waiting"
3129                                  " for user response"));
3130                         crStop(0);
3131                     }
3132                 } while (pktin || inlen > 0);
3133                 s->dlgret = ssh->user_response;
3134             }
3135             ssh_set_frozen(ssh, 0);
3136             if (s->dlgret == 0) {
3137                 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
3138                                0, TRUE);
3139                 crStop(0);
3140             }
3141         }
3142     }
3143
3144     switch (s->cipher_type) {
3145       case SSH_CIPHER_3DES:
3146         logevent("Using 3DES encryption");
3147         break;
3148       case SSH_CIPHER_DES:
3149         logevent("Using single-DES encryption");
3150         break;
3151       case SSH_CIPHER_BLOWFISH:
3152         logevent("Using Blowfish encryption");
3153         break;
3154     }
3155
3156     send_packet(ssh, SSH1_CMSG_SESSION_KEY,
3157                 PKT_CHAR, s->cipher_type,
3158                 PKT_DATA, cookie, 8,
3159                 PKT_CHAR, (s->len * 8) >> 8, PKT_CHAR, (s->len * 8) & 0xFF,
3160                 PKT_DATA, s->rsabuf, s->len,
3161                 PKT_INT, ssh->v1_local_protoflags, PKT_END);
3162
3163     logevent("Trying to enable encryption...");
3164
3165     sfree(s->rsabuf);
3166
3167     ssh->cipher = (s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
3168                    s->cipher_type == SSH_CIPHER_DES ? &ssh_des :
3169                    &ssh_3des);
3170     ssh->v1_cipher_ctx = ssh->cipher->make_context();
3171     ssh->cipher->sesskey(ssh->v1_cipher_ctx, ssh->session_key);
3172     logeventf(ssh, "Initialised %s encryption", ssh->cipher->text_name);
3173
3174     ssh->crcda_ctx = crcda_make_context();
3175     logevent("Installing CRC compensation attack detector");
3176
3177     if (servkey.modulus) {
3178         sfree(servkey.modulus);
3179         servkey.modulus = NULL;
3180     }
3181     if (servkey.exponent) {
3182         sfree(servkey.exponent);
3183         servkey.exponent = NULL;
3184     }
3185     if (hostkey.modulus) {
3186         sfree(hostkey.modulus);
3187         hostkey.modulus = NULL;
3188     }
3189     if (hostkey.exponent) {
3190         sfree(hostkey.exponent);
3191         hostkey.exponent = NULL;
3192     }
3193     crWaitUntil(pktin);
3194
3195     if (pktin->type != SSH1_SMSG_SUCCESS) {
3196         bombout(("Encryption not successfully enabled"));
3197         crStop(0);
3198     }
3199
3200     logevent("Successfully started encryption");
3201
3202     fflush(stdout);
3203     {
3204         if (!*ssh->cfg.username) {
3205             if (ssh_get_line && !ssh_getline_pw_only) {
3206                 if (!ssh_get_line("login as: ",
3207                                   s->username, sizeof(s->username), FALSE)) {
3208                     /*
3209                      * get_line failed to get a username.
3210                      * Terminate.
3211                      */
3212                     ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
3213                     crStop(1);
3214                 }
3215             } else {
3216                 int ret;               /* need not be kept over crReturn */
3217                 c_write_str(ssh, "login as: ");
3218                 ssh->send_ok = 1;
3219
3220                 setup_userpass_input(ssh, s->username, sizeof(s->username), 1);
3221                 do {
3222                     crWaitUntil(!pktin);
3223                     ret = process_userpass_input(ssh, in, inlen);
3224                 } while (ret == 0);
3225                 if (ret < 0)
3226                     cleanup_exit(0);
3227                 c_write_str(ssh, "\r\n");
3228             }
3229         } else {
3230             strncpy(s->username, ssh->cfg.username, sizeof(s->username));
3231             s->username[sizeof(s->username)-1] = '\0';
3232         }
3233
3234         send_packet(ssh, SSH1_CMSG_USER, PKT_STR, s->username, PKT_END);
3235         {
3236             char userlog[22 + sizeof(s->username)];
3237             sprintf(userlog, "Sent username \"%s\"", s->username);
3238             logevent(userlog);
3239             if (flags & FLAG_INTERACTIVE &&
3240                 (!((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)))) {
3241                 strcat(userlog, "\r\n");
3242                 c_write_str(ssh, userlog);
3243             }
3244         }
3245     }
3246
3247     crWaitUntil(pktin);
3248
3249     if ((ssh->remote_bugs & BUG_CHOKES_ON_RSA)) {
3250         /* We must not attempt PK auth. Pretend we've already tried it. */
3251         s->tried_publickey = s->tried_agent = 1;
3252     } else {
3253         s->tried_publickey = s->tried_agent = 0;
3254     }
3255     s->tis_auth_refused = s->ccard_auth_refused = 0;
3256     /* Load the public half of ssh->cfg.keyfile so we notice if it's in Pageant */
3257     if (!filename_is_null(ssh->cfg.keyfile)) {
3258         if (!rsakey_pubblob(&ssh->cfg.keyfile,
3259                             &s->publickey_blob, &s->publickey_bloblen,
3260                             NULL, NULL))
3261             s->publickey_blob = NULL;
3262     } else
3263         s->publickey_blob = NULL;
3264
3265     while (pktin->type == SSH1_SMSG_FAILURE) {
3266         s->pwpkt_type = SSH1_CMSG_AUTH_PASSWORD;
3267
3268         if (agent_exists() && !s->tried_agent) {
3269             /*
3270              * Attempt RSA authentication using Pageant.
3271              */
3272             void *r;
3273
3274             s->authed = FALSE;
3275             s->tried_agent = 1;
3276             logevent("Pageant is running. Requesting keys.");
3277
3278             /* Request the keys held by the agent. */
3279             PUT_32BIT(s->request, 1);
3280             s->request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;
3281             if (!agent_query(s->request, 5, &r, &s->responselen,
3282                              ssh_agent_callback, ssh)) {
3283                 do {
3284                     crReturn(0);
3285                     if (pktin) {
3286                         bombout(("Unexpected data from server while waiting"
3287                                  " for agent response"));
3288                         crStop(0);
3289                     }
3290                 } while (pktin || inlen > 0);
3291                 r = ssh->agent_response;
3292                 s->responselen = ssh->agent_response_len;
3293             }
3294             s->response = (unsigned char *) r;
3295             if (s->response && s->responselen >= 5 &&
3296                 s->response[4] == SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
3297                 s->p = s->response + 5;
3298                 s->nkeys = GET_32BIT(s->p);
3299                 s->p += 4;
3300                 logeventf(ssh, "Pageant has %d SSH-1 keys", s->nkeys);
3301                 for (s->keyi = 0; s->keyi < s->nkeys; s->keyi++) {
3302                     logeventf(ssh, "Trying Pageant key #%d", s->keyi);
3303                     if (s->publickey_blob &&
3304                         !memcmp(s->p, s->publickey_blob,
3305                                 s->publickey_bloblen)) {
3306                         logevent("This key matches configured key file");
3307                         s->tried_publickey = 1;
3308                     }
3309                     s->p += 4;
3310                     {
3311                         int n, ok = FALSE;
3312                         do {           /* do while (0) to make breaking easy */
3313                             n = ssh1_read_bignum
3314                                 (s->p, s->responselen-(s->p-s->response),
3315                                  &s->key.exponent);
3316                             if (n < 0)
3317                                 break;
3318                             s->p += n;
3319                             n = ssh1_read_bignum
3320                                 (s->p, s->responselen-(s->p-s->response),
3321                                  &s->key.modulus);
3322                             if (n < 0)
3323                             break;
3324                             s->p += n;
3325                             if (s->responselen - (s->p-s->response) < 4)
3326                                 break;
3327                             s->commentlen = GET_32BIT(s->p);
3328                             s->p += 4;
3329                             if (s->responselen - (s->p-s->response) <
3330                                 s->commentlen)
3331                                 break;
3332                             s->commentp = (char *)s->p;
3333                             s->p += s->commentlen;
3334                             ok = TRUE;
3335                         } while (0);
3336                         if (!ok) {
3337                             logevent("Pageant key list packet was truncated");
3338                             break;
3339                         }
3340                     }
3341                     send_packet(ssh, SSH1_CMSG_AUTH_RSA,
3342                                 PKT_BIGNUM, s->key.modulus, PKT_END);
3343                     crWaitUntil(pktin);
3344                     if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
3345                         logevent("Key refused");
3346                         continue;
3347                     }
3348                     logevent("Received RSA challenge");
3349                     if ((s->challenge = ssh1_pkt_getmp(pktin)) == NULL) {
3350                         bombout(("Server's RSA challenge was badly formatted"));
3351                         crStop(0);
3352                     }
3353
3354                     {
3355                         char *agentreq, *q, *ret;
3356                         void *vret;
3357                         int len, retlen;
3358                         len = 1 + 4;   /* message type, bit count */
3359                         len += ssh1_bignum_length(s->key.exponent);
3360                         len += ssh1_bignum_length(s->key.modulus);
3361                         len += ssh1_bignum_length(s->challenge);
3362                         len += 16;     /* session id */
3363                         len += 4;      /* response format */
3364                         agentreq = snewn(4 + len, char);
3365                         PUT_32BIT(agentreq, len);
3366                         q = agentreq + 4;
3367                         *q++ = SSH1_AGENTC_RSA_CHALLENGE;
3368                         PUT_32BIT(q, bignum_bitcount(s->key.modulus));
3369                         q += 4;
3370                         q += ssh1_write_bignum(q, s->key.exponent);
3371                         q += ssh1_write_bignum(q, s->key.modulus);
3372                         q += ssh1_write_bignum(q, s->challenge);
3373                         memcpy(q, s->session_id, 16);
3374                         q += 16;
3375                         PUT_32BIT(q, 1);        /* response format */
3376                         if (!agent_query(agentreq, len + 4, &vret, &retlen,
3377                                          ssh_agent_callback, ssh)) {
3378                             sfree(agentreq);
3379                             do {
3380                                 crReturn(0);
3381                                 if (pktin) {
3382                                     bombout(("Unexpected data from server"
3383                                              " while waiting for agent"
3384                                              " response"));
3385                                     crStop(0);
3386                                 }
3387                             } while (pktin || inlen > 0);
3388                             vret = ssh->agent_response;
3389                             retlen = ssh->agent_response_len;
3390                         } else
3391                             sfree(agentreq);
3392                         ret = vret;
3393                         if (ret) {
3394                             if (ret[4] == SSH1_AGENT_RSA_RESPONSE) {
3395                                 logevent("Sending Pageant's response");
3396                                 send_packet(ssh, SSH1_CMSG_AUTH_RSA_RESPONSE,
3397                                             PKT_DATA, ret + 5, 16,
3398                                             PKT_END);
3399                                 sfree(ret);
3400                                 crWaitUntil(pktin);
3401                                 if (pktin->type == SSH1_SMSG_SUCCESS) {
3402                                     logevent
3403                                         ("Pageant's response accepted");
3404                                     if (flags & FLAG_VERBOSE) {
3405                                         c_write_str(ssh, "Authenticated using"
3406                                                     " RSA key \"");
3407                                         c_write(ssh, s->commentp,
3408                                                 s->commentlen);
3409                                         c_write_str(ssh, "\" from agent\r\n");
3410                                     }
3411                                     s->authed = TRUE;
3412                                 } else
3413                                     logevent
3414                                         ("Pageant's response not accepted");
3415                             } else {
3416                                 logevent
3417                                     ("Pageant failed to answer challenge");
3418                                 sfree(ret);
3419                             }
3420                         } else {
3421                             logevent("No reply received from Pageant");
3422                         }
3423                     }
3424                     freebn(s->key.exponent);
3425                     freebn(s->key.modulus);
3426                     freebn(s->challenge);
3427                     if (s->authed)
3428                         break;
3429                 }
3430                 sfree(s->response);
3431             }
3432             if (s->authed)
3433                 break;
3434         }
3435         if (!filename_is_null(ssh->cfg.keyfile) && !s->tried_publickey)
3436             s->pwpkt_type = SSH1_CMSG_AUTH_RSA;
3437
3438         if (ssh->cfg.try_tis_auth &&
3439             (s->supported_auths_mask & (1 << SSH1_AUTH_TIS)) &&
3440             !s->tis_auth_refused) {
3441             s->pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
3442             logevent("Requested TIS authentication");
3443             send_packet(ssh, SSH1_CMSG_AUTH_TIS, PKT_END);
3444             crWaitUntil(pktin);
3445             if (pktin->type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
3446                 logevent("TIS authentication declined");
3447                 if (flags & FLAG_INTERACTIVE)
3448                     c_write_str(ssh, "TIS authentication refused.\r\n");
3449                 s->tis_auth_refused = 1;
3450                 continue;
3451             } else {
3452                 char *challenge;
3453                 int challengelen;
3454
3455                 ssh_pkt_getstring(pktin, &challenge, &challengelen);
3456                 if (!challenge) {
3457                     bombout(("TIS challenge packet was badly formed"));
3458                     crStop(0);
3459                 }
3460                 c_write_str(ssh, "Using TIS authentication.\r\n");
3461                 logevent("Received TIS challenge");
3462                 if (challengelen > sizeof(s->prompt) - 1)
3463                     challengelen = sizeof(s->prompt) - 1;/* prevent overrun */
3464                 memcpy(s->prompt, challenge, challengelen);
3465                 /* Prompt heuristic comes from OpenSSH */
3466                 strncpy(s->prompt + challengelen,
3467                         memchr(s->prompt, '\n', challengelen) ?
3468                         "": "\r\nResponse: ",
3469                         (sizeof s->prompt) - challengelen);
3470                 s->prompt[(sizeof s->prompt) - 1] = '\0';
3471             }
3472         }
3473         if (ssh->cfg.try_tis_auth &&
3474             (s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
3475             !s->ccard_auth_refused) {
3476             s->pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
3477             logevent("Requested CryptoCard authentication");
3478             send_packet(ssh, SSH1_CMSG_AUTH_CCARD, PKT_END);
3479             crWaitUntil(pktin);
3480             if (pktin->type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
3481                 logevent("CryptoCard authentication declined");
3482                 c_write_str(ssh, "CryptoCard authentication refused.\r\n");
3483                 s->ccard_auth_refused = 1;
3484                 continue;
3485             } else {
3486                 char *challenge;
3487                 int challengelen;
3488
3489                 ssh_pkt_getstring(pktin, &challenge, &challengelen);
3490                 if (!challenge) {
3491                     bombout(("CryptoCard challenge packet was badly formed"));
3492                     crStop(0);
3493                 }
3494                 c_write_str(ssh, "Using CryptoCard authentication.\r\n");
3495                 logevent("Received CryptoCard challenge");
3496                 if (challengelen > sizeof(s->prompt) - 1)
3497                     challengelen = sizeof(s->prompt) - 1;/* prevent overrun */
3498                 memcpy(s->prompt, challenge, challengelen);
3499                 strncpy(s->prompt + challengelen,
3500                         memchr(s->prompt, '\n', challengelen) ?
3501                         "" : "\r\nResponse: ",
3502                         sizeof(s->prompt) - challengelen);
3503                 s->prompt[sizeof(s->prompt) - 1] = '\0';
3504             }
3505         }
3506         if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
3507             sprintf(s->prompt, "%.90s@%.90s's password: ",
3508                     s->username, ssh->savedhost);
3509         }
3510         if (s->pwpkt_type == SSH1_CMSG_AUTH_RSA) {
3511             char *comment = NULL;
3512             int type;
3513             if (flags & FLAG_VERBOSE)
3514                 c_write_str(ssh, "Trying public key authentication.\r\n");
3515             logeventf(ssh, "Trying public key \"%s\"",
3516                       filename_to_str(&ssh->cfg.keyfile));
3517             type = key_type(&ssh->cfg.keyfile);
3518             if (type != SSH_KEYTYPE_SSH1) {
3519                 char *msg = dupprintf("Key is of wrong type (%s)",
3520                                       key_type_to_str(type));
3521                 logevent(msg);
3522                 c_write_str(ssh, msg);
3523                 c_write_str(ssh, "\r\n");
3524                 sfree(msg);
3525                 s->tried_publickey = 1;
3526                 continue;
3527             }
3528             if (!rsakey_encrypted(&ssh->cfg.keyfile, &comment)) {
3529                 if (flags & FLAG_VERBOSE)
3530                     c_write_str(ssh, "No passphrase required.\r\n");
3531                 goto tryauth;
3532             }
3533             sprintf(s->prompt, "Passphrase for key \"%.100s\": ", comment);
3534             sfree(comment);
3535         }
3536
3537         /*
3538          * Show password prompt, having first obtained it via a TIS
3539          * or CryptoCard exchange if we're doing TIS or CryptoCard
3540          * authentication.
3541          */
3542         if (ssh_get_line) {
3543             if (!ssh_get_line(s->prompt, s->password,
3544                               sizeof(s->password), TRUE)) {
3545                 /*
3546                  * get_line failed to get a password (for example
3547                  * because one was supplied on the command line
3548                  * which has already failed to work). Terminate.
3549                  */
3550                 ssh_disconnect(ssh, NULL, "Unable to authenticate", 0, FALSE);
3551                 crStop(1);
3552             }
3553         } else {
3554             /* Prompt may have come from server. We've munged it a bit, so
3555              * we know it to be zero-terminated at least once. */
3556             int ret;                   /* need not be saved over crReturn */
3557             c_write_untrusted(ssh, s->prompt, strlen(s->prompt));
3558             s->pos = 0;
3559
3560             setup_userpass_input(ssh, s->password, sizeof(s->password), 0);
3561             do {
3562                 crWaitUntil(!pktin);
3563                 ret = process_userpass_input(ssh, in, inlen);
3564             } while (ret == 0);
3565             if (ret < 0)
3566                 cleanup_exit(0);
3567             c_write_str(ssh, "\r\n");
3568         }
3569
3570       tryauth:
3571         if (s->pwpkt_type == SSH1_CMSG_AUTH_RSA) {
3572             /*
3573              * Try public key authentication with the specified
3574              * key file.
3575              */
3576             s->tried_publickey = 1;
3577             
3578             {
3579                 const char *error = NULL;
3580                 int ret = loadrsakey(&ssh->cfg.keyfile, &s->key, s->password,
3581                                      &error);
3582                 if (ret == 0) {
3583                     c_write_str(ssh, "Couldn't load private key from ");
3584                     c_write_str(ssh, filename_to_str(&ssh->cfg.keyfile));
3585                     c_write_str(ssh, " (");
3586                     c_write_str(ssh, error);
3587                     c_write_str(ssh, ").\r\n");
3588                     continue;          /* go and try password */
3589                 }
3590                 if (ret == -1) {
3591                     c_write_str(ssh, "Wrong passphrase.\r\n");
3592                     s->tried_publickey = 0;
3593                     continue;          /* try again */
3594                 }
3595             }
3596
3597             /*
3598              * Send a public key attempt.
3599              */
3600             send_packet(ssh, SSH1_CMSG_AUTH_RSA,
3601                         PKT_BIGNUM, s->key.modulus, PKT_END);
3602
3603             crWaitUntil(pktin);
3604             if (pktin->type == SSH1_SMSG_FAILURE) {
3605                 c_write_str(ssh, "Server refused our public key.\r\n");
3606                 continue;              /* go and try password */
3607             }
3608             if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
3609                 bombout(("Bizarre response to offer of public key"));
3610                 crStop(0);
3611             }
3612
3613             {
3614                 int i;
3615                 unsigned char buffer[32];
3616                 Bignum challenge, response;
3617
3618                 if ((challenge = ssh1_pkt_getmp(pktin)) == NULL) {
3619                     bombout(("Server's RSA challenge was badly formatted"));
3620                     crStop(0);
3621                 }
3622                 response = rsadecrypt(challenge, &s->key);
3623                 freebn(s->key.private_exponent);/* burn the evidence */
3624
3625                 for (i = 0; i < 32; i++) {
3626                     buffer[i] = bignum_byte(response, 31 - i);
3627                 }
3628
3629                 MD5Init(&md5c);
3630                 MD5Update(&md5c, buffer, 32);
3631                 MD5Update(&md5c, s->session_id, 16);
3632                 MD5Final(buffer, &md5c);
3633
3634                 send_packet(ssh, SSH1_CMSG_AUTH_RSA_RESPONSE,
3635                             PKT_DATA, buffer, 16, PKT_END);
3636
3637                 freebn(challenge);
3638                 freebn(response);
3639             }
3640
3641             crWaitUntil(pktin);
3642             if (pktin->type == SSH1_SMSG_FAILURE) {
3643                 if (flags & FLAG_VERBOSE)
3644                     c_write_str(ssh, "Failed to authenticate with"
3645                                 " our public key.\r\n");
3646                 continue;              /* go and try password */
3647             } else if (pktin->type != SSH1_SMSG_SUCCESS) {
3648                 bombout(("Bizarre response to RSA authentication response"));
3649                 crStop(0);
3650             }
3651
3652             break;                     /* we're through! */
3653         } else {
3654             if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
3655                 /*
3656                  * Defence against traffic analysis: we send a
3657                  * whole bunch of packets containing strings of
3658                  * different lengths. One of these strings is the
3659                  * password, in a SSH1_CMSG_AUTH_PASSWORD packet.
3660                  * The others are all random data in
3661                  * SSH1_MSG_IGNORE packets. This way a passive
3662                  * listener can't tell which is the password, and
3663                  * hence can't deduce the password length.
3664                  * 
3665                  * Anybody with a password length greater than 16
3666                  * bytes is going to have enough entropy in their
3667                  * password that a listener won't find it _that_
3668                  * much help to know how long it is. So what we'll
3669                  * do is:
3670                  * 
3671                  *  - if password length < 16, we send 15 packets
3672                  *    containing string lengths 1 through 15
3673                  * 
3674                  *  - otherwise, we let N be the nearest multiple
3675                  *    of 8 below the password length, and send 8
3676                  *    packets containing string lengths N through
3677                  *    N+7. This won't obscure the order of
3678                  *    magnitude of the password length, but it will
3679                  *    introduce a bit of extra uncertainty.
3680                  * 
3681                  * A few servers (the old 1.2.18 through 1.2.22)
3682                  * can't deal with SSH1_MSG_IGNORE. For these
3683                  * servers, we need an alternative defence. We make
3684                  * use of the fact that the password is interpreted
3685                  * as a C string: so we can append a NUL, then some
3686                  * random data.
3687                  * 
3688                  * One server (a Cisco one) can deal with neither
3689                  * SSH1_MSG_IGNORE _nor_ a padded password string.
3690                  * For this server we are left with no defences
3691                  * against password length sniffing.
3692                  */
3693                 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE)) {
3694                     /*
3695                      * The server can deal with SSH1_MSG_IGNORE, so
3696                      * we can use the primary defence.
3697                      */
3698                     int bottom, top, pwlen, i;
3699                     char *randomstr;
3700
3701                     pwlen = strlen(s->password);
3702                     if (pwlen < 16) {
3703                         bottom = 0;    /* zero length passwords are OK! :-) */
3704                         top = 15;
3705                     } else {
3706                         bottom = pwlen & ~7;
3707                         top = bottom + 7;
3708                     }
3709
3710                     assert(pwlen >= bottom && pwlen <= top);
3711
3712                     randomstr = snewn(top + 1, char);
3713
3714                     for (i = bottom; i <= top; i++) {
3715                         if (i == pwlen) {
3716                             defer_packet(ssh, s->pwpkt_type,
3717                                          PKTT_PASSWORD, PKT_STR, s->password,
3718                                          PKTT_OTHER, PKT_END);
3719                         } else {
3720                             for (j = 0; j < i; j++) {
3721                                 do {
3722                                     randomstr[j] = random_byte();
3723                                 } while (randomstr[j] == '\0');
3724                             }
3725                             randomstr[i] = '\0';
3726                             defer_packet(ssh, SSH1_MSG_IGNORE,
3727                                          PKT_STR, randomstr, PKT_END);
3728                         }
3729                     }
3730                     logevent("Sending password with camouflage packets");
3731                     ssh_pkt_defersend(ssh);
3732                     sfree(randomstr);
3733                 } 
3734                 else if (!(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
3735                     /*
3736                      * The server can't deal with SSH1_MSG_IGNORE
3737                      * but can deal with padded passwords, so we
3738                      * can use the secondary defence.
3739                      */
3740                     char string[64];
3741                     char *ss;
3742                     int len;
3743
3744                     len = strlen(s->password);
3745                     if (len < sizeof(string)) {
3746                         ss = string;
3747                         strcpy(string, s->password);
3748                         len++;         /* cover the zero byte */
3749                         while (len < sizeof(string)) {
3750                             string[len++] = (char) random_byte();
3751                         }
3752                     } else {
3753                         ss = s->password;
3754                     }
3755                     logevent("Sending length-padded password");
3756                     send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
3757                                 PKT_INT, len, PKT_DATA, ss, len,
3758                                 PKTT_OTHER, PKT_END);
3759                 } else {
3760                     /*
3761                      * The server has _both_
3762                      * BUG_CHOKES_ON_SSH1_IGNORE and
3763                      * BUG_NEEDS_SSH1_PLAIN_PASSWORD. There is
3764                      * therefore nothing we can do.
3765                      */
3766                     int len;
3767                     len = strlen(s->password);
3768                     logevent("Sending unpadded password");
3769                     send_packet(ssh, s->pwpkt_type,
3770                                 PKTT_PASSWORD, PKT_INT, len,
3771                                 PKT_DATA, s->password, len,
3772                                 PKTT_OTHER, PKT_END);
3773                 }
3774             } else {
3775                 send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
3776                             PKT_STR, s->password, PKTT_OTHER, PKT_END);
3777             }
3778         }
3779         logevent("Sent password");
3780         memset(s->password, 0, strlen(s->password));
3781         crWaitUntil(pktin);
3782         if (pktin->type == SSH1_SMSG_FAILURE) {
3783             if (flags & FLAG_VERBOSE)
3784                 c_write_str(ssh, "Access denied\r\n");
3785             logevent("Authentication refused");
3786         } else if (pktin->type != SSH1_SMSG_SUCCESS) {
3787             bombout(("Strange packet received, type %d", pktin->type));
3788             crStop(0);
3789         }
3790     }
3791
3792     logevent("Authentication successful");
3793
3794     crFinish(1);
3795 }
3796
3797 void sshfwd_close(struct ssh_channel *c)
3798 {
3799     Ssh ssh = c->ssh;
3800
3801     if (ssh->state == SSH_STATE_CLOSED)
3802         return;
3803
3804     if (c && !c->closes) {
3805         /*
3806          * If halfopen is true, we have sent
3807          * CHANNEL_OPEN for this channel, but it hasn't even been
3808          * acknowledged by the server. So we must set a close flag
3809          * on it now, and then when the server acks the channel
3810          * open, we can close it then.
3811          */
3812         if (!c->halfopen) {
3813             if (ssh->version == 1) {
3814                 send_packet(ssh, SSH1_MSG_CHANNEL_CLOSE, PKT_INT, c->remoteid,
3815                             PKT_END);
3816             } else {
3817                 struct Packet *pktout;
3818                 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
3819                 ssh2_pkt_adduint32(pktout, c->remoteid);
3820                 ssh2_pkt_send(ssh, pktout);
3821             }
3822         }
3823         c->closes = 1;                 /* sent MSG_CLOSE */
3824         if (c->type == CHAN_X11) {
3825             c->u.x11.s = NULL;
3826             logevent("Forwarded X11 connection terminated");
3827         } else if (c->type == CHAN_SOCKDATA ||
3828                    c->type == CHAN_SOCKDATA_DORMANT) {
3829             c->u.pfd.s = NULL;
3830             logevent("Forwarded port closed");
3831         }
3832     }
3833 }
3834
3835 int sshfwd_write(struct ssh_channel *c, char *buf, int len)
3836 {
3837     Ssh ssh = c->ssh;
3838
3839     if (ssh->state == SSH_STATE_CLOSED)
3840         return 0;
3841
3842     if (ssh->version == 1) {
3843         send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
3844                     PKT_INT, c->remoteid,
3845                     PKTT_DATA,
3846                     PKT_INT, len, PKT_DATA, buf, len,
3847                     PKTT_OTHER, PKT_END);
3848         /*
3849          * In SSH-1 we can return 0 here - implying that forwarded
3850          * connections are never individually throttled - because
3851          * the only circumstance that can cause throttling will be
3852          * the whole SSH connection backing up, in which case
3853          * _everything_ will be throttled as a whole.
3854          */
3855         return 0;
3856     } else {
3857         ssh2_add_channel_data(c, buf, len);
3858         return ssh2_try_send(c);
3859     }
3860 }
3861
3862 void sshfwd_unthrottle(struct ssh_channel *c, int bufsize)
3863 {
3864     Ssh ssh = c->ssh;
3865
3866     if (ssh->state == SSH_STATE_CLOSED)
3867         return;
3868
3869     if (ssh->version == 1) {
3870         if (c->v.v1.throttling && bufsize < SSH1_BUFFER_LIMIT) {
3871             c->v.v1.throttling = 0;
3872             ssh1_throttle(ssh, -1);
3873         }
3874     } else {
3875         ssh2_set_window(c, OUR_V2_WINSIZE - bufsize);
3876     }
3877 }
3878
3879 static void ssh_queueing_handler(Ssh ssh, struct Packet *pktin)
3880 {
3881     struct queued_handler *qh = ssh->qhead;
3882
3883     assert(qh != NULL);
3884
3885     assert(pktin->type == qh->msg1 || pktin->type == qh->msg2);
3886
3887     if (qh->msg1 > 0) {
3888         assert(ssh->packet_dispatch[qh->msg1] == ssh_queueing_handler);
3889         ssh->packet_dispatch[qh->msg1] = NULL;
3890     }
3891     if (qh->msg2 > 0) {
3892         assert(ssh->packet_dispatch[qh->msg2] == ssh_queueing_handler);
3893         ssh->packet_dispatch[qh->msg2] = NULL;
3894     }
3895
3896     if (qh->next) {
3897         ssh->qhead = qh->next;
3898
3899         if (ssh->qhead->msg1 > 0) {
3900             assert(ssh->packet_dispatch[ssh->qhead->msg1] == NULL);
3901             ssh->packet_dispatch[ssh->qhead->msg1] = ssh_queueing_handler;
3902         }
3903         if (ssh->qhead->msg2 > 0) {
3904             assert(ssh->packet_dispatch[ssh->qhead->msg2] == NULL);
3905             ssh->packet_dispatch[ssh->qhead->msg2] = ssh_queueing_handler;
3906         }
3907     } else {
3908         ssh->qhead = ssh->qtail = NULL;
3909         ssh->packet_dispatch[pktin->type] = NULL;
3910     }
3911
3912     qh->handler(ssh, pktin, qh->ctx);
3913
3914     sfree(qh);
3915 }
3916
3917 static void ssh_queue_handler(Ssh ssh, int msg1, int msg2,
3918                               chandler_fn_t handler, void *ctx)
3919 {
3920     struct queued_handler *qh;
3921
3922     qh = snew(struct queued_handler);
3923     qh->msg1 = msg1;
3924     qh->msg2 = msg2;
3925     qh->handler = handler;
3926     qh->ctx = ctx;
3927     qh->next = NULL;
3928
3929     if (ssh->qtail == NULL) {
3930         ssh->qhead = qh;
3931
3932         if (qh->msg1 > 0) {
3933             assert(ssh->packet_dispatch[qh->msg1] == NULL);
3934             ssh->packet_dispatch[qh->msg1] = ssh_queueing_handler;
3935         }
3936         if (qh->msg2 > 0) {
3937             assert(ssh->packet_dispatch[qh->msg2] == NULL);
3938             ssh->packet_dispatch[qh->msg2] = ssh_queueing_handler;
3939         }
3940     } else {
3941         ssh->qtail->next = qh;
3942     }
3943     ssh->qtail = qh;
3944 }
3945
3946 static void ssh_rportfwd_succfail(Ssh ssh, struct Packet *pktin, void *ctx)
3947 {
3948     struct ssh_rportfwd *rpf, *pf = (struct ssh_rportfwd *)ctx;
3949
3950     if (pktin->type == (ssh->version == 1 ? SSH1_SMSG_SUCCESS :
3951                         SSH2_MSG_REQUEST_SUCCESS)) {
3952         logeventf(ssh, "Remote port forwarding from %s enabled",
3953                   pf->sportdesc);
3954     } else {
3955         logeventf(ssh, "Remote port forwarding from %s refused",
3956                   pf->sportdesc);
3957
3958         rpf = del234(ssh->rportfwds, pf);
3959         assert(rpf == pf);
3960         free_rportfwd(pf);
3961     }
3962 }
3963
3964 static void ssh_setup_portfwd(Ssh ssh, const Config *cfg)
3965 {
3966     const char *portfwd_strptr = cfg->portfwd;
3967     struct ssh_portfwd *epf;
3968     int i;
3969
3970     if (!ssh->portfwds) {
3971         ssh->portfwds = newtree234(ssh_portcmp);
3972     } else {
3973         /*
3974          * Go through the existing port forwardings and tag them
3975          * with status==DESTROY. Any that we want to keep will be
3976          * re-enabled (status==KEEP) as we go through the
3977          * configuration and find out which bits are the same as
3978          * they were before.
3979          */
3980         struct ssh_portfwd *epf;
3981         int i;
3982         for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
3983             epf->status = DESTROY;
3984     }
3985
3986     while (*portfwd_strptr) {
3987         char address_family, type;
3988         int sport,dport,sserv,dserv;
3989         char sports[256], dports[256], saddr[256], host[256];
3990         int n;
3991
3992         address_family = 'A';
3993         type = 'L';
3994         if (*portfwd_strptr == 'A' ||
3995             *portfwd_strptr == '4' ||
3996             *portfwd_strptr == '6')
3997             address_family = *portfwd_strptr++;
3998         if (*portfwd_strptr == 'L' ||
3999             *portfwd_strptr == 'R' ||
4000             *portfwd_strptr == 'D')
4001             type = *portfwd_strptr++;
4002
4003         saddr[0] = '\0';
4004
4005         n = 0;
4006         while (*portfwd_strptr && *portfwd_strptr != '\t') {
4007             if (*portfwd_strptr == ':') {
4008                 /*
4009                  * We've seen a colon in the middle of the
4010                  * source port number. This means that
4011                  * everything we've seen until now is the
4012                  * source _address_, so we'll move it into
4013                  * saddr and start sports from the beginning
4014                  * again.
4015                  */
4016                 portfwd_strptr++;
4017                 sports[n] = '\0';
4018                 if (ssh->version == 1 && type == 'R') {
4019                     logeventf(ssh, "SSH-1 cannot handle remote source address "
4020                               "spec \"%s\"; ignoring", sports);
4021                 } else
4022                     strcpy(saddr, sports);
4023                 n = 0;
4024             }
4025             if (n < lenof(sports)-1) sports[n++] = *portfwd_strptr++;
4026         }
4027         sports[n] = 0;
4028         if (type != 'D') {
4029             if (*portfwd_strptr == '\t')
4030                 portfwd_strptr++;
4031             n = 0;
4032             while (*portfwd_strptr && *portfwd_strptr != ':') {
4033                 if (n < lenof(host)-1) host[n++] = *portfwd_strptr++;
4034             }
4035             host[n] = 0;
4036             if (*portfwd_strptr == ':')
4037                 portfwd_strptr++;
4038             n = 0;
4039             while (*portfwd_strptr) {
4040                 if (n < lenof(dports)-1) dports[n++] = *portfwd_strptr++;
4041             }
4042             dports[n] = 0;
4043             portfwd_strptr++;
4044             dport = atoi(dports);
4045             dserv = 0;
4046             if (dport == 0) {
4047                 dserv = 1;
4048                 dport = net_service_lookup(dports);
4049                 if (!dport) {
4050                     logeventf(ssh, "Service lookup failed for destination"
4051                               " port \"%s\"", dports);
4052                 }
4053             }
4054         } else {
4055             while (*portfwd_strptr) portfwd_strptr++;
4056             host[0] = 0;
4057             dports[0] = 0;
4058             dport = dserv = -1;
4059             portfwd_strptr++;          /* eat the NUL and move to next one */
4060         }
4061         sport = atoi(sports);
4062         sserv = 0;
4063         if (sport == 0) {
4064             sserv = 1;
4065             sport = net_service_lookup(sports);
4066             if (!sport) {
4067                 logeventf(ssh, "Service lookup failed for source"
4068                           " port \"%s\"", sports);
4069             }
4070         }
4071         if (sport && dport) {
4072             /* Set up a description of the source port. */
4073             struct ssh_portfwd *pfrec, *epfrec;
4074
4075             pfrec = snew(struct ssh_portfwd);
4076             pfrec->type = type;
4077             pfrec->saddr = *saddr ? dupstr(saddr) : NULL;
4078             pfrec->sserv = sserv ? dupstr(sports) : NULL;
4079             pfrec->sport = sport;
4080             pfrec->daddr = *host ? dupstr(host) : NULL;
4081             pfrec->dserv = dserv ? dupstr(dports) : NULL;
4082             pfrec->dport = dport;
4083             pfrec->local = NULL;
4084             pfrec->remote = NULL;
4085             pfrec->addressfamily = (address_family == '4' ? ADDRTYPE_IPV4 :
4086                                     address_family == '6' ? ADDRTYPE_IPV6 :
4087                                     ADDRTYPE_UNSPEC);
4088
4089             epfrec = add234(ssh->portfwds, pfrec);
4090             if (epfrec != pfrec) {
4091                 /*
4092                  * We already have a port forwarding with precisely
4093                  * these parameters. Hence, no need to do anything;
4094                  * simply tag the existing one as KEEP.
4095                  */
4096                 epfrec->status = KEEP;
4097                 free_portfwd(pfrec);
4098             } else {
4099                 pfrec->status = CREATE;
4100             }
4101         }
4102     }
4103
4104     /*
4105      * Now go through and destroy any port forwardings which were
4106      * not re-enabled.
4107      */
4108     for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
4109         if (epf->status == DESTROY) {
4110             char *message;
4111
4112             message = dupprintf("%s port forwarding from %s%s%d",
4113                                 epf->type == 'L' ? "local" :
4114                                 epf->type == 'R' ? "remote" : "dynamic",
4115                                 epf->saddr ? epf->saddr : "",
4116                                 epf->saddr ? ":" : "",
4117                                 epf->sport);
4118
4119             if (epf->type != 'D') {
4120                 char *msg2 = dupprintf("%s to %s:%d", message,
4121                                        epf->daddr, epf->dport);
4122                 sfree(message);
4123                 message = msg2;
4124             }
4125
4126             logeventf(ssh, "Cancelling %s", message);
4127             sfree(message);
4128
4129             if (epf->remote) {
4130                 struct ssh_rportfwd *rpf = epf->remote;
4131                 struct Packet *pktout;
4132
4133                 /*
4134                  * Cancel the port forwarding at the server
4135                  * end.
4136                  */
4137                 if (ssh->version == 1) {
4138                     /*
4139                      * We cannot cancel listening ports on the
4140                      * server side in SSH-1! There's no message
4141                      * to support it. Instead, we simply remove
4142                      * the rportfwd record from the local end
4143                      * so that any connections the server tries
4144                      * to make on it are rejected.
4145                      */
4146                 } else {
4147                     pktout = ssh2_pkt_init(SSH2_MSG_GLOBAL_REQUEST);
4148                     ssh2_pkt_addstring(pktout, "cancel-tcpip-forward");
4149                     ssh2_pkt_addbool(pktout, 0);/* _don't_ want reply */
4150                     if (epf->saddr) {
4151                         ssh2_pkt_addstring(pktout, epf->saddr);
4152                     } else if (ssh->cfg.rport_acceptall) {
4153                         /* XXX: ssh->cfg.rport_acceptall may not represent
4154                          * what was used to open the original connection,
4155                          * since it's reconfigurable. */
4156                         ssh2_pkt_addstring(pktout, "0.0.0.0");
4157                     } else {
4158                         ssh2_pkt_addstring(pktout, "127.0.0.1");
4159                     }
4160                     ssh2_pkt_adduint32(pktout, epf->sport);
4161                     ssh2_pkt_send(ssh, pktout);
4162                 }
4163
4164                 del234(ssh->rportfwds, rpf);
4165                 free_rportfwd(rpf);
4166             } else if (epf->local) {
4167                 pfd_terminate(epf->local);
4168             }
4169
4170             delpos234(ssh->portfwds, i);
4171             free_portfwd(epf);
4172             i--;                       /* so we don't skip one in the list */
4173         }
4174
4175     /*
4176      * And finally, set up any new port forwardings (status==CREATE).
4177      */
4178     for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
4179         if (epf->status == CREATE) {
4180             char *sportdesc, *dportdesc;
4181             sportdesc = dupprintf("%s%s%s%s%d%s",
4182                                   epf->saddr ? epf->saddr : "",
4183                                   epf->saddr ? ":" : "",
4184                                   epf->sserv ? epf->sserv : "",
4185                                   epf->sserv ? "(" : "",
4186                                   epf->sport,
4187                                   epf->sserv ? ")" : "");
4188             if (epf->type == 'D') {
4189                 dportdesc = NULL;
4190             } else {
4191                 dportdesc = dupprintf("%s:%s%s%d%s",
4192                                       epf->daddr,
4193                                       epf->dserv ? epf->dserv : "",
4194                                       epf->dserv ? "(" : "",
4195                                       epf->dport,
4196                                       epf->dserv ? ")" : "");
4197             }
4198
4199             if (epf->type == 'L') {
4200                 const char *err = pfd_addforward(epf->daddr, epf->dport,
4201                                                  epf->saddr, epf->sport,
4202                                                  ssh, cfg,
4203                                                  &epf->local,
4204                                                  epf->addressfamily);
4205
4206                 logeventf(ssh, "Local %sport %s forwarding to %s%s%s",
4207                           epf->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " :
4208                           epf->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "",
4209                           sportdesc, dportdesc,
4210                           err ? " failed: " : "", err ? err : "");
4211             } else if (epf->type == 'D') {
4212                 const char *err = pfd_addforward(NULL, -1,
4213                                                  epf->saddr, epf->sport,
4214                                                  ssh, cfg,
4215                                                  &epf->local,
4216                                                  epf->addressfamily);
4217
4218                 logeventf(ssh, "Local %sport %s SOCKS dynamic forwarding%s%s",
4219                           epf->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " :
4220                           epf->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "",
4221                           sportdesc,
4222                           err ? " failed: " : "", err ? err : "");
4223             } else {
4224                 struct ssh_rportfwd *pf;
4225
4226                 /*
4227                  * Ensure the remote port forwardings tree exists.
4228                  */
4229                 if (!ssh->rportfwds) {
4230                     if (ssh->version == 1)
4231                         ssh->rportfwds = newtree234(ssh_rportcmp_ssh1);
4232                     else
4233                         ssh->rportfwds = newtree234(ssh_rportcmp_ssh2);
4234                 }
4235
4236                 pf = snew(struct ssh_rportfwd);
4237                 strncpy(pf->dhost, epf->daddr, lenof(pf->dhost)-1);
4238                 pf->dhost[lenof(pf->dhost)-1] = '\0';
4239                 pf->dport = epf->dport;
4240                 pf->sport = epf->sport;
4241                 if (add234(ssh->rportfwds, pf) != pf) {
4242                     logeventf(ssh, "Duplicate remote port forwarding to %s:%d",
4243                               epf->daddr, epf->dport);
4244                     sfree(pf);
4245                 } else {
4246                     logeventf(ssh, "Requesting remote port %s"
4247                               " forward to %s", sportdesc, dportdesc);
4248
4249                     pf->sportdesc = sportdesc;
4250                     sportdesc = NULL;
4251                     epf->remote = pf;
4252                     pf->pfrec = epf;
4253
4254                     if (ssh->version == 1) {
4255                         send_packet(ssh, SSH1_CMSG_PORT_FORWARD_REQUEST,
4256                                     PKT_INT, epf->sport,
4257                                     PKT_STR, epf->daddr,
4258                                     PKT_INT, epf->dport,
4259                                     PKT_END);
4260                         ssh_queue_handler(ssh, SSH1_SMSG_SUCCESS,
4261                                           SSH1_SMSG_FAILURE,
4262                                           ssh_rportfwd_succfail, pf);
4263                     } else {
4264                         struct Packet *pktout;
4265                         pktout = ssh2_pkt_init(SSH2_MSG_GLOBAL_REQUEST);
4266                         ssh2_pkt_addstring(pktout, "tcpip-forward");
4267                         ssh2_pkt_addbool(pktout, 1);/* want reply */
4268                         if (epf->saddr) {
4269                             ssh2_pkt_addstring(pktout, epf->saddr);
4270                         } else if (cfg->rport_acceptall) {
4271                             ssh2_pkt_addstring(pktout, "0.0.0.0");
4272                         } else {
4273                             ssh2_pkt_addstring(pktout, "127.0.0.1");
4274                         }
4275                         ssh2_pkt_adduint32(pktout, epf->sport);
4276                         ssh2_pkt_send(ssh, pktout);
4277
4278                         ssh_queue_handler(ssh, SSH2_MSG_REQUEST_SUCCESS,
4279                                           SSH2_MSG_REQUEST_FAILURE,
4280                                           ssh_rportfwd_succfail, pf);
4281                     }
4282                 }
4283             }
4284             sfree(sportdesc);
4285             sfree(dportdesc);
4286         }
4287 }
4288
4289 static void ssh1_smsg_stdout_stderr_data(Ssh ssh, struct Packet *pktin)
4290 {
4291     char *string;
4292     int stringlen, bufsize;
4293
4294     ssh_pkt_getstring(pktin, &string, &stringlen);
4295     if (string == NULL) {
4296         bombout(("Incoming terminal data packet was badly formed"));
4297         return;
4298     }
4299
4300     bufsize = from_backend(ssh->frontend, pktin->type == SSH1_SMSG_STDERR_DATA,
4301                            string, stringlen);
4302     if (!ssh->v1_stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) {
4303         ssh->v1_stdout_throttling = 1;
4304         ssh1_throttle(ssh, +1);
4305     }
4306 }
4307
4308 static void ssh1_smsg_x11_open(Ssh ssh, struct Packet *pktin)
4309 {
4310     /* Remote side is trying to open a channel to talk to our
4311      * X-Server. Give them back a local channel number. */
4312     struct ssh_channel *c;
4313     int remoteid = ssh_pkt_getuint32(pktin);
4314
4315     logevent("Received X11 connect request");
4316     /* Refuse if X11 forwarding is disabled. */
4317     if (!ssh->X11_fwd_enabled) {
4318         send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4319                     PKT_INT, remoteid, PKT_END);
4320         logevent("Rejected X11 connect request");
4321     } else {
4322         c = snew(struct ssh_channel);
4323         c->ssh = ssh;
4324
4325         if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c,
4326                      ssh->x11auth, NULL, -1, &ssh->cfg) != NULL) {
4327             logevent("Opening X11 forward connection failed");
4328             sfree(c);
4329             send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4330                         PKT_INT, remoteid, PKT_END);
4331         } else {
4332             logevent
4333                 ("Opening X11 forward connection succeeded");
4334             c->remoteid = remoteid;
4335             c->halfopen = FALSE;
4336             c->localid = alloc_channel_id(ssh);
4337             c->closes = 0;
4338             c->v.v1.throttling = 0;
4339             c->type = CHAN_X11; /* identify channel type */
4340             add234(ssh->channels, c);
4341             send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4342                         PKT_INT, c->remoteid, PKT_INT,
4343                         c->localid, PKT_END);
4344             logevent("Opened X11 forward channel");
4345         }
4346     }
4347 }
4348
4349 static void ssh1_smsg_agent_open(Ssh ssh, struct Packet *pktin)
4350 {
4351     /* Remote side is trying to open a channel to talk to our
4352      * agent. Give them back a local channel number. */
4353     struct ssh_channel *c;
4354     int remoteid = ssh_pkt_getuint32(pktin);
4355
4356     /* Refuse if agent forwarding is disabled. */
4357     if (!ssh->agentfwd_enabled) {
4358         send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4359                     PKT_INT, remoteid, PKT_END);
4360     } else {
4361         c = snew(struct ssh_channel);
4362         c->ssh = ssh;
4363         c->remoteid = remoteid;
4364         c->halfopen = FALSE;
4365         c->localid = alloc_channel_id(ssh);
4366         c->closes = 0;
4367         c->v.v1.throttling = 0;
4368         c->type = CHAN_AGENT;   /* identify channel type */
4369         c->u.a.lensofar = 0;
4370         add234(ssh->channels, c);
4371         send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4372                     PKT_INT, c->remoteid, PKT_INT, c->localid,
4373                     PKT_END);
4374     }
4375 }
4376
4377 static void ssh1_msg_port_open(Ssh ssh, struct Packet *pktin)
4378 {
4379     /* Remote side is trying to open a channel to talk to a
4380      * forwarded port. Give them back a local channel number. */
4381     struct ssh_channel *c;
4382     struct ssh_rportfwd pf, *pfp;
4383     int remoteid;
4384     int hostsize, port;
4385     char *host;
4386     const char *e;
4387     c = snew(struct ssh_channel);
4388     c->ssh = ssh;
4389
4390     remoteid = ssh_pkt_getuint32(pktin);
4391     ssh_pkt_getstring(pktin, &host, &hostsize);
4392     port = ssh_pkt_getuint32(pktin);
4393
4394     if (hostsize >= lenof(pf.dhost))
4395         hostsize = lenof(pf.dhost)-1;
4396     memcpy(pf.dhost, host, hostsize);
4397     pf.dhost[hostsize] = '\0';
4398     pf.dport = port;
4399     pfp = find234(ssh->rportfwds, &pf, NULL);
4400
4401     if (pfp == NULL) {
4402         logeventf(ssh, "Rejected remote port open request for %s:%d",
4403                   pf.dhost, port);
4404         send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4405                     PKT_INT, remoteid, PKT_END);
4406     } else {
4407         logeventf(ssh, "Received remote port open request for %s:%d",
4408                   pf.dhost, port);
4409         e = pfd_newconnect(&c->u.pfd.s, pf.dhost, port,
4410                            c, &ssh->cfg, pfp->pfrec->addressfamily);
4411         if (e != NULL) {
4412             logeventf(ssh, "Port open failed: %s", e);
4413             sfree(c);
4414             send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4415                         PKT_INT, remoteid, PKT_END);
4416         } else {
4417             c->remoteid = remoteid;
4418             c->halfopen = FALSE;
4419             c->localid = alloc_channel_id(ssh);
4420             c->closes = 0;
4421             c->v.v1.throttling = 0;
4422             c->type = CHAN_SOCKDATA;    /* identify channel type */
4423             add234(ssh->channels, c);
4424             send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4425                         PKT_INT, c->remoteid, PKT_INT,
4426                         c->localid, PKT_END);
4427             logevent("Forwarded port opened successfully");
4428         }
4429     }
4430 }
4431
4432 static void ssh1_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
4433 {
4434     unsigned int remoteid = ssh_pkt_getuint32(pktin);
4435     unsigned int localid = ssh_pkt_getuint32(pktin);
4436     struct ssh_channel *c;
4437
4438     c = find234(ssh->channels, &remoteid, ssh_channelfind);
4439     if (c && c->type == CHAN_SOCKDATA_DORMANT) {
4440         c->remoteid = localid;
4441         c->halfopen = FALSE;
4442         c->type = CHAN_SOCKDATA;
4443         c->v.v1.throttling = 0;
4444         pfd_confirm(c->u.pfd.s);
4445     }
4446
4447     if (c && c->closes) {
4448         /*
4449          * We have a pending close on this channel,
4450          * which we decided on before the server acked
4451          * the channel open. So now we know the
4452          * remoteid, we can close it again.
4453          */
4454         send_packet(ssh, SSH1_MSG_CHANNEL_CLOSE,
4455                     PKT_INT, c->remoteid, PKT_END);
4456     }
4457 }
4458
4459 static void ssh1_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
4460 {
4461     unsigned int remoteid = ssh_pkt_getuint32(pktin);
4462     struct ssh_channel *c;
4463
4464     c = find234(ssh->channels, &remoteid, ssh_channelfind);
4465     if (c && c->type == CHAN_SOCKDATA_DORMANT) {
4466         logevent("Forwarded connection refused by server");
4467         pfd_close(c->u.pfd.s);
4468         del234(ssh->channels, c);
4469         sfree(c);
4470     }
4471 }
4472
4473 static void ssh1_msg_channel_close(Ssh ssh, struct Packet *pktin)
4474 {
4475     /* Remote side closes a channel. */
4476     unsigned i = ssh_pkt_getuint32(pktin);
4477     struct ssh_channel *c;
4478     c = find234(ssh->channels, &i, ssh_channelfind);
4479     if (c && !c->halfopen) {
4480         int closetype;
4481         closetype =
4482             (pktin->type == SSH1_MSG_CHANNEL_CLOSE ? 1 : 2);
4483
4484         if ((c->closes == 0) && (c->type == CHAN_X11)) {
4485             logevent("Forwarded X11 connection terminated");
4486             assert(c->u.x11.s != NULL);
4487             x11_close(c->u.x11.s);
4488             c->u.x11.s = NULL;
4489         }
4490         if ((c->closes == 0) && (c->type == CHAN_SOCKDATA)) {
4491             logevent("Forwarded port closed");
4492             assert(c->u.pfd.s != NULL);
4493             pfd_close(c->u.pfd.s);
4494             c->u.pfd.s = NULL;
4495         }
4496
4497         c->closes |= (closetype << 2);   /* seen this message */
4498         if (!(c->closes & closetype)) {
4499             send_packet(ssh, pktin->type, PKT_INT, c->remoteid,
4500                         PKT_END);
4501             c->closes |= closetype;      /* sent it too */
4502         }
4503
4504         if (c->closes == 15) {
4505             del234(ssh->channels, c);
4506             sfree(c);
4507         }
4508     } else {
4509         bombout(("Received CHANNEL_CLOSE%s for %s channel %d\n",
4510                  pktin->type == SSH1_MSG_CHANNEL_CLOSE ? "" :
4511                  "_CONFIRMATION", c ? "half-open" : "nonexistent",
4512                  i));
4513     }
4514 }
4515
4516 static void ssh1_msg_channel_data(Ssh ssh, struct Packet *pktin)
4517 {
4518     /* Data sent down one of our channels. */
4519     int i = ssh_pkt_getuint32(pktin);
4520     char *p;
4521     int len;
4522     struct ssh_channel *c;
4523
4524     ssh_pkt_getstring(pktin, &p, &len);
4525
4526     c = find234(ssh->channels, &i, ssh_channelfind);
4527     if (c) {
4528         int bufsize = 0;
4529         switch (c->type) {
4530           case CHAN_X11:
4531             bufsize = x11_send(c->u.x11.s, p, len);
4532             break;
4533           case CHAN_SOCKDATA:
4534             bufsize = pfd_send(c->u.pfd.s, p, len);
4535             break;
4536           case CHAN_AGENT:
4537             /* Data for an agent message. Buffer it. */
4538             while (len > 0) {
4539                 if (c->u.a.lensofar < 4) {
4540                     unsigned int l = min(4 - c->u.a.lensofar, len);
4541                     memcpy(c->u.a.msglen + c->u.a.lensofar, p,
4542                            l);
4543                     p += l;
4544                     len -= l;
4545                     c->u.a.lensofar += l;
4546                 }
4547                 if (c->u.a.lensofar == 4) {
4548                     c->u.a.totallen =
4549                         4 + GET_32BIT(c->u.a.msglen);
4550                     c->u.a.message = snewn(c->u.a.totallen,
4551                                            unsigned char);
4552                     memcpy(c->u.a.message, c->u.a.msglen, 4);
4553                 }
4554                 if (c->u.a.lensofar >= 4 && len > 0) {
4555                     unsigned int l =
4556                         min(c->u.a.totallen - c->u.a.lensofar,
4557                             len);
4558                     memcpy(c->u.a.message + c->u.a.lensofar, p,
4559                            l);
4560                     p += l;
4561                     len -= l;
4562                     c->u.a.lensofar += l;
4563                 }
4564                 if (c->u.a.lensofar == c->u.a.totallen) {
4565                     void *reply;
4566                     int replylen;
4567                     if (agent_query(c->u.a.message,
4568                                     c->u.a.totallen,
4569                                     &reply, &replylen,
4570                                     ssh_agentf_callback, c))
4571                         ssh_agentf_callback(c, reply, replylen);
4572                     sfree(c->u.a.message);
4573                     c->u.a.lensofar = 0;
4574                 }
4575             }
4576             bufsize = 0;   /* agent channels never back up */
4577             break;
4578         }
4579         if (!c->v.v1.throttling && bufsize > SSH1_BUFFER_LIMIT) {
4580             c->v.v1.throttling = 1;
4581             ssh1_throttle(ssh, +1);
4582         }
4583     }
4584 }
4585
4586 static void ssh1_smsg_exit_status(Ssh ssh, struct Packet *pktin)
4587 {
4588     ssh->exitcode = ssh_pkt_getuint32(pktin);
4589     logeventf(ssh, "Server sent command exit status %d", ssh->exitcode);
4590     send_packet(ssh, SSH1_CMSG_EXIT_CONFIRMATION, PKT_END);
4591     /*
4592      * In case `helpful' firewalls or proxies tack
4593      * extra human-readable text on the end of the
4594      * session which we might mistake for another
4595      * encrypted packet, we close the session once
4596      * we've sent EXIT_CONFIRMATION.
4597      */
4598     ssh_disconnect(ssh, NULL, NULL, 0, TRUE);
4599 }
4600
4601 /* Helper function to deal with sending tty modes for REQUEST_PTY */
4602 static void ssh1_send_ttymode(void *data, char *mode, char *val)
4603 {
4604     struct Packet *pktout = (struct Packet *)data;
4605     int i = 0;
4606     unsigned int arg = 0;
4607     while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
4608     if (i == lenof(ssh_ttymodes)) return;
4609     switch (ssh_ttymodes[i].type) {
4610       case TTY_OP_CHAR:
4611         arg = ssh_tty_parse_specchar(val);
4612         break;
4613       case TTY_OP_BOOL:
4614         arg = ssh_tty_parse_boolean(val);
4615         break;
4616     }
4617     ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
4618     ssh2_pkt_addbyte(pktout, arg);
4619 }
4620
4621
4622 static void do_ssh1_connection(Ssh ssh, unsigned char *in, int inlen,
4623                                struct Packet *pktin)
4624 {
4625     crBegin(ssh->do_ssh1_connection_crstate);
4626
4627     ssh->packet_dispatch[SSH1_SMSG_STDOUT_DATA] = 
4628         ssh->packet_dispatch[SSH1_SMSG_STDERR_DATA] =
4629         ssh1_smsg_stdout_stderr_data;
4630
4631     ssh->packet_dispatch[SSH1_MSG_CHANNEL_OPEN_CONFIRMATION] =
4632         ssh1_msg_channel_open_confirmation;
4633     ssh->packet_dispatch[SSH1_MSG_CHANNEL_OPEN_FAILURE] =
4634         ssh1_msg_channel_open_failure;
4635     ssh->packet_dispatch[SSH1_MSG_CHANNEL_CLOSE] =
4636         ssh->packet_dispatch[SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION] =
4637         ssh1_msg_channel_close;
4638     ssh->packet_dispatch[SSH1_MSG_CHANNEL_DATA] = ssh1_msg_channel_data;
4639     ssh->packet_dispatch[SSH1_SMSG_EXIT_STATUS] = ssh1_smsg_exit_status;
4640
4641     if (ssh->cfg.agentfwd && agent_exists()) {
4642         logevent("Requesting agent forwarding");
4643         send_packet(ssh, SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END);
4644         do {
4645             crReturnV;
4646         } while (!pktin);
4647         if (pktin->type != SSH1_SMSG_SUCCESS
4648             && pktin->type != SSH1_SMSG_FAILURE) {
4649             bombout(("Protocol confusion"));
4650             crStopV;
4651         } else if (pktin->type == SSH1_SMSG_FAILURE) {
4652             logevent("Agent forwarding refused");
4653         } else {
4654             logevent("Agent forwarding enabled");
4655             ssh->agentfwd_enabled = TRUE;
4656             ssh->packet_dispatch[SSH1_SMSG_AGENT_OPEN] = ssh1_smsg_agent_open;
4657         }
4658     }
4659
4660     if (ssh->cfg.x11_forward) {
4661         char proto[20], data[64];
4662         logevent("Requesting X11 forwarding");
4663         ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
4664                                        data, sizeof(data), ssh->cfg.x11_auth);
4665         x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
4666         /*
4667          * Note that while we blank the X authentication data here, we don't
4668          * take any special action to blank the start of an X11 channel,
4669          * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
4670          * without having session blanking enabled is likely to leak your
4671          * cookie into the log.
4672          */
4673         if (ssh->v1_local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER) {
4674             send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
4675                         PKT_STR, proto,
4676                         PKTT_PASSWORD, PKT_STR, data, PKTT_OTHER,
4677                         PKT_INT, x11_get_screen_number(ssh->cfg.x11_display),
4678                         PKT_END);
4679         } else {
4680             send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
4681                         PKT_STR, proto,
4682                         PKTT_PASSWORD, PKT_STR, data, PKTT_OTHER, PKT_END);
4683         }
4684         do {
4685             crReturnV;
4686         } while (!pktin);
4687         if (pktin->type != SSH1_SMSG_SUCCESS
4688             && pktin->type != SSH1_SMSG_FAILURE) {
4689             bombout(("Protocol confusion"));
4690             crStopV;
4691         } else if (pktin->type == SSH1_SMSG_FAILURE) {
4692             logevent("X11 forwarding refused");
4693         } else {
4694             logevent("X11 forwarding enabled");
4695             ssh->X11_fwd_enabled = TRUE;
4696             ssh->packet_dispatch[SSH1_SMSG_X11_OPEN] = ssh1_smsg_x11_open;
4697         }
4698     }
4699
4700     ssh_setup_portfwd(ssh, &ssh->cfg);
4701     ssh->packet_dispatch[SSH1_MSG_PORT_OPEN] = ssh1_msg_port_open;
4702
4703     if (!ssh->cfg.nopty) {
4704         struct Packet *pkt;
4705         /* Unpick the terminal-speed string. */
4706         /* XXX perhaps we should allow no speeds to be sent. */
4707         ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
4708         sscanf(ssh->cfg.termspeed, "%d,%d", &ssh->ospeed, &ssh->ispeed);
4709         /* Send the pty request. */
4710         pkt = ssh1_pkt_init(SSH1_CMSG_REQUEST_PTY);
4711         ssh_pkt_addstring(pkt, ssh->cfg.termtype);
4712         ssh_pkt_adduint32(pkt, ssh->term_height);
4713         ssh_pkt_adduint32(pkt, ssh->term_width);
4714         ssh_pkt_adduint32(pkt, 0); /* width in pixels */
4715         ssh_pkt_adduint32(pkt, 0); /* height in pixels */
4716         parse_ttymodes(ssh, ssh->cfg.ttymodes,
4717                        ssh1_send_ttymode, (void *)pkt);
4718         ssh_pkt_addbyte(pkt, SSH1_TTY_OP_ISPEED);
4719         ssh_pkt_adduint32(pkt, ssh->ispeed);
4720         ssh_pkt_addbyte(pkt, SSH1_TTY_OP_OSPEED);
4721         ssh_pkt_adduint32(pkt, ssh->ospeed);
4722         ssh_pkt_addbyte(pkt, SSH_TTY_OP_END);
4723         s_wrpkt(ssh, pkt);
4724         ssh->state = SSH_STATE_INTERMED;
4725         do {
4726             crReturnV;
4727         } while (!pktin);
4728         if (pktin->type != SSH1_SMSG_SUCCESS
4729             && pktin->type != SSH1_SMSG_FAILURE) {
4730             bombout(("Protocol confusion"));
4731             crStopV;
4732         } else if (pktin->type == SSH1_SMSG_FAILURE) {
4733             c_write_str(ssh, "Server refused to allocate pty\r\n");
4734             ssh->editing = ssh->echoing = 1;
4735         }
4736         logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
4737                   ssh->ospeed, ssh->ispeed);
4738     } else {
4739         ssh->editing = ssh->echoing = 1;
4740     }
4741
4742     if (ssh->cfg.compression) {
4743         send_packet(ssh, SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);
4744         do {
4745             crReturnV;
4746         } while (!pktin);
4747         if (pktin->type != SSH1_SMSG_SUCCESS
4748             && pktin->type != SSH1_SMSG_FAILURE) {
4749             bombout(("Protocol confusion"));
4750             crStopV;
4751         } else if (pktin->type == SSH1_SMSG_FAILURE) {
4752             c_write_str(ssh, "Server refused to compress\r\n");
4753         }
4754         logevent("Started compression");
4755         ssh->v1_compressing = TRUE;
4756         ssh->cs_comp_ctx = zlib_compress_init();
4757         logevent("Initialised zlib (RFC1950) compression");
4758         ssh->sc_comp_ctx = zlib_decompress_init();
4759         logevent("Initialised zlib (RFC1950) decompression");
4760     }
4761
4762     /*
4763      * Start the shell or command.
4764      * 
4765      * Special case: if the first-choice command is an SSH-2
4766      * subsystem (hence not usable here) and the second choice
4767      * exists, we fall straight back to that.
4768      */
4769     {
4770         char *cmd = ssh->cfg.remote_cmd_ptr;
4771
4772         if (!cmd) cmd = ssh->cfg.remote_cmd;
4773         
4774         if (ssh->cfg.ssh_subsys && ssh->cfg.remote_cmd_ptr2) {
4775             cmd = ssh->cfg.remote_cmd_ptr2;
4776             ssh->fallback_cmd = TRUE;
4777         }
4778         if (*cmd)
4779             send_packet(ssh, SSH1_CMSG_EXEC_CMD, PKT_STR, cmd, PKT_END);
4780         else
4781             send_packet(ssh, SSH1_CMSG_EXEC_SHELL, PKT_END);
4782         logevent("Started session");
4783     }
4784
4785     ssh->state = SSH_STATE_SESSION;
4786     if (ssh->size_needed)
4787         ssh_size(ssh, ssh->term_width, ssh->term_height);
4788     if (ssh->eof_needed)
4789         ssh_special(ssh, TS_EOF);
4790
4791     if (ssh->ldisc)
4792         ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
4793     ssh->send_ok = 1;
4794     ssh->channels = newtree234(ssh_channelcmp);
4795     while (1) {
4796
4797         /*
4798          * By this point, most incoming packets are already being
4799          * handled by the dispatch table, and we need only pay
4800          * attention to the unusual ones.
4801          */
4802
4803         crReturnV;
4804         if (pktin) {
4805             if (pktin->type == SSH1_SMSG_SUCCESS) {
4806                 /* may be from EXEC_SHELL on some servers */
4807             } else if (pktin->type == SSH1_SMSG_FAILURE) {
4808                 /* may be from EXEC_SHELL on some servers
4809                  * if no pty is available or in other odd cases. Ignore */
4810             } else {
4811                 bombout(("Strange packet received: type %d", pktin->type));
4812                 crStopV;
4813             }
4814         } else {
4815             while (inlen > 0) {
4816                 int len = min(inlen, 512);
4817                 send_packet(ssh, SSH1_CMSG_STDIN_DATA, PKTT_DATA,
4818                             PKT_INT, len, PKT_DATA, in, len,
4819                             PKTT_OTHER, PKT_END);
4820                 in += len;
4821                 inlen -= len;
4822             }
4823         }
4824     }
4825
4826     crFinishV;
4827 }
4828
4829 /*
4830  * Handle the top-level SSH-2 protocol.
4831  */
4832 static void ssh1_msg_debug(Ssh ssh, struct Packet *pktin)
4833 {
4834     char *msg;
4835     int msglen;
4836
4837     ssh_pkt_getstring(pktin, &msg, &msglen);
4838     logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
4839 }
4840
4841 static void ssh1_msg_disconnect(Ssh ssh, struct Packet *pktin)
4842 {
4843     /* log reason code in disconnect message */
4844     char *msg;
4845     int msglen;
4846
4847     ssh_pkt_getstring(pktin, &msg, &msglen);
4848     bombout(("Server sent disconnect message:\n\"%.*s\"", msglen, msg));
4849 }
4850
4851 static void ssh_msg_ignore(Ssh ssh, struct Packet *pktin)
4852 {
4853     /* Do nothing, because we're ignoring it! Duhh. */
4854 }
4855
4856 static void ssh1_protocol_setup(Ssh ssh)
4857 {
4858     int i;
4859
4860     /*
4861      * Most messages are handled by the coroutines.
4862      */
4863     for (i = 0; i < 256; i++)
4864         ssh->packet_dispatch[i] = NULL;
4865
4866     /*
4867      * These special message types we install handlers for.
4868      */
4869     ssh->packet_dispatch[SSH1_MSG_DISCONNECT] = ssh1_msg_disconnect;
4870     ssh->packet_dispatch[SSH1_MSG_IGNORE] = ssh_msg_ignore;
4871     ssh->packet_dispatch[SSH1_MSG_DEBUG] = ssh1_msg_debug;
4872 }
4873
4874 static void ssh1_protocol(Ssh ssh, void *vin, int inlen,
4875                           struct Packet *pktin)
4876 {
4877     unsigned char *in=(unsigned char*)vin;
4878     if (ssh->state == SSH_STATE_CLOSED)
4879         return;
4880
4881     if (pktin && ssh->packet_dispatch[pktin->type]) {
4882         ssh->packet_dispatch[pktin->type](ssh, pktin);
4883         return;
4884     }
4885
4886     if (!ssh->protocol_initial_phase_done) {
4887         if (do_ssh1_login(ssh, in, inlen, pktin))
4888             ssh->protocol_initial_phase_done = TRUE;
4889         else
4890             return;
4891     }
4892
4893     do_ssh1_connection(ssh, in, inlen, pktin);
4894 }
4895
4896 /*
4897  * Utility routine for decoding comma-separated strings in KEXINIT.
4898  */
4899 static int in_commasep_string(char *needle, char *haystack, int haylen)
4900 {
4901     int needlen;
4902     if (!needle || !haystack)          /* protect against null pointers */
4903         return 0;
4904     needlen = strlen(needle);
4905     while (1) {
4906         /*
4907          * Is it at the start of the string?
4908          */
4909         if (haylen >= needlen &&       /* haystack is long enough */
4910             !memcmp(needle, haystack, needlen) &&       /* initial match */
4911             (haylen == needlen || haystack[needlen] == ',')
4912             /* either , or EOS follows */
4913             )
4914             return 1;
4915         /*
4916          * If not, search for the next comma and resume after that.
4917          * If no comma found, terminate.
4918          */
4919         while (haylen > 0 && *haystack != ',')
4920             haylen--, haystack++;
4921         if (haylen == 0)
4922             return 0;
4923         haylen--, haystack++;          /* skip over comma itself */
4924     }
4925 }
4926
4927 /*
4928  * Similar routine for checking whether we have the first string in a list.
4929  */
4930 static int first_in_commasep_string(char *needle, char *haystack, int haylen)
4931 {
4932     int needlen;
4933     if (!needle || !haystack)          /* protect against null pointers */
4934         return 0;
4935     needlen = strlen(needle);
4936     /*
4937      * Is it at the start of the string?
4938      */
4939     if (haylen >= needlen &&       /* haystack is long enough */
4940         !memcmp(needle, haystack, needlen) &&   /* initial match */
4941         (haylen == needlen || haystack[needlen] == ',')
4942         /* either , or EOS follows */
4943         )
4944         return 1;
4945     return 0;
4946 }
4947
4948
4949 /*
4950  * SSH-2 key creation method.
4951  */
4952 static void ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, char chr,
4953                        unsigned char *keyspace)
4954 {
4955     const struct ssh_hash *h = ssh->kex->hash;
4956     void *s;
4957     /* First hlen bytes. */
4958     s = h->init();
4959     if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
4960         hash_mpint(h, s, K);
4961     h->bytes(s, H, h->hlen);
4962     h->bytes(s, &chr, 1);
4963     h->bytes(s, ssh->v2_session_id, ssh->v2_session_id_len);
4964     h->final(s, keyspace);
4965     /* Next hlen bytes. */
4966     s = h->init();
4967     if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
4968         hash_mpint(h, s, K);
4969     h->bytes(s, H, h->hlen);
4970     h->bytes(s, keyspace, h->hlen);
4971     h->final(s, keyspace + h->hlen);
4972 }
4973
4974 /*
4975  * Handle the SSH-2 transport layer.
4976  */
4977 static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
4978                              struct Packet *pktin)
4979 {
4980     unsigned char *in = (unsigned char *)vin;
4981     struct do_ssh2_transport_state {
4982         int nbits, pbits, warn_kex, warn_cscipher, warn_sccipher;
4983         Bignum p, g, e, f, K;
4984         void *our_kexinit;
4985         int our_kexinitlen;
4986         int kex_init_value, kex_reply_value;
4987         const struct ssh_mac **maclist;
4988         int nmacs;
4989         const struct ssh2_cipher *cscipher_tobe;
4990         const struct ssh2_cipher *sccipher_tobe;
4991         const struct ssh_mac *csmac_tobe;
4992         const struct ssh_mac *scmac_tobe;
4993         const struct ssh_compress *cscomp_tobe;
4994         const struct ssh_compress *sccomp_tobe;
4995         char *hostkeydata, *sigdata, *keystr, *fingerprint;
4996         int hostkeylen, siglen;
4997         void *hkey;                    /* actual host key */
4998         unsigned char exchange_hash[32];
4999         int n_preferred_kex;
5000         const struct ssh_kexes *preferred_kex[KEX_MAX];
5001         int n_preferred_ciphers;
5002         const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX];
5003         const struct ssh_compress *preferred_comp;
5004         int got_session_id, activated_authconn;
5005         struct Packet *pktout;
5006         int dlgret;
5007         int guessok;
5008         int ignorepkt;
5009     };
5010     crState(do_ssh2_transport_state);
5011
5012     crBegin(ssh->do_ssh2_transport_crstate);
5013
5014     s->cscipher_tobe = s->sccipher_tobe = NULL;
5015     s->csmac_tobe = s->scmac_tobe = NULL;
5016     s->cscomp_tobe = s->sccomp_tobe = NULL;
5017
5018     s->got_session_id = s->activated_authconn = FALSE;
5019
5020     /*
5021      * Be prepared to work around the buggy MAC problem.
5022      */
5023     if (ssh->remote_bugs & BUG_SSH2_HMAC)
5024         s->maclist = buggymacs, s->nmacs = lenof(buggymacs);
5025     else
5026         s->maclist = macs, s->nmacs = lenof(macs);
5027
5028   begin_key_exchange:
5029     ssh->pkt_ctx &= ~SSH2_PKTCTX_KEX_MASK;
5030     {
5031         int i, j, commalist_started;
5032
5033         /*
5034          * Set up the preferred key exchange. (NULL => warn below here)
5035          */
5036         s->n_preferred_kex = 0;
5037         for (i = 0; i < KEX_MAX; i++) {
5038             switch (ssh->cfg.ssh_kexlist[i]) {
5039               case KEX_DHGEX:
5040                 s->preferred_kex[s->n_preferred_kex++] =
5041                     &ssh_diffiehellman_gex;
5042                 break;
5043               case KEX_DHGROUP14:
5044                 s->preferred_kex[s->n_preferred_kex++] =
5045                     &ssh_diffiehellman_group14;
5046                 break;
5047               case KEX_DHGROUP1:
5048                 s->preferred_kex[s->n_preferred_kex++] =
5049                     &ssh_diffiehellman_group1;
5050                 break;
5051               case CIPHER_WARN:
5052                 /* Flag for later. Don't bother if it's the last in
5053                  * the list. */
5054                 if (i < KEX_MAX - 1) {
5055                     s->preferred_kex[s->n_preferred_kex++] = NULL;
5056                 }
5057                 break;
5058             }
5059         }
5060
5061         /*
5062          * Set up the preferred ciphers. (NULL => warn below here)
5063          */
5064         s->n_preferred_ciphers = 0;
5065         for (i = 0; i < CIPHER_MAX; i++) {
5066             switch (ssh->cfg.ssh_cipherlist[i]) {
5067               case CIPHER_BLOWFISH:
5068                 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_blowfish;
5069                 break;
5070               case CIPHER_DES:
5071                 if (ssh->cfg.ssh2_des_cbc) {
5072                     s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_des;
5073                 }
5074                 break;
5075               case CIPHER_3DES:
5076                 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_3des;
5077                 break;
5078               case CIPHER_AES:
5079                 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_aes;
5080                 break;
5081               case CIPHER_ARCFOUR:
5082                 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_arcfour;
5083                 break;
5084               case CIPHER_WARN:
5085                 /* Flag for later. Don't bother if it's the last in
5086                  * the list. */
5087                 if (i < CIPHER_MAX - 1) {
5088                     s->preferred_ciphers[s->n_preferred_ciphers++] = NULL;
5089                 }
5090                 break;
5091             }
5092         }
5093
5094         /*
5095          * Set up preferred compression.
5096          */
5097         if (ssh->cfg.compression)
5098             s->preferred_comp = &ssh_zlib;
5099         else
5100             s->preferred_comp = &ssh_comp_none;
5101
5102         /*
5103          * Enable queueing of outgoing auth- or connection-layer
5104          * packets while we are in the middle of a key exchange.
5105          */
5106         ssh->queueing = TRUE;
5107
5108         /*
5109          * Flag that KEX is in progress.
5110          */
5111         ssh->kex_in_progress = TRUE;
5112
5113         /*
5114          * Construct and send our key exchange packet.
5115          */
5116         s->pktout = ssh2_pkt_init(SSH2_MSG_KEXINIT);
5117         for (i = 0; i < 16; i++)
5118             ssh2_pkt_addbyte(s->pktout, (unsigned char) random_byte());
5119         /* List key exchange algorithms. */
5120         ssh2_pkt_addstring_start(s->pktout);
5121         commalist_started = 0;
5122         for (i = 0; i < s->n_preferred_kex; i++) {
5123             const struct ssh_kexes *k = s->preferred_kex[i];
5124             if (!k) continue;          /* warning flag */
5125             for (j = 0; j < k->nkexes; j++) {
5126                 if (commalist_started)
5127                     ssh2_pkt_addstring_str(s->pktout, ",");
5128                 ssh2_pkt_addstring_str(s->pktout, k->list[j]->name);
5129                 commalist_started = 1;
5130             }
5131         }
5132         /* List server host key algorithms. */
5133         ssh2_pkt_addstring_start(s->pktout);
5134         for (i = 0; i < lenof(hostkey_algs); i++) {
5135             ssh2_pkt_addstring_str(s->pktout, hostkey_algs[i]->name);
5136             if (i < lenof(hostkey_algs) - 1)
5137                 ssh2_pkt_addstring_str(s->pktout, ",");
5138         }
5139         /* List client->server encryption algorithms. */
5140         ssh2_pkt_addstring_start(s->pktout);
5141         commalist_started = 0;
5142         for (i = 0; i < s->n_preferred_ciphers; i++) {
5143             const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5144             if (!c) continue;          /* warning flag */
5145             for (j = 0; j < c->nciphers; j++) {
5146                 if (commalist_started)
5147                     ssh2_pkt_addstring_str(s->pktout, ",");
5148                 ssh2_pkt_addstring_str(s->pktout, c->list[j]->name);
5149                 commalist_started = 1;
5150             }
5151         }
5152         /* List server->client encryption algorithms. */
5153         ssh2_pkt_addstring_start(s->pktout);
5154         commalist_started = 0;
5155         for (i = 0; i < s->n_preferred_ciphers; i++) {
5156             const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5157             if (!c) continue; /* warning flag */
5158             for (j = 0; j < c->nciphers; j++) {
5159                 if (commalist_started)
5160                     ssh2_pkt_addstring_str(s->pktout, ",");
5161                 ssh2_pkt_addstring_str(s->pktout, c->list[j]->name);
5162                 commalist_started = 1;
5163             }
5164         }
5165         /* List client->server MAC algorithms. */
5166         ssh2_pkt_addstring_start(s->pktout);
5167         for (i = 0; i < s->nmacs; i++) {
5168             ssh2_pkt_addstring_str(s->pktout, s->maclist[i]->name);
5169             if (i < s->nmacs - 1)
5170                 ssh2_pkt_addstring_str(s->pktout, ",");
5171         }
5172         /* List server->client MAC algorithms. */
5173         ssh2_pkt_addstring_start(s->pktout);
5174         for (i = 0; i < s->nmacs; i++) {
5175             ssh2_pkt_addstring_str(s->pktout, s->maclist[i]->name);
5176             if (i < s->nmacs - 1)
5177                 ssh2_pkt_addstring_str(s->pktout, ",");
5178         }
5179         /* List client->server compression algorithms. */
5180         ssh2_pkt_addstring_start(s->pktout);
5181         assert(lenof(compressions) > 1);
5182         ssh2_pkt_addstring_str(s->pktout, s->preferred_comp->name);
5183         for (i = 0; i < lenof(compressions); i++) {
5184             const struct ssh_compress *c = compressions[i];
5185             if (c != s->preferred_comp) {
5186                 ssh2_pkt_addstring_str(s->pktout, ",");
5187                 ssh2_pkt_addstring_str(s->pktout, c->name);
5188             }
5189         }
5190         /* List server->client compression algorithms. */
5191         ssh2_pkt_addstring_start(s->pktout);
5192         assert(lenof(compressions) > 1);
5193         ssh2_pkt_addstring_str(s->pktout, s->preferred_comp->name);
5194         for (i = 0; i < lenof(compressions); i++) {
5195             const struct ssh_compress *c = compressions[i];
5196             if (c != s->preferred_comp) {
5197                 ssh2_pkt_addstring_str(s->pktout, ",");
5198                 ssh2_pkt_addstring_str(s->pktout, c->name);
5199             }
5200         }
5201         /* List client->server languages. Empty list. */
5202         ssh2_pkt_addstring_start(s->pktout);
5203         /* List server->client languages. Empty list. */
5204         ssh2_pkt_addstring_start(s->pktout);
5205         /* First KEX packet does _not_ follow, because we're not that brave. */
5206         ssh2_pkt_addbool(s->pktout, FALSE);
5207         /* Reserved. */
5208         ssh2_pkt_adduint32(s->pktout, 0);
5209     }
5210
5211     s->our_kexinitlen = s->pktout->length - 5;
5212     s->our_kexinit = snewn(s->our_kexinitlen, unsigned char);
5213     memcpy(s->our_kexinit, s->pktout->data + 5, s->our_kexinitlen); 
5214
5215     ssh2_pkt_send_noqueue(ssh, s->pktout);
5216
5217     if (!pktin)
5218         crWaitUntil(pktin);
5219
5220     /*
5221      * Now examine the other side's KEXINIT to see what we're up
5222      * to.
5223      */
5224     {
5225         char *str, *preferred;
5226         int i, j, len;
5227
5228         if (pktin->type != SSH2_MSG_KEXINIT) {
5229             bombout(("expected key exchange packet from server"));
5230             crStop(0);
5231         }
5232         ssh->kex = NULL;
5233         ssh->hostkey = NULL;
5234         s->cscipher_tobe = NULL;
5235         s->sccipher_tobe = NULL;
5236         s->csmac_tobe = NULL;
5237         s->scmac_tobe = NULL;
5238         s->cscomp_tobe = NULL;
5239         s->sccomp_tobe = NULL;
5240         s->warn_kex = s->warn_cscipher = s->warn_sccipher = FALSE;
5241
5242         pktin->savedpos += 16;          /* skip garbage cookie */
5243         ssh_pkt_getstring(pktin, &str, &len);    /* key exchange algorithms */
5244
5245         preferred = NULL;
5246         for (i = 0; i < s->n_preferred_kex; i++) {
5247             const struct ssh_kexes *k = s->preferred_kex[i];
5248             if (!k) {
5249                 s->warn_kex = TRUE;
5250             } else {
5251                 for (j = 0; j < k->nkexes; j++) {
5252                     if (!preferred) preferred = k->list[j]->name;
5253                     if (in_commasep_string(k->list[j]->name, str, len)) {
5254                         ssh->kex = k->list[j];
5255                         break;
5256                     }
5257                 }
5258             }
5259             if (ssh->kex)
5260                 break;
5261         }
5262         if (!ssh->kex) {
5263             bombout(("Couldn't agree a key exchange algorithm (available: %s)",
5264                      str ? str : "(null)"));
5265             crStop(0);
5266         }
5267         /*
5268          * Note that the server's guess is considered wrong if it doesn't match
5269          * the first algorithm in our list, even if it's still the algorithm
5270          * we end up using.
5271          */
5272         s->guessok = first_in_commasep_string(preferred, str, len);
5273         ssh_pkt_getstring(pktin, &str, &len);    /* host key algorithms */
5274         for (i = 0; i < lenof(hostkey_algs); i++) {
5275             if (in_commasep_string(hostkey_algs[i]->name, str, len)) {
5276                 ssh->hostkey = hostkey_algs[i];
5277                 break;
5278             }
5279         }
5280         s->guessok = s->guessok &&
5281             first_in_commasep_string(hostkey_algs[0]->name, str, len);
5282         ssh_pkt_getstring(pktin, &str, &len);    /* client->server cipher */
5283         for (i = 0; i < s->n_preferred_ciphers; i++) {
5284             const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5285             if (!c) {
5286                 s->warn_cscipher = TRUE;
5287             } else {
5288                 for (j = 0; j < c->nciphers; j++) {
5289                     if (in_commasep_string(c->list[j]->name, str, len)) {
5290                         s->cscipher_tobe = c->list[j];
5291                         break;
5292                     }
5293                 }
5294             }
5295             if (s->cscipher_tobe)
5296                 break;
5297         }
5298         if (!s->cscipher_tobe) {
5299             bombout(("Couldn't agree a client-to-server cipher (available: %s)",
5300                      str ? str : "(null)"));
5301             crStop(0);
5302         }
5303
5304         ssh_pkt_getstring(pktin, &str, &len);    /* server->client cipher */
5305         for (i = 0; i < s->n_preferred_ciphers; i++) {
5306             const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5307             if (!c) {
5308                 s->warn_sccipher = TRUE;
5309             } else {
5310                 for (j = 0; j < c->nciphers; j++) {
5311                     if (in_commasep_string(c->list[j]->name, str, len)) {
5312                         s->sccipher_tobe = c->list[j];
5313                         break;
5314                     }
5315                 }
5316             }
5317             if (s->sccipher_tobe)
5318                 break;
5319         }
5320         if (!s->sccipher_tobe) {
5321             bombout(("Couldn't agree a server-to-client cipher (available: %s)",
5322                      str ? str : "(null)"));
5323             crStop(0);
5324         }
5325
5326         ssh_pkt_getstring(pktin, &str, &len);    /* client->server mac */
5327         for (i = 0; i < s->nmacs; i++) {
5328             if (in_commasep_string(s->maclist[i]->name, str, len)) {
5329                 s->csmac_tobe = s->maclist[i];
5330                 break;
5331             }
5332         }
5333         ssh_pkt_getstring(pktin, &str, &len);    /* server->client mac */
5334         for (i = 0; i < s->nmacs; i++) {
5335             if (in_commasep_string(s->maclist[i]->name, str, len)) {
5336                 s->scmac_tobe = s->maclist[i];
5337                 break;
5338             }
5339         }
5340         ssh_pkt_getstring(pktin, &str, &len);  /* client->server compression */
5341         for (i = 0; i < lenof(compressions) + 1; i++) {
5342             const struct ssh_compress *c =
5343                 i == 0 ? s->preferred_comp : compressions[i - 1];
5344             if (in_commasep_string(c->name, str, len)) {
5345                 s->cscomp_tobe = c;
5346                 break;
5347             }
5348         }
5349         ssh_pkt_getstring(pktin, &str, &len);  /* server->client compression */
5350         for (i = 0; i < lenof(compressions) + 1; i++) {
5351             const struct ssh_compress *c =
5352                 i == 0 ? s->preferred_comp : compressions[i - 1];
5353             if (in_commasep_string(c->name, str, len)) {
5354                 s->sccomp_tobe = c;
5355                 break;
5356             }
5357         }
5358         ssh_pkt_getstring(pktin, &str, &len);  /* client->server language */
5359         ssh_pkt_getstring(pktin, &str, &len);  /* server->client language */
5360         s->ignorepkt = ssh2_pkt_getbool(pktin) && !s->guessok;
5361
5362         if (s->warn_kex) {
5363             ssh_set_frozen(ssh, 1);
5364             s->dlgret = askalg(ssh->frontend, "key-exchange algorithm",
5365                                ssh->kex->name,
5366                                ssh_dialog_callback, ssh);
5367             if (s->dlgret < 0) {
5368                 do {
5369                     crReturn(0);
5370                     if (pktin) {
5371                         bombout(("Unexpected data from server while"
5372                                  " waiting for user response"));
5373                         crStop(0);
5374                     }
5375                 } while (pktin || inlen > 0);
5376                 s->dlgret = ssh->user_response;
5377             }
5378             ssh_set_frozen(ssh, 0);
5379             if (s->dlgret == 0) {
5380                 ssh_disconnect(ssh, "User aborted at kex warning", NULL,
5381                                0, TRUE);
5382                 crStop(0);
5383             }
5384         }
5385
5386         if (s->warn_cscipher) {
5387             ssh_set_frozen(ssh, 1);
5388             s->dlgret = askalg(ssh->frontend,
5389                                "client-to-server cipher",
5390                                s->cscipher_tobe->name,
5391                                ssh_dialog_callback, ssh);
5392             if (s->dlgret < 0) {
5393                 do {
5394                     crReturn(0);
5395                     if (pktin) {
5396                         bombout(("Unexpected data from server while"
5397                                  " waiting for user response"));
5398                         crStop(0);
5399                     }
5400                 } while (pktin || inlen > 0);
5401                 s->dlgret = ssh->user_response;
5402             }
5403             ssh_set_frozen(ssh, 0);
5404             if (s->dlgret == 0) {
5405                 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
5406                                0, TRUE);
5407                 crStop(0);
5408             }
5409         }
5410
5411         if (s->warn_sccipher) {
5412             ssh_set_frozen(ssh, 1);
5413             s->dlgret = askalg(ssh->frontend,
5414                                "server-to-client cipher",
5415                                s->sccipher_tobe->name,
5416                                ssh_dialog_callback, ssh);
5417             if (s->dlgret < 0) {
5418                 do {
5419                     crReturn(0);
5420                     if (pktin) {
5421                         bombout(("Unexpected data from server while"
5422                                  " waiting for user response"));
5423                         crStop(0);
5424                     }
5425                 } while (pktin || inlen > 0);
5426                 s->dlgret = ssh->user_response;
5427             }
5428             ssh_set_frozen(ssh, 0);
5429             if (s->dlgret == 0) {
5430                 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
5431                                0, TRUE);
5432                 crStop(0);
5433             }
5434         }
5435
5436         ssh->exhash = ssh->kex->hash->init();
5437         hash_string(ssh->kex->hash, ssh->exhash, ssh->v_c, strlen(ssh->v_c));
5438         hash_string(ssh->kex->hash, ssh->exhash, ssh->v_s, strlen(ssh->v_s));
5439         hash_string(ssh->kex->hash, ssh->exhash,
5440             s->our_kexinit, s->our_kexinitlen);
5441         sfree(s->our_kexinit);
5442         if (pktin->length > 5)
5443             hash_string(ssh->kex->hash, ssh->exhash,
5444                 pktin->data + 5, pktin->length - 5);
5445
5446         if (s->ignorepkt) /* first_kex_packet_follows */
5447             crWaitUntil(pktin);                /* Ignore packet */
5448     }
5449
5450     /*
5451      * Work out the number of bits of key we will need from the key
5452      * exchange. We start with the maximum key length of either
5453      * cipher...
5454      */
5455     {
5456         int csbits, scbits;
5457
5458         csbits = s->cscipher_tobe->keylen;
5459         scbits = s->sccipher_tobe->keylen;
5460         s->nbits = (csbits > scbits ? csbits : scbits);
5461     }
5462     /* The keys only have hlen-bit entropy, since they're based on
5463      * a hash. So cap the key size at hlen bits. */
5464     if (s->nbits > ssh->kex->hash->hlen * 8)
5465         s->nbits = ssh->kex->hash->hlen * 8;
5466
5467     /*
5468      * If we're doing Diffie-Hellman group exchange, start by
5469      * requesting a group.
5470      */
5471     if (!ssh->kex->pdata) {
5472         logevent("Doing Diffie-Hellman group exchange");
5473         ssh->pkt_ctx |= SSH2_PKTCTX_DHGEX;
5474         /*
5475          * Work out how big a DH group we will need to allow that
5476          * much data.
5477          */
5478         s->pbits = 512 << ((s->nbits - 1) / 64);
5479         s->pktout = ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
5480         ssh2_pkt_adduint32(s->pktout, s->pbits);
5481         ssh2_pkt_send_noqueue(ssh, s->pktout);
5482
5483         crWaitUntil(pktin);
5484         if (pktin->type != SSH2_MSG_KEX_DH_GEX_GROUP) {
5485             bombout(("expected key exchange group packet from server"));
5486             crStop(0);
5487         }
5488         s->p = ssh2_pkt_getmp(pktin);
5489         s->g = ssh2_pkt_getmp(pktin);
5490         if (!s->p || !s->g) {
5491             bombout(("unable to read mp-ints from incoming group packet"));
5492             crStop(0);
5493         }
5494         ssh->kex_ctx = dh_setup_gex(s->p, s->g);
5495         s->kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
5496         s->kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
5497     } else {
5498         ssh->pkt_ctx |= SSH2_PKTCTX_DHGROUP;
5499         ssh->kex_ctx = dh_setup_group(ssh->kex);
5500         s->kex_init_value = SSH2_MSG_KEXDH_INIT;
5501         s->kex_reply_value = SSH2_MSG_KEXDH_REPLY;
5502         logeventf(ssh, "Using Diffie-Hellman with standard group \"%s\"",
5503                   ssh->kex->groupname);
5504     }
5505
5506     logevent("Doing Diffie-Hellman key exchange");
5507     /*
5508      * Now generate and send e for Diffie-Hellman.
5509      */
5510     set_busy_status(ssh->frontend, BUSY_CPU); /* this can take a while */
5511     s->e = dh_create_e(ssh->kex_ctx, s->nbits * 2);
5512     s->pktout = ssh2_pkt_init(s->kex_init_value);
5513     ssh2_pkt_addmp(s->pktout, s->e);
5514     ssh2_pkt_send_noqueue(ssh, s->pktout);
5515
5516     set_busy_status(ssh->frontend, BUSY_WAITING); /* wait for server */
5517     crWaitUntil(pktin);
5518     if (pktin->type != s->kex_reply_value) {
5519         bombout(("expected key exchange reply packet from server"));
5520         crStop(0);
5521     }
5522     set_busy_status(ssh->frontend, BUSY_CPU); /* cogitate */
5523     ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
5524     s->f = ssh2_pkt_getmp(pktin);
5525     if (!s->f) {
5526         bombout(("unable to parse key exchange reply packet"));
5527         crStop(0);
5528     }
5529     ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
5530
5531     s->K = dh_find_K(ssh->kex_ctx, s->f);
5532
5533     /* We assume everything from now on will be quick, and it might
5534      * involve user interaction. */
5535     set_busy_status(ssh->frontend, BUSY_NOT);
5536
5537     hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen);
5538     if (!ssh->kex->pdata) {
5539         hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits);
5540         hash_mpint(ssh->kex->hash, ssh->exhash, s->p);
5541         hash_mpint(ssh->kex->hash, ssh->exhash, s->g);
5542     }
5543     hash_mpint(ssh->kex->hash, ssh->exhash, s->e);
5544     hash_mpint(ssh->kex->hash, ssh->exhash, s->f);
5545     hash_mpint(ssh->kex->hash, ssh->exhash, s->K);
5546     assert(ssh->kex->hash->hlen <= sizeof(s->exchange_hash));
5547     ssh->kex->hash->final(ssh->exhash, s->exchange_hash);
5548
5549     dh_cleanup(ssh->kex_ctx);
5550     ssh->kex_ctx = NULL;
5551
5552 #if 0
5553     debug(("Exchange hash is:\n"));
5554     dmemdump(s->exchange_hash, ssh->kex->hash->hlen);
5555 #endif
5556
5557     s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
5558     if (!s->hkey ||
5559         !ssh->hostkey->verifysig(s->hkey, s->sigdata, s->siglen,
5560                                  (char *)s->exchange_hash,
5561                                  ssh->kex->hash->hlen)) {
5562         bombout(("Server's host key did not match the signature supplied"));
5563         crStop(0);
5564     }
5565
5566     /*
5567      * Authenticate remote host: verify host key. (We've already
5568      * checked the signature of the exchange hash.)
5569      */
5570     s->keystr = ssh->hostkey->fmtkey(s->hkey);
5571     s->fingerprint = ssh->hostkey->fingerprint(s->hkey);
5572     ssh_set_frozen(ssh, 1);
5573     s->dlgret = verify_ssh_host_key(ssh->frontend,
5574                                     ssh->savedhost, ssh->savedport,
5575                                     ssh->hostkey->keytype, s->keystr,
5576                                     s->fingerprint,
5577                                     ssh_dialog_callback, ssh);
5578     if (s->dlgret < 0) {
5579         do {
5580             crReturn(0);
5581             if (pktin) {
5582                 bombout(("Unexpected data from server while waiting"
5583                          " for user host key response"));
5584                     crStop(0);
5585             }
5586         } while (pktin || inlen > 0);
5587         s->dlgret = ssh->user_response;
5588     }
5589     ssh_set_frozen(ssh, 0);
5590     if (s->dlgret == 0) {
5591         ssh_disconnect(ssh, "User aborted at host key verification", NULL,
5592                        0, TRUE);
5593         crStop(0);
5594     }
5595     if (!s->got_session_id) {     /* don't bother logging this in rekeys */
5596         logevent("Host key fingerprint is:");
5597         logevent(s->fingerprint);
5598     }
5599     sfree(s->fingerprint);
5600     sfree(s->keystr);
5601     ssh->hostkey->freekey(s->hkey);
5602
5603     /*
5604      * The exchange hash from the very first key exchange is also
5605      * the session id, used in session key construction and
5606      * authentication.
5607      */
5608     if (!s->got_session_id) {
5609         assert(sizeof(s->exchange_hash) <= sizeof(ssh->v2_session_id));
5610         memcpy(ssh->v2_session_id, s->exchange_hash,
5611                sizeof(s->exchange_hash));
5612         ssh->v2_session_id_len = ssh->kex->hash->hlen;
5613         assert(ssh->v2_session_id_len <= sizeof(ssh->v2_session_id));
5614         s->got_session_id = TRUE;
5615     }
5616
5617     /*
5618      * Send SSH2_MSG_NEWKEYS.
5619      */
5620     s->pktout = ssh2_pkt_init(SSH2_MSG_NEWKEYS);
5621     ssh2_pkt_send_noqueue(ssh, s->pktout);
5622     ssh->outgoing_data_size = 0;       /* start counting from here */
5623
5624     /*
5625      * We've sent client NEWKEYS, so create and initialise
5626      * client-to-server session keys.
5627      */
5628     if (ssh->cs_cipher_ctx)
5629         ssh->cscipher->free_context(ssh->cs_cipher_ctx);
5630     ssh->cscipher = s->cscipher_tobe;
5631     ssh->cs_cipher_ctx = ssh->cscipher->make_context();
5632
5633     if (ssh->cs_mac_ctx)
5634         ssh->csmac->free_context(ssh->cs_mac_ctx);
5635     ssh->csmac = s->csmac_tobe;
5636     ssh->cs_mac_ctx = ssh->csmac->make_context();
5637
5638     if (ssh->cs_comp_ctx)
5639         ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
5640     ssh->cscomp = s->cscomp_tobe;
5641     ssh->cs_comp_ctx = ssh->cscomp->compress_init();
5642
5643     /*
5644      * Set IVs on client-to-server keys. Here we use the exchange
5645      * hash from the _first_ key exchange.
5646      */
5647     {
5648         unsigned char keyspace[40];
5649         ssh2_mkkey(ssh,s->K,s->exchange_hash,'C',keyspace);
5650         ssh->cscipher->setkey(ssh->cs_cipher_ctx, keyspace);
5651         ssh2_mkkey(ssh,s->K,s->exchange_hash,'A',keyspace);
5652         ssh->cscipher->setiv(ssh->cs_cipher_ctx, keyspace);
5653         ssh2_mkkey(ssh,s->K,s->exchange_hash,'E',keyspace);
5654         ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace);
5655     }
5656
5657     logeventf(ssh, "Initialised %.200s client->server encryption",
5658               ssh->cscipher->text_name);
5659     logeventf(ssh, "Initialised %.200s client->server MAC algorithm",
5660               ssh->csmac->text_name);
5661     if (ssh->cscomp->text_name)
5662         logeventf(ssh, "Initialised %s compression",
5663                   ssh->cscomp->text_name);
5664
5665     /*
5666      * Now our end of the key exchange is complete, we can send all
5667      * our queued higher-layer packets.
5668      */
5669     ssh->queueing = FALSE;
5670     ssh2_pkt_queuesend(ssh);
5671
5672     /*
5673      * Expect SSH2_MSG_NEWKEYS from server.
5674      */
5675     crWaitUntil(pktin);
5676     if (pktin->type != SSH2_MSG_NEWKEYS) {
5677         bombout(("expected new-keys packet from server"));
5678         crStop(0);
5679     }
5680     ssh->incoming_data_size = 0;       /* start counting from here */
5681
5682     /*
5683      * We've seen server NEWKEYS, so create and initialise
5684      * server-to-client session keys.
5685      */
5686     if (ssh->sc_cipher_ctx)
5687         ssh->sccipher->free_context(ssh->sc_cipher_ctx);
5688     ssh->sccipher = s->sccipher_tobe;
5689     ssh->sc_cipher_ctx = ssh->sccipher->make_context();
5690
5691     if (ssh->sc_mac_ctx)
5692         ssh->scmac->free_context(ssh->sc_mac_ctx);
5693     ssh->scmac = s->scmac_tobe;
5694     ssh->sc_mac_ctx = ssh->scmac->make_context();
5695
5696     if (ssh->sc_comp_ctx)
5697         ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
5698     ssh->sccomp = s->sccomp_tobe;
5699     ssh->sc_comp_ctx = ssh->sccomp->decompress_init();
5700
5701     /*
5702      * Set IVs on server-to-client keys. Here we use the exchange
5703      * hash from the _first_ key exchange.
5704      */
5705     {
5706         unsigned char keyspace[40];
5707         ssh2_mkkey(ssh,s->K,s->exchange_hash,'D',keyspace);
5708         ssh->sccipher->setkey(ssh->sc_cipher_ctx, keyspace);
5709         ssh2_mkkey(ssh,s->K,s->exchange_hash,'B',keyspace);
5710         ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace);
5711         ssh2_mkkey(ssh,s->K,s->exchange_hash,'F',keyspace);
5712         ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace);
5713     }
5714     logeventf(ssh, "Initialised %.200s server->client encryption",
5715               ssh->sccipher->text_name);
5716     logeventf(ssh, "Initialised %.200s server->client MAC algorithm",
5717               ssh->scmac->text_name);
5718     if (ssh->sccomp->text_name)
5719         logeventf(ssh, "Initialised %s decompression",
5720                   ssh->sccomp->text_name);
5721
5722     /*
5723      * Free key exchange data.
5724      */
5725     freebn(s->f);
5726     freebn(s->K);
5727     if (!ssh->kex->pdata) {
5728         freebn(s->g);
5729         freebn(s->p);
5730     }
5731
5732     /*
5733      * Key exchange is over. Loop straight back round if we have a
5734      * deferred rekey reason.
5735      */
5736     if (ssh->deferred_rekey_reason) {
5737         logevent(ssh->deferred_rekey_reason);
5738         pktin = NULL;
5739         ssh->deferred_rekey_reason = NULL;
5740         goto begin_key_exchange;
5741     }
5742
5743     /*
5744      * Otherwise, schedule a timer for our next rekey.
5745      */
5746     ssh->kex_in_progress = FALSE;
5747     ssh->last_rekey = GETTICKCOUNT();
5748     if (ssh->cfg.ssh_rekey_time != 0)
5749         ssh->next_rekey = schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
5750                                          ssh2_timer, ssh);
5751
5752     /*
5753      * If this is the first key exchange phase, we must pass the
5754      * SSH2_MSG_NEWKEYS packet to the next layer, not because it
5755      * wants to see it but because it will need time to initialise
5756      * itself before it sees an actual packet. In subsequent key
5757      * exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
5758      * it would only confuse the layer above.
5759      */
5760     if (s->activated_authconn) {
5761         crReturn(0);
5762     }
5763     s->activated_authconn = TRUE;
5764
5765     /*
5766      * Now we're encrypting. Begin returning 1 to the protocol main
5767      * function so that other things can run on top of the
5768      * transport. If we ever see a KEXINIT, we must go back to the
5769      * start.
5770      * 
5771      * We _also_ go back to the start if we see pktin==NULL and
5772      * inlen==-1, because this is a special signal meaning
5773      * `initiate client-driven rekey', and `in' contains a message
5774      * giving the reason for the rekey.
5775      */
5776     while (!((pktin && pktin->type == SSH2_MSG_KEXINIT) ||
5777              (!pktin && inlen == -1))) {
5778         wait_for_rekey:
5779         crReturn(1);
5780     }
5781     if (pktin) {
5782         logevent("Server initiated key re-exchange");
5783     } else {
5784         /*
5785          * Special case: if the server bug is set that doesn't
5786          * allow rekeying, we give a different log message and
5787          * continue waiting. (If such a server _initiates_ a rekey,
5788          * we process it anyway!)
5789          */
5790         if ((ssh->remote_bugs & BUG_SSH2_REKEY)) {
5791             logeventf(ssh, "Server bug prevents key re-exchange (%s)",
5792                       (char *)in);
5793             /* Reset the counters, so that at least this message doesn't
5794              * hit the event log _too_ often. */
5795             ssh->outgoing_data_size = 0;
5796             ssh->incoming_data_size = 0;
5797             if (ssh->cfg.ssh_rekey_time != 0) {
5798                 ssh->next_rekey =
5799                     schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
5800                                    ssh2_timer, ssh);
5801             }
5802             goto wait_for_rekey;       /* this is utterly horrid */
5803         } else {
5804             logeventf(ssh, "Initiating key re-exchange (%s)", (char *)in);
5805         }
5806     }
5807     goto begin_key_exchange;
5808
5809     crFinish(1);
5810 }
5811
5812 /*
5813  * Add data to an SSH-2 channel output buffer.
5814  */
5815 static void ssh2_add_channel_data(struct ssh_channel *c, char *buf,
5816                                   int len)
5817 {
5818     bufchain_add(&c->v.v2.outbuffer, buf, len);
5819 }
5820
5821 /*
5822  * Attempt to send data on an SSH-2 channel.
5823  */
5824 static int ssh2_try_send(struct ssh_channel *c)
5825 {
5826     Ssh ssh = c->ssh;
5827     struct Packet *pktout;
5828
5829     while (c->v.v2.remwindow > 0 && bufchain_size(&c->v.v2.outbuffer) > 0) {
5830         int len;
5831         void *data;
5832         bufchain_prefix(&c->v.v2.outbuffer, &data, &len);
5833         if ((unsigned)len > c->v.v2.remwindow)
5834             len = c->v.v2.remwindow;
5835         if ((unsigned)len > c->v.v2.remmaxpkt)
5836             len = c->v.v2.remmaxpkt;
5837         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
5838         ssh2_pkt_adduint32(pktout, c->remoteid);
5839         dont_log_data(ssh, pktout, PKTLOG_OMIT);
5840         ssh2_pkt_addstring_start(pktout);
5841         ssh2_pkt_addstring_data(pktout, data, len);
5842         end_log_omission(ssh, pktout);
5843         ssh2_pkt_send(ssh, pktout);
5844         bufchain_consume(&c->v.v2.outbuffer, len);
5845         c->v.v2.remwindow -= len;
5846     }
5847
5848     /*
5849      * After having sent as much data as we can, return the amount
5850      * still buffered.
5851      */
5852     return bufchain_size(&c->v.v2.outbuffer);
5853 }
5854
5855 static void ssh2_try_send_and_unthrottle(struct ssh_channel *c)
5856 {
5857     int bufsize;
5858     if (c->closes)
5859         return;                        /* don't send on closing channels */
5860     bufsize = ssh2_try_send(c);
5861     if (bufsize == 0) {
5862         switch (c->type) {
5863           case CHAN_MAINSESSION:
5864             /* stdin need not receive an unthrottle
5865              * notification since it will be polled */
5866             break;
5867           case CHAN_X11:
5868             x11_unthrottle(c->u.x11.s);
5869             break;
5870           case CHAN_AGENT:
5871             /* agent sockets are request/response and need no
5872              * buffer management */
5873             break;
5874           case CHAN_SOCKDATA:
5875             pfd_unthrottle(c->u.pfd.s);
5876             break;
5877         }
5878     }
5879 }
5880
5881 /*
5882  * Potentially enlarge the window on an SSH-2 channel.
5883  */
5884 static void ssh2_set_window(struct ssh_channel *c, unsigned newwin)
5885 {
5886     Ssh ssh = c->ssh;
5887
5888     /*
5889      * Never send WINDOW_ADJUST for a channel that the remote side
5890      * already thinks it's closed; there's no point, since it won't
5891      * be sending any more data anyway.
5892      */
5893     if (c->closes != 0)
5894         return;
5895
5896     /*
5897      * Only send a WINDOW_ADJUST if there's significantly more window
5898      * available than the other end thinks there is.  This saves us
5899      * sending a WINDOW_ADJUST for every character in a shell session.
5900      *
5901      * "Significant" is arbitrarily defined as half the window size.
5902      */
5903     if (newwin > c->v.v2.locwindow * 2) {
5904         struct Packet *pktout;
5905
5906         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
5907         ssh2_pkt_adduint32(pktout, c->remoteid);
5908         ssh2_pkt_adduint32(pktout, newwin - c->v.v2.locwindow);
5909         ssh2_pkt_send(ssh, pktout);
5910         c->v.v2.locwindow = newwin;
5911     }
5912 }
5913
5914 static void ssh2_msg_channel_window_adjust(Ssh ssh, struct Packet *pktin)
5915 {
5916     unsigned i = ssh_pkt_getuint32(pktin);
5917     struct ssh_channel *c;
5918     c = find234(ssh->channels, &i, ssh_channelfind);
5919     if (c && !c->closes) {
5920         c->v.v2.remwindow += ssh_pkt_getuint32(pktin);
5921         ssh2_try_send_and_unthrottle(c);
5922     }
5923 }
5924
5925 static void ssh2_msg_channel_data(Ssh ssh, struct Packet *pktin)
5926 {
5927     char *data;
5928     int length;
5929     unsigned i = ssh_pkt_getuint32(pktin);
5930     struct ssh_channel *c;
5931     c = find234(ssh->channels, &i, ssh_channelfind);
5932     if (!c)
5933         return;                        /* nonexistent channel */
5934     if (pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
5935         ssh_pkt_getuint32(pktin) != SSH2_EXTENDED_DATA_STDERR)
5936         return;                        /* extended but not stderr */
5937     ssh_pkt_getstring(pktin, &data, &length);
5938     if (data) {
5939         int bufsize = 0;
5940         c->v.v2.locwindow -= length;
5941         switch (c->type) {
5942           case CHAN_MAINSESSION:
5943             bufsize =
5944                 from_backend(ssh->frontend, pktin->type ==
5945                              SSH2_MSG_CHANNEL_EXTENDED_DATA,
5946                              data, length);
5947             break;
5948           case CHAN_X11:
5949             bufsize = x11_send(c->u.x11.s, data, length);
5950             break;
5951           case CHAN_SOCKDATA:
5952             bufsize = pfd_send(c->u.pfd.s, data, length);
5953             break;
5954           case CHAN_AGENT:
5955             while (length > 0) {
5956                 if (c->u.a.lensofar < 4) {
5957                     unsigned int l = min(4 - c->u.a.lensofar, length);
5958                     memcpy(c->u.a.msglen + c->u.a.lensofar,
5959                            data, l);
5960                     data += l;
5961                     length -= l;
5962                     c->u.a.lensofar += l;
5963                 }
5964                 if (c->u.a.lensofar == 4) {
5965                     c->u.a.totallen =
5966                         4 + GET_32BIT(c->u.a.msglen);
5967                     c->u.a.message = snewn(c->u.a.totallen,
5968                                            unsigned char);
5969                     memcpy(c->u.a.message, c->u.a.msglen, 4);
5970                 }
5971                 if (c->u.a.lensofar >= 4 && length > 0) {
5972                     unsigned int l =
5973                         min(c->u.a.totallen - c->u.a.lensofar,
5974                             length);
5975                     memcpy(c->u.a.message + c->u.a.lensofar,
5976                            data, l);
5977                     data += l;
5978                     length -= l;
5979                     c->u.a.lensofar += l;
5980                 }
5981                 if (c->u.a.lensofar == c->u.a.totallen) {
5982                     void *reply;
5983                     int replylen;
5984                     if (agent_query(c->u.a.message,
5985                                     c->u.a.totallen,
5986                                     &reply, &replylen,
5987                                     ssh_agentf_callback, c))
5988                         ssh_agentf_callback(c, reply, replylen);
5989                     sfree(c->u.a.message);
5990                     c->u.a.lensofar = 0;
5991                 }
5992             }
5993             bufsize = 0;
5994             break;
5995         }
5996         /*
5997          * If we are not buffering too much data,
5998          * enlarge the window again at the remote side.
5999          */
6000         if (bufsize < OUR_V2_WINSIZE)
6001             ssh2_set_window(c, OUR_V2_WINSIZE - bufsize);
6002     }
6003 }
6004
6005 static void ssh2_msg_channel_eof(Ssh ssh, struct Packet *pktin)
6006 {
6007     unsigned i = ssh_pkt_getuint32(pktin);
6008     struct ssh_channel *c;
6009
6010     c = find234(ssh->channels, &i, ssh_channelfind);
6011     if (!c)
6012         return;                        /* nonexistent channel */
6013
6014     if (c->type == CHAN_X11) {
6015         /*
6016          * Remote EOF on an X11 channel means we should
6017          * wrap up and close the channel ourselves.
6018          */
6019         x11_close(c->u.x11.s);
6020         sshfwd_close(c);
6021     } else if (c->type == CHAN_AGENT) {
6022         sshfwd_close(c);
6023     } else if (c->type == CHAN_SOCKDATA) {
6024         pfd_close(c->u.pfd.s);
6025         sshfwd_close(c);
6026     }
6027 }
6028
6029 static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
6030 {
6031     unsigned i = ssh_pkt_getuint32(pktin);
6032     struct ssh_channel *c;
6033     struct Packet *pktout;
6034
6035     c = find234(ssh->channels, &i, ssh_channelfind);
6036     if (!c || c->halfopen) {
6037         bombout(("Received CHANNEL_CLOSE for %s channel %d\n",
6038                  c ? "half-open" : "nonexistent", i));
6039         return;
6040     }
6041     /* Do pre-close processing on the channel. */
6042     switch (c->type) {
6043       case CHAN_MAINSESSION:
6044         ssh->mainchan = NULL;
6045         update_specials_menu(ssh->frontend);
6046         break;
6047       case CHAN_X11:
6048         if (c->u.x11.s != NULL)
6049             x11_close(c->u.x11.s);
6050         sshfwd_close(c);
6051         break;
6052       case CHAN_AGENT:
6053         sshfwd_close(c);
6054         break;
6055       case CHAN_SOCKDATA:
6056         if (c->u.pfd.s != NULL)
6057             pfd_close(c->u.pfd.s);
6058         sshfwd_close(c);
6059         break;
6060     }
6061     if (c->closes == 0) {
6062         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6063         ssh2_pkt_adduint32(pktout, c->remoteid);
6064         ssh2_pkt_send(ssh, pktout);
6065     }
6066     del234(ssh->channels, c);
6067     bufchain_clear(&c->v.v2.outbuffer);
6068     sfree(c);
6069
6070     /*
6071      * See if that was the last channel left open.
6072      * (This is only our termination condition if we're
6073      * not running in -N mode.)
6074      */
6075     if (!ssh->cfg.ssh_no_shell && count234(ssh->channels) == 0) {
6076         /*
6077          * We used to send SSH_MSG_DISCONNECT here,
6078          * because I'd believed that _every_ conforming
6079          * SSH-2 connection had to end with a disconnect
6080          * being sent by at least one side; apparently
6081          * I was wrong and it's perfectly OK to
6082          * unceremoniously slam the connection shut
6083          * when you're done, and indeed OpenSSH feels
6084          * this is more polite than sending a
6085          * DISCONNECT. So now we don't.
6086          */
6087         ssh_disconnect(ssh, "All channels closed", NULL, 0, TRUE);
6088     }
6089 }
6090
6091 static void ssh2_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
6092 {
6093     unsigned i = ssh_pkt_getuint32(pktin);
6094     struct ssh_channel *c;
6095     struct Packet *pktout;
6096
6097     c = find234(ssh->channels, &i, ssh_channelfind);
6098     if (!c)
6099         return;                        /* nonexistent channel */
6100     if (c->type != CHAN_SOCKDATA_DORMANT)
6101         return;                        /* dunno why they're confirming this */
6102     c->remoteid = ssh_pkt_getuint32(pktin);
6103     c->halfopen = FALSE;
6104     c->type = CHAN_SOCKDATA;
6105     c->v.v2.remwindow = ssh_pkt_getuint32(pktin);
6106     c->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
6107     if (c->u.pfd.s)
6108         pfd_confirm(c->u.pfd.s);
6109     if (c->closes) {
6110         /*
6111          * We have a pending close on this channel,
6112          * which we decided on before the server acked
6113          * the channel open. So now we know the
6114          * remoteid, we can close it again.
6115          */
6116         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6117         ssh2_pkt_adduint32(pktout, c->remoteid);
6118         ssh2_pkt_send(ssh, pktout);
6119     }
6120 }
6121
6122 static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
6123 {
6124     static const char *const reasons[] = {
6125         "<unknown reason code>",
6126             "Administratively prohibited",
6127             "Connect failed",
6128             "Unknown channel type",
6129             "Resource shortage",
6130     };
6131     unsigned i = ssh_pkt_getuint32(pktin);
6132     unsigned reason_code;
6133     char *reason_string;
6134     int reason_length;
6135     struct ssh_channel *c;
6136     c = find234(ssh->channels, &i, ssh_channelfind);
6137     if (!c)
6138         return;                        /* nonexistent channel */
6139     if (c->type != CHAN_SOCKDATA_DORMANT)
6140         return;                        /* dunno why they're failing this */
6141
6142     reason_code = ssh_pkt_getuint32(pktin);
6143     if (reason_code >= lenof(reasons))
6144         reason_code = 0; /* ensure reasons[reason_code] in range */
6145     ssh_pkt_getstring(pktin, &reason_string, &reason_length);
6146     logeventf(ssh, "Forwarded connection refused by server: %s [%.*s]",
6147               reasons[reason_code], reason_length, reason_string);
6148
6149     pfd_close(c->u.pfd.s);
6150
6151     del234(ssh->channels, c);
6152     sfree(c);
6153 }
6154
6155 static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin)
6156 {
6157     unsigned localid;
6158     char *type;
6159     int typelen, want_reply;
6160     int reply = SSH2_MSG_CHANNEL_FAILURE; /* default */
6161     struct ssh_channel *c;
6162     struct Packet *pktout;
6163
6164     localid = ssh_pkt_getuint32(pktin);
6165     ssh_pkt_getstring(pktin, &type, &typelen);
6166     want_reply = ssh2_pkt_getbool(pktin);
6167
6168     /*
6169      * First, check that the channel exists. Otherwise,
6170      * we can instantly disconnect with a rude message.
6171      */
6172     c = find234(ssh->channels, &localid, ssh_channelfind);
6173     if (!c) {
6174         char *buf = dupprintf("Received channel request for nonexistent"
6175                               " channel %d", localid);
6176         ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6177         sfree(buf);
6178         return;
6179     }
6180
6181     /*
6182      * Having got the channel number, we now look at
6183      * the request type string to see if it's something
6184      * we recognise.
6185      */
6186     if (c == ssh->mainchan) {
6187         /*
6188          * We recognise "exit-status" and "exit-signal" on
6189          * the primary channel.
6190          */
6191         if (typelen == 11 &&
6192             !memcmp(type, "exit-status", 11)) {
6193
6194             ssh->exitcode = ssh_pkt_getuint32(pktin);
6195             logeventf(ssh, "Server sent command exit status %d",
6196                       ssh->exitcode);
6197             reply = SSH2_MSG_CHANNEL_SUCCESS;
6198
6199         } else if (typelen == 11 &&
6200                    !memcmp(type, "exit-signal", 11)) {
6201
6202             int is_plausible = TRUE, is_int = FALSE;
6203             char *fmt_sig = "", *fmt_msg = "";
6204             char *msg;
6205             int msglen = 0, core = FALSE;
6206             /* ICK: older versions of OpenSSH (e.g. 3.4p1)
6207              * provide an `int' for the signal, despite its
6208              * having been a `string' in the drafts since at
6209              * least 2001. (Fixed in session.c 1.147.) Try to
6210              * infer which we can safely parse it as. */
6211             {
6212                 unsigned char *p = pktin->body +
6213                     pktin->savedpos;
6214                 long len = pktin->length - pktin->savedpos;
6215                 unsigned long num = GET_32BIT(p); /* what is it? */
6216                 /* If it's 0, it hardly matters; assume string */
6217                 if (num == 0) {
6218                     is_int = FALSE;
6219                 } else {
6220                     int maybe_int = FALSE, maybe_str = FALSE;
6221 #define CHECK_HYPOTHESIS(offset, result) \
6222     do { \
6223         long q = offset; \
6224         if (q >= 0 && q+4 <= len) { \
6225             q = q + 4 + GET_32BIT(p+q); \
6226             if (q >= 0 && q+4 <= len && \
6227                     ((q = q + 4 + GET_32BIT(p+q))!= 0) && q == len) \
6228                 result = TRUE; \
6229         } \
6230     } while(0)
6231                     CHECK_HYPOTHESIS(4+1, maybe_int);
6232                     CHECK_HYPOTHESIS(4+num+1, maybe_str);
6233 #undef CHECK_HYPOTHESIS
6234                     if (maybe_int && !maybe_str)
6235                         is_int = TRUE;
6236                     else if (!maybe_int && maybe_str)
6237                         is_int = FALSE;
6238                     else
6239                         /* Crikey. Either or neither. Panic. */
6240                         is_plausible = FALSE;
6241                 }
6242             }
6243             if (is_plausible) {
6244                 if (is_int) {
6245                     /* Old non-standard OpenSSH. */
6246                     int signum = ssh_pkt_getuint32(pktin);
6247                     fmt_sig = dupprintf(" %d", signum);
6248                 } else {
6249                     /* As per the drafts. */
6250                     char *sig;
6251                     int siglen;
6252                     ssh_pkt_getstring(pktin, &sig, &siglen);
6253                     /* Signal name isn't supposed to be blank, but
6254                      * let's cope gracefully if it is. */
6255                     if (siglen) {
6256                         fmt_sig = dupprintf(" \"%.*s\"",
6257                                             siglen, sig);
6258                     }
6259                 }
6260                 core = ssh2_pkt_getbool(pktin);
6261                 ssh_pkt_getstring(pktin, &msg, &msglen);
6262                 if (msglen) {
6263                     fmt_msg = dupprintf(" (\"%.*s\")", msglen, msg);
6264                 }
6265                 /* ignore lang tag */
6266             } /* else don't attempt to parse */
6267             logeventf(ssh, "Server exited on signal%s%s%s",
6268                       fmt_sig, core ? " (core dumped)" : "",
6269                       fmt_msg);
6270             if (*fmt_sig) sfree(fmt_sig);
6271             if (*fmt_msg) sfree(fmt_msg);
6272             reply = SSH2_MSG_CHANNEL_SUCCESS;
6273
6274         }
6275     } else {
6276         /*
6277          * This is a channel request we don't know
6278          * about, so we now either ignore the request
6279          * or respond with CHANNEL_FAILURE, depending
6280          * on want_reply.
6281          */
6282         reply = SSH2_MSG_CHANNEL_FAILURE;
6283     }
6284     if (want_reply) {
6285         pktout = ssh2_pkt_init(reply);
6286         ssh2_pkt_adduint32(pktout, c->remoteid);
6287         ssh2_pkt_send(ssh, pktout);
6288     }
6289 }
6290
6291 static void ssh2_msg_global_request(Ssh ssh, struct Packet *pktin)
6292 {
6293     char *type;
6294     int typelen, want_reply;
6295     struct Packet *pktout;
6296
6297     ssh_pkt_getstring(pktin, &type, &typelen);
6298     want_reply = ssh2_pkt_getbool(pktin);
6299
6300     /*
6301      * We currently don't support any global requests
6302      * at all, so we either ignore the request or
6303      * respond with REQUEST_FAILURE, depending on
6304      * want_reply.
6305      */
6306     if (want_reply) {
6307         pktout = ssh2_pkt_init(SSH2_MSG_REQUEST_FAILURE);
6308         ssh2_pkt_send(ssh, pktout);
6309     }
6310 }
6311
6312 static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin)
6313 {
6314     char *type;
6315     int typelen;
6316     char *peeraddr;
6317     int peeraddrlen;
6318     int peerport;
6319     char *error = NULL;
6320     struct ssh_channel *c;
6321     unsigned remid, winsize, pktsize;
6322     struct Packet *pktout;
6323
6324     ssh_pkt_getstring(pktin, &type, &typelen);
6325     c = snew(struct ssh_channel);
6326     c->ssh = ssh;
6327
6328     remid = ssh_pkt_getuint32(pktin);
6329     winsize = ssh_pkt_getuint32(pktin);
6330     pktsize = ssh_pkt_getuint32(pktin);
6331
6332     if (typelen == 3 && !memcmp(type, "x11", 3)) {
6333         char *addrstr;
6334
6335         ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
6336         addrstr = snewn(peeraddrlen+1, char);
6337         memcpy(addrstr, peeraddr, peeraddrlen);
6338         addrstr[peeraddrlen] = '\0';
6339         peerport = ssh_pkt_getuint32(pktin);
6340
6341         logeventf(ssh, "Received X11 connect request from %s:%d",
6342                   addrstr, peerport);
6343
6344         if (!ssh->X11_fwd_enabled)
6345             error = "X11 forwarding is not enabled";
6346         else if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c,
6347                           ssh->x11auth, addrstr, peerport,
6348                           &ssh->cfg) != NULL) {
6349             error = "Unable to open an X11 connection";
6350         } else {
6351             logevent("Opening X11 forward connection succeeded");
6352             c->type = CHAN_X11;
6353         }
6354
6355         sfree(addrstr);
6356     } else if (typelen == 15 &&
6357                !memcmp(type, "forwarded-tcpip", 15)) {
6358         struct ssh_rportfwd pf, *realpf;
6359         char *dummy;
6360         int dummylen;
6361         ssh_pkt_getstring(pktin, &dummy, &dummylen);/* skip address */
6362         pf.sport = ssh_pkt_getuint32(pktin);
6363         ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
6364         peerport = ssh_pkt_getuint32(pktin);
6365         realpf = find234(ssh->rportfwds, &pf, NULL);
6366         logeventf(ssh, "Received remote port %d open request "
6367                   "from %s:%d", pf.sport, peeraddr, peerport);
6368         if (realpf == NULL) {
6369             error = "Remote port is not recognised";
6370         } else {
6371             const char *e = pfd_newconnect(&c->u.pfd.s,
6372                                            realpf->dhost,
6373                                            realpf->dport, c,
6374                                            &ssh->cfg,
6375                                            realpf->pfrec->addressfamily);
6376             logeventf(ssh, "Attempting to forward remote port to "
6377                       "%s:%d", realpf->dhost, realpf->dport);
6378             if (e != NULL) {
6379                 logeventf(ssh, "Port open failed: %s", e);
6380                 error = "Port open failed";
6381             } else {
6382                 logevent("Forwarded port opened successfully");
6383                 c->type = CHAN_SOCKDATA;
6384             }
6385         }
6386     } else if (typelen == 22 &&
6387                !memcmp(type, "auth-agent@openssh.com", 22)) {
6388         if (!ssh->agentfwd_enabled)
6389             error = "Agent forwarding is not enabled";
6390         else {
6391             c->type = CHAN_AGENT;       /* identify channel type */
6392             c->u.a.lensofar = 0;
6393         }
6394     } else {
6395         error = "Unsupported channel type requested";
6396     }
6397
6398     c->remoteid = remid;
6399     c->halfopen = FALSE;
6400     if (error) {
6401         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_FAILURE);
6402         ssh2_pkt_adduint32(pktout, c->remoteid);
6403         ssh2_pkt_adduint32(pktout, SSH2_OPEN_CONNECT_FAILED);
6404         ssh2_pkt_addstring(pktout, error);
6405         ssh2_pkt_addstring(pktout, "en");       /* language tag */
6406         ssh2_pkt_send(ssh, pktout);
6407         logeventf(ssh, "Rejected channel open: %s", error);
6408         sfree(c);
6409     } else {
6410         c->localid = alloc_channel_id(ssh);
6411         c->closes = 0;
6412         c->v.v2.locwindow = OUR_V2_WINSIZE;
6413         c->v.v2.remwindow = winsize;
6414         c->v.v2.remmaxpkt = pktsize;
6415         bufchain_init(&c->v.v2.outbuffer);
6416         add234(ssh->channels, c);
6417         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
6418         ssh2_pkt_adduint32(pktout, c->remoteid);
6419         ssh2_pkt_adduint32(pktout, c->localid);
6420         ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);
6421         ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT);      /* our max pkt size */
6422         ssh2_pkt_send(ssh, pktout);
6423     }
6424 }
6425
6426 /*
6427  * Buffer banner messages for later display at some convenient point.
6428  */
6429 static void ssh2_msg_userauth_banner(Ssh ssh, struct Packet *pktin)
6430 {
6431     /* Arbitrary limit to prevent unbounded inflation of buffer */
6432     if (bufchain_size(&ssh->banner) <= 131072) {
6433         char *banner = NULL;
6434         int size = 0;
6435         ssh_pkt_getstring(pktin, &banner, &size);
6436         if (banner)
6437             bufchain_add(&ssh->banner, banner, size);
6438     }
6439 }
6440
6441 /* Helper function to deal with sending tty modes for "pty-req" */
6442 static void ssh2_send_ttymode(void *data, char *mode, char *val)
6443 {
6444     struct Packet *pktout = (struct Packet *)data;
6445     int i = 0;
6446     unsigned int arg = 0;
6447     while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
6448     if (i == lenof(ssh_ttymodes)) return;
6449     switch (ssh_ttymodes[i].type) {
6450       case TTY_OP_CHAR:
6451         arg = ssh_tty_parse_specchar(val);
6452         break;
6453       case TTY_OP_BOOL:
6454         arg = ssh_tty_parse_boolean(val);
6455         break;
6456     }
6457     ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
6458     ssh2_pkt_adduint32(pktout, arg);
6459 }
6460
6461 /*
6462  * Handle the SSH-2 userauth and connection layers.
6463  */
6464 static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
6465                              struct Packet *pktin)
6466 {
6467     struct do_ssh2_authconn_state {
6468         enum {
6469             AUTH_INVALID, AUTH_PUBLICKEY_AGENT, AUTH_PUBLICKEY_FILE,
6470                 AUTH_PASSWORD,
6471                 AUTH_KEYBOARD_INTERACTIVE
6472         } method;
6473         enum {
6474             AUTH_TYPE_NONE,
6475                 AUTH_TYPE_PUBLICKEY,
6476                 AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
6477                 AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
6478                 AUTH_TYPE_PASSWORD,
6479                 AUTH_TYPE_KEYBOARD_INTERACTIVE,
6480                 AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
6481         } type;
6482         int done_service_req;
6483         int gotit, need_pw, can_pubkey, can_passwd, can_keyb_inter;
6484         int tried_pubkey_config, tried_agent;
6485         int kbd_inter_running, kbd_inter_refused;
6486         int we_are_in;
6487         int num_prompts, curr_prompt, echo;
6488         char username[100];
6489         int got_username;
6490         char pwprompt[512];
6491         char password[100];
6492         void *publickey_blob;
6493         int publickey_bloblen;
6494         unsigned char request[5], *response, *p;
6495         int responselen;
6496         int keyi, nkeys;
6497         int authed;
6498         char *pkblob, *alg, *commentp;
6499         int pklen, alglen, commentlen;
6500         int siglen, retlen, len;
6501         char *q, *agentreq, *ret;
6502         int try_send;
6503         int num_env, env_left, env_ok;
6504         struct Packet *pktout;
6505     };
6506     crState(do_ssh2_authconn_state);
6507
6508     crBegin(ssh->do_ssh2_authconn_crstate);
6509
6510     s->done_service_req = FALSE;
6511     s->we_are_in = FALSE;
6512     if (!ssh->cfg.ssh_no_userauth) {
6513         /*
6514          * Request userauth protocol, and await a response to it.
6515          */
6516         s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
6517         ssh2_pkt_addstring(s->pktout, "ssh-userauth");
6518         ssh2_pkt_send(ssh, s->pktout);
6519         crWaitUntilV(pktin);
6520         if (pktin->type == SSH2_MSG_SERVICE_ACCEPT)
6521             s->done_service_req = TRUE;
6522     }
6523     if (!s->done_service_req) {
6524         /*
6525          * Request connection protocol directly, without authentication.
6526          */
6527         s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
6528         ssh2_pkt_addstring(s->pktout, "ssh-connection");
6529         ssh2_pkt_send(ssh, s->pktout);
6530         crWaitUntilV(pktin);
6531         if (pktin->type == SSH2_MSG_SERVICE_ACCEPT) {
6532             s->we_are_in = TRUE; /* no auth required */
6533         } else {
6534             bombout(("Server refused service request"));
6535             crStopV;
6536         }
6537     }
6538
6539     /*
6540      * We repeat this whole loop, including the username prompt,
6541      * until we manage a successful authentication. If the user
6542      * types the wrong _password_, they can be sent back to the
6543      * beginning to try another username, if this is configured on.
6544      * (If they specify a username in the config, they are never
6545      * asked, even if they do give a wrong password.)
6546      * 
6547      * I think this best serves the needs of
6548      * 
6549      *  - the people who have no configuration, no keys, and just
6550      *    want to try repeated (username,password) pairs until they
6551      *    type both correctly
6552      * 
6553      *  - people who have keys and configuration but occasionally
6554      *    need to fall back to passwords
6555      * 
6556      *  - people with a key held in Pageant, who might not have
6557      *    logged in to a particular machine before; so they want to
6558      *    type a username, and then _either_ their key will be
6559      *    accepted, _or_ they will type a password. If they mistype
6560      *    the username they will want to be able to get back and
6561      *    retype it!
6562      */
6563     s->username[0] = '\0';
6564     s->got_username = FALSE;
6565     bufchain_init(&ssh->banner);
6566     ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] =
6567         ssh2_msg_userauth_banner;
6568     while (!s->we_are_in) {
6569         /*
6570          * Get a username.
6571          */
6572         if (s->got_username && !ssh->cfg.change_username) {
6573             /*
6574              * We got a username last time round this loop, and
6575              * with change_username turned off we don't try to get
6576              * it again.
6577              */
6578         } else if (!*ssh->cfg.username) {
6579             if (ssh_get_line && !ssh_getline_pw_only) {
6580                 if (!ssh_get_line("login as: ",
6581                                   s->username, sizeof(s->username), FALSE)) {
6582                     /*
6583                      * get_line failed to get a username.
6584                      * Terminate.
6585                      */
6586                     ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
6587                     crStopV;
6588                 }
6589             } else {
6590                 int ret;               /* need not be saved across crReturn */
6591                 c_write_str(ssh, "login as: ");
6592                 ssh->send_ok = 1;
6593                 setup_userpass_input(ssh, s->username, sizeof(s->username), 1);
6594                 do {
6595                     crWaitUntilV(!pktin);
6596                     ret = process_userpass_input(ssh, in, inlen);
6597                 } while (ret == 0);
6598                 if (ret < 0)
6599                     cleanup_exit(0);
6600                 c_write_str(ssh, "\r\n");
6601             }
6602             s->username[strcspn(s->username, "\n\r")] = '\0';
6603         } else {
6604             char *stuff;
6605             strncpy(s->username, ssh->cfg.username, sizeof(s->username));
6606             s->username[sizeof(s->username)-1] = '\0';
6607             if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
6608                 stuff = dupprintf("Using username \"%s\".\r\n", s->username);
6609                 c_write_str(ssh, stuff);
6610                 sfree(stuff);
6611             }
6612         }
6613         s->got_username = TRUE;
6614
6615         /*
6616          * Send an authentication request using method "none": (a)
6617          * just in case it succeeds, and (b) so that we know what
6618          * authentication methods we can usefully try next.
6619          */
6620         ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
6621
6622         s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
6623         ssh2_pkt_addstring(s->pktout, s->username);
6624         ssh2_pkt_addstring(s->pktout, "ssh-connection");/* service requested */
6625         ssh2_pkt_addstring(s->pktout, "none");    /* method */
6626         ssh2_pkt_send(ssh, s->pktout);
6627         s->type = AUTH_TYPE_NONE;
6628         s->gotit = FALSE;
6629         s->we_are_in = FALSE;
6630
6631         s->tried_pubkey_config = FALSE;
6632         s->tried_agent = FALSE;
6633         s->kbd_inter_running = FALSE;
6634         s->kbd_inter_refused = FALSE;
6635         /* Load the pub half of ssh->cfg.keyfile so we notice if it's in Pageant */
6636         if (!filename_is_null(ssh->cfg.keyfile)) {
6637             int keytype;
6638             logeventf(ssh, "Reading private key file \"%.150s\"",
6639                       filename_to_str(&ssh->cfg.keyfile));
6640             keytype = key_type(&ssh->cfg.keyfile);
6641             if (keytype == SSH_KEYTYPE_SSH2) {
6642                 s->publickey_blob =
6643                     ssh2_userkey_loadpub(&ssh->cfg.keyfile, NULL,
6644                                          &s->publickey_bloblen, NULL, NULL);
6645             } else {
6646                 char *msgbuf;
6647                 logeventf(ssh, "Unable to use this key file (%s)",
6648                           key_type_to_str(keytype));
6649                 msgbuf = dupprintf("Unable to use key file \"%.150s\""
6650                                    " (%s)\r\n",
6651                                    filename_to_str(&ssh->cfg.keyfile),
6652                                    key_type_to_str(keytype));
6653                 c_write_str(ssh, msgbuf);
6654                 sfree(msgbuf);
6655                 s->publickey_blob = NULL;
6656             }
6657         } else
6658             s->publickey_blob = NULL;
6659
6660         while (1) {
6661             /*
6662              * Wait for the result of the last authentication request.
6663              */
6664             if (!s->gotit)
6665                 crWaitUntilV(pktin);
6666             /*
6667              * Now is a convenient point to spew any banner material
6668              * that we've accumulated. (This should ensure that when
6669              * we exit the auth loop, we haven't any left to deal
6670              * with.)
6671              */
6672             {
6673                 int size = bufchain_size(&ssh->banner);
6674                 /*
6675                  * Don't show the banner if we're operating in
6676                  * non-verbose non-interactive mode. (It's probably
6677                  * a script, which means nobody will read the
6678                  * banner _anyway_, and moreover the printing of
6679                  * the banner will screw up processing on the
6680                  * output of (say) plink.)
6681                  */
6682                 if (size && (flags & (FLAG_VERBOSE | FLAG_INTERACTIVE))) {
6683                     char *banner = snewn(size, char);
6684                     bufchain_fetch(&ssh->banner, banner, size);
6685                     c_write_untrusted(ssh, banner, size);
6686                     sfree(banner);
6687                 }
6688                 bufchain_clear(&ssh->banner);
6689             }
6690             if (pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
6691                 logevent("Access granted");
6692                 s->we_are_in = TRUE;
6693                 break;
6694             }
6695
6696             if (s->kbd_inter_running &&
6697                 pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
6698                 /*
6699                  * This is either a further set-of-prompts packet
6700                  * in keyboard-interactive authentication, or it's
6701                  * the same one and we came back here with `gotit'
6702                  * set. In the former case, we must reset the
6703                  * curr_prompt variable.
6704                  */
6705                 if (!s->gotit)
6706                     s->curr_prompt = 0;
6707             } else if (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
6708                 /* FIXME: perhaps we should support this? */
6709                 bombout(("PASSWD_CHANGEREQ not yet supported"));
6710                 crStopV;
6711             } else if (pktin->type != SSH2_MSG_USERAUTH_FAILURE) {
6712                 bombout(("Strange packet received during authentication: type %d",
6713                          pktin->type));
6714                 crStopV;
6715             }
6716
6717             s->gotit = FALSE;
6718
6719             /*
6720              * OK, we're now sitting on a USERAUTH_FAILURE message, so
6721              * we can look at the string in it and know what we can
6722              * helpfully try next.
6723              */
6724             if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
6725                 char *methods;
6726                 int methlen;
6727                 ssh_pkt_getstring(pktin, &methods, &methlen);
6728                 s->kbd_inter_running = FALSE;
6729                 if (!ssh2_pkt_getbool(pktin)) {
6730                     /*
6731                      * We have received an unequivocal Access
6732                      * Denied. This can translate to a variety of
6733                      * messages:
6734                      * 
6735                      *  - if we'd just tried "none" authentication,
6736                      *    it's not worth printing anything at all
6737                      * 
6738                      *  - if we'd just tried a public key _offer_,
6739                      *    the message should be "Server refused our
6740                      *    key" (or no message at all if the key
6741                      *    came from Pageant)
6742                      * 
6743                      *  - if we'd just tried anything else, the
6744                      *    message really should be "Access denied".
6745                      * 
6746                      * Additionally, if we'd just tried password
6747                      * authentication, we should break out of this
6748                      * whole loop so as to go back to the username
6749                      * prompt (iff we're configured to allow
6750                      * username change attempts).
6751                      */
6752                     if (s->type == AUTH_TYPE_NONE) {
6753                         /* do nothing */
6754                     } else if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
6755                                s->type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
6756                         if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
6757                             c_write_str(ssh, "Server refused our key\r\n");
6758                         logevent("Server refused public key");
6759                     } else if (s->type==AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET) {
6760                         /* server declined keyboard-interactive; ignore */
6761                     } else {
6762                         c_write_str(ssh, "Access denied\r\n");
6763                         logevent("Access denied");
6764                         if (s->type == AUTH_TYPE_PASSWORD &&
6765                             ssh->cfg.change_username) {
6766                             /* XXX perhaps we should allow
6767                              * keyboard-interactive to do this too? */
6768                             s->we_are_in = FALSE;
6769                             break;
6770                         }
6771                     }
6772                 } else {
6773                     c_write_str(ssh, "Further authentication required\r\n");
6774                     logevent("Further authentication required");
6775                 }
6776
6777                 s->can_pubkey =
6778                     in_commasep_string("publickey", methods, methlen);
6779                 s->can_passwd =
6780                     in_commasep_string("password", methods, methlen);
6781                 s->can_keyb_inter = ssh->cfg.try_ki_auth &&
6782                     in_commasep_string("keyboard-interactive", methods, methlen);
6783             }
6784
6785             s->method = 0;
6786             ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
6787             s->need_pw = FALSE;
6788
6789             /*
6790              * Most password/passphrase prompts will be
6791              * non-echoing, so we set this to 0 by default.
6792              * Exception is that some keyboard-interactive prompts
6793              * can be echoing, in which case we'll set this to 1.
6794              */
6795             s->echo = 0;
6796
6797             if (!s->method && s->can_pubkey &&
6798                 agent_exists() && !s->tried_agent) {
6799                 /*
6800                  * Attempt public-key authentication using Pageant.
6801                  */
6802                 void *r;
6803                 s->authed = FALSE;
6804
6805                 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
6806                 ssh->pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
6807
6808                 s->tried_agent = TRUE;
6809
6810                 logevent("Pageant is running. Requesting keys.");
6811
6812                 /* Request the keys held by the agent. */
6813                 PUT_32BIT(s->request, 1);
6814                 s->request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
6815                 if (!agent_query(s->request, 5, &r, &s->responselen,
6816                                  ssh_agent_callback, ssh)) {
6817                     do {
6818                         crReturnV;
6819                         if (pktin) {
6820                             bombout(("Unexpected data from server while"
6821                                      " waiting for agent response"));
6822                             crStopV;
6823                         }
6824                     } while (pktin || inlen > 0);
6825                     r = ssh->agent_response;
6826                     s->responselen = ssh->agent_response_len;
6827                 }
6828                 s->response = (unsigned char *) r;
6829                 if (s->response && s->responselen >= 5 &&
6830                     s->response[4] == SSH2_AGENT_IDENTITIES_ANSWER) {
6831                     s->p = s->response + 5;
6832                     s->nkeys = GET_32BIT(s->p);
6833                     s->p += 4;
6834                     logeventf(ssh, "Pageant has %d SSH-2 keys", s->nkeys);
6835                     for (s->keyi = 0; s->keyi < s->nkeys; s->keyi++) {
6836                         void *vret;
6837
6838                         logeventf(ssh, "Trying Pageant key #%d", s->keyi);
6839                         s->pklen = GET_32BIT(s->p);
6840                         s->p += 4;
6841                         if (s->publickey_blob &&
6842                             s->pklen == s->publickey_bloblen &&
6843                             !memcmp(s->p, s->publickey_blob,
6844                                     s->publickey_bloblen)) {
6845                             logevent("This key matches configured key file");
6846                             s->tried_pubkey_config = 1;
6847                         }
6848                         s->pkblob = (char *)s->p;
6849                         s->p += s->pklen;
6850                         s->alglen = GET_32BIT(s->pkblob);
6851                         s->alg = s->pkblob + 4;
6852                         s->commentlen = GET_32BIT(s->p);
6853                         s->p += 4;
6854                         s->commentp = (char *)s->p;
6855                         s->p += s->commentlen;
6856                         s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
6857                         ssh2_pkt_addstring(s->pktout, s->username);
6858                         ssh2_pkt_addstring(s->pktout, "ssh-connection");        /* service requested */
6859                         ssh2_pkt_addstring(s->pktout, "publickey");     /* method */
6860                         ssh2_pkt_addbool(s->pktout, FALSE);     /* no signature included */
6861                         ssh2_pkt_addstring_start(s->pktout);
6862                         ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
6863                         ssh2_pkt_addstring_start(s->pktout);
6864                         ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
6865                         ssh2_pkt_send(ssh, s->pktout);
6866
6867                         crWaitUntilV(pktin);
6868                         if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
6869                             logevent("Key refused");
6870                             continue;
6871                         }
6872
6873                         if (flags & FLAG_VERBOSE) {
6874                             c_write_str(ssh, "Authenticating with "
6875                                         "public key \"");
6876                             c_write(ssh, s->commentp, s->commentlen);
6877                             c_write_str(ssh, "\" from agent\r\n");
6878                         }
6879
6880                         /*
6881                          * Server is willing to accept the key.
6882                          * Construct a SIGN_REQUEST.
6883                          */
6884                         s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
6885                         ssh2_pkt_addstring(s->pktout, s->username);
6886                         ssh2_pkt_addstring(s->pktout, "ssh-connection");        /* service requested */
6887                         ssh2_pkt_addstring(s->pktout, "publickey");     /* method */
6888                         ssh2_pkt_addbool(s->pktout, TRUE);
6889                         ssh2_pkt_addstring_start(s->pktout);
6890                         ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
6891                         ssh2_pkt_addstring_start(s->pktout);
6892                         ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
6893
6894                         s->siglen = s->pktout->length - 5 + 4 +
6895                             ssh->v2_session_id_len;
6896                         if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
6897                             s->siglen -= 4;
6898                         s->len = 1;       /* message type */
6899                         s->len += 4 + s->pklen; /* key blob */
6900                         s->len += 4 + s->siglen;        /* data to sign */
6901                         s->len += 4;      /* flags */
6902                         s->agentreq = snewn(4 + s->len, char);
6903                         PUT_32BIT(s->agentreq, s->len);
6904                         s->q = s->agentreq + 4;
6905                         *s->q++ = SSH2_AGENTC_SIGN_REQUEST;
6906                         PUT_32BIT(s->q, s->pklen);
6907                         s->q += 4;
6908                         memcpy(s->q, s->pkblob, s->pklen);
6909                         s->q += s->pklen;
6910                         PUT_32BIT(s->q, s->siglen);
6911                         s->q += 4;
6912                         /* Now the data to be signed... */
6913                         if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
6914                             PUT_32BIT(s->q, ssh->v2_session_id_len);
6915                             s->q += 4;
6916                         }
6917                         memcpy(s->q, ssh->v2_session_id,
6918                                ssh->v2_session_id_len);
6919                         s->q += ssh->v2_session_id_len;
6920                         memcpy(s->q, s->pktout->data + 5,
6921                                s->pktout->length - 5);
6922                         s->q += s->pktout->length - 5;
6923                         /* And finally the (zero) flags word. */
6924                         PUT_32BIT(s->q, 0);
6925                         if (!agent_query(s->agentreq, s->len + 4,
6926                                          &vret, &s->retlen,
6927                                          ssh_agent_callback, ssh)) {
6928                             do {
6929                                 crReturnV;
6930                                 if (pktin) {
6931                                     bombout(("Unexpected data from server"
6932                                              " while waiting for agent"
6933                                              " response"));
6934                                     crStopV;
6935                                 }
6936                             } while (pktin || inlen > 0);
6937                             vret = ssh->agent_response;
6938                             s->retlen = ssh->agent_response_len;
6939                         }
6940                         s->ret = vret;
6941                         sfree(s->agentreq);
6942                         if (s->ret) {
6943                             if (s->ret[4] == SSH2_AGENT_SIGN_RESPONSE) {
6944                                 logevent("Sending Pageant's response");
6945                                 ssh2_add_sigblob(ssh, s->pktout,
6946                                                  s->pkblob, s->pklen,
6947                                                  s->ret + 9,
6948                                                  GET_32BIT(s->ret + 5));
6949                                 ssh2_pkt_send(ssh, s->pktout);
6950                                 s->authed = TRUE;
6951                                 break;
6952                             } else {
6953                                 logevent
6954                                     ("Pageant failed to answer challenge");
6955                                 sfree(s->ret);
6956                             }
6957                         }
6958                     }
6959                     if (s->authed)
6960                         continue;
6961                 }
6962                 sfree(s->response);
6963             }
6964
6965             if (!s->method && s->can_pubkey && s->publickey_blob
6966                 && !s->tried_pubkey_config) {
6967                 unsigned char *pub_blob;
6968                 char *algorithm, *comment;
6969                 int pub_blob_len;
6970
6971                 s->tried_pubkey_config = TRUE;
6972
6973                 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
6974                 ssh->pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
6975
6976                 /*
6977                  * Try the public key supplied in the configuration.
6978                  *
6979                  * First, offer the public blob to see if the server is
6980                  * willing to accept it.
6981                  */
6982                 pub_blob =
6983                     (unsigned char *)ssh2_userkey_loadpub(&ssh->cfg.keyfile,
6984                                                           &algorithm,
6985                                                           &pub_blob_len,
6986                                                           NULL, NULL);
6987                 if (pub_blob) {
6988                     s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
6989                     ssh2_pkt_addstring(s->pktout, s->username);
6990                     ssh2_pkt_addstring(s->pktout, "ssh-connection");    /* service requested */
6991                     ssh2_pkt_addstring(s->pktout, "publickey"); /* method */
6992                     ssh2_pkt_addbool(s->pktout, FALSE); /* no signature included */
6993                     ssh2_pkt_addstring(s->pktout, algorithm);
6994                     ssh2_pkt_addstring_start(s->pktout);
6995                     ssh2_pkt_addstring_data(s->pktout, (char *)pub_blob,
6996                                             pub_blob_len);
6997                     ssh2_pkt_send(ssh, s->pktout);
6998                     logevent("Offered public key");
6999
7000                     crWaitUntilV(pktin);
7001                     if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
7002                         s->gotit = TRUE;
7003                         s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
7004                         continue;      /* key refused; give up on it */
7005                     }
7006
7007                     logevent("Offer of public key accepted");
7008                     /*
7009                      * Actually attempt a serious authentication using
7010                      * the key.
7011                      */
7012                     if (ssh2_userkey_encrypted(&ssh->cfg.keyfile, &comment)) {
7013                         sprintf(s->pwprompt,
7014                                 "Passphrase for key \"%.100s\": ",
7015                                 comment);
7016                         s->need_pw = TRUE;
7017                     } else {
7018                         s->need_pw = FALSE;
7019                     }
7020                     if (flags & FLAG_VERBOSE) {
7021                         c_write_str(ssh, "Authenticating with public key \"");
7022                         c_write_str(ssh, comment);
7023                         c_write_str(ssh, "\"\r\n");
7024                     }
7025                     s->method = AUTH_PUBLICKEY_FILE;
7026                 }
7027             }
7028
7029             if (!s->method && s->can_keyb_inter && !s->kbd_inter_refused &&
7030                 !s->kbd_inter_running) {
7031                 s->method = AUTH_KEYBOARD_INTERACTIVE;
7032                 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
7033
7034                 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7035                 ssh->pkt_ctx |= SSH2_PKTCTX_KBDINTER;
7036
7037                 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7038                 ssh2_pkt_addstring(s->pktout, s->username);
7039                 ssh2_pkt_addstring(s->pktout, "ssh-connection");        /* service requested */
7040                 ssh2_pkt_addstring(s->pktout, "keyboard-interactive");  /* method */
7041                 ssh2_pkt_addstring(s->pktout, ""); /* lang */
7042                 ssh2_pkt_addstring(s->pktout, "");
7043                 ssh2_pkt_send(ssh, s->pktout);
7044
7045                 crWaitUntilV(pktin);
7046                 if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
7047                     if (pktin->type == SSH2_MSG_USERAUTH_FAILURE)
7048                         s->gotit = TRUE;
7049                     logevent("Keyboard-interactive authentication refused");
7050                     s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
7051                     s->kbd_inter_refused = TRUE; /* don't try it again */
7052                     continue;
7053                 }
7054
7055                 c_write_str(ssh, "Using keyboard-interactive authentication.\r\n");
7056                 s->kbd_inter_running = TRUE;
7057                 s->curr_prompt = 0;
7058             }
7059
7060             if (s->kbd_inter_running) {
7061                 s->method = AUTH_KEYBOARD_INTERACTIVE;
7062                 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
7063
7064                 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7065                 ssh->pkt_ctx |= SSH2_PKTCTX_KBDINTER;
7066
7067                 if (s->curr_prompt == 0) {
7068                     /*
7069                      * We've got a fresh USERAUTH_INFO_REQUEST.
7070                      * Display header data, and start going through
7071                      * the prompts.
7072                      */
7073                     char *name, *inst, *lang;
7074                     int name_len, inst_len, lang_len;
7075
7076                     ssh_pkt_getstring(pktin, &name, &name_len);
7077                     ssh_pkt_getstring(pktin, &inst, &inst_len);
7078                     ssh_pkt_getstring(pktin, &lang, &lang_len);
7079                     if (name_len > 0) {
7080                         c_write_untrusted(ssh, name, name_len);
7081                         c_write_str(ssh, "\r\n");
7082                     }
7083                     if (inst_len > 0) {
7084                         c_write_untrusted(ssh, inst, inst_len);
7085                         c_write_str(ssh, "\r\n");
7086                     }
7087                     s->num_prompts = ssh_pkt_getuint32(pktin);
7088                 }
7089
7090                 /*
7091                  * If there are prompts remaining in the packet,
7092                  * display one and get a response.
7093                  */
7094                 if (s->curr_prompt < s->num_prompts) {
7095                     char *prompt;
7096                     int prompt_len;
7097
7098                     ssh_pkt_getstring(pktin, &prompt, &prompt_len);
7099                     if (prompt_len > 0) {
7100                         static const char trunc[] = "<prompt truncated>: ";
7101                         static const int prlen = sizeof(s->pwprompt) -
7102                                                  lenof(trunc);
7103                         if (prompt_len > prlen) {
7104                             memcpy(s->pwprompt, prompt, prlen);
7105                             strcpy(s->pwprompt + prlen, trunc);
7106                         } else {
7107                             memcpy(s->pwprompt, prompt, prompt_len);
7108                             s->pwprompt[prompt_len] = '\0';
7109                         }
7110                     } else {
7111                         strcpy(s->pwprompt,
7112                                "<server failed to send prompt>: ");
7113                     }
7114                     s->echo = ssh2_pkt_getbool(pktin);
7115                     s->need_pw = TRUE;
7116                 } else
7117                     s->need_pw = FALSE;
7118             }
7119
7120             if (!s->method && s->can_passwd) {
7121                 s->method = AUTH_PASSWORD;
7122                 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7123                 ssh->pkt_ctx |= SSH2_PKTCTX_PASSWORD;
7124                 sprintf(s->pwprompt, "%.90s@%.90s's password: ", s->username,
7125                         ssh->savedhost);
7126                 s->need_pw = TRUE;
7127             }
7128
7129             if (s->need_pw) {
7130                 if (ssh_get_line) {
7131                     if (!ssh_get_line(s->pwprompt, s->password,
7132                                       sizeof(s->password), TRUE)) {
7133                         /*
7134                          * get_line failed to get a password (for
7135                          * example because one was supplied on the
7136                          * command line which has already failed to
7137                          * work). Terminate.
7138                          */
7139                         ssh_disconnect(ssh, NULL, "Unable to authenticate",
7140                                        SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7141                                        FALSE);
7142                         crStopV;
7143                     }
7144                 } else {
7145                     int ret;           /* need not be saved across crReturn */
7146                     c_write_untrusted(ssh, s->pwprompt, strlen(s->pwprompt));
7147                     ssh->send_ok = 1;
7148
7149                     setup_userpass_input(ssh, s->password,
7150                                          sizeof(s->password), s->echo);
7151                     do {
7152                         crWaitUntilV(!pktin);
7153                         ret = process_userpass_input(ssh, in, inlen);
7154                     } while (ret == 0);
7155                     if (ret < 0)
7156                         cleanup_exit(0);
7157                     c_write_str(ssh, "\r\n");
7158                 }
7159             }
7160
7161             if (s->method == AUTH_PUBLICKEY_FILE) {
7162                 /*
7163                  * We have our passphrase. Now try the actual authentication.
7164                  */
7165                 struct ssh2_userkey *key;
7166                 const char *error = NULL;
7167
7168                 key = ssh2_load_userkey(&ssh->cfg.keyfile, s->password,
7169                                         &error);
7170                 if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
7171                     if (key == SSH2_WRONG_PASSPHRASE) {
7172                         c_write_str(ssh, "Wrong passphrase\r\n");
7173                         s->tried_pubkey_config = FALSE;
7174                     } else {
7175                         c_write_str(ssh, "Unable to load private key (");
7176                         c_write_str(ssh, error);
7177                         c_write_str(ssh, ")\r\n");
7178                         s->tried_pubkey_config = TRUE;
7179                     }
7180                     /* Send a spurious AUTH_NONE to return to the top. */
7181                     s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7182                     ssh2_pkt_addstring(s->pktout, s->username);
7183                     ssh2_pkt_addstring(s->pktout, "ssh-connection");    /* service requested */
7184                     ssh2_pkt_addstring(s->pktout, "none");      /* method */
7185                     ssh2_pkt_send(ssh, s->pktout);
7186                     s->type = AUTH_TYPE_NONE;
7187                 } else {
7188                     unsigned char *pkblob, *sigblob, *sigdata;
7189                     int pkblob_len, sigblob_len, sigdata_len;
7190                     int p;
7191
7192                     /*
7193                      * We have loaded the private key and the server
7194                      * has announced that it's willing to accept it.
7195                      * Hallelujah. Generate a signature and send it.
7196                      */
7197                     s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7198                     ssh2_pkt_addstring(s->pktout, s->username);
7199                     ssh2_pkt_addstring(s->pktout, "ssh-connection");    /* service requested */
7200                     ssh2_pkt_addstring(s->pktout, "publickey"); /* method */
7201                     ssh2_pkt_addbool(s->pktout, TRUE);
7202                     ssh2_pkt_addstring(s->pktout, key->alg->name);
7203                     pkblob = key->alg->public_blob(key->data, &pkblob_len);
7204                     ssh2_pkt_addstring_start(s->pktout);
7205                     ssh2_pkt_addstring_data(s->pktout, (char *)pkblob, pkblob_len);
7206
7207                     /*
7208                      * The data to be signed is:
7209                      *
7210                      *   string  session-id
7211                      *
7212                      * followed by everything so far placed in the
7213                      * outgoing packet.
7214                      */
7215                     sigdata_len = s->pktout->length - 5 + 4 +
7216                         ssh->v2_session_id_len;
7217                     if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7218                         sigdata_len -= 4;
7219                     sigdata = snewn(sigdata_len, unsigned char);
7220                     p = 0;
7221                     if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7222                         PUT_32BIT(sigdata+p, ssh->v2_session_id_len);
7223                         p += 4;
7224                     }
7225                     memcpy(sigdata+p, ssh->v2_session_id,
7226                            ssh->v2_session_id_len);
7227                     p += ssh->v2_session_id_len;
7228                     memcpy(sigdata+p, s->pktout->data + 5,
7229                            s->pktout->length - 5);
7230                     p += s->pktout->length - 5;
7231                     assert(p == sigdata_len);
7232                     sigblob = key->alg->sign(key->data, (char *)sigdata,
7233                                              sigdata_len, &sigblob_len);
7234                     ssh2_add_sigblob(ssh, s->pktout, pkblob, pkblob_len,
7235                                      sigblob, sigblob_len);
7236                     sfree(pkblob);
7237                     sfree(sigblob);
7238                     sfree(sigdata);
7239
7240                     ssh2_pkt_send(ssh, s->pktout);
7241                     s->type = AUTH_TYPE_PUBLICKEY;
7242                     key->alg->freekey(key->data);
7243                 }
7244             } else if (s->method == AUTH_PASSWORD) {
7245                 /*
7246                  * We pad out the password packet to 256 bytes to make
7247                  * it harder for an attacker to find the length of the
7248                  * user's password.
7249                  *
7250                  * Anyone using a password longer than 256 bytes
7251                  * probably doesn't have much to worry about from
7252                  * people who find out how long their password is!
7253                  */
7254                 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7255                 s->pktout->forcepad = 256;
7256                 ssh2_pkt_addstring(s->pktout, s->username);
7257                 ssh2_pkt_addstring(s->pktout, "ssh-connection");        /* service requested */
7258                 ssh2_pkt_addstring(s->pktout, "password");
7259                 ssh2_pkt_addbool(s->pktout, FALSE);
7260                 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
7261                 ssh2_pkt_addstring(s->pktout, s->password);
7262                 memset(s->password, 0, sizeof(s->password));
7263                 end_log_omission(ssh, s->pktout);
7264                 ssh2_pkt_send(ssh, s->pktout);
7265                 logevent("Sent password");
7266                 s->type = AUTH_TYPE_PASSWORD;
7267             } else if (s->method == AUTH_KEYBOARD_INTERACTIVE) {
7268                 if (s->curr_prompt == 0) {
7269                     s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_INFO_RESPONSE);
7270                     s->pktout->forcepad = 256;
7271                     ssh2_pkt_adduint32(s->pktout, s->num_prompts);
7272                 }
7273                 if (s->need_pw) {      /* only add pw if we just got one! */
7274                     dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
7275                     ssh2_pkt_addstring(s->pktout, s->password);
7276                     memset(s->password, 0, sizeof(s->password));
7277                     end_log_omission(ssh, s->pktout);
7278                     s->curr_prompt++;
7279                 }
7280                 if (s->curr_prompt >= s->num_prompts) {
7281                     ssh2_pkt_send(ssh, s->pktout);
7282                 } else {
7283                     /*
7284                      * If there are prompts remaining, we set
7285                      * `gotit' so that we won't attempt to get
7286                      * another packet. Then we go back round the
7287                      * loop and will end up retrieving another
7288                      * prompt out of the existing packet. Funky or
7289                      * what?
7290                      */
7291                     s->gotit = TRUE;
7292                 }
7293                 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
7294             } else {
7295                 ssh_disconnect(ssh, NULL,
7296                                "No supported authentication methods available",
7297                                SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
7298                                FALSE);
7299                 crStopV;
7300             }
7301         }
7302     }
7303     ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
7304
7305     /*
7306      * Now the connection protocol has started, one way or another.
7307      */
7308
7309     ssh->channels = newtree234(ssh_channelcmp);
7310
7311     /*
7312      * Set up handlers for some connection protocol messages, so we
7313      * don't have to handle them repeatedly in this coroutine.
7314      */
7315     ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] =
7316         ssh2_msg_channel_window_adjust;
7317     ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] =
7318         ssh2_msg_global_request;
7319
7320     /*
7321      * Create the main session channel.
7322      */
7323     if (!ssh->cfg.ssh_no_shell) {
7324         ssh->mainchan = snew(struct ssh_channel);
7325         ssh->mainchan->ssh = ssh;
7326         ssh->mainchan->localid = alloc_channel_id(ssh);
7327         s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
7328         ssh2_pkt_addstring(s->pktout, "session");
7329         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
7330         ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
7331         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
7332         ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT);    /* our max pkt size */
7333         ssh2_pkt_send(ssh, s->pktout);
7334         crWaitUntilV(pktin);
7335         if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
7336             bombout(("Server refused to open a session"));
7337             crStopV;
7338             /* FIXME: error data comes back in FAILURE packet */
7339         }
7340         if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
7341             bombout(("Server's channel confirmation cited wrong channel"));
7342             crStopV;
7343         }
7344         ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
7345         ssh->mainchan->halfopen = FALSE;
7346         ssh->mainchan->type = CHAN_MAINSESSION;
7347         ssh->mainchan->closes = 0;
7348         ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
7349         ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
7350         bufchain_init(&ssh->mainchan->v.v2.outbuffer);
7351         add234(ssh->channels, ssh->mainchan);
7352         update_specials_menu(ssh->frontend);
7353         logevent("Opened channel for session");
7354     } else
7355         ssh->mainchan = NULL;
7356
7357     /*
7358      * Now we have a channel, make dispatch table entries for
7359      * general channel-based messages.
7360      */
7361     ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] =
7362     ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] =
7363         ssh2_msg_channel_data;
7364     ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_channel_eof;
7365     ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_channel_close;
7366     ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] =
7367         ssh2_msg_channel_open_confirmation;
7368     ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] =
7369         ssh2_msg_channel_open_failure;
7370     ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] =
7371         ssh2_msg_channel_request;
7372     ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] =
7373         ssh2_msg_channel_open;
7374
7375     /*
7376      * Potentially enable X11 forwarding.
7377      */
7378     if (ssh->mainchan && ssh->cfg.x11_forward) {
7379         char proto[20], data[64];
7380         logevent("Requesting X11 forwarding");
7381         ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
7382                                        data, sizeof(data), ssh->cfg.x11_auth);
7383         x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
7384         s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7385         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
7386         ssh2_pkt_addstring(s->pktout, "x11-req");
7387         ssh2_pkt_addbool(s->pktout, 1);        /* want reply */
7388         ssh2_pkt_addbool(s->pktout, 0);        /* many connections */
7389         ssh2_pkt_addstring(s->pktout, proto);
7390         /*
7391          * Note that while we blank the X authentication data here, we don't
7392          * take any special action to blank the start of an X11 channel,
7393          * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
7394          * without having session blanking enabled is likely to leak your
7395          * cookie into the log.
7396          */
7397         dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
7398         ssh2_pkt_addstring(s->pktout, data);
7399         end_log_omission(ssh, s->pktout);
7400         ssh2_pkt_adduint32(s->pktout, x11_get_screen_number(ssh->cfg.x11_display));
7401         ssh2_pkt_send(ssh, s->pktout);
7402
7403         crWaitUntilV(pktin);
7404
7405         if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
7406             if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
7407                 bombout(("Unexpected response to X11 forwarding request:"
7408                          " packet type %d", pktin->type));
7409                 crStopV;
7410             }
7411             logevent("X11 forwarding refused");
7412         } else {
7413             logevent("X11 forwarding enabled");
7414             ssh->X11_fwd_enabled = TRUE;
7415         }
7416     }
7417
7418     /*
7419      * Enable port forwardings.
7420      */
7421     ssh_setup_portfwd(ssh, &ssh->cfg);
7422
7423     /*
7424      * Potentially enable agent forwarding.
7425      */
7426     if (ssh->mainchan && ssh->cfg.agentfwd && agent_exists()) {
7427         logevent("Requesting OpenSSH-style agent forwarding");
7428         s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7429         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
7430         ssh2_pkt_addstring(s->pktout, "auth-agent-req@openssh.com");
7431         ssh2_pkt_addbool(s->pktout, 1);        /* want reply */
7432         ssh2_pkt_send(ssh, s->pktout);
7433
7434         crWaitUntilV(pktin);
7435
7436         if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
7437             if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
7438                 bombout(("Unexpected response to agent forwarding request:"
7439                          " packet type %d", pktin->type));
7440                 crStopV;
7441             }
7442             logevent("Agent forwarding refused");
7443         } else {
7444             logevent("Agent forwarding enabled");
7445             ssh->agentfwd_enabled = TRUE;
7446         }
7447     }
7448
7449     /*
7450      * Now allocate a pty for the session.
7451      */
7452     if (ssh->mainchan && !ssh->cfg.nopty) {
7453         /* Unpick the terminal-speed string. */
7454         /* XXX perhaps we should allow no speeds to be sent. */
7455         ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
7456         sscanf(ssh->cfg.termspeed, "%d,%d", &ssh->ospeed, &ssh->ispeed);
7457         /* Build the pty request. */
7458         s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7459         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); /* recipient channel */
7460         ssh2_pkt_addstring(s->pktout, "pty-req");
7461         ssh2_pkt_addbool(s->pktout, 1);        /* want reply */
7462         ssh2_pkt_addstring(s->pktout, ssh->cfg.termtype);
7463         ssh2_pkt_adduint32(s->pktout, ssh->term_width);
7464         ssh2_pkt_adduint32(s->pktout, ssh->term_height);
7465         ssh2_pkt_adduint32(s->pktout, 0);              /* pixel width */
7466         ssh2_pkt_adduint32(s->pktout, 0);              /* pixel height */
7467         ssh2_pkt_addstring_start(s->pktout);
7468         parse_ttymodes(ssh, ssh->cfg.ttymodes,
7469                        ssh2_send_ttymode, (void *)s->pktout);
7470         ssh2_pkt_addbyte(s->pktout, SSH2_TTY_OP_ISPEED);
7471         ssh2_pkt_adduint32(s->pktout, ssh->ispeed);
7472         ssh2_pkt_addbyte(s->pktout, SSH2_TTY_OP_OSPEED);
7473         ssh2_pkt_adduint32(s->pktout, ssh->ospeed);
7474         ssh2_pkt_addstring_data(s->pktout, "\0", 1); /* TTY_OP_END */
7475         ssh2_pkt_send(ssh, s->pktout);
7476         ssh->state = SSH_STATE_INTERMED;
7477
7478         crWaitUntilV(pktin);
7479
7480         if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
7481             if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
7482                 bombout(("Unexpected response to pty request:"
7483                          " packet type %d", pktin->type));
7484                 crStopV;
7485             }
7486             c_write_str(ssh, "Server refused to allocate pty\r\n");
7487             ssh->editing = ssh->echoing = 1;
7488         } else {
7489             logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
7490                       ssh->ospeed, ssh->ispeed);
7491         }
7492     } else {
7493         ssh->editing = ssh->echoing = 1;
7494     }
7495
7496     /*
7497      * Send environment variables.
7498      * 
7499      * Simplest thing here is to send all the requests at once, and
7500      * then wait for a whole bunch of successes or failures.
7501      */
7502     if (ssh->mainchan && *ssh->cfg.environmt) {
7503         char *e = ssh->cfg.environmt;
7504         char *var, *varend, *val;
7505
7506         s->num_env = 0;
7507
7508         while (*e) {
7509             var = e;
7510             while (*e && *e != '\t') e++;
7511             varend = e;
7512             if (*e == '\t') e++;
7513             val = e;
7514             while (*e) e++;
7515             e++;
7516
7517             s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7518             ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
7519             ssh2_pkt_addstring(s->pktout, "env");
7520             ssh2_pkt_addbool(s->pktout, 1);            /* want reply */
7521             ssh2_pkt_addstring_start(s->pktout);
7522             ssh2_pkt_addstring_data(s->pktout, var, varend-var);
7523             ssh2_pkt_addstring(s->pktout, val);
7524             ssh2_pkt_send(ssh, s->pktout);
7525
7526             s->num_env++;
7527         }
7528
7529         logeventf(ssh, "Sent %d environment variables", s->num_env);
7530
7531         s->env_ok = 0;
7532         s->env_left = s->num_env;
7533
7534         while (s->env_left > 0) {
7535             crWaitUntilV(pktin);
7536
7537             if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
7538                 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
7539                     bombout(("Unexpected response to environment request:"
7540                              " packet type %d", pktin->type));
7541                     crStopV;
7542                 }
7543             } else {
7544                 s->env_ok++;
7545             }
7546
7547             s->env_left--;
7548         }
7549
7550         if (s->env_ok == s->num_env) {
7551             logevent("All environment variables successfully set");
7552         } else if (s->env_ok == 0) {
7553             logevent("All environment variables refused");
7554             c_write_str(ssh, "Server refused to set environment variables\r\n");
7555         } else {
7556             logeventf(ssh, "%d environment variables refused",
7557                       s->num_env - s->env_ok);
7558             c_write_str(ssh, "Server refused to set all environment variables\r\n");
7559         }
7560     }
7561
7562     /*
7563      * Start a shell or a remote command. We may have to attempt
7564      * this twice if the config data has provided a second choice
7565      * of command.
7566      */
7567     if (ssh->mainchan) while (1) {
7568         int subsys;
7569         char *cmd;
7570
7571         if (ssh->fallback_cmd) {
7572             subsys = ssh->cfg.ssh_subsys2;
7573             cmd = ssh->cfg.remote_cmd_ptr2;
7574         } else {
7575             subsys = ssh->cfg.ssh_subsys;
7576             cmd = ssh->cfg.remote_cmd_ptr;
7577             if (!cmd) cmd = ssh->cfg.remote_cmd;
7578         }
7579
7580         s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7581         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); /* recipient channel */
7582         if (subsys) {
7583             ssh2_pkt_addstring(s->pktout, "subsystem");
7584             ssh2_pkt_addbool(s->pktout, 1);            /* want reply */
7585             ssh2_pkt_addstring(s->pktout, cmd);
7586         } else if (*cmd) {
7587             ssh2_pkt_addstring(s->pktout, "exec");
7588             ssh2_pkt_addbool(s->pktout, 1);            /* want reply */
7589             ssh2_pkt_addstring(s->pktout, cmd);
7590         } else {
7591             ssh2_pkt_addstring(s->pktout, "shell");
7592             ssh2_pkt_addbool(s->pktout, 1);            /* want reply */
7593         }
7594         ssh2_pkt_send(ssh, s->pktout);
7595
7596         crWaitUntilV(pktin);
7597
7598         if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
7599             if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
7600                 bombout(("Unexpected response to shell/command request:"
7601                          " packet type %d", pktin->type));
7602                 crStopV;
7603             }
7604             /*
7605              * We failed to start the command. If this is the
7606              * fallback command, we really are finished; if it's
7607              * not, and if the fallback command exists, try falling
7608              * back to it before complaining.
7609              */
7610             if (!ssh->fallback_cmd && ssh->cfg.remote_cmd_ptr2 != NULL) {
7611                 logevent("Primary command failed; attempting fallback");
7612                 ssh->fallback_cmd = TRUE;
7613                 continue;
7614             }
7615             bombout(("Server refused to start a shell/command"));
7616             crStopV;
7617         } else {
7618             logevent("Started a shell/command");
7619         }
7620         break;
7621     }
7622
7623     ssh->state = SSH_STATE_SESSION;
7624     if (ssh->size_needed)
7625         ssh_size(ssh, ssh->term_width, ssh->term_height);
7626     if (ssh->eof_needed)
7627         ssh_special(ssh, TS_EOF);
7628
7629     /*
7630      * Transfer data!
7631      */
7632     if (ssh->ldisc)
7633         ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
7634     if (ssh->mainchan)
7635         ssh->send_ok = 1;
7636     while (1) {
7637         crReturnV;
7638         s->try_send = FALSE;
7639         if (pktin) {
7640
7641             /*
7642              * _All_ the connection-layer packets we expect to
7643              * receive are now handled by the dispatch table.
7644              * Anything that reaches here must be bogus.
7645              */
7646
7647             bombout(("Strange packet received: type %d", pktin->type));
7648             crStopV;
7649         } else if (ssh->mainchan) {
7650             /*
7651              * We have spare data. Add it to the channel buffer.
7652              */
7653             ssh2_add_channel_data(ssh->mainchan, (char *)in, inlen);
7654             s->try_send = TRUE;
7655         }
7656         if (s->try_send) {
7657             int i;
7658             struct ssh_channel *c;
7659             /*
7660              * Try to send data on all channels if we can.
7661              */
7662             for (i = 0; NULL != (c = index234(ssh->channels, i)); i++)
7663                 ssh2_try_send_and_unthrottle(c);
7664         }
7665     }
7666
7667     crFinishV;
7668 }
7669
7670 /*
7671  * Handlers for SSH-2 messages that might arrive at any moment.
7672  */
7673 static void ssh2_msg_disconnect(Ssh ssh, struct Packet *pktin)
7674 {
7675     /* log reason code in disconnect message */
7676     char *buf, *msg;
7677     int nowlen, reason, msglen;
7678
7679     reason = ssh_pkt_getuint32(pktin);
7680     ssh_pkt_getstring(pktin, &msg, &msglen);
7681
7682     if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {
7683         buf = dupprintf("Received disconnect message (%s)",
7684                         ssh2_disconnect_reasons[reason]);
7685     } else {
7686         buf = dupprintf("Received disconnect message (unknown"
7687                         " type %d)", reason);
7688     }
7689     logevent(buf);
7690     sfree(buf);
7691     buf = dupprintf("Disconnection message text: %n%.*s",
7692                     &nowlen, msglen, msg);
7693     logevent(buf);
7694     bombout(("Server sent disconnect message\ntype %d (%s):\n\"%s\"",
7695              reason,
7696              (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?
7697              ssh2_disconnect_reasons[reason] : "unknown",
7698              buf+nowlen));
7699     sfree(buf);
7700 }
7701
7702 static void ssh2_msg_debug(Ssh ssh, struct Packet *pktin)
7703 {
7704     /* log the debug message */
7705     char *msg;
7706     int msglen;
7707     int always_display;
7708
7709     /* XXX maybe we should actually take notice of this */
7710     always_display = ssh2_pkt_getbool(pktin);
7711     ssh_pkt_getstring(pktin, &msg, &msglen);
7712
7713     logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
7714 }
7715
7716 static void ssh2_msg_something_unimplemented(Ssh ssh, struct Packet *pktin)
7717 {
7718     struct Packet *pktout;
7719     pktout = ssh2_pkt_init(SSH2_MSG_UNIMPLEMENTED);
7720     ssh2_pkt_adduint32(pktout, pktin->sequence);
7721     /*
7722      * UNIMPLEMENTED messages MUST appear in the same order as the
7723      * messages they respond to. Hence, never queue them.
7724      */
7725     ssh2_pkt_send_noqueue(ssh, pktout);
7726 }
7727
7728 /*
7729  * Handle the top-level SSH-2 protocol.
7730  */
7731 static void ssh2_protocol_setup(Ssh ssh)
7732 {
7733     int i;
7734
7735     /*
7736      * Most messages cause SSH2_MSG_UNIMPLEMENTED.
7737      */
7738     for (i = 0; i < 256; i++)
7739         ssh->packet_dispatch[i] = ssh2_msg_something_unimplemented;
7740
7741     /*
7742      * Any message we actually understand, we set to NULL so that
7743      * the coroutines will get it.
7744      */
7745     ssh->packet_dispatch[SSH2_MSG_UNIMPLEMENTED] = NULL;
7746     ssh->packet_dispatch[SSH2_MSG_SERVICE_REQUEST] = NULL;
7747     ssh->packet_dispatch[SSH2_MSG_SERVICE_ACCEPT] = NULL;
7748     ssh->packet_dispatch[SSH2_MSG_KEXINIT] = NULL;
7749     ssh->packet_dispatch[SSH2_MSG_NEWKEYS] = NULL;
7750     ssh->packet_dispatch[SSH2_MSG_KEXDH_INIT] = NULL;
7751     ssh->packet_dispatch[SSH2_MSG_KEXDH_REPLY] = NULL;
7752     /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REQUEST] = NULL; duplicate case value */
7753     /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_GROUP] = NULL; duplicate case value */
7754     ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_INIT] = NULL;
7755     ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REPLY] = NULL;
7756     ssh->packet_dispatch[SSH2_MSG_USERAUTH_REQUEST] = NULL;
7757     ssh->packet_dispatch[SSH2_MSG_USERAUTH_FAILURE] = NULL;
7758     ssh->packet_dispatch[SSH2_MSG_USERAUTH_SUCCESS] = NULL;
7759     ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
7760     ssh->packet_dispatch[SSH2_MSG_USERAUTH_PK_OK] = NULL;
7761     /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ] = NULL; duplicate case value */
7762     /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_REQUEST] = NULL; duplicate case value */
7763     ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_RESPONSE] = NULL;
7764     ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] = NULL;
7765     ssh->packet_dispatch[SSH2_MSG_REQUEST_SUCCESS] = NULL;
7766     ssh->packet_dispatch[SSH2_MSG_REQUEST_FAILURE] = NULL;
7767     ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = NULL;
7768     ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] = NULL;
7769     ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] = NULL;
7770     ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] = NULL;
7771     ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] = NULL;
7772     ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] = NULL;
7773     ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = NULL;
7774     ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = NULL;
7775     ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] = NULL;
7776     ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = NULL;
7777     ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = NULL;
7778
7779     /*
7780      * These special message types we install handlers for.
7781      */
7782     ssh->packet_dispatch[SSH2_MSG_DISCONNECT] = ssh2_msg_disconnect;
7783     ssh->packet_dispatch[SSH2_MSG_IGNORE] = ssh_msg_ignore; /* shared with SSH-1 */
7784     ssh->packet_dispatch[SSH2_MSG_DEBUG] = ssh2_msg_debug;
7785 }
7786
7787 static void ssh2_timer(void *ctx, long now)
7788 {
7789     Ssh ssh = (Ssh)ctx;
7790
7791     if (ssh->state == SSH_STATE_CLOSED)
7792         return;
7793
7794     if (!ssh->kex_in_progress && ssh->cfg.ssh_rekey_time != 0 &&
7795         now - ssh->next_rekey >= 0) {
7796         do_ssh2_transport(ssh, "timeout", -1, NULL);
7797     }
7798 }
7799
7800 static void ssh2_protocol(Ssh ssh, void *vin, int inlen,
7801                           struct Packet *pktin)
7802 {
7803     unsigned char *in = (unsigned char *)vin;
7804     if (ssh->state == SSH_STATE_CLOSED)
7805         return;
7806
7807     if (pktin) {
7808         ssh->incoming_data_size += pktin->encrypted_len;
7809         if (!ssh->kex_in_progress &&
7810             ssh->max_data_size != 0 &&
7811             ssh->incoming_data_size > ssh->max_data_size)
7812             do_ssh2_transport(ssh, "too much data received", -1, NULL);
7813     }
7814
7815     if (pktin && ssh->packet_dispatch[pktin->type]) {
7816         ssh->packet_dispatch[pktin->type](ssh, pktin);
7817         return;
7818     }
7819
7820     if (!ssh->protocol_initial_phase_done ||
7821         (pktin && pktin->type >= 20 && pktin->type < 50)) {
7822         if (do_ssh2_transport(ssh, in, inlen, pktin) &&
7823             !ssh->protocol_initial_phase_done) {
7824             ssh->protocol_initial_phase_done = TRUE;
7825             /*
7826              * Allow authconn to initialise itself.
7827              */
7828             do_ssh2_authconn(ssh, NULL, 0, NULL);
7829         }
7830     } else {
7831         do_ssh2_authconn(ssh, in, inlen, pktin);
7832     }
7833 }
7834
7835 /*
7836  * Called to set up the connection.
7837  *
7838  * Returns an error message, or NULL on success.
7839  */
7840 static const char *ssh_init(void *frontend_handle, void **backend_handle,
7841                             Config *cfg,
7842                             char *host, int port, char **realhost, int nodelay,
7843                             int keepalive)
7844 {
7845     const char *p;
7846     Ssh ssh;
7847
7848     ssh = snew(struct ssh_tag);
7849     ssh->cfg = *cfg;                   /* STRUCTURE COPY */
7850     ssh->version = 0;                  /* when not ready yet */
7851     ssh->s = NULL;
7852     ssh->cipher = NULL;
7853     ssh->v1_cipher_ctx = NULL;
7854     ssh->crcda_ctx = NULL;
7855     ssh->cscipher = NULL;
7856     ssh->cs_cipher_ctx = NULL;
7857     ssh->sccipher = NULL;
7858     ssh->sc_cipher_ctx = NULL;
7859     ssh->csmac = NULL;
7860     ssh->cs_mac_ctx = NULL;
7861     ssh->scmac = NULL;
7862     ssh->sc_mac_ctx = NULL;
7863     ssh->cscomp = NULL;
7864     ssh->cs_comp_ctx = NULL;
7865     ssh->sccomp = NULL;
7866     ssh->sc_comp_ctx = NULL;
7867     ssh->kex = NULL;
7868     ssh->kex_ctx = NULL;
7869     ssh->hostkey = NULL;
7870     ssh->exitcode = -1;
7871     ssh->close_expected = FALSE;
7872     ssh->clean_exit = FALSE;
7873     ssh->state = SSH_STATE_PREPACKET;
7874     ssh->size_needed = FALSE;
7875     ssh->eof_needed = FALSE;
7876     ssh->ldisc = NULL;
7877     ssh->logctx = NULL;
7878     ssh->deferred_send_data = NULL;
7879     ssh->deferred_len = 0;
7880     ssh->deferred_size = 0;
7881     ssh->fallback_cmd = 0;
7882     ssh->pkt_ctx = 0;
7883     ssh->x11auth = NULL;
7884     ssh->v1_compressing = FALSE;
7885     ssh->v2_outgoing_sequence = 0;
7886     ssh->ssh1_rdpkt_crstate = 0;
7887     ssh->ssh2_rdpkt_crstate = 0;
7888     ssh->do_ssh_init_crstate = 0;
7889     ssh->ssh_gotdata_crstate = 0;
7890     ssh->do_ssh1_connection_crstate = 0;
7891     ssh->do_ssh1_login_crstate = 0;
7892     ssh->do_ssh2_transport_crstate = 0;
7893     ssh->do_ssh2_authconn_crstate = 0;
7894     ssh->do_ssh_init_state = NULL;
7895     ssh->do_ssh1_login_state = NULL;
7896     ssh->do_ssh2_transport_state = NULL;
7897     ssh->do_ssh2_authconn_state = NULL;
7898     ssh->v_c = NULL;
7899     ssh->v_s = NULL;
7900     ssh->mainchan = NULL;
7901     ssh->throttled_all = 0;
7902     ssh->v1_stdout_throttling = 0;
7903     ssh->queue = NULL;
7904     ssh->queuelen = ssh->queuesize = 0;
7905     ssh->queueing = FALSE;
7906     ssh->qhead = ssh->qtail = NULL;
7907     ssh->deferred_rekey_reason = NULL;
7908     bufchain_init(&ssh->queued_incoming_data);
7909     ssh->frozen = FALSE;
7910
7911     *backend_handle = ssh;
7912
7913 #ifdef MSCRYPTOAPI
7914     if (crypto_startup() == 0)
7915         return "Microsoft high encryption pack not installed!";
7916 #endif
7917
7918     ssh->frontend = frontend_handle;
7919     ssh->term_width = ssh->cfg.width;
7920     ssh->term_height = ssh->cfg.height;
7921
7922     ssh->channels = NULL;
7923     ssh->rportfwds = NULL;
7924     ssh->portfwds = NULL;
7925
7926     ssh->send_ok = 0;
7927     ssh->editing = 0;
7928     ssh->echoing = 0;
7929     ssh->v1_throttle_count = 0;
7930     ssh->overall_bufsize = 0;
7931     ssh->fallback_cmd = 0;
7932
7933     ssh->protocol = NULL;
7934
7935     ssh->protocol_initial_phase_done = FALSE;
7936
7937     ssh->pinger = NULL;
7938
7939     ssh->incoming_data_size = ssh->outgoing_data_size =
7940         ssh->deferred_data_size = 0L;
7941     ssh->max_data_size = parse_blocksize(ssh->cfg.ssh_rekey_data);
7942     ssh->kex_in_progress = FALSE;
7943
7944     p = connect_to_host(ssh, host, port, realhost, nodelay, keepalive);
7945     if (p != NULL)
7946         return p;
7947
7948     random_ref();
7949
7950     return NULL;
7951 }
7952
7953 static void ssh_free(void *handle)
7954 {
7955     Ssh ssh = (Ssh) handle;
7956     struct ssh_channel *c;
7957     struct ssh_rportfwd *pf;
7958
7959     if (ssh->v1_cipher_ctx)
7960         ssh->cipher->free_context(ssh->v1_cipher_ctx);
7961     if (ssh->cs_cipher_ctx)
7962         ssh->cscipher->free_context(ssh->cs_cipher_ctx);
7963     if (ssh->sc_cipher_ctx)
7964         ssh->sccipher->free_context(ssh->sc_cipher_ctx);
7965     if (ssh->cs_mac_ctx)
7966         ssh->csmac->free_context(ssh->cs_mac_ctx);
7967     if (ssh->sc_mac_ctx)
7968         ssh->scmac->free_context(ssh->sc_mac_ctx);
7969     if (ssh->cs_comp_ctx) {
7970         if (ssh->cscomp)
7971             ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
7972         else
7973             zlib_compress_cleanup(ssh->cs_comp_ctx);
7974     }
7975     if (ssh->sc_comp_ctx) {
7976         if (ssh->sccomp)
7977             ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
7978         else
7979             zlib_decompress_cleanup(ssh->sc_comp_ctx);
7980     }
7981     if (ssh->kex_ctx)
7982         dh_cleanup(ssh->kex_ctx);
7983     sfree(ssh->savedhost);
7984
7985     while (ssh->queuelen-- > 0)
7986         ssh_free_packet(ssh->queue[ssh->queuelen]);
7987     sfree(ssh->queue);
7988
7989     while (ssh->qhead) {
7990         struct queued_handler *qh = ssh->qhead;
7991         ssh->qhead = qh->next;
7992         sfree(ssh->qhead);
7993     }
7994     ssh->qhead = ssh->qtail = NULL;
7995
7996     if (ssh->channels) {
7997         while ((c = delpos234(ssh->channels, 0)) != NULL) {
7998             switch (c->type) {
7999               case CHAN_X11:
8000                 if (c->u.x11.s != NULL)
8001                     x11_close(c->u.x11.s);
8002                 break;
8003               case CHAN_SOCKDATA:
8004                 if (c->u.pfd.s != NULL)
8005                     pfd_close(c->u.pfd.s);
8006                 break;
8007             }
8008             sfree(c);
8009         }
8010         freetree234(ssh->channels);
8011         ssh->channels = NULL;
8012     }
8013
8014     if (ssh->rportfwds) {
8015         while ((pf = delpos234(ssh->rportfwds, 0)) != NULL)
8016             sfree(pf);
8017         freetree234(ssh->rportfwds);
8018         ssh->rportfwds = NULL;
8019     }
8020     sfree(ssh->deferred_send_data);
8021     if (ssh->x11auth)
8022         x11_free_auth(ssh->x11auth);
8023     sfree(ssh->do_ssh_init_state);
8024     sfree(ssh->do_ssh1_login_state);
8025     sfree(ssh->do_ssh2_transport_state);
8026     sfree(ssh->do_ssh2_authconn_state);
8027     sfree(ssh->v_c);
8028     sfree(ssh->v_s);
8029     if (ssh->crcda_ctx) {
8030         crcda_free_context(ssh->crcda_ctx);
8031         ssh->crcda_ctx = NULL;
8032     }
8033     if (ssh->s)
8034         ssh_do_close(ssh, TRUE);
8035     expire_timer_context(ssh);
8036     if (ssh->pinger)
8037         pinger_free(ssh->pinger);
8038     bufchain_clear(&ssh->queued_incoming_data);
8039     sfree(ssh);
8040
8041     random_unref();
8042 }
8043
8044 /*
8045  * Reconfigure the SSH backend.
8046  */
8047 static void ssh_reconfig(void *handle, Config *cfg)
8048 {
8049     Ssh ssh = (Ssh) handle;
8050     char *rekeying = NULL, rekey_mandatory = FALSE;
8051     unsigned long old_max_data_size;
8052
8053     pinger_reconfig(ssh->pinger, &ssh->cfg, cfg);
8054     if (ssh->portfwds)
8055         ssh_setup_portfwd(ssh, cfg);
8056
8057     if (ssh->cfg.ssh_rekey_time != cfg->ssh_rekey_time &&
8058         cfg->ssh_rekey_time != 0) {
8059         long new_next = ssh->last_rekey + cfg->ssh_rekey_time*60*TICKSPERSEC;
8060         long now = GETTICKCOUNT();
8061
8062         if (new_next - now < 0) {
8063             rekeying = "timeout shortened";
8064         } else {
8065             ssh->next_rekey = schedule_timer(new_next - now, ssh2_timer, ssh);
8066         }
8067     }
8068
8069     old_max_data_size = ssh->max_data_size;
8070     ssh->max_data_size = parse_blocksize(cfg->ssh_rekey_data);
8071     if (old_max_data_size != ssh->max_data_size &&
8072         ssh->max_data_size != 0) {
8073         if (ssh->outgoing_data_size > ssh->max_data_size ||
8074             ssh->incoming_data_size > ssh->max_data_size)
8075             rekeying = "data limit lowered";
8076     }
8077
8078     if (ssh->cfg.compression != cfg->compression) {
8079         rekeying = "compression setting changed";
8080         rekey_mandatory = TRUE;
8081     }
8082
8083     if (ssh->cfg.ssh2_des_cbc != cfg->ssh2_des_cbc ||
8084         memcmp(ssh->cfg.ssh_cipherlist, cfg->ssh_cipherlist,
8085                sizeof(ssh->cfg.ssh_cipherlist))) {
8086         rekeying = "cipher settings changed";
8087         rekey_mandatory = TRUE;
8088     }
8089
8090     ssh->cfg = *cfg;                   /* STRUCTURE COPY */
8091
8092     if (rekeying) {
8093         if (!ssh->kex_in_progress) {
8094             do_ssh2_transport(ssh, rekeying, -1, NULL);
8095         } else if (rekey_mandatory) {
8096             ssh->deferred_rekey_reason = rekeying;
8097         }
8098     }
8099 }
8100
8101 /*
8102  * Called to send data down the SSH connection.
8103  */
8104 static int ssh_send(void *handle, char *buf, int len)
8105 {
8106     Ssh ssh = (Ssh) handle;
8107
8108     if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
8109         return 0;
8110
8111     ssh->protocol(ssh, (unsigned char *)buf, len, 0);
8112
8113     return ssh_sendbuffer(ssh);
8114 }
8115
8116 /*
8117  * Called to query the current amount of buffered stdin data.
8118  */
8119 static int ssh_sendbuffer(void *handle)
8120 {
8121     Ssh ssh = (Ssh) handle;
8122     int override_value;
8123
8124     if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
8125         return 0;
8126
8127     /*
8128      * If the SSH socket itself has backed up, add the total backup
8129      * size on that to any individual buffer on the stdin channel.
8130      */
8131     override_value = 0;
8132     if (ssh->throttled_all)
8133         override_value = ssh->overall_bufsize;
8134
8135     if (ssh->version == 1) {
8136         return override_value;
8137     } else if (ssh->version == 2) {
8138         if (!ssh->mainchan || ssh->mainchan->closes > 0)
8139             return override_value;
8140         else
8141             return (override_value +
8142                     bufchain_size(&ssh->mainchan->v.v2.outbuffer));
8143     }
8144
8145     return 0;
8146 }
8147
8148 /*
8149  * Called to set the size of the window from SSH's POV.
8150  */
8151 static void ssh_size(void *handle, int width, int height)
8152 {
8153     Ssh ssh = (Ssh) handle;
8154     struct Packet *pktout;
8155
8156     ssh->term_width = width;
8157     ssh->term_height = height;
8158
8159     switch (ssh->state) {
8160       case SSH_STATE_BEFORE_SIZE:
8161       case SSH_STATE_PREPACKET:
8162       case SSH_STATE_CLOSED:
8163         break;                         /* do nothing */
8164       case SSH_STATE_INTERMED:
8165         ssh->size_needed = TRUE;       /* buffer for later */
8166         break;
8167       case SSH_STATE_SESSION:
8168         if (!ssh->cfg.nopty) {
8169             if (ssh->version == 1) {
8170                 send_packet(ssh, SSH1_CMSG_WINDOW_SIZE,
8171                             PKT_INT, ssh->term_height,
8172                             PKT_INT, ssh->term_width,
8173                             PKT_INT, 0, PKT_INT, 0, PKT_END);
8174             } else if (ssh->mainchan) {
8175                 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8176                 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8177                 ssh2_pkt_addstring(pktout, "window-change");
8178                 ssh2_pkt_addbool(pktout, 0);
8179                 ssh2_pkt_adduint32(pktout, ssh->term_width);
8180                 ssh2_pkt_adduint32(pktout, ssh->term_height);
8181                 ssh2_pkt_adduint32(pktout, 0);
8182                 ssh2_pkt_adduint32(pktout, 0);
8183                 ssh2_pkt_send(ssh, pktout);
8184             }
8185         }
8186         break;
8187     }
8188 }
8189
8190 /*
8191  * Return a list of the special codes that make sense in this
8192  * protocol.
8193  */
8194 static const struct telnet_special *ssh_get_specials(void *handle)
8195 {
8196     static const struct telnet_special ssh1_ignore_special[] = {
8197         {"IGNORE message", TS_NOP}
8198     };
8199     static const struct telnet_special ssh2_transport_specials[] = {
8200         {"IGNORE message", TS_NOP},
8201         {"Repeat key exchange", TS_REKEY},
8202     };
8203     static const struct telnet_special ssh2_session_specials[] = {
8204         {NULL, TS_SEP},
8205         {"Break", TS_BRK},
8206         /* These are the signal names defined by draft-ietf-secsh-connect-23.
8207          * They include all the ISO C signals, but are a subset of the POSIX
8208          * required signals. */
8209         {"SIGINT (Interrupt)", TS_SIGINT},
8210         {"SIGTERM (Terminate)", TS_SIGTERM},
8211         {"SIGKILL (Kill)", TS_SIGKILL},
8212         {"SIGQUIT (Quit)", TS_SIGQUIT},
8213         {"SIGHUP (Hangup)", TS_SIGHUP},
8214         {"More signals", TS_SUBMENU},
8215           {"SIGABRT", TS_SIGABRT}, {"SIGALRM", TS_SIGALRM},
8216           {"SIGFPE",  TS_SIGFPE},  {"SIGILL",  TS_SIGILL},
8217           {"SIGPIPE", TS_SIGPIPE}, {"SIGSEGV", TS_SIGSEGV},
8218           {"SIGUSR1", TS_SIGUSR1}, {"SIGUSR2", TS_SIGUSR2},
8219         {NULL, TS_EXITMENU}
8220     };
8221     static const struct telnet_special specials_end[] = {
8222         {NULL, TS_EXITMENU}
8223     };
8224     /* XXX review this length for any changes: */
8225     static struct telnet_special ssh_specials[lenof(ssh2_transport_specials) +
8226                                               lenof(ssh2_session_specials) +
8227                                               lenof(specials_end)];
8228     Ssh ssh = (Ssh) handle;
8229     int i = 0;
8230 #define ADD_SPECIALS(name) \
8231     do { \
8232         assert((i + lenof(name)) <= lenof(ssh_specials)); \
8233         memcpy(&ssh_specials[i], name, sizeof name); \
8234         i += lenof(name); \
8235     } while(0)
8236
8237     if (ssh->version == 1) {
8238         /* Don't bother offering IGNORE if we've decided the remote
8239          * won't cope with it, since we wouldn't bother sending it if
8240          * asked anyway. */
8241         if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
8242             ADD_SPECIALS(ssh1_ignore_special);
8243     } else if (ssh->version == 2) {
8244         ADD_SPECIALS(ssh2_transport_specials);
8245         if (ssh->mainchan)
8246             ADD_SPECIALS(ssh2_session_specials);
8247     } /* else we're not ready yet */
8248
8249     if (i) {
8250         ADD_SPECIALS(specials_end);
8251         return ssh_specials;
8252     } else {
8253         return NULL;
8254     }
8255 #undef ADD_SPECIALS
8256 }
8257
8258 /*
8259  * Send special codes. TS_EOF is useful for `plink', so you
8260  * can send an EOF and collect resulting output (e.g. `plink
8261  * hostname sort').
8262  */
8263 static void ssh_special(void *handle, Telnet_Special code)
8264 {
8265     Ssh ssh = (Ssh) handle;
8266     struct Packet *pktout;
8267
8268     if (code == TS_EOF) {
8269         if (ssh->state != SSH_STATE_SESSION) {
8270             /*
8271              * Buffer the EOF in case we are pre-SESSION, so we can
8272              * send it as soon as we reach SESSION.
8273              */
8274             if (code == TS_EOF)
8275                 ssh->eof_needed = TRUE;
8276             return;
8277         }
8278         if (ssh->version == 1) {
8279             send_packet(ssh, SSH1_CMSG_EOF, PKT_END);
8280         } else if (ssh->mainchan) {
8281             struct Packet *pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
8282             ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8283             ssh2_pkt_send(ssh, pktout);
8284             ssh->send_ok = 0;          /* now stop trying to read from stdin */
8285         }
8286         logevent("Sent EOF message");
8287     } else if (code == TS_PING || code == TS_NOP) {
8288         if (ssh->state == SSH_STATE_CLOSED
8289             || ssh->state == SSH_STATE_PREPACKET) return;
8290         if (ssh->version == 1) {
8291             if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
8292                 send_packet(ssh, SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
8293         } else {
8294             pktout = ssh2_pkt_init(SSH2_MSG_IGNORE);
8295             ssh2_pkt_addstring_start(pktout);
8296             ssh2_pkt_send_noqueue(ssh, pktout);
8297         }
8298     } else if (code == TS_REKEY) {
8299         if (!ssh->kex_in_progress && ssh->version == 2) {
8300             do_ssh2_transport(ssh, "at user request", -1, NULL);
8301         }
8302     } else if (code == TS_BRK) {
8303         if (ssh->state == SSH_STATE_CLOSED
8304             || ssh->state == SSH_STATE_PREPACKET) return;
8305         if (ssh->version == 1) {
8306             logevent("Unable to send BREAK signal in SSH-1");
8307         } else if (ssh->mainchan) {
8308             pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8309             ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8310             ssh2_pkt_addstring(pktout, "break");
8311             ssh2_pkt_addbool(pktout, 0);
8312             ssh2_pkt_adduint32(pktout, 0);   /* default break length */
8313             ssh2_pkt_send(ssh, pktout);
8314         }
8315     } else {
8316         /* Is is a POSIX signal? */
8317         char *signame = NULL;
8318         if (code == TS_SIGABRT) signame = "ABRT";
8319         if (code == TS_SIGALRM) signame = "ALRM";
8320         if (code == TS_SIGFPE)  signame = "FPE";
8321         if (code == TS_SIGHUP)  signame = "HUP";
8322         if (code == TS_SIGILL)  signame = "ILL";
8323         if (code == TS_SIGINT)  signame = "INT";
8324         if (code == TS_SIGKILL) signame = "KILL";
8325         if (code == TS_SIGPIPE) signame = "PIPE";
8326         if (code == TS_SIGQUIT) signame = "QUIT";
8327         if (code == TS_SIGSEGV) signame = "SEGV";
8328         if (code == TS_SIGTERM) signame = "TERM";
8329         if (code == TS_SIGUSR1) signame = "USR1";
8330         if (code == TS_SIGUSR2) signame = "USR2";
8331         /* The SSH-2 protocol does in principle support arbitrary named
8332          * signals, including signame@domain, but we don't support those. */
8333         if (signame) {
8334             /* It's a signal. */
8335             if (ssh->version == 2 && ssh->mainchan) {
8336                 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8337                 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8338                 ssh2_pkt_addstring(pktout, "signal");
8339                 ssh2_pkt_addbool(pktout, 0);
8340                 ssh2_pkt_addstring(pktout, signame);
8341                 ssh2_pkt_send(ssh, pktout);
8342                 logeventf(ssh, "Sent signal SIG%s", signame);
8343             }
8344         } else {
8345             /* Never heard of it. Do nothing */
8346         }
8347     }
8348 }
8349
8350 void *new_sock_channel(void *handle, Socket s)
8351 {
8352     Ssh ssh = (Ssh) handle;
8353     struct ssh_channel *c;
8354     c = snew(struct ssh_channel);
8355     c->ssh = ssh;
8356
8357     if (c) {
8358         c->halfopen = TRUE;
8359         c->localid = alloc_channel_id(ssh);
8360         c->closes = 0;
8361         c->type = CHAN_SOCKDATA_DORMANT;/* identify channel type */
8362         c->u.pfd.s = s;
8363         bufchain_init(&c->v.v2.outbuffer);
8364         add234(ssh->channels, c);
8365     }
8366     return c;
8367 }
8368
8369 /*
8370  * This is called when stdout/stderr (the entity to which
8371  * from_backend sends data) manages to clear some backlog.
8372  */
8373 static void ssh_unthrottle(void *handle, int bufsize)
8374 {
8375     Ssh ssh = (Ssh) handle;
8376     if (ssh->version == 1) {
8377         if (ssh->v1_stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
8378             ssh->v1_stdout_throttling = 0;
8379             ssh1_throttle(ssh, -1);
8380         }
8381     } else {
8382         if (ssh->mainchan && ssh->mainchan->closes == 0)
8383             ssh2_set_window(ssh->mainchan, OUR_V2_WINSIZE - bufsize);
8384     }
8385 }
8386
8387 void ssh_send_port_open(void *channel, char *hostname, int port, char *org)
8388 {
8389     struct ssh_channel *c = (struct ssh_channel *)channel;
8390     Ssh ssh = c->ssh;
8391     struct Packet *pktout;
8392
8393     logeventf(ssh, "Opening forwarded connection to %s:%d", hostname, port);
8394
8395     if (ssh->version == 1) {
8396         send_packet(ssh, SSH1_MSG_PORT_OPEN,
8397                     PKT_INT, c->localid,
8398                     PKT_STR, hostname,
8399                     PKT_INT, port,
8400                     /* PKT_STR, <org:orgport>, */
8401                     PKT_END);
8402     } else {
8403         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
8404         ssh2_pkt_addstring(pktout, "direct-tcpip");
8405         ssh2_pkt_adduint32(pktout, c->localid);
8406         c->v.v2.locwindow = OUR_V2_WINSIZE;
8407         ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);/* our window size */
8408         ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT);      /* our max pkt size */
8409         ssh2_pkt_addstring(pktout, hostname);
8410         ssh2_pkt_adduint32(pktout, port);
8411         /*
8412          * We make up values for the originator data; partly it's
8413          * too much hassle to keep track, and partly I'm not
8414          * convinced the server should be told details like that
8415          * about my local network configuration.
8416          */
8417         ssh2_pkt_addstring(pktout, "client-side-connection");
8418         ssh2_pkt_adduint32(pktout, 0);
8419         ssh2_pkt_send(ssh, pktout);
8420     }
8421 }
8422
8423 static Socket ssh_socket(void *handle)
8424 {
8425     Ssh ssh = (Ssh) handle;
8426     return ssh->s;
8427 }
8428
8429 static int ssh_sendok(void *handle)
8430 {
8431     Ssh ssh = (Ssh) handle;
8432     return ssh->send_ok;
8433 }
8434
8435 static int ssh_ldisc(void *handle, int option)
8436 {
8437     Ssh ssh = (Ssh) handle;
8438     if (option == LD_ECHO)
8439         return ssh->echoing;
8440     if (option == LD_EDIT)
8441         return ssh->editing;
8442     return FALSE;
8443 }
8444
8445 static void ssh_provide_ldisc(void *handle, void *ldisc)
8446 {
8447     Ssh ssh = (Ssh) handle;
8448     ssh->ldisc = ldisc;
8449 }
8450
8451 static void ssh_provide_logctx(void *handle, void *logctx)
8452 {
8453     Ssh ssh = (Ssh) handle;
8454     ssh->logctx = logctx;
8455 }
8456
8457 static int ssh_return_exitcode(void *handle)
8458 {
8459     Ssh ssh = (Ssh) handle;
8460     if (ssh->s != NULL)
8461         return -1;
8462     else
8463         return (ssh->exitcode >= 0 ? ssh->exitcode : 0);
8464 }
8465
8466 /*
8467  * cfg_info for SSH is the currently running version of the
8468  * protocol. (1 for 1; 2 for 2; 0 for not-decided-yet.)
8469  */
8470 static int ssh_cfg_info(void *handle)
8471 {
8472     Ssh ssh = (Ssh) handle;
8473     return ssh->version;
8474 }
8475
8476 /*
8477  * Gross hack: pscp will try to start SFTP but fall back to scp1 if
8478  * that fails. This variable is the means by which scp.c can reach
8479  * into the SSH code and find out which one it got.
8480  */
8481 extern int ssh_fallback_cmd(void *handle)
8482 {
8483     Ssh ssh = (Ssh) handle;
8484     return ssh->fallback_cmd;
8485 }
8486
8487 Backend ssh_backend = {
8488     ssh_init,
8489     ssh_free,
8490     ssh_reconfig,
8491     ssh_send,
8492     ssh_sendbuffer,
8493     ssh_size,
8494     ssh_special,
8495     ssh_get_specials,
8496     ssh_socket,
8497     ssh_return_exitcode,
8498     ssh_sendok,
8499     ssh_ldisc,
8500     ssh_provide_ldisc,
8501     ssh_provide_logctx,
8502     ssh_unthrottle,
8503     ssh_cfg_info,
8504     22
8505 };