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