]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - ssh.c
In SSH packet logging mode, log SSH-2 packet sequence numbers, in
[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     void *x11auth;
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->cfg.x11_display, c,
4582                      ssh->x11auth, 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         char proto[20], data[64];
4918         logevent("Requesting X11 forwarding");
4919         ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
4920                                        data, sizeof(data), ssh->cfg.x11_auth);
4921         x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
4922         /*
4923          * Note that while we blank the X authentication data here, we don't
4924          * take any special action to blank the start of an X11 channel,
4925          * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
4926          * without having session blanking enabled is likely to leak your
4927          * cookie into the log.
4928          */
4929         if (ssh->v1_local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER) {
4930             send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
4931                         PKT_STR, proto,
4932                         PKTT_PASSWORD, PKT_STR, data, PKTT_OTHER,
4933                         PKT_INT, x11_get_screen_number(ssh->cfg.x11_display),
4934                         PKT_END);
4935         } else {
4936             send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
4937                         PKT_STR, proto,
4938                         PKTT_PASSWORD, PKT_STR, data, PKTT_OTHER, PKT_END);
4939         }
4940         do {
4941             crReturnV;
4942         } while (!pktin);
4943         if (pktin->type != SSH1_SMSG_SUCCESS
4944             && pktin->type != SSH1_SMSG_FAILURE) {
4945             bombout(("Protocol confusion"));
4946             crStopV;
4947         } else if (pktin->type == SSH1_SMSG_FAILURE) {
4948             logevent("X11 forwarding refused");
4949         } else {
4950             logevent("X11 forwarding enabled");
4951             ssh->X11_fwd_enabled = TRUE;
4952             ssh->packet_dispatch[SSH1_SMSG_X11_OPEN] = ssh1_smsg_x11_open;
4953         }
4954     }
4955
4956     ssh_setup_portfwd(ssh, &ssh->cfg);
4957     ssh->packet_dispatch[SSH1_MSG_PORT_OPEN] = ssh1_msg_port_open;
4958
4959     if (!ssh->cfg.nopty) {
4960         struct Packet *pkt;
4961         /* Unpick the terminal-speed string. */
4962         /* XXX perhaps we should allow no speeds to be sent. */
4963         ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
4964         sscanf(ssh->cfg.termspeed, "%d,%d", &ssh->ospeed, &ssh->ispeed);
4965         /* Send the pty request. */
4966         pkt = ssh1_pkt_init(SSH1_CMSG_REQUEST_PTY);
4967         ssh_pkt_addstring(pkt, ssh->cfg.termtype);
4968         ssh_pkt_adduint32(pkt, ssh->term_height);
4969         ssh_pkt_adduint32(pkt, ssh->term_width);
4970         ssh_pkt_adduint32(pkt, 0); /* width in pixels */
4971         ssh_pkt_adduint32(pkt, 0); /* height in pixels */
4972         parse_ttymodes(ssh, ssh->cfg.ttymodes,
4973                        ssh1_send_ttymode, (void *)pkt);
4974         ssh_pkt_addbyte(pkt, SSH1_TTY_OP_ISPEED);
4975         ssh_pkt_adduint32(pkt, ssh->ispeed);
4976         ssh_pkt_addbyte(pkt, SSH1_TTY_OP_OSPEED);
4977         ssh_pkt_adduint32(pkt, ssh->ospeed);
4978         ssh_pkt_addbyte(pkt, SSH_TTY_OP_END);
4979         s_wrpkt(ssh, pkt);
4980         ssh->state = SSH_STATE_INTERMED;
4981         do {
4982             crReturnV;
4983         } while (!pktin);
4984         if (pktin->type != SSH1_SMSG_SUCCESS
4985             && pktin->type != SSH1_SMSG_FAILURE) {
4986             bombout(("Protocol confusion"));
4987             crStopV;
4988         } else if (pktin->type == SSH1_SMSG_FAILURE) {
4989             c_write_str(ssh, "Server refused to allocate pty\r\n");
4990             ssh->editing = ssh->echoing = 1;
4991         }
4992         logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
4993                   ssh->ospeed, ssh->ispeed);
4994     } else {
4995         ssh->editing = ssh->echoing = 1;
4996     }
4997
4998     if (ssh->cfg.compression) {
4999         send_packet(ssh, SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);
5000         do {
5001             crReturnV;
5002         } while (!pktin);
5003         if (pktin->type != SSH1_SMSG_SUCCESS
5004             && pktin->type != SSH1_SMSG_FAILURE) {
5005             bombout(("Protocol confusion"));
5006             crStopV;
5007         } else if (pktin->type == SSH1_SMSG_FAILURE) {
5008             c_write_str(ssh, "Server refused to compress\r\n");
5009         }
5010         logevent("Started compression");
5011         ssh->v1_compressing = TRUE;
5012         ssh->cs_comp_ctx = zlib_compress_init();
5013         logevent("Initialised zlib (RFC1950) compression");
5014         ssh->sc_comp_ctx = zlib_decompress_init();
5015         logevent("Initialised zlib (RFC1950) decompression");
5016     }
5017
5018     /*
5019      * Start the shell or command.
5020      * 
5021      * Special case: if the first-choice command is an SSH-2
5022      * subsystem (hence not usable here) and the second choice
5023      * exists, we fall straight back to that.
5024      */
5025     {
5026         char *cmd = ssh->cfg.remote_cmd_ptr;
5027
5028         if (!cmd) cmd = ssh->cfg.remote_cmd;
5029         
5030         if (ssh->cfg.ssh_subsys && ssh->cfg.remote_cmd_ptr2) {
5031             cmd = ssh->cfg.remote_cmd_ptr2;
5032             ssh->fallback_cmd = TRUE;
5033         }
5034         if (*cmd)
5035             send_packet(ssh, SSH1_CMSG_EXEC_CMD, PKT_STR, cmd, PKT_END);
5036         else
5037             send_packet(ssh, SSH1_CMSG_EXEC_SHELL, PKT_END);
5038         logevent("Started session");
5039     }
5040
5041     ssh->state = SSH_STATE_SESSION;
5042     if (ssh->size_needed)
5043         ssh_size(ssh, ssh->term_width, ssh->term_height);
5044     if (ssh->eof_needed)
5045         ssh_special(ssh, TS_EOF);
5046
5047     if (ssh->ldisc)
5048         ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
5049     ssh->send_ok = 1;
5050     ssh->channels = newtree234(ssh_channelcmp);
5051     while (1) {
5052
5053         /*
5054          * By this point, most incoming packets are already being
5055          * handled by the dispatch table, and we need only pay
5056          * attention to the unusual ones.
5057          */
5058
5059         crReturnV;
5060         if (pktin) {
5061             if (pktin->type == SSH1_SMSG_SUCCESS) {
5062                 /* may be from EXEC_SHELL on some servers */
5063             } else if (pktin->type == SSH1_SMSG_FAILURE) {
5064                 /* may be from EXEC_SHELL on some servers
5065                  * if no pty is available or in other odd cases. Ignore */
5066             } else {
5067                 bombout(("Strange packet received: type %d", pktin->type));
5068                 crStopV;
5069             }
5070         } else {
5071             while (inlen > 0) {
5072                 int len = min(inlen, 512);
5073                 send_packet(ssh, SSH1_CMSG_STDIN_DATA,
5074                             PKT_INT, len,  PKTT_DATA, PKT_DATA, in, len,
5075                             PKTT_OTHER, PKT_END);
5076                 in += len;
5077                 inlen -= len;
5078             }
5079         }
5080     }
5081
5082     crFinishV;
5083 }
5084
5085 /*
5086  * Handle the top-level SSH-2 protocol.
5087  */
5088 static void ssh1_msg_debug(Ssh ssh, struct Packet *pktin)
5089 {
5090     char *msg;
5091     int msglen;
5092
5093     ssh_pkt_getstring(pktin, &msg, &msglen);
5094     logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
5095 }
5096
5097 static void ssh1_msg_disconnect(Ssh ssh, struct Packet *pktin)
5098 {
5099     /* log reason code in disconnect message */
5100     char *msg;
5101     int msglen;
5102
5103     ssh_pkt_getstring(pktin, &msg, &msglen);
5104     bombout(("Server sent disconnect message:\n\"%.*s\"", msglen, msg));
5105 }
5106
5107 static void ssh_msg_ignore(Ssh ssh, struct Packet *pktin)
5108 {
5109     /* Do nothing, because we're ignoring it! Duhh. */
5110 }
5111
5112 static void ssh1_protocol_setup(Ssh ssh)
5113 {
5114     int i;
5115
5116     /*
5117      * Most messages are handled by the coroutines.
5118      */
5119     for (i = 0; i < 256; i++)
5120         ssh->packet_dispatch[i] = NULL;
5121
5122     /*
5123      * These special message types we install handlers for.
5124      */
5125     ssh->packet_dispatch[SSH1_MSG_DISCONNECT] = ssh1_msg_disconnect;
5126     ssh->packet_dispatch[SSH1_MSG_IGNORE] = ssh_msg_ignore;
5127     ssh->packet_dispatch[SSH1_MSG_DEBUG] = ssh1_msg_debug;
5128 }
5129
5130 static void ssh1_protocol(Ssh ssh, void *vin, int inlen,
5131                           struct Packet *pktin)
5132 {
5133     unsigned char *in=(unsigned char*)vin;
5134     if (ssh->state == SSH_STATE_CLOSED)
5135         return;
5136
5137     if (pktin && ssh->packet_dispatch[pktin->type]) {
5138         ssh->packet_dispatch[pktin->type](ssh, pktin);
5139         return;
5140     }
5141
5142     if (!ssh->protocol_initial_phase_done) {
5143         if (do_ssh1_login(ssh, in, inlen, pktin))
5144             ssh->protocol_initial_phase_done = TRUE;
5145         else
5146             return;
5147     }
5148
5149     do_ssh1_connection(ssh, in, inlen, pktin);
5150 }
5151
5152 /*
5153  * Utility routine for decoding comma-separated strings in KEXINIT.
5154  */
5155 static int in_commasep_string(char *needle, char *haystack, int haylen)
5156 {
5157     int needlen;
5158     if (!needle || !haystack)          /* protect against null pointers */
5159         return 0;
5160     needlen = strlen(needle);
5161     while (1) {
5162         /*
5163          * Is it at the start of the string?
5164          */
5165         if (haylen >= needlen &&       /* haystack is long enough */
5166             !memcmp(needle, haystack, needlen) &&       /* initial match */
5167             (haylen == needlen || haystack[needlen] == ',')
5168             /* either , or EOS follows */
5169             )
5170             return 1;
5171         /*
5172          * If not, search for the next comma and resume after that.
5173          * If no comma found, terminate.
5174          */
5175         while (haylen > 0 && *haystack != ',')
5176             haylen--, haystack++;
5177         if (haylen == 0)
5178             return 0;
5179         haylen--, haystack++;          /* skip over comma itself */
5180     }
5181 }
5182
5183 /*
5184  * Similar routine for checking whether we have the first string in a list.
5185  */
5186 static int first_in_commasep_string(char *needle, char *haystack, int haylen)
5187 {
5188     int needlen;
5189     if (!needle || !haystack)          /* protect against null pointers */
5190         return 0;
5191     needlen = strlen(needle);
5192     /*
5193      * Is it at the start of the string?
5194      */
5195     if (haylen >= needlen &&       /* haystack is long enough */
5196         !memcmp(needle, haystack, needlen) &&   /* initial match */
5197         (haylen == needlen || haystack[needlen] == ',')
5198         /* either , or EOS follows */
5199         )
5200         return 1;
5201     return 0;
5202 }
5203
5204
5205 /*
5206  * SSH-2 key creation method.
5207  * (Currently assumes 2 lots of any hash are sufficient to generate
5208  * keys/IVs for any cipher/MAC. SSH2_MKKEY_ITERS documents this assumption.)
5209  */
5210 #define SSH2_MKKEY_ITERS (2)
5211 static void ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, char chr,
5212                        unsigned char *keyspace)
5213 {
5214     const struct ssh_hash *h = ssh->kex->hash;
5215     void *s;
5216     /* First hlen bytes. */
5217     s = h->init();
5218     if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
5219         hash_mpint(h, s, K);
5220     h->bytes(s, H, h->hlen);
5221     h->bytes(s, &chr, 1);
5222     h->bytes(s, ssh->v2_session_id, ssh->v2_session_id_len);
5223     h->final(s, keyspace);
5224     /* Next hlen bytes. */
5225     s = h->init();
5226     if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
5227         hash_mpint(h, s, K);
5228     h->bytes(s, H, h->hlen);
5229     h->bytes(s, keyspace, h->hlen);
5230     h->final(s, keyspace + h->hlen);
5231 }
5232
5233 /*
5234  * Handle the SSH-2 transport layer.
5235  */
5236 static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
5237                              struct Packet *pktin)
5238 {
5239     unsigned char *in = (unsigned char *)vin;
5240     struct do_ssh2_transport_state {
5241         int nbits, pbits, warn_kex, warn_cscipher, warn_sccipher;
5242         Bignum p, g, e, f, K;
5243         void *our_kexinit;
5244         int our_kexinitlen;
5245         int kex_init_value, kex_reply_value;
5246         const struct ssh_mac **maclist;
5247         int nmacs;
5248         const struct ssh2_cipher *cscipher_tobe;
5249         const struct ssh2_cipher *sccipher_tobe;
5250         const struct ssh_mac *csmac_tobe;
5251         const struct ssh_mac *scmac_tobe;
5252         const struct ssh_compress *cscomp_tobe;
5253         const struct ssh_compress *sccomp_tobe;
5254         char *hostkeydata, *sigdata, *rsakeydata, *keystr, *fingerprint;
5255         int hostkeylen, siglen, rsakeylen;
5256         void *hkey;                    /* actual host key */
5257         void *rsakey;                  /* for RSA kex */
5258         unsigned char exchange_hash[SSH2_KEX_MAX_HASH_LEN];
5259         int n_preferred_kex;
5260         const struct ssh_kexes *preferred_kex[KEX_MAX];
5261         int n_preferred_ciphers;
5262         const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX];
5263         const struct ssh_compress *preferred_comp;
5264         int got_session_id, activated_authconn;
5265         struct Packet *pktout;
5266         int dlgret;
5267         int guessok;
5268         int ignorepkt;
5269     };
5270     crState(do_ssh2_transport_state);
5271
5272     crBegin(ssh->do_ssh2_transport_crstate);
5273
5274     s->cscipher_tobe = s->sccipher_tobe = NULL;
5275     s->csmac_tobe = s->scmac_tobe = NULL;
5276     s->cscomp_tobe = s->sccomp_tobe = NULL;
5277
5278     s->got_session_id = s->activated_authconn = FALSE;
5279
5280     /*
5281      * Be prepared to work around the buggy MAC problem.
5282      */
5283     if (ssh->remote_bugs & BUG_SSH2_HMAC)
5284         s->maclist = buggymacs, s->nmacs = lenof(buggymacs);
5285     else
5286         s->maclist = macs, s->nmacs = lenof(macs);
5287
5288   begin_key_exchange:
5289     ssh->pkt_kctx = SSH2_PKTCTX_NOKEX;
5290     {
5291         int i, j, commalist_started;
5292
5293         /*
5294          * Set up the preferred key exchange. (NULL => warn below here)
5295          */
5296         s->n_preferred_kex = 0;
5297         for (i = 0; i < KEX_MAX; i++) {
5298             switch (ssh->cfg.ssh_kexlist[i]) {
5299               case KEX_DHGEX:
5300                 s->preferred_kex[s->n_preferred_kex++] =
5301                     &ssh_diffiehellman_gex;
5302                 break;
5303               case KEX_DHGROUP14:
5304                 s->preferred_kex[s->n_preferred_kex++] =
5305                     &ssh_diffiehellman_group14;
5306                 break;
5307               case KEX_DHGROUP1:
5308                 s->preferred_kex[s->n_preferred_kex++] =
5309                     &ssh_diffiehellman_group1;
5310                 break;
5311               case KEX_RSA:
5312                 s->preferred_kex[s->n_preferred_kex++] =
5313                     &ssh_rsa_kex;
5314                 break;
5315               case KEX_WARN:
5316                 /* Flag for later. Don't bother if it's the last in
5317                  * the list. */
5318                 if (i < KEX_MAX - 1) {
5319                     s->preferred_kex[s->n_preferred_kex++] = NULL;
5320                 }
5321                 break;
5322             }
5323         }
5324
5325         /*
5326          * Set up the preferred ciphers. (NULL => warn below here)
5327          */
5328         s->n_preferred_ciphers = 0;
5329         for (i = 0; i < CIPHER_MAX; i++) {
5330             switch (ssh->cfg.ssh_cipherlist[i]) {
5331               case CIPHER_BLOWFISH:
5332                 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_blowfish;
5333                 break;
5334               case CIPHER_DES:
5335                 if (ssh->cfg.ssh2_des_cbc) {
5336                     s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_des;
5337                 }
5338                 break;
5339               case CIPHER_3DES:
5340                 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_3des;
5341                 break;
5342               case CIPHER_AES:
5343                 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_aes;
5344                 break;
5345               case CIPHER_ARCFOUR:
5346                 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_arcfour;
5347                 break;
5348               case CIPHER_WARN:
5349                 /* Flag for later. Don't bother if it's the last in
5350                  * the list. */
5351                 if (i < CIPHER_MAX - 1) {
5352                     s->preferred_ciphers[s->n_preferred_ciphers++] = NULL;
5353                 }
5354                 break;
5355             }
5356         }
5357
5358         /*
5359          * Set up preferred compression.
5360          */
5361         if (ssh->cfg.compression)
5362             s->preferred_comp = &ssh_zlib;
5363         else
5364             s->preferred_comp = &ssh_comp_none;
5365
5366         /*
5367          * Enable queueing of outgoing auth- or connection-layer
5368          * packets while we are in the middle of a key exchange.
5369          */
5370         ssh->queueing = TRUE;
5371
5372         /*
5373          * Flag that KEX is in progress.
5374          */
5375         ssh->kex_in_progress = TRUE;
5376
5377         /*
5378          * Construct and send our key exchange packet.
5379          */
5380         s->pktout = ssh2_pkt_init(SSH2_MSG_KEXINIT);
5381         for (i = 0; i < 16; i++)
5382             ssh2_pkt_addbyte(s->pktout, (unsigned char) random_byte());
5383         /* List key exchange algorithms. */
5384         ssh2_pkt_addstring_start(s->pktout);
5385         commalist_started = 0;
5386         for (i = 0; i < s->n_preferred_kex; i++) {
5387             const struct ssh_kexes *k = s->preferred_kex[i];
5388             if (!k) continue;          /* warning flag */
5389             for (j = 0; j < k->nkexes; j++) {
5390                 if (commalist_started)
5391                     ssh2_pkt_addstring_str(s->pktout, ",");
5392                 ssh2_pkt_addstring_str(s->pktout, k->list[j]->name);
5393                 commalist_started = 1;
5394             }
5395         }
5396         /* List server host key algorithms. */
5397         ssh2_pkt_addstring_start(s->pktout);
5398         for (i = 0; i < lenof(hostkey_algs); i++) {
5399             ssh2_pkt_addstring_str(s->pktout, hostkey_algs[i]->name);
5400             if (i < lenof(hostkey_algs) - 1)
5401                 ssh2_pkt_addstring_str(s->pktout, ",");
5402         }
5403         /* List client->server encryption algorithms. */
5404         ssh2_pkt_addstring_start(s->pktout);
5405         commalist_started = 0;
5406         for (i = 0; i < s->n_preferred_ciphers; i++) {
5407             const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5408             if (!c) continue;          /* warning flag */
5409             for (j = 0; j < c->nciphers; j++) {
5410                 if (commalist_started)
5411                     ssh2_pkt_addstring_str(s->pktout, ",");
5412                 ssh2_pkt_addstring_str(s->pktout, c->list[j]->name);
5413                 commalist_started = 1;
5414             }
5415         }
5416         /* List server->client encryption algorithms. */
5417         ssh2_pkt_addstring_start(s->pktout);
5418         commalist_started = 0;
5419         for (i = 0; i < s->n_preferred_ciphers; i++) {
5420             const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5421             if (!c) continue; /* warning flag */
5422             for (j = 0; j < c->nciphers; j++) {
5423                 if (commalist_started)
5424                     ssh2_pkt_addstring_str(s->pktout, ",");
5425                 ssh2_pkt_addstring_str(s->pktout, c->list[j]->name);
5426                 commalist_started = 1;
5427             }
5428         }
5429         /* List client->server MAC algorithms. */
5430         ssh2_pkt_addstring_start(s->pktout);
5431         for (i = 0; i < s->nmacs; i++) {
5432             ssh2_pkt_addstring_str(s->pktout, s->maclist[i]->name);
5433             if (i < s->nmacs - 1)
5434                 ssh2_pkt_addstring_str(s->pktout, ",");
5435         }
5436         /* List server->client MAC algorithms. */
5437         ssh2_pkt_addstring_start(s->pktout);
5438         for (i = 0; i < s->nmacs; i++) {
5439             ssh2_pkt_addstring_str(s->pktout, s->maclist[i]->name);
5440             if (i < s->nmacs - 1)
5441                 ssh2_pkt_addstring_str(s->pktout, ",");
5442         }
5443         /* List client->server compression algorithms. */
5444         ssh2_pkt_addstring_start(s->pktout);
5445         assert(lenof(compressions) > 1);
5446         ssh2_pkt_addstring_str(s->pktout, s->preferred_comp->name);
5447         for (i = 0; i < lenof(compressions); i++) {
5448             const struct ssh_compress *c = compressions[i];
5449             if (c != s->preferred_comp) {
5450                 ssh2_pkt_addstring_str(s->pktout, ",");
5451                 ssh2_pkt_addstring_str(s->pktout, c->name);
5452             }
5453         }
5454         /* List server->client compression algorithms. */
5455         ssh2_pkt_addstring_start(s->pktout);
5456         assert(lenof(compressions) > 1);
5457         ssh2_pkt_addstring_str(s->pktout, s->preferred_comp->name);
5458         for (i = 0; i < lenof(compressions); i++) {
5459             const struct ssh_compress *c = compressions[i];
5460             if (c != s->preferred_comp) {
5461                 ssh2_pkt_addstring_str(s->pktout, ",");
5462                 ssh2_pkt_addstring_str(s->pktout, c->name);
5463             }
5464         }
5465         /* List client->server languages. Empty list. */
5466         ssh2_pkt_addstring_start(s->pktout);
5467         /* List server->client languages. Empty list. */
5468         ssh2_pkt_addstring_start(s->pktout);
5469         /* First KEX packet does _not_ follow, because we're not that brave. */
5470         ssh2_pkt_addbool(s->pktout, FALSE);
5471         /* Reserved. */
5472         ssh2_pkt_adduint32(s->pktout, 0);
5473     }
5474
5475     s->our_kexinitlen = s->pktout->length - 5;
5476     s->our_kexinit = snewn(s->our_kexinitlen, unsigned char);
5477     memcpy(s->our_kexinit, s->pktout->data + 5, s->our_kexinitlen); 
5478
5479     ssh2_pkt_send_noqueue(ssh, s->pktout);
5480
5481     if (!pktin)
5482         crWaitUntil(pktin);
5483
5484     /*
5485      * Now examine the other side's KEXINIT to see what we're up
5486      * to.
5487      */
5488     {
5489         char *str, *preferred;
5490         int i, j, len;
5491
5492         if (pktin->type != SSH2_MSG_KEXINIT) {
5493             bombout(("expected key exchange packet from server"));
5494             crStop(0);
5495         }
5496         ssh->kex = NULL;
5497         ssh->hostkey = NULL;
5498         s->cscipher_tobe = NULL;
5499         s->sccipher_tobe = NULL;
5500         s->csmac_tobe = NULL;
5501         s->scmac_tobe = NULL;
5502         s->cscomp_tobe = NULL;
5503         s->sccomp_tobe = NULL;
5504         s->warn_kex = s->warn_cscipher = s->warn_sccipher = FALSE;
5505
5506         pktin->savedpos += 16;          /* skip garbage cookie */
5507         ssh_pkt_getstring(pktin, &str, &len);    /* key exchange algorithms */
5508
5509         preferred = NULL;
5510         for (i = 0; i < s->n_preferred_kex; i++) {
5511             const struct ssh_kexes *k = s->preferred_kex[i];
5512             if (!k) {
5513                 s->warn_kex = TRUE;
5514             } else {
5515                 for (j = 0; j < k->nkexes; j++) {
5516                     if (!preferred) preferred = k->list[j]->name;
5517                     if (in_commasep_string(k->list[j]->name, str, len)) {
5518                         ssh->kex = k->list[j];
5519                         break;
5520                     }
5521                 }
5522             }
5523             if (ssh->kex)
5524                 break;
5525         }
5526         if (!ssh->kex) {
5527             bombout(("Couldn't agree a key exchange algorithm (available: %s)",
5528                      str ? str : "(null)"));
5529             crStop(0);
5530         }
5531         /*
5532          * Note that the server's guess is considered wrong if it doesn't match
5533          * the first algorithm in our list, even if it's still the algorithm
5534          * we end up using.
5535          */
5536         s->guessok = first_in_commasep_string(preferred, str, len);
5537         ssh_pkt_getstring(pktin, &str, &len);    /* host key algorithms */
5538         for (i = 0; i < lenof(hostkey_algs); i++) {
5539             if (in_commasep_string(hostkey_algs[i]->name, str, len)) {
5540                 ssh->hostkey = hostkey_algs[i];
5541                 break;
5542             }
5543         }
5544         s->guessok = s->guessok &&
5545             first_in_commasep_string(hostkey_algs[0]->name, str, len);
5546         ssh_pkt_getstring(pktin, &str, &len);    /* client->server cipher */
5547         for (i = 0; i < s->n_preferred_ciphers; i++) {
5548             const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5549             if (!c) {
5550                 s->warn_cscipher = TRUE;
5551             } else {
5552                 for (j = 0; j < c->nciphers; j++) {
5553                     if (in_commasep_string(c->list[j]->name, str, len)) {
5554                         s->cscipher_tobe = c->list[j];
5555                         break;
5556                     }
5557                 }
5558             }
5559             if (s->cscipher_tobe)
5560                 break;
5561         }
5562         if (!s->cscipher_tobe) {
5563             bombout(("Couldn't agree a client-to-server cipher (available: %s)",
5564                      str ? str : "(null)"));
5565             crStop(0);
5566         }
5567
5568         ssh_pkt_getstring(pktin, &str, &len);    /* server->client cipher */
5569         for (i = 0; i < s->n_preferred_ciphers; i++) {
5570             const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5571             if (!c) {
5572                 s->warn_sccipher = TRUE;
5573             } else {
5574                 for (j = 0; j < c->nciphers; j++) {
5575                     if (in_commasep_string(c->list[j]->name, str, len)) {
5576                         s->sccipher_tobe = c->list[j];
5577                         break;
5578                     }
5579                 }
5580             }
5581             if (s->sccipher_tobe)
5582                 break;
5583         }
5584         if (!s->sccipher_tobe) {
5585             bombout(("Couldn't agree a server-to-client cipher (available: %s)",
5586                      str ? str : "(null)"));
5587             crStop(0);
5588         }
5589
5590         ssh_pkt_getstring(pktin, &str, &len);    /* client->server mac */
5591         for (i = 0; i < s->nmacs; i++) {
5592             if (in_commasep_string(s->maclist[i]->name, str, len)) {
5593                 s->csmac_tobe = s->maclist[i];
5594                 break;
5595             }
5596         }
5597         ssh_pkt_getstring(pktin, &str, &len);    /* server->client mac */
5598         for (i = 0; i < s->nmacs; i++) {
5599             if (in_commasep_string(s->maclist[i]->name, str, len)) {
5600                 s->scmac_tobe = s->maclist[i];
5601                 break;
5602             }
5603         }
5604         ssh_pkt_getstring(pktin, &str, &len);  /* client->server compression */
5605         for (i = 0; i < lenof(compressions) + 1; i++) {
5606             const struct ssh_compress *c =
5607                 i == 0 ? s->preferred_comp : compressions[i - 1];
5608             if (in_commasep_string(c->name, str, len)) {
5609                 s->cscomp_tobe = c;
5610                 break;
5611             }
5612         }
5613         ssh_pkt_getstring(pktin, &str, &len);  /* server->client compression */
5614         for (i = 0; i < lenof(compressions) + 1; i++) {
5615             const struct ssh_compress *c =
5616                 i == 0 ? s->preferred_comp : compressions[i - 1];
5617             if (in_commasep_string(c->name, str, len)) {
5618                 s->sccomp_tobe = c;
5619                 break;
5620             }
5621         }
5622         ssh_pkt_getstring(pktin, &str, &len);  /* client->server language */
5623         ssh_pkt_getstring(pktin, &str, &len);  /* server->client language */
5624         s->ignorepkt = ssh2_pkt_getbool(pktin) && !s->guessok;
5625
5626         if (s->warn_kex) {
5627             ssh_set_frozen(ssh, 1);
5628             s->dlgret = askalg(ssh->frontend, "key-exchange algorithm",
5629                                ssh->kex->name,
5630                                ssh_dialog_callback, ssh);
5631             if (s->dlgret < 0) {
5632                 do {
5633                     crReturn(0);
5634                     if (pktin) {
5635                         bombout(("Unexpected data from server while"
5636                                  " waiting for user response"));
5637                         crStop(0);
5638                     }
5639                 } while (pktin || inlen > 0);
5640                 s->dlgret = ssh->user_response;
5641             }
5642             ssh_set_frozen(ssh, 0);
5643             if (s->dlgret == 0) {
5644                 ssh_disconnect(ssh, "User aborted at kex warning", NULL,
5645                                0, TRUE);
5646                 crStop(0);
5647             }
5648         }
5649
5650         if (s->warn_cscipher) {
5651             ssh_set_frozen(ssh, 1);
5652             s->dlgret = askalg(ssh->frontend,
5653                                "client-to-server cipher",
5654                                s->cscipher_tobe->name,
5655                                ssh_dialog_callback, ssh);
5656             if (s->dlgret < 0) {
5657                 do {
5658                     crReturn(0);
5659                     if (pktin) {
5660                         bombout(("Unexpected data from server while"
5661                                  " waiting for user response"));
5662                         crStop(0);
5663                     }
5664                 } while (pktin || inlen > 0);
5665                 s->dlgret = ssh->user_response;
5666             }
5667             ssh_set_frozen(ssh, 0);
5668             if (s->dlgret == 0) {
5669                 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
5670                                0, TRUE);
5671                 crStop(0);
5672             }
5673         }
5674
5675         if (s->warn_sccipher) {
5676             ssh_set_frozen(ssh, 1);
5677             s->dlgret = askalg(ssh->frontend,
5678                                "server-to-client cipher",
5679                                s->sccipher_tobe->name,
5680                                ssh_dialog_callback, ssh);
5681             if (s->dlgret < 0) {
5682                 do {
5683                     crReturn(0);
5684                     if (pktin) {
5685                         bombout(("Unexpected data from server while"
5686                                  " waiting for user response"));
5687                         crStop(0);
5688                     }
5689                 } while (pktin || inlen > 0);
5690                 s->dlgret = ssh->user_response;
5691             }
5692             ssh_set_frozen(ssh, 0);
5693             if (s->dlgret == 0) {
5694                 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
5695                                0, TRUE);
5696                 crStop(0);
5697             }
5698         }
5699
5700         ssh->exhash = ssh->kex->hash->init();
5701         hash_string(ssh->kex->hash, ssh->exhash, ssh->v_c, strlen(ssh->v_c));
5702         hash_string(ssh->kex->hash, ssh->exhash, ssh->v_s, strlen(ssh->v_s));
5703         hash_string(ssh->kex->hash, ssh->exhash,
5704             s->our_kexinit, s->our_kexinitlen);
5705         sfree(s->our_kexinit);
5706         if (pktin->length > 5)
5707             hash_string(ssh->kex->hash, ssh->exhash,
5708                 pktin->data + 5, pktin->length - 5);
5709
5710         if (s->ignorepkt) /* first_kex_packet_follows */
5711             crWaitUntil(pktin);                /* Ignore packet */
5712     }
5713
5714     if (ssh->kex->main_type == KEXTYPE_DH) {
5715         /*
5716          * Work out the number of bits of key we will need from the
5717          * key exchange. We start with the maximum key length of
5718          * either cipher...
5719          */
5720         {
5721             int csbits, scbits;
5722
5723             csbits = s->cscipher_tobe->keylen;
5724             scbits = s->sccipher_tobe->keylen;
5725             s->nbits = (csbits > scbits ? csbits : scbits);
5726         }
5727         /* The keys only have hlen-bit entropy, since they're based on
5728          * a hash. So cap the key size at hlen bits. */
5729         if (s->nbits > ssh->kex->hash->hlen * 8)
5730             s->nbits = ssh->kex->hash->hlen * 8;
5731
5732         /*
5733          * If we're doing Diffie-Hellman group exchange, start by
5734          * requesting a group.
5735          */
5736         if (!ssh->kex->pdata) {
5737             logevent("Doing Diffie-Hellman group exchange");
5738             ssh->pkt_kctx = SSH2_PKTCTX_DHGEX;
5739             /*
5740              * Work out how big a DH group we will need to allow that
5741              * much data.
5742              */
5743             s->pbits = 512 << ((s->nbits - 1) / 64);
5744             s->pktout = ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
5745             ssh2_pkt_adduint32(s->pktout, s->pbits);
5746             ssh2_pkt_send_noqueue(ssh, s->pktout);
5747
5748             crWaitUntil(pktin);
5749             if (pktin->type != SSH2_MSG_KEX_DH_GEX_GROUP) {
5750                 bombout(("expected key exchange group packet from server"));
5751                 crStop(0);
5752             }
5753             s->p = ssh2_pkt_getmp(pktin);
5754             s->g = ssh2_pkt_getmp(pktin);
5755             if (!s->p || !s->g) {
5756                 bombout(("unable to read mp-ints from incoming group packet"));
5757                 crStop(0);
5758             }
5759             ssh->kex_ctx = dh_setup_gex(s->p, s->g);
5760             s->kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
5761             s->kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
5762         } else {
5763             ssh->pkt_kctx = SSH2_PKTCTX_DHGROUP;
5764             ssh->kex_ctx = dh_setup_group(ssh->kex);
5765             s->kex_init_value = SSH2_MSG_KEXDH_INIT;
5766             s->kex_reply_value = SSH2_MSG_KEXDH_REPLY;
5767             logeventf(ssh, "Using Diffie-Hellman with standard group \"%s\"",
5768                       ssh->kex->groupname);
5769         }
5770
5771         logeventf(ssh, "Doing Diffie-Hellman key exchange with hash %s",
5772                   ssh->kex->hash->text_name);
5773         /*
5774          * Now generate and send e for Diffie-Hellman.
5775          */
5776         set_busy_status(ssh->frontend, BUSY_CPU); /* this can take a while */
5777         s->e = dh_create_e(ssh->kex_ctx, s->nbits * 2);
5778         s->pktout = ssh2_pkt_init(s->kex_init_value);
5779         ssh2_pkt_addmp(s->pktout, s->e);
5780         ssh2_pkt_send_noqueue(ssh, s->pktout);
5781
5782         set_busy_status(ssh->frontend, BUSY_WAITING); /* wait for server */
5783         crWaitUntil(pktin);
5784         if (pktin->type != s->kex_reply_value) {
5785             bombout(("expected key exchange reply packet from server"));
5786             crStop(0);
5787         }
5788         set_busy_status(ssh->frontend, BUSY_CPU); /* cogitate */
5789         ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
5790         s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
5791         s->f = ssh2_pkt_getmp(pktin);
5792         if (!s->f) {
5793             bombout(("unable to parse key exchange reply packet"));
5794             crStop(0);
5795         }
5796         ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
5797
5798         s->K = dh_find_K(ssh->kex_ctx, s->f);
5799
5800         /* We assume everything from now on will be quick, and it might
5801          * involve user interaction. */
5802         set_busy_status(ssh->frontend, BUSY_NOT);
5803
5804         hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen);
5805         if (!ssh->kex->pdata) {
5806             hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits);
5807             hash_mpint(ssh->kex->hash, ssh->exhash, s->p);
5808             hash_mpint(ssh->kex->hash, ssh->exhash, s->g);
5809         }
5810         hash_mpint(ssh->kex->hash, ssh->exhash, s->e);
5811         hash_mpint(ssh->kex->hash, ssh->exhash, s->f);
5812
5813         dh_cleanup(ssh->kex_ctx);
5814         freebn(s->f);
5815         if (!ssh->kex->pdata) {
5816             freebn(s->g);
5817             freebn(s->p);
5818         }
5819     } else {
5820         logeventf(ssh, "Doing RSA key exchange with hash %s",
5821                   ssh->kex->hash->text_name);
5822         ssh->pkt_kctx = SSH2_PKTCTX_RSAKEX;
5823         /*
5824          * RSA key exchange. First expect a KEXRSA_PUBKEY packet
5825          * from the server.
5826          */
5827         crWaitUntil(pktin);
5828         if (pktin->type != SSH2_MSG_KEXRSA_PUBKEY) {
5829             bombout(("expected RSA public key packet from server"));
5830             crStop(0);
5831         }
5832
5833         ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
5834         hash_string(ssh->kex->hash, ssh->exhash,
5835                     s->hostkeydata, s->hostkeylen);
5836         s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
5837
5838         {
5839             char *keydata;
5840             ssh_pkt_getstring(pktin, &keydata, &s->rsakeylen);
5841             s->rsakeydata = snewn(s->rsakeylen, char);
5842             memcpy(s->rsakeydata, keydata, s->rsakeylen);
5843         }
5844
5845         s->rsakey = ssh_rsakex_newkey(s->rsakeydata, s->rsakeylen);
5846         if (!s->rsakey) {
5847             sfree(s->rsakeydata);
5848             bombout(("unable to parse RSA public key from server"));
5849             crStop(0);
5850         }
5851
5852         hash_string(ssh->kex->hash, ssh->exhash, s->rsakeydata, s->rsakeylen);
5853
5854         /*
5855          * Next, set up a shared secret K, of precisely KLEN -
5856          * 2*HLEN - 49 bits, where KLEN is the bit length of the
5857          * RSA key modulus and HLEN is the bit length of the hash
5858          * we're using.
5859          */
5860         {
5861             int klen = ssh_rsakex_klen(s->rsakey);
5862             int nbits = klen - (2*ssh->kex->hash->hlen*8 + 49);
5863             int i, byte = 0;
5864             unsigned char *kstr1, *kstr2, *outstr;
5865             int kstr1len, kstr2len, outstrlen;
5866
5867             s->K = bn_power_2(nbits - 1);
5868
5869             for (i = 0; i < nbits; i++) {
5870                 if ((i & 7) == 0) {
5871                     byte = random_byte();
5872                 }
5873                 bignum_set_bit(s->K, i, (byte >> (i & 7)) & 1);
5874             }
5875
5876             /*
5877              * Encode this as an mpint.
5878              */
5879             kstr1 = ssh2_mpint_fmt(s->K, &kstr1len);
5880             kstr2 = snewn(kstr2len = 4 + kstr1len, unsigned char);
5881             PUT_32BIT(kstr2, kstr1len);
5882             memcpy(kstr2 + 4, kstr1, kstr1len);
5883
5884             /*
5885              * Encrypt it with the given RSA key.
5886              */
5887             outstrlen = (klen + 7) / 8;
5888             outstr = snewn(outstrlen, unsigned char);
5889             ssh_rsakex_encrypt(ssh->kex->hash, kstr2, kstr2len,
5890                                outstr, outstrlen, s->rsakey);
5891
5892             /*
5893              * And send it off in a return packet.
5894              */
5895             s->pktout = ssh2_pkt_init(SSH2_MSG_KEXRSA_SECRET);
5896             ssh2_pkt_addstring_start(s->pktout);
5897             ssh2_pkt_addstring_data(s->pktout, (char *)outstr, outstrlen);
5898             ssh2_pkt_send_noqueue(ssh, s->pktout);
5899
5900             hash_string(ssh->kex->hash, ssh->exhash, outstr, outstrlen);
5901
5902             sfree(kstr2);
5903             sfree(kstr1);
5904             sfree(outstr);
5905         }
5906
5907         ssh_rsakex_freekey(s->rsakey);
5908
5909         crWaitUntil(pktin);
5910         if (pktin->type != SSH2_MSG_KEXRSA_DONE) {
5911             sfree(s->rsakeydata);
5912             bombout(("expected signature packet from server"));
5913             crStop(0);
5914         }
5915
5916         ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
5917
5918         sfree(s->rsakeydata);
5919     }
5920
5921     hash_mpint(ssh->kex->hash, ssh->exhash, s->K);
5922     assert(ssh->kex->hash->hlen <= sizeof(s->exchange_hash));
5923     ssh->kex->hash->final(ssh->exhash, s->exchange_hash);
5924
5925     ssh->kex_ctx = NULL;
5926
5927 #if 0
5928     debug(("Exchange hash is:\n"));
5929     dmemdump(s->exchange_hash, ssh->kex->hash->hlen);
5930 #endif
5931
5932     if (!s->hkey ||
5933         !ssh->hostkey->verifysig(s->hkey, s->sigdata, s->siglen,
5934                                  (char *)s->exchange_hash,
5935                                  ssh->kex->hash->hlen)) {
5936         bombout(("Server's host key did not match the signature supplied"));
5937         crStop(0);
5938     }
5939
5940     /*
5941      * Authenticate remote host: verify host key. (We've already
5942      * checked the signature of the exchange hash.)
5943      */
5944     s->keystr = ssh->hostkey->fmtkey(s->hkey);
5945     s->fingerprint = ssh->hostkey->fingerprint(s->hkey);
5946     ssh_set_frozen(ssh, 1);
5947     s->dlgret = verify_ssh_host_key(ssh->frontend,
5948                                     ssh->savedhost, ssh->savedport,
5949                                     ssh->hostkey->keytype, s->keystr,
5950                                     s->fingerprint,
5951                                     ssh_dialog_callback, ssh);
5952     if (s->dlgret < 0) {
5953         do {
5954             crReturn(0);
5955             if (pktin) {
5956                 bombout(("Unexpected data from server while waiting"
5957                          " for user host key response"));
5958                     crStop(0);
5959             }
5960         } while (pktin || inlen > 0);
5961         s->dlgret = ssh->user_response;
5962     }
5963     ssh_set_frozen(ssh, 0);
5964     if (s->dlgret == 0) {
5965         ssh_disconnect(ssh, "User aborted at host key verification", NULL,
5966                        0, TRUE);
5967         crStop(0);
5968     }
5969     if (!s->got_session_id) {     /* don't bother logging this in rekeys */
5970         logevent("Host key fingerprint is:");
5971         logevent(s->fingerprint);
5972     }
5973     sfree(s->fingerprint);
5974     sfree(s->keystr);
5975     ssh->hostkey->freekey(s->hkey);
5976
5977     /*
5978      * The exchange hash from the very first key exchange is also
5979      * the session id, used in session key construction and
5980      * authentication.
5981      */
5982     if (!s->got_session_id) {
5983         assert(sizeof(s->exchange_hash) <= sizeof(ssh->v2_session_id));
5984         memcpy(ssh->v2_session_id, s->exchange_hash,
5985                sizeof(s->exchange_hash));
5986         ssh->v2_session_id_len = ssh->kex->hash->hlen;
5987         assert(ssh->v2_session_id_len <= sizeof(ssh->v2_session_id));
5988         s->got_session_id = TRUE;
5989     }
5990
5991     /*
5992      * Send SSH2_MSG_NEWKEYS.
5993      */
5994     s->pktout = ssh2_pkt_init(SSH2_MSG_NEWKEYS);
5995     ssh2_pkt_send_noqueue(ssh, s->pktout);
5996     ssh->outgoing_data_size = 0;       /* start counting from here */
5997
5998     /*
5999      * We've sent client NEWKEYS, so create and initialise
6000      * client-to-server session keys.
6001      */
6002     if (ssh->cs_cipher_ctx)
6003         ssh->cscipher->free_context(ssh->cs_cipher_ctx);
6004     ssh->cscipher = s->cscipher_tobe;
6005     ssh->cs_cipher_ctx = ssh->cscipher->make_context();
6006
6007     if (ssh->cs_mac_ctx)
6008         ssh->csmac->free_context(ssh->cs_mac_ctx);
6009     ssh->csmac = s->csmac_tobe;
6010     ssh->cs_mac_ctx = ssh->csmac->make_context();
6011
6012     if (ssh->cs_comp_ctx)
6013         ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
6014     ssh->cscomp = s->cscomp_tobe;
6015     ssh->cs_comp_ctx = ssh->cscomp->compress_init();
6016
6017     /*
6018      * Set IVs on client-to-server keys. Here we use the exchange
6019      * hash from the _first_ key exchange.
6020      */
6021     {
6022         unsigned char keyspace[SSH2_KEX_MAX_HASH_LEN * SSH2_MKKEY_ITERS];
6023         assert(sizeof(keyspace) >= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
6024         ssh2_mkkey(ssh,s->K,s->exchange_hash,'C',keyspace);
6025         assert((ssh->cscipher->keylen+7) / 8 <=
6026                ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
6027         ssh->cscipher->setkey(ssh->cs_cipher_ctx, keyspace);
6028         ssh2_mkkey(ssh,s->K,s->exchange_hash,'A',keyspace);
6029         assert(ssh->cscipher->blksize <=
6030                ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
6031         ssh->cscipher->setiv(ssh->cs_cipher_ctx, keyspace);
6032         ssh2_mkkey(ssh,s->K,s->exchange_hash,'E',keyspace);
6033         assert(ssh->csmac->len <=
6034                ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
6035         ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace);
6036         memset(keyspace, 0, sizeof(keyspace));
6037     }
6038
6039     logeventf(ssh, "Initialised %.200s client->server encryption",
6040               ssh->cscipher->text_name);
6041     logeventf(ssh, "Initialised %.200s client->server MAC algorithm",
6042               ssh->csmac->text_name);
6043     if (ssh->cscomp->text_name)
6044         logeventf(ssh, "Initialised %s compression",
6045                   ssh->cscomp->text_name);
6046
6047     /*
6048      * Now our end of the key exchange is complete, we can send all
6049      * our queued higher-layer packets.
6050      */
6051     ssh->queueing = FALSE;
6052     ssh2_pkt_queuesend(ssh);
6053
6054     /*
6055      * Expect SSH2_MSG_NEWKEYS from server.
6056      */
6057     crWaitUntil(pktin);
6058     if (pktin->type != SSH2_MSG_NEWKEYS) {
6059         bombout(("expected new-keys packet from server"));
6060         crStop(0);
6061     }
6062     ssh->incoming_data_size = 0;       /* start counting from here */
6063
6064     /*
6065      * We've seen server NEWKEYS, so create and initialise
6066      * server-to-client session keys.
6067      */
6068     if (ssh->sc_cipher_ctx)
6069         ssh->sccipher->free_context(ssh->sc_cipher_ctx);
6070     ssh->sccipher = s->sccipher_tobe;
6071     ssh->sc_cipher_ctx = ssh->sccipher->make_context();
6072
6073     if (ssh->sc_mac_ctx)
6074         ssh->scmac->free_context(ssh->sc_mac_ctx);
6075     ssh->scmac = s->scmac_tobe;
6076     ssh->sc_mac_ctx = ssh->scmac->make_context();
6077
6078     if (ssh->sc_comp_ctx)
6079         ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
6080     ssh->sccomp = s->sccomp_tobe;
6081     ssh->sc_comp_ctx = ssh->sccomp->decompress_init();
6082
6083     /*
6084      * Set IVs on server-to-client keys. Here we use the exchange
6085      * hash from the _first_ key exchange.
6086      */
6087     {
6088         unsigned char keyspace[SSH2_KEX_MAX_HASH_LEN * SSH2_MKKEY_ITERS];
6089         assert(sizeof(keyspace) >= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
6090         ssh2_mkkey(ssh,s->K,s->exchange_hash,'D',keyspace);
6091         assert((ssh->sccipher->keylen+7) / 8 <=
6092                ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
6093         ssh->sccipher->setkey(ssh->sc_cipher_ctx, keyspace);
6094         ssh2_mkkey(ssh,s->K,s->exchange_hash,'B',keyspace);
6095         assert(ssh->sccipher->blksize <=
6096                ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
6097         ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace);
6098         ssh2_mkkey(ssh,s->K,s->exchange_hash,'F',keyspace);
6099         assert(ssh->scmac->len <=
6100                ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
6101         ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace);
6102         memset(keyspace, 0, sizeof(keyspace));
6103     }
6104     logeventf(ssh, "Initialised %.200s server->client encryption",
6105               ssh->sccipher->text_name);
6106     logeventf(ssh, "Initialised %.200s server->client MAC algorithm",
6107               ssh->scmac->text_name);
6108     if (ssh->sccomp->text_name)
6109         logeventf(ssh, "Initialised %s decompression",
6110                   ssh->sccomp->text_name);
6111
6112     /*
6113      * Free shared secret.
6114      */
6115     freebn(s->K);
6116
6117     /*
6118      * Key exchange is over. Loop straight back round if we have a
6119      * deferred rekey reason.
6120      */
6121     if (ssh->deferred_rekey_reason) {
6122         logevent(ssh->deferred_rekey_reason);
6123         pktin = NULL;
6124         ssh->deferred_rekey_reason = NULL;
6125         goto begin_key_exchange;
6126     }
6127
6128     /*
6129      * Otherwise, schedule a timer for our next rekey.
6130      */
6131     ssh->kex_in_progress = FALSE;
6132     ssh->last_rekey = GETTICKCOUNT();
6133     if (ssh->cfg.ssh_rekey_time != 0)
6134         ssh->next_rekey = schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
6135                                          ssh2_timer, ssh);
6136
6137     /*
6138      * If this is the first key exchange phase, we must pass the
6139      * SSH2_MSG_NEWKEYS packet to the next layer, not because it
6140      * wants to see it but because it will need time to initialise
6141      * itself before it sees an actual packet. In subsequent key
6142      * exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
6143      * it would only confuse the layer above.
6144      */
6145     if (s->activated_authconn) {
6146         crReturn(0);
6147     }
6148     s->activated_authconn = TRUE;
6149
6150     /*
6151      * Now we're encrypting. Begin returning 1 to the protocol main
6152      * function so that other things can run on top of the
6153      * transport. If we ever see a KEXINIT, we must go back to the
6154      * start.
6155      * 
6156      * We _also_ go back to the start if we see pktin==NULL and
6157      * inlen==-1, because this is a special signal meaning
6158      * `initiate client-driven rekey', and `in' contains a message
6159      * giving the reason for the rekey.
6160      */
6161     while (!((pktin && pktin->type == SSH2_MSG_KEXINIT) ||
6162              (!pktin && inlen == -1))) {
6163         wait_for_rekey:
6164         crReturn(1);
6165     }
6166     if (pktin) {
6167         logevent("Server initiated key re-exchange");
6168     } else {
6169         /*
6170          * Special case: if the server bug is set that doesn't
6171          * allow rekeying, we give a different log message and
6172          * continue waiting. (If such a server _initiates_ a rekey,
6173          * we process it anyway!)
6174          */
6175         if ((ssh->remote_bugs & BUG_SSH2_REKEY)) {
6176             logeventf(ssh, "Server bug prevents key re-exchange (%s)",
6177                       (char *)in);
6178             /* Reset the counters, so that at least this message doesn't
6179              * hit the event log _too_ often. */
6180             ssh->outgoing_data_size = 0;
6181             ssh->incoming_data_size = 0;
6182             if (ssh->cfg.ssh_rekey_time != 0) {
6183                 ssh->next_rekey =
6184                     schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
6185                                    ssh2_timer, ssh);
6186             }
6187             goto wait_for_rekey;       /* this is utterly horrid */
6188         } else {
6189             logeventf(ssh, "Initiating key re-exchange (%s)", (char *)in);
6190         }
6191     }
6192     goto begin_key_exchange;
6193
6194     crFinish(1);
6195 }
6196
6197 /*
6198  * Add data to an SSH-2 channel output buffer.
6199  */
6200 static void ssh2_add_channel_data(struct ssh_channel *c, char *buf,
6201                                   int len)
6202 {
6203     bufchain_add(&c->v.v2.outbuffer, buf, len);
6204 }
6205
6206 /*
6207  * Attempt to send data on an SSH-2 channel.
6208  */
6209 static int ssh2_try_send(struct ssh_channel *c)
6210 {
6211     Ssh ssh = c->ssh;
6212     struct Packet *pktout;
6213
6214     while (c->v.v2.remwindow > 0 && bufchain_size(&c->v.v2.outbuffer) > 0) {
6215         int len;
6216         void *data;
6217         bufchain_prefix(&c->v.v2.outbuffer, &data, &len);
6218         if ((unsigned)len > c->v.v2.remwindow)
6219             len = c->v.v2.remwindow;
6220         if ((unsigned)len > c->v.v2.remmaxpkt)
6221             len = c->v.v2.remmaxpkt;
6222         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
6223         ssh2_pkt_adduint32(pktout, c->remoteid);
6224         ssh2_pkt_addstring_start(pktout);
6225         dont_log_data(ssh, pktout, PKTLOG_OMIT);
6226         ssh2_pkt_addstring_data(pktout, data, len);
6227         end_log_omission(ssh, pktout);
6228         ssh2_pkt_send(ssh, pktout);
6229         bufchain_consume(&c->v.v2.outbuffer, len);
6230         c->v.v2.remwindow -= len;
6231     }
6232
6233     /*
6234      * After having sent as much data as we can, return the amount
6235      * still buffered.
6236      */
6237     return bufchain_size(&c->v.v2.outbuffer);
6238 }
6239
6240 static void ssh2_try_send_and_unthrottle(struct ssh_channel *c)
6241 {
6242     int bufsize;
6243     if (c->closes)
6244         return;                        /* don't send on closing channels */
6245     bufsize = ssh2_try_send(c);
6246     if (bufsize == 0) {
6247         switch (c->type) {
6248           case CHAN_MAINSESSION:
6249             /* stdin need not receive an unthrottle
6250              * notification since it will be polled */
6251             break;
6252           case CHAN_X11:
6253             x11_unthrottle(c->u.x11.s);
6254             break;
6255           case CHAN_AGENT:
6256             /* agent sockets are request/response and need no
6257              * buffer management */
6258             break;
6259           case CHAN_SOCKDATA:
6260             pfd_unthrottle(c->u.pfd.s);
6261             break;
6262         }
6263     }
6264 }
6265
6266 /*
6267  * Set up most of a new ssh_channel for SSH-2.
6268  */
6269 static void ssh2_channel_init(struct ssh_channel *c)
6270 {
6271     Ssh ssh = c->ssh;
6272     c->localid = alloc_channel_id(ssh);
6273     c->closes = 0;
6274     c->throttling_conn = FALSE;
6275     c->v.v2.locwindow = c->v.v2.locmaxwin = c->v.v2.remlocwin =
6276         ssh->cfg.ssh_simple ? OUR_V2_BIGWIN : OUR_V2_WINSIZE;
6277     c->v.v2.winadj_head = c->v.v2.winadj_tail = NULL;
6278     c->v.v2.throttle_state = UNTHROTTLED;
6279     bufchain_init(&c->v.v2.outbuffer);
6280 }
6281
6282 /*
6283  * Potentially enlarge the window on an SSH-2 channel.
6284  */
6285 static void ssh2_set_window(struct ssh_channel *c, int newwin)
6286 {
6287     Ssh ssh = c->ssh;
6288
6289     /*
6290      * Never send WINDOW_ADJUST for a channel that the remote side
6291      * already thinks it's closed; there's no point, since it won't
6292      * be sending any more data anyway.
6293      */
6294     if (c->closes != 0)
6295         return;
6296
6297     /*
6298      * If the remote end has a habit of ignoring maxpkt, limit the
6299      * window so that it has no choice (assuming it doesn't ignore the
6300      * window as well).
6301      */
6302     if ((ssh->remote_bugs & BUG_SSH2_MAXPKT) && newwin > OUR_V2_MAXPKT)
6303         newwin = OUR_V2_MAXPKT;
6304         
6305
6306     /*
6307      * Only send a WINDOW_ADJUST if there's significantly more window
6308      * available than the other end thinks there is.  This saves us
6309      * sending a WINDOW_ADJUST for every character in a shell session.
6310      *
6311      * "Significant" is arbitrarily defined as half the window size.
6312      */
6313     if (newwin / 2 >= c->v.v2.locwindow) {
6314         struct Packet *pktout;
6315         struct winadj *wa;
6316
6317         /*
6318          * In order to keep track of how much window the client
6319          * actually has available, we'd like it to acknowledge each
6320          * WINDOW_ADJUST.  We can't do that directly, so we accompany
6321          * it with a CHANNEL_REQUEST that has to be acknowledged.
6322          *
6323          * This is only necessary if we're opening the window wide.
6324          * If we're not, then throughput is being constrained by
6325          * something other than the maximum window size anyway.
6326          *
6327          * We also only send this if the main channel has finished its
6328          * initial CHANNEL_REQUESTs and installed the default
6329          * CHANNEL_FAILURE handler, so as not to risk giving it
6330          * unexpected CHANNEL_FAILUREs.
6331          */
6332         if (newwin == c->v.v2.locmaxwin &&
6333             ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE]) {
6334             pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
6335             ssh2_pkt_adduint32(pktout, c->remoteid);
6336             ssh2_pkt_addstring(pktout, "winadj@putty.projects.tartarus.org");
6337             ssh2_pkt_addbool(pktout, TRUE);
6338             ssh2_pkt_send(ssh, pktout);
6339
6340             /*
6341              * CHANNEL_FAILURE doesn't come with any indication of
6342              * what message caused it, so we have to keep track of the
6343              * outstanding CHANNEL_REQUESTs ourselves.
6344              */
6345             wa = snew(struct winadj);
6346             wa->size = newwin - c->v.v2.locwindow;
6347             wa->next = NULL;
6348             if (!c->v.v2.winadj_head)
6349                 c->v.v2.winadj_head = wa;
6350             else
6351                 c->v.v2.winadj_tail->next = wa;
6352             c->v.v2.winadj_tail = wa;
6353             if (c->v.v2.throttle_state != UNTHROTTLED)
6354                 c->v.v2.throttle_state = UNTHROTTLING;
6355         } else {
6356             /* Pretend the WINDOW_ADJUST was acked immediately. */
6357             c->v.v2.remlocwin = newwin;
6358             c->v.v2.throttle_state = THROTTLED;
6359         }
6360         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
6361         ssh2_pkt_adduint32(pktout, c->remoteid);
6362         ssh2_pkt_adduint32(pktout, newwin - c->v.v2.locwindow);
6363         ssh2_pkt_send(ssh, pktout);
6364         c->v.v2.locwindow = newwin;
6365     }
6366 }
6367
6368 /*
6369  * Find the channel associated with a message.  If there's no channel,
6370  * or it's not properly open, make a noise about it and return NULL.
6371  */
6372 static struct ssh_channel *ssh2_channel_msg(Ssh ssh, struct Packet *pktin)
6373 {
6374     unsigned localid = ssh_pkt_getuint32(pktin);
6375     struct ssh_channel *c;
6376
6377     c = find234(ssh->channels, &localid, ssh_channelfind);
6378     if (!c ||
6379         (c->halfopen && pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION &&
6380          pktin->type != SSH2_MSG_CHANNEL_OPEN_FAILURE)) {
6381         char *buf = dupprintf("Received %s for %s channel %u",
6382                               ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx,
6383                                             pktin->type),
6384                               c ? "half-open" : "nonexistent", localid);
6385         ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6386         sfree(buf);
6387         return NULL;
6388     }
6389     return c;
6390 }
6391
6392 static void ssh2_msg_channel_success(Ssh ssh, struct Packet *pktin)
6393 {
6394     /*
6395      * This should never get called.  All channel requests are either
6396      * sent with want_reply false or are sent before this handler gets
6397      * installed.
6398      */
6399     struct ssh_channel *c;
6400     struct winadj *wa;
6401
6402     c = ssh2_channel_msg(ssh, pktin);
6403     if (!c)
6404         return;
6405     wa = c->v.v2.winadj_head;
6406     if (wa)
6407         ssh_disconnect(ssh, NULL, "Received SSH_MSG_CHANNEL_SUCCESS for "
6408                        "\"winadj@putty.projects.tartarus.org\"",
6409                        SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6410     else
6411         ssh_disconnect(ssh, NULL,
6412                        "Received unsolicited SSH_MSG_CHANNEL_SUCCESS",
6413                        SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6414 }
6415
6416 static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin)
6417 {
6418     /*
6419      * The only time this should get called is for "winadj@putty"
6420      * messages sent above.  All other channel requests are either
6421      * sent with want_reply false or are sent before this handler gets
6422      * installed.
6423      */
6424     struct ssh_channel *c;
6425     struct winadj *wa;
6426
6427     c = ssh2_channel_msg(ssh, pktin);
6428     if (!c)
6429         return;
6430     wa = c->v.v2.winadj_head;
6431     if (!wa) {
6432         ssh_disconnect(ssh, NULL,
6433                        "Received unsolicited SSH_MSG_CHANNEL_FAILURE",
6434                        SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6435         return;
6436     }
6437     c->v.v2.winadj_head = wa->next;
6438     c->v.v2.remlocwin += wa->size;
6439     sfree(wa);
6440     /*
6441      * winadj messages are only sent when the window is fully open, so
6442      * if we get an ack of one, we know any pending unthrottle is
6443      * complete.
6444      */
6445     if (c->v.v2.throttle_state == UNTHROTTLING)
6446         c->v.v2.throttle_state = UNTHROTTLED;
6447 }
6448
6449 static void ssh2_msg_channel_window_adjust(Ssh ssh, struct Packet *pktin)
6450 {
6451     struct ssh_channel *c;
6452     c = ssh2_channel_msg(ssh, pktin);
6453     if (!c)
6454         return;
6455     if (!c->closes) {
6456         c->v.v2.remwindow += ssh_pkt_getuint32(pktin);
6457         ssh2_try_send_and_unthrottle(c);
6458     }
6459 }
6460
6461 static void ssh2_msg_channel_data(Ssh ssh, struct Packet *pktin)
6462 {
6463     char *data;
6464     int length;
6465     struct ssh_channel *c;
6466     c = ssh2_channel_msg(ssh, pktin);
6467     if (!c)
6468         return;
6469     if (pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
6470         ssh_pkt_getuint32(pktin) != SSH2_EXTENDED_DATA_STDERR)
6471         return;                        /* extended but not stderr */
6472     ssh_pkt_getstring(pktin, &data, &length);
6473     if (data) {
6474         int bufsize = 0;
6475         c->v.v2.locwindow -= length;
6476         c->v.v2.remlocwin -= length;
6477         switch (c->type) {
6478           case CHAN_MAINSESSION:
6479             bufsize =
6480                 from_backend(ssh->frontend, pktin->type ==
6481                              SSH2_MSG_CHANNEL_EXTENDED_DATA,
6482                              data, length);
6483             break;
6484           case CHAN_X11:
6485             bufsize = x11_send(c->u.x11.s, data, length);
6486             break;
6487           case CHAN_SOCKDATA:
6488             bufsize = pfd_send(c->u.pfd.s, data, length);
6489             break;
6490           case CHAN_AGENT:
6491             while (length > 0) {
6492                 if (c->u.a.lensofar < 4) {
6493                     unsigned int l = min(4 - c->u.a.lensofar,
6494                                          (unsigned)length);
6495                     memcpy(c->u.a.msglen + c->u.a.lensofar,
6496                            data, l);
6497                     data += l;
6498                     length -= l;
6499                     c->u.a.lensofar += l;
6500                 }
6501                 if (c->u.a.lensofar == 4) {
6502                     c->u.a.totallen =
6503                         4 + GET_32BIT(c->u.a.msglen);
6504                     c->u.a.message = snewn(c->u.a.totallen,
6505                                            unsigned char);
6506                     memcpy(c->u.a.message, c->u.a.msglen, 4);
6507                 }
6508                 if (c->u.a.lensofar >= 4 && length > 0) {
6509                     unsigned int l =
6510                         min(c->u.a.totallen - c->u.a.lensofar,
6511                             (unsigned)length);
6512                     memcpy(c->u.a.message + c->u.a.lensofar,
6513                            data, l);
6514                     data += l;
6515                     length -= l;
6516                     c->u.a.lensofar += l;
6517                 }
6518                 if (c->u.a.lensofar == c->u.a.totallen) {
6519                     void *reply;
6520                     int replylen;
6521                     if (agent_query(c->u.a.message,
6522                                     c->u.a.totallen,
6523                                     &reply, &replylen,
6524                                     ssh_agentf_callback, c))
6525                         ssh_agentf_callback(c, reply, replylen);
6526                     sfree(c->u.a.message);
6527                     c->u.a.lensofar = 0;
6528                 }
6529             }
6530             bufsize = 0;
6531             break;
6532         }
6533         /*
6534          * If it looks like the remote end hit the end of its window,
6535          * and we didn't want it to do that, think about using a
6536          * larger window.
6537          */
6538         if (c->v.v2.remlocwin <= 0 && c->v.v2.throttle_state == UNTHROTTLED &&
6539             c->v.v2.locmaxwin < 0x40000000)
6540             c->v.v2.locmaxwin += OUR_V2_WINSIZE;
6541         /*
6542          * If we are not buffering too much data,
6543          * enlarge the window again at the remote side.
6544          * If we are buffering too much, we may still
6545          * need to adjust the window if the server's
6546          * sent excess data.
6547          */
6548         ssh2_set_window(c, bufsize < c->v.v2.locmaxwin ?
6549                         c->v.v2.locmaxwin - bufsize : 0);
6550         /*
6551          * If we're either buffering way too much data, or if we're
6552          * buffering anything at all and we're in "simple" mode,
6553          * throttle the whole channel.
6554          */
6555         if ((bufsize > c->v.v2.locmaxwin ||
6556              (ssh->cfg.ssh_simple && bufsize > 0)) &&
6557             !c->throttling_conn) {
6558             c->throttling_conn = 1;
6559             ssh_throttle_conn(ssh, +1);
6560         }
6561     }
6562 }
6563
6564 static void ssh2_msg_channel_eof(Ssh ssh, struct Packet *pktin)
6565 {
6566     struct ssh_channel *c;
6567
6568     c = ssh2_channel_msg(ssh, pktin);
6569     if (!c)
6570         return;
6571
6572     if (c->type == CHAN_X11) {
6573         /*
6574          * Remote EOF on an X11 channel means we should
6575          * wrap up and close the channel ourselves.
6576          */
6577         x11_close(c->u.x11.s);
6578         sshfwd_close(c);
6579     } else if (c->type == CHAN_AGENT) {
6580         sshfwd_close(c);
6581     } else if (c->type == CHAN_SOCKDATA) {
6582         pfd_close(c->u.pfd.s);
6583         sshfwd_close(c);
6584     }
6585 }
6586
6587 static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
6588 {
6589     struct ssh_channel *c;
6590     struct Packet *pktout;
6591
6592     c = ssh2_channel_msg(ssh, pktin);
6593     if (!c)
6594         return;
6595     /* Do pre-close processing on the channel. */
6596     switch (c->type) {
6597       case CHAN_MAINSESSION:
6598         ssh->mainchan = NULL;
6599         update_specials_menu(ssh->frontend);
6600         break;
6601       case CHAN_X11:
6602         if (c->u.x11.s != NULL)
6603             x11_close(c->u.x11.s);
6604         sshfwd_close(c);
6605         break;
6606       case CHAN_AGENT:
6607         sshfwd_close(c);
6608         break;
6609       case CHAN_SOCKDATA:
6610         if (c->u.pfd.s != NULL)
6611             pfd_close(c->u.pfd.s);
6612         sshfwd_close(c);
6613         break;
6614     }
6615     if (c->closes == 0) {
6616         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6617         ssh2_pkt_adduint32(pktout, c->remoteid);
6618         ssh2_pkt_send(ssh, pktout);
6619     }
6620     del234(ssh->channels, c);
6621     bufchain_clear(&c->v.v2.outbuffer);
6622     sfree(c);
6623
6624     /*
6625      * See if that was the last channel left open.
6626      * (This is only our termination condition if we're
6627      * not running in -N mode.)
6628      */
6629     if (!ssh->cfg.ssh_no_shell && count234(ssh->channels) == 0) {
6630         /*
6631          * We used to send SSH_MSG_DISCONNECT here,
6632          * because I'd believed that _every_ conforming
6633          * SSH-2 connection had to end with a disconnect
6634          * being sent by at least one side; apparently
6635          * I was wrong and it's perfectly OK to
6636          * unceremoniously slam the connection shut
6637          * when you're done, and indeed OpenSSH feels
6638          * this is more polite than sending a
6639          * DISCONNECT. So now we don't.
6640          */
6641         ssh_disconnect(ssh, "All channels closed", NULL, 0, TRUE);
6642     }
6643 }
6644
6645 static void ssh2_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
6646 {
6647     struct ssh_channel *c;
6648     struct Packet *pktout;
6649
6650     c = ssh2_channel_msg(ssh, pktin);
6651     if (!c)
6652         return;
6653     if (c->type != CHAN_SOCKDATA_DORMANT)
6654         return;                        /* dunno why they're confirming this */
6655     c->remoteid = ssh_pkt_getuint32(pktin);
6656     c->halfopen = FALSE;
6657     c->type = CHAN_SOCKDATA;
6658     c->v.v2.remwindow = ssh_pkt_getuint32(pktin);
6659     c->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
6660     if (c->u.pfd.s)
6661         pfd_confirm(c->u.pfd.s);
6662     if (c->closes) {
6663         /*
6664          * We have a pending close on this channel,
6665          * which we decided on before the server acked
6666          * the channel open. So now we know the
6667          * remoteid, we can close it again.
6668          */
6669         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6670         ssh2_pkt_adduint32(pktout, c->remoteid);
6671         ssh2_pkt_send(ssh, pktout);
6672     }
6673 }
6674
6675 static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
6676 {
6677     static const char *const reasons[] = {
6678         "<unknown reason code>",
6679             "Administratively prohibited",
6680             "Connect failed",
6681             "Unknown channel type",
6682             "Resource shortage",
6683     };
6684     unsigned reason_code;
6685     char *reason_string;
6686     int reason_length;
6687     struct ssh_channel *c;
6688     c = ssh2_channel_msg(ssh, pktin);
6689     if (!c)
6690         return;
6691     if (c->type != CHAN_SOCKDATA_DORMANT)
6692         return;                        /* dunno why they're failing this */
6693
6694     reason_code = ssh_pkt_getuint32(pktin);
6695     if (reason_code >= lenof(reasons))
6696         reason_code = 0; /* ensure reasons[reason_code] in range */
6697     ssh_pkt_getstring(pktin, &reason_string, &reason_length);
6698     logeventf(ssh, "Forwarded connection refused by server: %s [%.*s]",
6699               reasons[reason_code], reason_length, reason_string);
6700
6701     pfd_close(c->u.pfd.s);
6702
6703     del234(ssh->channels, c);
6704     sfree(c);
6705 }
6706
6707 static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin)
6708 {
6709     char *type;
6710     int typelen, want_reply;
6711     int reply = SSH2_MSG_CHANNEL_FAILURE; /* default */
6712     struct ssh_channel *c;
6713     struct Packet *pktout;
6714
6715     c = ssh2_channel_msg(ssh, pktin);
6716     if (!c)
6717         return;
6718     ssh_pkt_getstring(pktin, &type, &typelen);
6719     want_reply = ssh2_pkt_getbool(pktin);
6720
6721     /*
6722      * Having got the channel number, we now look at
6723      * the request type string to see if it's something
6724      * we recognise.
6725      */
6726     if (c == ssh->mainchan) {
6727         /*
6728          * We recognise "exit-status" and "exit-signal" on
6729          * the primary channel.
6730          */
6731         if (typelen == 11 &&
6732             !memcmp(type, "exit-status", 11)) {
6733
6734             ssh->exitcode = ssh_pkt_getuint32(pktin);
6735             logeventf(ssh, "Server sent command exit status %d",
6736                       ssh->exitcode);
6737             reply = SSH2_MSG_CHANNEL_SUCCESS;
6738
6739         } else if (typelen == 11 &&
6740                    !memcmp(type, "exit-signal", 11)) {
6741
6742             int is_plausible = TRUE, is_int = FALSE;
6743             char *fmt_sig = "", *fmt_msg = "";
6744             char *msg;
6745             int msglen = 0, core = FALSE;
6746             /* ICK: older versions of OpenSSH (e.g. 3.4p1)
6747              * provide an `int' for the signal, despite its
6748              * having been a `string' in the drafts of RFC 4254 since at
6749              * least 2001. (Fixed in session.c 1.147.) Try to
6750              * infer which we can safely parse it as. */
6751             {
6752                 unsigned char *p = pktin->body +
6753                     pktin->savedpos;
6754                 long len = pktin->length - pktin->savedpos;
6755                 unsigned long num = GET_32BIT(p); /* what is it? */
6756                 /* If it's 0, it hardly matters; assume string */
6757                 if (num == 0) {
6758                     is_int = FALSE;
6759                 } else {
6760                     int maybe_int = FALSE, maybe_str = FALSE;
6761 #define CHECK_HYPOTHESIS(offset, result) \
6762     do { \
6763         long q = offset; \
6764         if (q >= 0 && q+4 <= len) { \
6765             q = q + 4 + GET_32BIT(p+q); \
6766             if (q >= 0 && q+4 <= len && \
6767                     ((q = q + 4 + GET_32BIT(p+q))!= 0) && q == len) \
6768                 result = TRUE; \
6769         } \
6770     } while(0)
6771                     CHECK_HYPOTHESIS(4+1, maybe_int);
6772                     CHECK_HYPOTHESIS(4+num+1, maybe_str);
6773 #undef CHECK_HYPOTHESIS
6774                     if (maybe_int && !maybe_str)
6775                         is_int = TRUE;
6776                     else if (!maybe_int && maybe_str)
6777                         is_int = FALSE;
6778                     else
6779                         /* Crikey. Either or neither. Panic. */
6780                         is_plausible = FALSE;
6781                 }
6782             }
6783             ssh->exitcode = 128;       /* means `unknown signal' */
6784             if (is_plausible) {
6785                 if (is_int) {
6786                     /* Old non-standard OpenSSH. */
6787                     int signum = ssh_pkt_getuint32(pktin);
6788                     fmt_sig = dupprintf(" %d", signum);
6789                     ssh->exitcode = 128 + signum;
6790                 } else {
6791                     /* As per RFC 4254. */
6792                     char *sig;
6793                     int siglen;
6794                     ssh_pkt_getstring(pktin, &sig, &siglen);
6795                     /* Signal name isn't supposed to be blank, but
6796                      * let's cope gracefully if it is. */
6797                     if (siglen) {
6798                         fmt_sig = dupprintf(" \"%.*s\"",
6799                                             siglen, sig);
6800                     }
6801
6802                     /*
6803                      * Really hideous method of translating the
6804                      * signal description back into a locally
6805                      * meaningful number.
6806                      */
6807
6808                     if (0)
6809                         ;
6810 #define TRANSLATE_SIGNAL(s) \
6811     else if (siglen == lenof(#s)-1 && !memcmp(sig, #s, siglen)) \
6812         ssh->exitcode = 128 + SIG ## s
6813 #ifdef SIGABRT
6814                     TRANSLATE_SIGNAL(ABRT);
6815 #endif
6816 #ifdef SIGALRM
6817                     TRANSLATE_SIGNAL(ALRM);
6818 #endif
6819 #ifdef SIGFPE
6820                     TRANSLATE_SIGNAL(FPE);
6821 #endif
6822 #ifdef SIGHUP
6823                     TRANSLATE_SIGNAL(HUP);
6824 #endif
6825 #ifdef SIGILL
6826                     TRANSLATE_SIGNAL(ILL);
6827 #endif
6828 #ifdef SIGINT
6829                     TRANSLATE_SIGNAL(INT);
6830 #endif
6831 #ifdef SIGKILL
6832                     TRANSLATE_SIGNAL(KILL);
6833 #endif
6834 #ifdef SIGPIPE
6835                     TRANSLATE_SIGNAL(PIPE);
6836 #endif
6837 #ifdef SIGQUIT
6838                     TRANSLATE_SIGNAL(QUIT);
6839 #endif
6840 #ifdef SIGSEGV
6841                     TRANSLATE_SIGNAL(SEGV);
6842 #endif
6843 #ifdef SIGTERM
6844                     TRANSLATE_SIGNAL(TERM);
6845 #endif
6846 #ifdef SIGUSR1
6847                     TRANSLATE_SIGNAL(USR1);
6848 #endif
6849 #ifdef SIGUSR2
6850                     TRANSLATE_SIGNAL(USR2);
6851 #endif
6852 #undef TRANSLATE_SIGNAL
6853                     else
6854                         ssh->exitcode = 128;
6855                 }
6856                 core = ssh2_pkt_getbool(pktin);
6857                 ssh_pkt_getstring(pktin, &msg, &msglen);
6858                 if (msglen) {
6859                     fmt_msg = dupprintf(" (\"%.*s\")", msglen, msg);
6860                 }
6861                 /* ignore lang tag */
6862             } /* else don't attempt to parse */
6863             logeventf(ssh, "Server exited on signal%s%s%s",
6864                       fmt_sig, core ? " (core dumped)" : "",
6865                       fmt_msg);
6866             if (*fmt_sig) sfree(fmt_sig);
6867             if (*fmt_msg) sfree(fmt_msg);
6868             reply = SSH2_MSG_CHANNEL_SUCCESS;
6869
6870         }
6871     } else {
6872         /*
6873          * This is a channel request we don't know
6874          * about, so we now either ignore the request
6875          * or respond with CHANNEL_FAILURE, depending
6876          * on want_reply.
6877          */
6878         reply = SSH2_MSG_CHANNEL_FAILURE;
6879     }
6880     if (want_reply) {
6881         pktout = ssh2_pkt_init(reply);
6882         ssh2_pkt_adduint32(pktout, c->remoteid);
6883         ssh2_pkt_send(ssh, pktout);
6884     }
6885 }
6886
6887 static void ssh2_msg_global_request(Ssh ssh, struct Packet *pktin)
6888 {
6889     char *type;
6890     int typelen, want_reply;
6891     struct Packet *pktout;
6892
6893     ssh_pkt_getstring(pktin, &type, &typelen);
6894     want_reply = ssh2_pkt_getbool(pktin);
6895
6896     /*
6897      * We currently don't support any global requests
6898      * at all, so we either ignore the request or
6899      * respond with REQUEST_FAILURE, depending on
6900      * want_reply.
6901      */
6902     if (want_reply) {
6903         pktout = ssh2_pkt_init(SSH2_MSG_REQUEST_FAILURE);
6904         ssh2_pkt_send(ssh, pktout);
6905     }
6906 }
6907
6908 static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin)
6909 {
6910     char *type;
6911     int typelen;
6912     char *peeraddr;
6913     int peeraddrlen;
6914     int peerport;
6915     char *error = NULL;
6916     struct ssh_channel *c;
6917     unsigned remid, winsize, pktsize;
6918     struct Packet *pktout;
6919
6920     ssh_pkt_getstring(pktin, &type, &typelen);
6921     c = snew(struct ssh_channel);
6922     c->ssh = ssh;
6923
6924     remid = ssh_pkt_getuint32(pktin);
6925     winsize = ssh_pkt_getuint32(pktin);
6926     pktsize = ssh_pkt_getuint32(pktin);
6927
6928     if (typelen == 3 && !memcmp(type, "x11", 3)) {
6929         char *addrstr;
6930
6931         ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
6932         addrstr = snewn(peeraddrlen+1, char);
6933         memcpy(addrstr, peeraddr, peeraddrlen);
6934         addrstr[peeraddrlen] = '\0';
6935         peerport = ssh_pkt_getuint32(pktin);
6936
6937         logeventf(ssh, "Received X11 connect request from %s:%d",
6938                   addrstr, peerport);
6939
6940         if (!ssh->X11_fwd_enabled)
6941             error = "X11 forwarding is not enabled";
6942         else if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c,
6943                           ssh->x11auth, addrstr, peerport,
6944                           &ssh->cfg) != NULL) {
6945             error = "Unable to open an X11 connection";
6946         } else {
6947             logevent("Opening X11 forward connection succeeded");
6948             c->type = CHAN_X11;
6949         }
6950
6951         sfree(addrstr);
6952     } else if (typelen == 15 &&
6953                !memcmp(type, "forwarded-tcpip", 15)) {
6954         struct ssh_rportfwd pf, *realpf;
6955         char *dummy;
6956         int dummylen;
6957         ssh_pkt_getstring(pktin, &dummy, &dummylen);/* skip address */
6958         pf.sport = ssh_pkt_getuint32(pktin);
6959         ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
6960         peerport = ssh_pkt_getuint32(pktin);
6961         realpf = find234(ssh->rportfwds, &pf, NULL);
6962         logeventf(ssh, "Received remote port %d open request "
6963                   "from %s:%d", pf.sport, peeraddr, peerport);
6964         if (realpf == NULL) {
6965             error = "Remote port is not recognised";
6966         } else {
6967             const char *e = pfd_newconnect(&c->u.pfd.s,
6968                                            realpf->dhost,
6969                                            realpf->dport, c,
6970                                            &ssh->cfg,
6971                                            realpf->pfrec->addressfamily);
6972             logeventf(ssh, "Attempting to forward remote port to "
6973                       "%s:%d", realpf->dhost, realpf->dport);
6974             if (e != NULL) {
6975                 logeventf(ssh, "Port open failed: %s", e);
6976                 error = "Port open failed";
6977             } else {
6978                 logevent("Forwarded port opened successfully");
6979                 c->type = CHAN_SOCKDATA;
6980             }
6981         }
6982     } else if (typelen == 22 &&
6983                !memcmp(type, "auth-agent@openssh.com", 22)) {
6984         if (!ssh->agentfwd_enabled)
6985             error = "Agent forwarding is not enabled";
6986         else {
6987             c->type = CHAN_AGENT;       /* identify channel type */
6988             c->u.a.lensofar = 0;
6989         }
6990     } else {
6991         error = "Unsupported channel type requested";
6992     }
6993
6994     c->remoteid = remid;
6995     c->halfopen = FALSE;
6996     if (error) {
6997         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_FAILURE);
6998         ssh2_pkt_adduint32(pktout, c->remoteid);
6999         ssh2_pkt_adduint32(pktout, SSH2_OPEN_CONNECT_FAILED);
7000         ssh2_pkt_addstring(pktout, error);
7001         ssh2_pkt_addstring(pktout, "en");       /* language tag */
7002         ssh2_pkt_send(ssh, pktout);
7003         logeventf(ssh, "Rejected channel open: %s", error);
7004         sfree(c);
7005     } else {
7006         ssh2_channel_init(c);
7007         c->v.v2.remwindow = winsize;
7008         c->v.v2.remmaxpkt = pktsize;
7009         add234(ssh->channels, c);
7010         pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
7011         ssh2_pkt_adduint32(pktout, c->remoteid);
7012         ssh2_pkt_adduint32(pktout, c->localid);
7013         ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);
7014         ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT);      /* our max pkt size */
7015         ssh2_pkt_send(ssh, pktout);
7016     }
7017 }
7018
7019 /*
7020  * Buffer banner messages for later display at some convenient point.
7021  */
7022 static void ssh2_msg_userauth_banner(Ssh ssh, struct Packet *pktin)
7023 {
7024     /* Arbitrary limit to prevent unbounded inflation of buffer */
7025     if (bufchain_size(&ssh->banner) <= 131072) {
7026         char *banner = NULL;
7027         int size = 0;
7028         ssh_pkt_getstring(pktin, &banner, &size);
7029         if (banner)
7030             bufchain_add(&ssh->banner, banner, size);
7031     }
7032 }
7033
7034 /* Helper function to deal with sending tty modes for "pty-req" */
7035 static void ssh2_send_ttymode(void *data, char *mode, char *val)
7036 {
7037     struct Packet *pktout = (struct Packet *)data;
7038     int i = 0;
7039     unsigned int arg = 0;
7040     while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
7041     if (i == lenof(ssh_ttymodes)) return;
7042     switch (ssh_ttymodes[i].type) {
7043       case TTY_OP_CHAR:
7044         arg = ssh_tty_parse_specchar(val);
7045         break;
7046       case TTY_OP_BOOL:
7047         arg = ssh_tty_parse_boolean(val);
7048         break;
7049     }
7050     ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
7051     ssh2_pkt_adduint32(pktout, arg);
7052 }
7053
7054 /*
7055  * Handle the SSH-2 userauth and connection layers.
7056  */
7057 static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
7058                              struct Packet *pktin)
7059 {
7060     struct do_ssh2_authconn_state {
7061         enum {
7062             AUTH_TYPE_NONE,
7063                 AUTH_TYPE_PUBLICKEY,
7064                 AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
7065                 AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
7066                 AUTH_TYPE_PASSWORD,
7067                 AUTH_TYPE_GSSAPI,
7068                 AUTH_TYPE_KEYBOARD_INTERACTIVE,
7069                 AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
7070         } type;
7071         int done_service_req;
7072         int gotit, need_pw, can_pubkey, can_passwd, can_keyb_inter;
7073         int tried_pubkey_config, done_agent;
7074         int can_gssapi;
7075         int tried_gssapi;
7076         int kbd_inter_refused;
7077         int we_are_in;
7078         prompts_t *cur_prompt;
7079         int num_prompts;
7080         char username[100];
7081         char *password;
7082         int got_username;
7083         void *publickey_blob;
7084         int publickey_bloblen;
7085         int publickey_encrypted;
7086         char *publickey_algorithm;
7087         char *publickey_comment;
7088         unsigned char agent_request[5], *agent_response, *agentp;
7089         int agent_responselen;
7090         unsigned char *pkblob_in_agent;
7091         int keyi, nkeys;
7092         char *pkblob, *alg, *commentp;
7093         int pklen, alglen, commentlen;
7094         int siglen, retlen, len;
7095         char *q, *agentreq, *ret;
7096         int try_send;
7097         int num_env, env_left, env_ok;
7098         struct Packet *pktout;
7099         Ssh_gss_ctx gss_ctx;
7100         Ssh_gss_buf gss_buf;
7101         Ssh_gss_buf gss_rcvtok, gss_sndtok;
7102         Ssh_gss_name gss_srv_name;
7103         Ssh_gss_stat gss_stat;
7104     };
7105     crState(do_ssh2_authconn_state);
7106
7107     crBegin(ssh->do_ssh2_authconn_crstate);
7108
7109     s->done_service_req = FALSE;
7110     s->we_are_in = FALSE;
7111     s->tried_gssapi = FALSE;
7112
7113     if (!ssh->cfg.ssh_no_userauth) {
7114         /*
7115          * Request userauth protocol, and await a response to it.
7116          */
7117         s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
7118         ssh2_pkt_addstring(s->pktout, "ssh-userauth");
7119         ssh2_pkt_send(ssh, s->pktout);
7120         crWaitUntilV(pktin);
7121         if (pktin->type == SSH2_MSG_SERVICE_ACCEPT)
7122             s->done_service_req = TRUE;
7123     }
7124     if (!s->done_service_req) {
7125         /*
7126          * Request connection protocol directly, without authentication.
7127          */
7128         s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
7129         ssh2_pkt_addstring(s->pktout, "ssh-connection");
7130         ssh2_pkt_send(ssh, s->pktout);
7131         crWaitUntilV(pktin);
7132         if (pktin->type == SSH2_MSG_SERVICE_ACCEPT) {
7133             s->we_are_in = TRUE; /* no auth required */
7134         } else {
7135             bombout(("Server refused service request"));
7136             crStopV;
7137         }
7138     }
7139
7140     /* Arrange to be able to deal with any BANNERs that come in.
7141      * (We do this now as packets may come in during the next bit.) */
7142     bufchain_init(&ssh->banner);
7143     ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] =
7144         ssh2_msg_userauth_banner;
7145
7146     /*
7147      * Misc one-time setup for authentication.
7148      */
7149     s->publickey_blob = NULL;
7150     if (!s->we_are_in) {
7151
7152         /*
7153          * Load the public half of any configured public key file
7154          * for later use.
7155          */
7156         if (!filename_is_null(ssh->cfg.keyfile)) {
7157             int keytype;
7158             logeventf(ssh, "Reading private key file \"%.150s\"",
7159                       filename_to_str(&ssh->cfg.keyfile));
7160             keytype = key_type(&ssh->cfg.keyfile);
7161             if (keytype == SSH_KEYTYPE_SSH2) {
7162                 const char *error;
7163                 s->publickey_blob =
7164                     ssh2_userkey_loadpub(&ssh->cfg.keyfile,
7165                                          &s->publickey_algorithm,
7166                                          &s->publickey_bloblen, 
7167                                          &s->publickey_comment, &error);
7168                 if (s->publickey_blob) {
7169                     s->publickey_encrypted =
7170                         ssh2_userkey_encrypted(&ssh->cfg.keyfile, NULL);
7171                 } else {
7172                     char *msgbuf;
7173                     logeventf(ssh, "Unable to load private key (%s)", 
7174                               error);
7175                     msgbuf = dupprintf("Unable to load private key file "
7176                                        "\"%.150s\" (%s)\r\n",
7177                                        filename_to_str(&ssh->cfg.keyfile),
7178                                        error);
7179                     c_write_str(ssh, msgbuf);
7180                     sfree(msgbuf);
7181                 }
7182             } else {
7183                 char *msgbuf;
7184                 logeventf(ssh, "Unable to use this key file (%s)",
7185                           key_type_to_str(keytype));
7186                 msgbuf = dupprintf("Unable to use key file \"%.150s\""
7187                                    " (%s)\r\n",
7188                                    filename_to_str(&ssh->cfg.keyfile),
7189                                    key_type_to_str(keytype));
7190                 c_write_str(ssh, msgbuf);
7191                 sfree(msgbuf);
7192                 s->publickey_blob = NULL;
7193             }
7194         }
7195
7196         /*
7197          * Find out about any keys Pageant has (but if there's a
7198          * public key configured, filter out all others).
7199          */
7200         s->nkeys = 0;
7201         s->agent_response = NULL;
7202         s->pkblob_in_agent = NULL;
7203         if (ssh->cfg.tryagent && agent_exists()) {
7204
7205             void *r;
7206
7207             logevent("Pageant is running. Requesting keys.");
7208
7209             /* Request the keys held by the agent. */
7210             PUT_32BIT(s->agent_request, 1);
7211             s->agent_request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
7212             if (!agent_query(s->agent_request, 5, &r, &s->agent_responselen,
7213                              ssh_agent_callback, ssh)) {
7214                 do {
7215                     crReturnV;
7216                     if (pktin) {
7217                         bombout(("Unexpected data from server while"
7218                                  " waiting for agent response"));
7219                         crStopV;
7220                     }
7221                 } while (pktin || inlen > 0);
7222                 r = ssh->agent_response;
7223                 s->agent_responselen = ssh->agent_response_len;
7224             }
7225             s->agent_response = (unsigned char *) r;
7226             if (s->agent_response && s->agent_responselen >= 5 &&
7227                 s->agent_response[4] == SSH2_AGENT_IDENTITIES_ANSWER) {
7228                 int keyi;
7229                 unsigned char *p;
7230                 p = s->agent_response + 5;
7231                 s->nkeys = GET_32BIT(p);
7232                 p += 4;
7233                 logeventf(ssh, "Pageant has %d SSH-2 keys", s->nkeys);
7234                 if (s->publickey_blob) {
7235                     /* See if configured key is in agent. */
7236                     for (keyi = 0; keyi < s->nkeys; keyi++) {
7237                         s->pklen = GET_32BIT(p);
7238                         if (s->pklen == s->publickey_bloblen &&
7239                             !memcmp(p+4, s->publickey_blob,
7240                                     s->publickey_bloblen)) {
7241                             logeventf(ssh, "Pageant key #%d matches "
7242                                       "configured key file", keyi);
7243                             s->keyi = keyi;
7244                             s->pkblob_in_agent = p;
7245                             break;
7246                         }
7247                         p += 4 + s->pklen;
7248                         p += GET_32BIT(p) + 4; /* comment */
7249                     }
7250                     if (!s->pkblob_in_agent) {
7251                         logevent("Configured key file not in Pageant");
7252                         s->nkeys = 0;
7253                     }
7254                 }
7255             }
7256         }
7257
7258     }
7259
7260     /*
7261      * We repeat this whole loop, including the username prompt,
7262      * until we manage a successful authentication. If the user
7263      * types the wrong _password_, they can be sent back to the
7264      * beginning to try another username, if this is configured on.
7265      * (If they specify a username in the config, they are never
7266      * asked, even if they do give a wrong password.)
7267      * 
7268      * I think this best serves the needs of
7269      * 
7270      *  - the people who have no configuration, no keys, and just
7271      *    want to try repeated (username,password) pairs until they
7272      *    type both correctly
7273      * 
7274      *  - people who have keys and configuration but occasionally
7275      *    need to fall back to passwords
7276      * 
7277      *  - people with a key held in Pageant, who might not have
7278      *    logged in to a particular machine before; so they want to
7279      *    type a username, and then _either_ their key will be
7280      *    accepted, _or_ they will type a password. If they mistype
7281      *    the username they will want to be able to get back and
7282      *    retype it!
7283      */
7284     s->username[0] = '\0';
7285     s->got_username = FALSE;
7286     while (!s->we_are_in) {
7287         /*
7288          * Get a username.
7289          */
7290         if (s->got_username && !ssh->cfg.change_username) {
7291             /*
7292              * We got a username last time round this loop, and
7293              * with change_username turned off we don't try to get
7294              * it again.
7295              */
7296         } else if (!*ssh->cfg.username) {
7297             int ret; /* need not be kept over crReturn */
7298             s->cur_prompt = new_prompts(ssh->frontend);
7299             s->cur_prompt->to_server = TRUE;
7300             s->cur_prompt->name = dupstr("SSH login name");
7301             add_prompt(s->cur_prompt, dupstr("login as: "), TRUE,
7302                        lenof(s->username)); 
7303             ret = get_userpass_input(s->cur_prompt, NULL, 0);
7304             while (ret < 0) {
7305                 ssh->send_ok = 1;
7306                 crWaitUntilV(!pktin);
7307                 ret = get_userpass_input(s->cur_prompt, in, inlen);
7308                 ssh->send_ok = 0;
7309             }
7310             if (!ret) {
7311                 /*
7312                  * get_userpass_input() failed to get a username.
7313                  * Terminate.
7314                  */
7315                 free_prompts(s->cur_prompt);
7316                 ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
7317                 crStopV;
7318             }
7319             memcpy(s->username, s->cur_prompt->prompts[0]->result,
7320                    lenof(s->username));
7321             free_prompts(s->cur_prompt);
7322         } else {
7323             char *stuff;
7324             strncpy(s->username, ssh->cfg.username, sizeof(s->username));
7325             s->username[sizeof(s->username)-1] = '\0';
7326             if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
7327                 stuff = dupprintf("Using username \"%s\".\r\n", s->username);
7328                 c_write_str(ssh, stuff);
7329                 sfree(stuff);
7330             }
7331         }
7332         s->got_username = TRUE;
7333
7334         /*
7335          * Send an authentication request using method "none": (a)
7336          * just in case it succeeds, and (b) so that we know what
7337          * authentication methods we can usefully try next.
7338          */
7339         ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
7340
7341         s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7342         ssh2_pkt_addstring(s->pktout, s->username);
7343         ssh2_pkt_addstring(s->pktout, "ssh-connection");/* service requested */
7344         ssh2_pkt_addstring(s->pktout, "none");    /* method */
7345         ssh2_pkt_send(ssh, s->pktout);
7346         s->type = AUTH_TYPE_NONE;
7347         s->gotit = FALSE;
7348         s->we_are_in = FALSE;
7349
7350         s->tried_pubkey_config = FALSE;
7351         s->kbd_inter_refused = FALSE;
7352
7353         /* Reset agent request state. */
7354         s->done_agent = FALSE;
7355         if (s->agent_response) {
7356             if (s->pkblob_in_agent) {
7357                 s->agentp = s->pkblob_in_agent;
7358             } else {
7359                 s->agentp = s->agent_response + 5 + 4;
7360                 s->keyi = 0;
7361             }
7362         }
7363
7364         while (1) {
7365             /*
7366              * Wait for the result of the last authentication request.
7367              */
7368             if (!s->gotit)
7369                 crWaitUntilV(pktin);
7370             /*
7371              * Now is a convenient point to spew any banner material
7372              * that we've accumulated. (This should ensure that when
7373              * we exit the auth loop, we haven't any left to deal
7374              * with.)
7375              */
7376             {
7377                 int size = bufchain_size(&ssh->banner);
7378                 /*
7379                  * Don't show the banner if we're operating in
7380                  * non-verbose non-interactive mode. (It's probably
7381                  * a script, which means nobody will read the
7382                  * banner _anyway_, and moreover the printing of
7383                  * the banner will screw up processing on the
7384                  * output of (say) plink.)
7385                  */
7386                 if (size && (flags & (FLAG_VERBOSE | FLAG_INTERACTIVE))) {
7387                     char *banner = snewn(size, char);
7388                     bufchain_fetch(&ssh->banner, banner, size);
7389                     c_write_untrusted(ssh, banner, size);
7390                     sfree(banner);
7391                 }
7392                 bufchain_clear(&ssh->banner);
7393             }
7394             if (pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
7395                 logevent("Access granted");
7396                 s->we_are_in = TRUE;
7397                 break;
7398             }
7399
7400             if (pktin->type != SSH2_MSG_USERAUTH_FAILURE && s->type != AUTH_TYPE_GSSAPI) {
7401                 bombout(("Strange packet received during authentication: "
7402                          "type %d", pktin->type));
7403                 crStopV;
7404             }
7405
7406             s->gotit = FALSE;
7407
7408             /*
7409              * OK, we're now sitting on a USERAUTH_FAILURE message, so
7410              * we can look at the string in it and know what we can
7411              * helpfully try next.
7412              */
7413             if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
7414                 char *methods;
7415                 int methlen;
7416                 ssh_pkt_getstring(pktin, &methods, &methlen);
7417                 if (!ssh2_pkt_getbool(pktin)) {
7418                     /*
7419                      * We have received an unequivocal Access
7420                      * Denied. This can translate to a variety of
7421                      * messages:
7422                      * 
7423                      *  - if we'd just tried "none" authentication,
7424                      *    it's not worth printing anything at all
7425                      * 
7426                      *  - if we'd just tried a public key _offer_,
7427                      *    the message should be "Server refused our
7428                      *    key" (or no message at all if the key
7429                      *    came from Pageant)
7430                      * 
7431                      *  - if we'd just tried anything else, the
7432                      *    message really should be "Access denied".
7433                      * 
7434                      * Additionally, if we'd just tried password
7435                      * authentication, we should break out of this
7436                      * whole loop so as to go back to the username
7437                      * prompt (iff we're configured to allow
7438                      * username change attempts).
7439                      */
7440                     if (s->type == AUTH_TYPE_NONE) {
7441                         /* do nothing */
7442                     } else if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
7443                                s->type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
7444                         if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
7445                             c_write_str(ssh, "Server refused our key\r\n");
7446                         logevent("Server refused public key");
7447                     } else if (s->type==AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET) {
7448                         /* server declined keyboard-interactive; ignore */
7449                     } else {
7450                         c_write_str(ssh, "Access denied\r\n");
7451                         logevent("Access denied");
7452                         if (s->type == AUTH_TYPE_PASSWORD &&
7453                             ssh->cfg.change_username) {
7454                             /* XXX perhaps we should allow
7455                              * keyboard-interactive to do this too? */
7456                             s->we_are_in = FALSE;
7457                             break;
7458                         }
7459                     }
7460                 } else {
7461                     c_write_str(ssh, "Further authentication required\r\n");
7462                     logevent("Further authentication required");
7463                 }
7464
7465                 s->can_pubkey =
7466                     in_commasep_string("publickey", methods, methlen);
7467                 s->can_passwd =
7468                     in_commasep_string("password", methods, methlen);
7469                 s->can_keyb_inter = ssh->cfg.try_ki_auth &&
7470                     in_commasep_string("keyboard-interactive", methods, methlen);
7471 #ifndef NO_GSSAPI               
7472                 s->can_gssapi = ssh->cfg.try_gssapi_auth &&
7473                   in_commasep_string("gssapi-with-mic", methods, methlen) &&
7474                   ssh_gss_init();
7475 #endif
7476             }
7477
7478             ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
7479
7480             if (s->can_pubkey && !s->done_agent && s->nkeys) {
7481
7482                 /*
7483                  * Attempt public-key authentication using a key from Pageant.
7484                  */
7485
7486                 ssh->pkt_actx = SSH2_PKTCTX_PUBLICKEY;
7487
7488                 logeventf(ssh, "Trying Pageant key #%d", s->keyi);
7489
7490                 /* Unpack key from agent response */
7491                 s->pklen = GET_32BIT(s->agentp);
7492                 s->agentp += 4;
7493                 s->pkblob = (char *)s->agentp;
7494                 s->agentp += s->pklen;
7495                 s->alglen = GET_32BIT(s->pkblob);
7496                 s->alg = s->pkblob + 4;
7497                 s->commentlen = GET_32BIT(s->agentp);
7498                 s->agentp += 4;
7499                 s->commentp = (char *)s->agentp;
7500                 s->agentp += s->commentlen;
7501                 /* s->agentp now points at next key, if any */
7502
7503                 /* See if server will accept it */
7504                 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7505                 ssh2_pkt_addstring(s->pktout, s->username);
7506                 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7507                                                     /* service requested */
7508                 ssh2_pkt_addstring(s->pktout, "publickey");
7509                                                     /* method */
7510                 ssh2_pkt_addbool(s->pktout, FALSE); /* no signature included */
7511                 ssh2_pkt_addstring_start(s->pktout);
7512                 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
7513                 ssh2_pkt_addstring_start(s->pktout);
7514                 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
7515                 ssh2_pkt_send(ssh, s->pktout);
7516                 s->type = AUTH_TYPE_PUBLICKEY_OFFER_QUIET;
7517
7518                 crWaitUntilV(pktin);
7519                 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
7520
7521                     /* Offer of key refused. */
7522                     s->gotit = TRUE;
7523
7524                 } else {
7525                     
7526                     void *vret;
7527
7528                     if (flags & FLAG_VERBOSE) {
7529                         c_write_str(ssh, "Authenticating with "
7530                                     "public key \"");
7531                         c_write(ssh, s->commentp, s->commentlen);
7532                         c_write_str(ssh, "\" from agent\r\n");
7533                     }
7534
7535                     /*
7536                      * Server is willing to accept the key.
7537                      * Construct a SIGN_REQUEST.
7538                      */
7539                     s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7540                     ssh2_pkt_addstring(s->pktout, s->username);
7541                     ssh2_pkt_addstring(s->pktout, "ssh-connection");
7542                                                         /* service requested */
7543                     ssh2_pkt_addstring(s->pktout, "publickey");
7544                                                         /* method */
7545                     ssh2_pkt_addbool(s->pktout, TRUE);  /* signature included */
7546                     ssh2_pkt_addstring_start(s->pktout);
7547                     ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
7548                     ssh2_pkt_addstring_start(s->pktout);
7549                     ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
7550
7551                     /* Ask agent for signature. */
7552                     s->siglen = s->pktout->length - 5 + 4 +
7553                         ssh->v2_session_id_len;
7554                     if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7555                         s->siglen -= 4;
7556                     s->len = 1;       /* message type */
7557                     s->len += 4 + s->pklen;     /* key blob */
7558                     s->len += 4 + s->siglen;    /* data to sign */
7559                     s->len += 4;      /* flags */
7560                     s->agentreq = snewn(4 + s->len, char);
7561                     PUT_32BIT(s->agentreq, s->len);
7562                     s->q = s->agentreq + 4;
7563                     *s->q++ = SSH2_AGENTC_SIGN_REQUEST;
7564                     PUT_32BIT(s->q, s->pklen);
7565                     s->q += 4;
7566                     memcpy(s->q, s->pkblob, s->pklen);
7567                     s->q += s->pklen;
7568                     PUT_32BIT(s->q, s->siglen);
7569                     s->q += 4;
7570                     /* Now the data to be signed... */
7571                     if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7572                         PUT_32BIT(s->q, ssh->v2_session_id_len);
7573                         s->q += 4;
7574                     }
7575                     memcpy(s->q, ssh->v2_session_id,
7576                            ssh->v2_session_id_len);
7577                     s->q += ssh->v2_session_id_len;
7578                     memcpy(s->q, s->pktout->data + 5,
7579                            s->pktout->length - 5);
7580                     s->q += s->pktout->length - 5;
7581                     /* And finally the (zero) flags word. */
7582                     PUT_32BIT(s->q, 0);
7583                     if (!agent_query(s->agentreq, s->len + 4,
7584                                      &vret, &s->retlen,
7585                                      ssh_agent_callback, ssh)) {
7586                         do {
7587                             crReturnV;
7588                             if (pktin) {
7589                                 bombout(("Unexpected data from server"
7590                                          " while waiting for agent"
7591                                          " response"));
7592                                 crStopV;
7593                             }
7594                         } while (pktin || inlen > 0);
7595                         vret = ssh->agent_response;
7596                         s->retlen = ssh->agent_response_len;
7597                     }
7598                     s->ret = vret;
7599                     sfree(s->agentreq);
7600                     if (s->ret) {
7601                         if (s->ret[4] == SSH2_AGENT_SIGN_RESPONSE) {
7602                             logevent("Sending Pageant's response");
7603                             ssh2_add_sigblob(ssh, s->pktout,
7604                                              s->pkblob, s->pklen,
7605                                              s->ret + 9,
7606                                              GET_32BIT(s->ret + 5));
7607                             ssh2_pkt_send(ssh, s->pktout);
7608                             s->type = AUTH_TYPE_PUBLICKEY;
7609                         } else {
7610                             /* FIXME: less drastic response */
7611                             bombout(("Pageant failed to answer challenge"));
7612                             crStopV;
7613                         }
7614                     }
7615                 }
7616
7617                 /* Do we have any keys left to try? */
7618                 if (s->pkblob_in_agent) {
7619                     s->done_agent = TRUE;
7620                     s->tried_pubkey_config = TRUE;
7621                 } else {
7622                     s->keyi++;
7623                     if (s->keyi >= s->nkeys)
7624                         s->done_agent = TRUE;
7625                 }
7626
7627             } else if (s->can_pubkey && s->publickey_blob &&
7628                        !s->tried_pubkey_config) {
7629
7630                 struct ssh2_userkey *key;   /* not live over crReturn */
7631                 char *passphrase;           /* not live over crReturn */
7632
7633                 ssh->pkt_actx = SSH2_PKTCTX_PUBLICKEY;
7634
7635                 s->tried_pubkey_config = TRUE;
7636
7637                 /*
7638                  * Try the public key supplied in the configuration.
7639                  *
7640                  * First, offer the public blob to see if the server is
7641                  * willing to accept it.
7642                  */
7643                 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7644                 ssh2_pkt_addstring(s->pktout, s->username);
7645                 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7646                                                 /* service requested */
7647                 ssh2_pkt_addstring(s->pktout, "publickey");     /* method */
7648                 ssh2_pkt_addbool(s->pktout, FALSE);
7649                                                 /* no signature included */
7650                 ssh2_pkt_addstring(s->pktout, s->publickey_algorithm);
7651                 ssh2_pkt_addstring_start(s->pktout);
7652                 ssh2_pkt_addstring_data(s->pktout,
7653                                         (char *)s->publickey_blob,
7654                                         s->publickey_bloblen);
7655                 ssh2_pkt_send(ssh, s->pktout);
7656                 logevent("Offered public key");
7657
7658                 crWaitUntilV(pktin);
7659                 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
7660                     /* Key refused. Give up. */
7661                     s->gotit = TRUE; /* reconsider message next loop */
7662                     s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
7663                     continue; /* process this new message */
7664                 }
7665                 logevent("Offer of public key accepted");
7666
7667                 /*
7668                  * Actually attempt a serious authentication using
7669                  * the key.
7670                  */
7671                 if (flags & FLAG_VERBOSE) {
7672                     c_write_str(ssh, "Authenticating with public key \"");
7673                     c_write_str(ssh, s->publickey_comment);
7674                     c_write_str(ssh, "\"\r\n");
7675                 }
7676                 key = NULL;
7677                 while (!key) {
7678                     const char *error;  /* not live over crReturn */
7679                     if (s->publickey_encrypted) {
7680                         /*
7681                          * Get a passphrase from the user.
7682                          */
7683                         int ret; /* need not be kept over crReturn */
7684                         s->cur_prompt = new_prompts(ssh->frontend);
7685                         s->cur_prompt->to_server = FALSE;
7686                         s->cur_prompt->name = dupstr("SSH key passphrase");
7687                         add_prompt(s->cur_prompt,
7688                                    dupprintf("Passphrase for key \"%.100s\": ",
7689                                              s->publickey_comment),
7690                                    FALSE, SSH_MAX_PASSWORD_LEN);
7691                         ret = get_userpass_input(s->cur_prompt, NULL, 0);
7692                         while (ret < 0) {
7693                             ssh->send_ok = 1;
7694                             crWaitUntilV(!pktin);
7695                             ret = get_userpass_input(s->cur_prompt,
7696                                                      in, inlen);
7697                             ssh->send_ok = 0;
7698                         }
7699                         if (!ret) {
7700                             /* Failed to get a passphrase. Terminate. */
7701                             free_prompts(s->cur_prompt);
7702                             ssh_disconnect(ssh, NULL,
7703                                            "Unable to authenticate",
7704                                            SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7705                                            TRUE);
7706                             crStopV;
7707                         }
7708                         passphrase =
7709                             dupstr(s->cur_prompt->prompts[0]->result);
7710                         free_prompts(s->cur_prompt);
7711                     } else {
7712                         passphrase = NULL; /* no passphrase needed */
7713                     }
7714
7715                     /*
7716                      * Try decrypting the key.
7717                      */
7718                     key = ssh2_load_userkey(&ssh->cfg.keyfile, passphrase,
7719                                             &error);
7720                     if (passphrase) {
7721                         /* burn the evidence */
7722                         memset(passphrase, 0, strlen(passphrase));
7723                         sfree(passphrase);
7724                     }
7725                     if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
7726                         if (passphrase &&
7727                             (key == SSH2_WRONG_PASSPHRASE)) {
7728                             c_write_str(ssh, "Wrong passphrase\r\n");
7729                             key = NULL;
7730                             /* and loop again */
7731                         } else {
7732                             c_write_str(ssh, "Unable to load private key (");
7733                             c_write_str(ssh, error);
7734                             c_write_str(ssh, ")\r\n");
7735                             key = NULL;
7736                             break; /* try something else */
7737                         }
7738                     }
7739                 }
7740
7741                 if (key) {
7742                     unsigned char *pkblob, *sigblob, *sigdata;
7743                     int pkblob_len, sigblob_len, sigdata_len;
7744                     int p;
7745
7746                     /*
7747                      * We have loaded the private key and the server
7748                      * has announced that it's willing to accept it.
7749                      * Hallelujah. Generate a signature and send it.
7750                      */
7751                     s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7752                     ssh2_pkt_addstring(s->pktout, s->username);
7753                     ssh2_pkt_addstring(s->pktout, "ssh-connection");
7754                                                     /* service requested */
7755                     ssh2_pkt_addstring(s->pktout, "publickey");
7756                                                     /* method */
7757                     ssh2_pkt_addbool(s->pktout, TRUE);
7758                                                     /* signature follows */
7759                     ssh2_pkt_addstring(s->pktout, key->alg->name);
7760                     pkblob = key->alg->public_blob(key->data,
7761                                                    &pkblob_len);
7762                     ssh2_pkt_addstring_start(s->pktout);
7763                     ssh2_pkt_addstring_data(s->pktout, (char *)pkblob,
7764                                             pkblob_len);
7765
7766                     /*
7767                      * The data to be signed is:
7768                      *
7769                      *   string  session-id
7770                      *
7771                      * followed by everything so far placed in the
7772                      * outgoing packet.
7773                      */
7774                     sigdata_len = s->pktout->length - 5 + 4 +
7775                         ssh->v2_session_id_len;
7776                     if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7777                         sigdata_len -= 4;
7778                     sigdata = snewn(sigdata_len, unsigned char);
7779                     p = 0;
7780                     if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7781                         PUT_32BIT(sigdata+p, ssh->v2_session_id_len);
7782                         p += 4;
7783                     }
7784                     memcpy(sigdata+p, ssh->v2_session_id,
7785                            ssh->v2_session_id_len);
7786                     p += ssh->v2_session_id_len;
7787                     memcpy(sigdata+p, s->pktout->data + 5,
7788                            s->pktout->length - 5);
7789                     p += s->pktout->length - 5;
7790                     assert(p == sigdata_len);
7791                     sigblob = key->alg->sign(key->data, (char *)sigdata,
7792                                              sigdata_len, &sigblob_len);
7793                     ssh2_add_sigblob(ssh, s->pktout, pkblob, pkblob_len,
7794                                      sigblob, sigblob_len);
7795                     sfree(pkblob);
7796                     sfree(sigblob);
7797                     sfree(sigdata);
7798
7799                     ssh2_pkt_send(ssh, s->pktout);
7800                     s->type = AUTH_TYPE_PUBLICKEY;
7801                     key->alg->freekey(key->data);
7802                 }
7803
7804 #ifndef NO_GSSAPI
7805             } else if (s->can_gssapi && !s->tried_gssapi) {
7806
7807                 /* GSSAPI Authentication */
7808
7809                 int micoffset;
7810                 Ssh_gss_buf mic;
7811                 s->type = AUTH_TYPE_GSSAPI;
7812                 s->tried_gssapi = TRUE;
7813                 s->gotit = TRUE;
7814                 ssh->pkt_actx = SSH2_PKTCTX_GSSAPI;
7815
7816                 /* Sending USERAUTH_REQUEST with "gssapi-with-mic" method */
7817                 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7818                 ssh2_pkt_addstring(s->pktout, s->username);
7819                 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7820                 ssh2_pkt_addstring(s->pktout, "gssapi-with-mic");
7821
7822                 /* add mechanism info */
7823                 ssh_gss_indicate_mech(&s->gss_buf);
7824
7825                 /* number of GSSAPI mechanisms */
7826                 ssh2_pkt_adduint32(s->pktout,1);
7827
7828                 /* length of OID + 2 */
7829                 ssh2_pkt_adduint32(s->pktout, s->gss_buf.len + 2);
7830                 ssh2_pkt_addbyte(s->pktout, SSH2_GSS_OIDTYPE);
7831
7832                 /* length of OID */
7833                 ssh2_pkt_addbyte(s->pktout, (unsigned char) s->gss_buf.len);
7834
7835                 ssh_pkt_adddata(s->pktout, s->gss_buf.data, s->gss_buf.len);
7836                 ssh2_pkt_send(ssh, s->pktout);
7837                 crWaitUntilV(pktin);
7838                 if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_RESPONSE) {
7839                     logevent("GSSAPI authentication request refused");
7840                     continue;
7841                 }
7842
7843                 /* check returned packet ... */
7844
7845                 ssh_pkt_getstring(pktin,&s->gss_rcvtok.data,&s->gss_rcvtok.len);
7846                 if (s->gss_rcvtok.len != s->gss_buf.len + 2 ||
7847                     s->gss_rcvtok.data[0] != SSH2_GSS_OIDTYPE ||
7848                     s->gss_rcvtok.data[1] != s->gss_buf.len ||
7849                     memcmp(s->gss_rcvtok.data+2,s->gss_buf.data,s->gss_buf.len) ) {
7850                     logevent("GSSAPI authentication - wrong response from server");
7851                     continue;
7852                 }
7853
7854                 /* now start running */
7855                 s->gss_stat = ssh_gss_import_name(ssh->fullhostname,
7856                                                   &s->gss_srv_name);
7857                 if (s->gss_stat != SSH_GSS_OK) {
7858                     if (s->gss_stat == SSH_GSS_BAD_HOST_NAME)
7859                         logevent("GSSAPI import name failed - Bad service name");
7860                     else
7861                         logevent("GSSAPI import name failed");
7862                     continue;
7863                 }
7864
7865                 /* fetch TGT into GSS engine */
7866                 s->gss_stat = ssh_gss_acquire_cred(&s->gss_ctx);
7867
7868                 if (s->gss_stat != SSH_GSS_OK) {
7869                     logevent("GSSAPI authentication failed to get credentials");
7870                     ssh_gss_release_name(&s->gss_srv_name);
7871                     continue;
7872                 }
7873
7874                 /* initial tokens are empty */
7875                 s->gss_rcvtok.len = s->gss_sndtok.len = 0;
7876                 s->gss_rcvtok.data = s->gss_sndtok.data = NULL;
7877
7878                 /* now enter the loop */
7879                 do {
7880                     s->gss_stat = ssh_gss_init_sec_context(&s->gss_ctx,
7881                                                            s->gss_srv_name,
7882                                                            ssh->cfg.gssapifwd,
7883                                                            &s->gss_rcvtok,
7884                                                            &s->gss_sndtok);
7885
7886                     if (s->gss_stat!=SSH_GSS_S_COMPLETE &&
7887                         s->gss_stat!=SSH_GSS_S_CONTINUE_NEEDED) {
7888                         logevent("GSSAPI authentication initialisation failed");
7889
7890                         if (ssh_gss_display_status(s->gss_ctx,&s->gss_buf) == SSH_GSS_OK) {
7891                             logevent(s->gss_buf.data);
7892                             sfree(s->gss_buf.data);
7893                         }
7894
7895                         break;
7896                     }
7897                     logevent("GSSAPI authentication initialised");
7898
7899                     /* Client and server now exchange tokens until GSSAPI
7900                      * no longer says CONTINUE_NEEDED */
7901
7902                     if (s->gss_sndtok.len != 0) {
7903                         s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
7904                         ssh_pkt_addstring_start(s->pktout);
7905                         ssh_pkt_addstring_data(s->pktout,s->gss_sndtok.data,s->gss_sndtok.len);
7906                         ssh2_pkt_send(ssh, s->pktout);
7907                         ssh_gss_free_tok(&s->gss_sndtok);
7908                     }
7909
7910                     if (s->gss_stat == SSH_GSS_S_CONTINUE_NEEDED) {
7911                         crWaitUntilV(pktin);
7912                         if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_TOKEN) {
7913                             logevent("GSSAPI authentication - bad server response");
7914                             s->gss_stat = SSH_GSS_FAILURE;
7915                             break;
7916                         }
7917                         ssh_pkt_getstring(pktin,&s->gss_rcvtok.data,&s->gss_rcvtok.len);
7918                     }
7919                 } while (s-> gss_stat == SSH_GSS_S_CONTINUE_NEEDED);
7920
7921                 if (s->gss_stat != SSH_GSS_OK) {
7922                     ssh_gss_release_name(&s->gss_srv_name);
7923                     ssh_gss_release_cred(&s->gss_ctx);
7924                     continue;
7925                 }
7926                 logevent("GSSAPI authentication loop finished OK");
7927
7928                 /* Now send the MIC */
7929
7930                 s->pktout = ssh2_pkt_init(0);
7931                 micoffset = s->pktout->length;
7932                 ssh_pkt_addstring_start(s->pktout);
7933                 ssh_pkt_addstring_data(s->pktout, (char *)ssh->v2_session_id, ssh->v2_session_id_len);
7934                 ssh_pkt_addbyte(s->pktout, SSH2_MSG_USERAUTH_REQUEST);
7935                 ssh_pkt_addstring(s->pktout, s->username);
7936                 ssh_pkt_addstring(s->pktout, "ssh-connection");
7937                 ssh_pkt_addstring(s->pktout, "gssapi-with-mic");
7938
7939                 s->gss_buf.data = (char *)s->pktout->data + micoffset;
7940                 s->gss_buf.len = s->pktout->length - micoffset;
7941
7942                 ssh_gss_get_mic(s->gss_ctx, &s->gss_buf, &mic);
7943                 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_GSSAPI_MIC);
7944                 ssh_pkt_addstring_start(s->pktout);
7945                 ssh_pkt_addstring_data(s->pktout, mic.data, mic.len);
7946                 ssh2_pkt_send(ssh, s->pktout);
7947                 ssh_gss_free_mic(&mic);
7948
7949                 s->gotit = FALSE;
7950
7951                 ssh_gss_release_name(&s->gss_srv_name);
7952                 ssh_gss_release_cred(&s->gss_ctx);
7953                 continue;
7954 #endif
7955             } else if (s->can_keyb_inter && !s->kbd_inter_refused) {
7956
7957                 /*
7958                  * Keyboard-interactive authentication.
7959                  */
7960
7961                 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
7962
7963                 ssh->pkt_actx = SSH2_PKTCTX_KBDINTER;
7964
7965                 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7966                 ssh2_pkt_addstring(s->pktout, s->username);
7967                 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7968                                                         /* service requested */
7969                 ssh2_pkt_addstring(s->pktout, "keyboard-interactive");
7970                                                         /* method */
7971                 ssh2_pkt_addstring(s->pktout, "");      /* lang */
7972                 ssh2_pkt_addstring(s->pktout, "");      /* submethods */
7973                 ssh2_pkt_send(ssh, s->pktout);
7974
7975                 crWaitUntilV(pktin);
7976                 if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
7977                     /* Server is not willing to do keyboard-interactive
7978                      * at all (or, bizarrely but legally, accepts the
7979                      * user without actually issuing any prompts).
7980                      * Give up on it entirely. */
7981                     s->gotit = TRUE;
7982                     if (pktin->type == SSH2_MSG_USERAUTH_FAILURE)
7983                         logevent("Keyboard-interactive authentication refused");
7984                     s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
7985                     s->kbd_inter_refused = TRUE; /* don't try it again */
7986                     continue;
7987                 }
7988
7989                 /*
7990                  * Loop while the server continues to send INFO_REQUESTs.
7991                  */
7992                 while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
7993
7994                     char *name, *inst, *lang;
7995                     int name_len, inst_len, lang_len;
7996                     int i;
7997
7998                     /*
7999                      * We've got a fresh USERAUTH_INFO_REQUEST.
8000                      * Get the preamble and start building a prompt.
8001                      */
8002                     ssh_pkt_getstring(pktin, &name, &name_len);
8003                     ssh_pkt_getstring(pktin, &inst, &inst_len);
8004                     ssh_pkt_getstring(pktin, &lang, &lang_len);
8005                     s->cur_prompt = new_prompts(ssh->frontend);
8006                     s->cur_prompt->to_server = TRUE;
8007                     if (name_len) {
8008                         /* FIXME: better prefix to distinguish from
8009                          * local prompts? */
8010                         s->cur_prompt->name =
8011                             dupprintf("SSH server: %.*s", name_len, name);
8012                         s->cur_prompt->name_reqd = TRUE;
8013                     } else {
8014                         s->cur_prompt->name =
8015                             dupstr("SSH server authentication");
8016                         s->cur_prompt->name_reqd = FALSE;
8017                     }
8018                     /* FIXME: ugly to print "Using..." in prompt _every_
8019                      * time round. Can this be done more subtly? */
8020                     s->cur_prompt->instruction =
8021                         dupprintf("Using keyboard-interactive authentication.%s%.*s",
8022                                   inst_len ? "\n" : "", inst_len, inst);
8023                     s->cur_prompt->instr_reqd = TRUE;
8024
8025                     /*
8026                      * Get any prompt(s) from the packet.
8027                      */
8028                     s->num_prompts = ssh_pkt_getuint32(pktin);
8029                     for (i = 0; i < s->num_prompts; i++) {
8030                         char *prompt;
8031                         int prompt_len;
8032                         int echo;
8033                         static char noprompt[] =
8034                             "<server failed to send prompt>: ";
8035
8036                         ssh_pkt_getstring(pktin, &prompt, &prompt_len);
8037                         echo = ssh2_pkt_getbool(pktin);
8038                         if (!prompt_len) {
8039                             prompt = noprompt;
8040                             prompt_len = lenof(noprompt)-1;
8041                         }
8042                         add_prompt(s->cur_prompt,
8043                                    dupprintf("%.*s", prompt_len, prompt),
8044                                    echo, SSH_MAX_PASSWORD_LEN);
8045                     }
8046
8047                     /*
8048                      * Display any instructions, and get the user's
8049                      * response(s).
8050                      */
8051                     {
8052                         int ret; /* not live over crReturn */
8053                         ret = get_userpass_input(s->cur_prompt, NULL, 0);
8054                         while (ret < 0) {
8055                             ssh->send_ok = 1;
8056                             crWaitUntilV(!pktin);
8057                             ret = get_userpass_input(s->cur_prompt, in, inlen);
8058                             ssh->send_ok = 0;
8059                         }
8060                         if (!ret) {
8061                             /*
8062                              * Failed to get responses. Terminate.
8063                              */
8064                             free_prompts(s->cur_prompt);
8065                             ssh_disconnect(ssh, NULL, "Unable to authenticate",
8066                                            SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
8067                                            TRUE);
8068                             crStopV;
8069                         }
8070                     }
8071
8072                     /*
8073                      * Send the response(s) to the server.
8074                      */
8075                     s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_INFO_RESPONSE);
8076                     ssh2_pkt_adduint32(s->pktout, s->num_prompts);
8077                     for (i=0; i < s->num_prompts; i++) {
8078                         dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
8079                         ssh2_pkt_addstring(s->pktout,
8080                                            s->cur_prompt->prompts[i]->result);
8081                         end_log_omission(ssh, s->pktout);
8082                     }
8083                     ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
8084
8085                     /*
8086                      * Get the next packet in case it's another
8087                      * INFO_REQUEST.
8088                      */
8089                     crWaitUntilV(pktin);
8090
8091                 }
8092
8093                 /*
8094                  * We should have SUCCESS or FAILURE now.
8095                  */
8096                 s->gotit = TRUE;
8097
8098             } else if (s->can_passwd) {
8099
8100                 /*
8101                  * Plain old password authentication.
8102                  */
8103                 int ret; /* not live over crReturn */
8104                 int changereq_first_time; /* not live over crReturn */
8105
8106                 ssh->pkt_actx = SSH2_PKTCTX_PASSWORD;
8107
8108                 s->cur_prompt = new_prompts(ssh->frontend);
8109                 s->cur_prompt->to_server = TRUE;
8110                 s->cur_prompt->name = dupstr("SSH password");
8111                 add_prompt(s->cur_prompt, dupprintf("%.90s@%.90s's password: ",
8112                                                     s->username,
8113                                                     ssh->savedhost),
8114                            FALSE, SSH_MAX_PASSWORD_LEN);
8115
8116                 ret = get_userpass_input(s->cur_prompt, NULL, 0);
8117                 while (ret < 0) {
8118                     ssh->send_ok = 1;
8119                     crWaitUntilV(!pktin);
8120                     ret = get_userpass_input(s->cur_prompt, in, inlen);
8121                     ssh->send_ok = 0;
8122                 }
8123                 if (!ret) {
8124                     /*
8125                      * Failed to get responses. Terminate.
8126                      */
8127                     free_prompts(s->cur_prompt);
8128                     ssh_disconnect(ssh, NULL, "Unable to authenticate",
8129                                    SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
8130                                    TRUE);
8131                     crStopV;
8132                 }
8133                 /*
8134                  * Squirrel away the password. (We may need it later if
8135                  * asked to change it.)
8136                  */
8137                 s->password = dupstr(s->cur_prompt->prompts[0]->result);
8138                 free_prompts(s->cur_prompt);
8139
8140                 /*
8141                  * Send the password packet.
8142                  *
8143                  * We pad out the password packet to 256 bytes to make
8144                  * it harder for an attacker to find the length of the
8145                  * user's password.
8146                  *
8147                  * Anyone using a password longer than 256 bytes
8148                  * probably doesn't have much to worry about from
8149                  * people who find out how long their password is!
8150                  */
8151                 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
8152                 ssh2_pkt_addstring(s->pktout, s->username);
8153                 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8154                                                         /* service requested */
8155                 ssh2_pkt_addstring(s->pktout, "password");
8156                 ssh2_pkt_addbool(s->pktout, FALSE);
8157                 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
8158                 ssh2_pkt_addstring(s->pktout, s->password);
8159                 end_log_omission(ssh, s->pktout);
8160                 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
8161                 logevent("Sent password");
8162                 s->type = AUTH_TYPE_PASSWORD;
8163
8164                 /*
8165                  * Wait for next packet, in case it's a password change
8166                  * request.
8167                  */
8168                 crWaitUntilV(pktin);
8169                 changereq_first_time = TRUE;
8170
8171                 while (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
8172
8173                     /* 
8174                      * We're being asked for a new password
8175                      * (perhaps not for the first time).
8176                      * Loop until the server accepts it.
8177                      */
8178
8179                     int got_new = FALSE; /* not live over crReturn */
8180                     char *prompt;   /* not live over crReturn */
8181                     int prompt_len; /* not live over crReturn */
8182                     
8183                     {
8184                         char *msg;
8185                         if (changereq_first_time)
8186                             msg = "Server requested password change";
8187                         else
8188                             msg = "Server rejected new password";
8189                         logevent(msg);
8190                         c_write_str(ssh, msg);
8191                         c_write_str(ssh, "\r\n");
8192                     }
8193
8194                     ssh_pkt_getstring(pktin, &prompt, &prompt_len);
8195
8196                     s->cur_prompt = new_prompts(ssh->frontend);
8197                     s->cur_prompt->to_server = TRUE;
8198                     s->cur_prompt->name = dupstr("New SSH password");
8199                     s->cur_prompt->instruction =
8200                         dupprintf("%.*s", prompt_len, prompt);
8201                     s->cur_prompt->instr_reqd = TRUE;
8202                     /*
8203                      * There's no explicit requirement in the protocol
8204                      * for the "old" passwords in the original and
8205                      * password-change messages to be the same, and
8206                      * apparently some Cisco kit supports password change
8207                      * by the user entering a blank password originally
8208                      * and the real password subsequently, so,
8209                      * reluctantly, we prompt for the old password again.
8210                      *
8211                      * (On the other hand, some servers don't even bother
8212                      * to check this field.)
8213                      */
8214                     add_prompt(s->cur_prompt,
8215                                dupstr("Current password (blank for previously entered password): "),
8216                                FALSE, SSH_MAX_PASSWORD_LEN);
8217                     add_prompt(s->cur_prompt, dupstr("Enter new password: "),
8218                                FALSE, SSH_MAX_PASSWORD_LEN);
8219                     add_prompt(s->cur_prompt, dupstr("Confirm new password: "),
8220                                FALSE, SSH_MAX_PASSWORD_LEN);
8221
8222                     /*
8223                      * Loop until the user manages to enter the same
8224                      * password twice.
8225                      */
8226                     while (!got_new) {
8227
8228                         ret = get_userpass_input(s->cur_prompt, NULL, 0);
8229                         while (ret < 0) {
8230                             ssh->send_ok = 1;
8231                             crWaitUntilV(!pktin);
8232                             ret = get_userpass_input(s->cur_prompt, in, inlen);
8233                             ssh->send_ok = 0;
8234                         }
8235                         if (!ret) {
8236                             /*
8237                              * Failed to get responses. Terminate.
8238                              */
8239                             /* burn the evidence */
8240                             free_prompts(s->cur_prompt);
8241                             memset(s->password, 0, strlen(s->password));
8242                             sfree(s->password);
8243                             ssh_disconnect(ssh, NULL, "Unable to authenticate",
8244                                            SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
8245                                            TRUE);
8246                             crStopV;
8247                         }
8248
8249                         /*
8250                          * If the user specified a new original password
8251                          * (IYSWIM), overwrite any previously specified
8252                          * one.
8253                          * (A side effect is that the user doesn't have to
8254                          * re-enter it if they louse up the new password.)
8255                          */
8256                         if (s->cur_prompt->prompts[0]->result[0]) {
8257                             memset(s->password, 0, strlen(s->password));
8258                                 /* burn the evidence */
8259                             sfree(s->password);
8260                             s->password =
8261                                 dupstr(s->cur_prompt->prompts[0]->result);
8262                         }
8263
8264                         /*
8265                          * Check the two new passwords match.
8266                          */
8267                         got_new = (strcmp(s->cur_prompt->prompts[1]->result,
8268                                           s->cur_prompt->prompts[2]->result)
8269                                    == 0);
8270                         if (!got_new)
8271                             /* They don't. Silly user. */
8272                             c_write_str(ssh, "Passwords do not match\r\n");
8273
8274                     }
8275
8276                     /*
8277                      * Send the new password (along with the old one).
8278                      * (see above for padding rationale)
8279                      */
8280                     s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
8281                     ssh2_pkt_addstring(s->pktout, s->username);
8282                     ssh2_pkt_addstring(s->pktout, "ssh-connection");
8283                                                         /* service requested */
8284                     ssh2_pkt_addstring(s->pktout, "password");
8285                     ssh2_pkt_addbool(s->pktout, TRUE);
8286                     dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
8287                     ssh2_pkt_addstring(s->pktout, s->password);
8288                     ssh2_pkt_addstring(s->pktout,
8289                                        s->cur_prompt->prompts[1]->result);
8290                     free_prompts(s->cur_prompt);
8291                     end_log_omission(ssh, s->pktout);
8292                     ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
8293                     logevent("Sent new password");
8294                     
8295                     /*
8296                      * Now see what the server has to say about it.
8297                      * (If it's CHANGEREQ again, it's not happy with the
8298                      * new password.)
8299                      */
8300                     crWaitUntilV(pktin);
8301                     changereq_first_time = FALSE;
8302
8303                 }
8304
8305                 /*
8306                  * We need to reexamine the current pktin at the top
8307                  * of the loop. Either:
8308                  *  - we weren't asked to change password at all, in
8309                  *    which case it's a SUCCESS or FAILURE with the
8310                  *    usual meaning
8311                  *  - we sent a new password, and the server was
8312                  *    either OK with it (SUCCESS or FAILURE w/partial
8313                  *    success) or unhappy with the _old_ password
8314                  *    (FAILURE w/o partial success)
8315                  * In any of these cases, we go back to the top of
8316                  * the loop and start again.
8317                  */
8318                 s->gotit = TRUE;
8319
8320                 /*
8321                  * We don't need the old password any more, in any
8322                  * case. Burn the evidence.
8323                  */
8324                 memset(s->password, 0, strlen(s->password));
8325                 sfree(s->password);
8326
8327             } else {
8328
8329                 ssh_disconnect(ssh, NULL,
8330                                "No supported authentication methods available",
8331                                SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
8332                                FALSE);
8333                 crStopV;
8334
8335             }
8336
8337         }
8338     }
8339     ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
8340
8341     /* Clear up various bits and pieces from authentication. */
8342     if (s->publickey_blob) {
8343         sfree(s->publickey_blob);
8344         sfree(s->publickey_comment);
8345     }
8346     if (s->agent_response)
8347         sfree(s->agent_response);
8348
8349     /*
8350      * Now the connection protocol has started, one way or another.
8351      */
8352
8353     ssh->channels = newtree234(ssh_channelcmp);
8354
8355     /*
8356      * Set up handlers for some connection protocol messages, so we
8357      * don't have to handle them repeatedly in this coroutine.
8358      */
8359     ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] =
8360         ssh2_msg_channel_window_adjust;
8361     ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] =
8362         ssh2_msg_global_request;
8363
8364     /*
8365      * Create the main session channel.
8366      */
8367     if (ssh->cfg.ssh_no_shell) {
8368         ssh->mainchan = NULL;
8369     } else if (*ssh->cfg.ssh_nc_host) {
8370         /*
8371          * Just start a direct-tcpip channel and use it as the main
8372          * channel.
8373          */
8374         ssh->mainchan = snew(struct ssh_channel);
8375         ssh->mainchan->ssh = ssh;
8376         ssh2_channel_init(ssh->mainchan);
8377         logeventf(ssh,
8378                   "Opening direct-tcpip channel to %s:%d in place of session",
8379                   ssh->cfg.ssh_nc_host, ssh->cfg.ssh_nc_port);
8380         s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
8381         ssh2_pkt_addstring(s->pktout, "direct-tcpip");
8382         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
8383         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
8384         ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT);      /* our max pkt size */
8385         ssh2_pkt_addstring(s->pktout, ssh->cfg.ssh_nc_host);
8386         ssh2_pkt_adduint32(s->pktout, ssh->cfg.ssh_nc_port);
8387         /*
8388          * There's nothing meaningful to put in the originator
8389          * fields, but some servers insist on syntactically correct
8390          * information.
8391          */
8392         ssh2_pkt_addstring(s->pktout, "0.0.0.0");
8393         ssh2_pkt_adduint32(s->pktout, 0);
8394         ssh2_pkt_send(ssh, s->pktout);
8395
8396         crWaitUntilV(pktin);
8397         if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
8398             bombout(("Server refused to open a direct-tcpip channel"));
8399             crStopV;
8400             /* FIXME: error data comes back in FAILURE packet */
8401         }
8402         if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
8403             bombout(("Server's channel confirmation cited wrong channel"));
8404             crStopV;
8405         }
8406         ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
8407         ssh->mainchan->halfopen = FALSE;
8408         ssh->mainchan->type = CHAN_MAINSESSION;
8409         ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
8410         ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
8411         add234(ssh->channels, ssh->mainchan);
8412         update_specials_menu(ssh->frontend);
8413         logevent("Opened direct-tcpip channel");
8414         ssh->ncmode = TRUE;
8415     } else {
8416         ssh->mainchan = snew(struct ssh_channel);
8417         ssh->mainchan->ssh = ssh;
8418         ssh2_channel_init(ssh->mainchan);
8419         s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
8420         ssh2_pkt_addstring(s->pktout, "session");
8421         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
8422         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
8423         ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT);    /* our max pkt size */
8424         ssh2_pkt_send(ssh, s->pktout);
8425         crWaitUntilV(pktin);
8426         if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
8427             bombout(("Server refused to open a session"));
8428             crStopV;
8429             /* FIXME: error data comes back in FAILURE packet */
8430         }
8431         if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
8432             bombout(("Server's channel confirmation cited wrong channel"));
8433             crStopV;
8434         }
8435         ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
8436         ssh->mainchan->halfopen = FALSE;
8437         ssh->mainchan->type = CHAN_MAINSESSION;
8438         ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
8439         ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
8440         add234(ssh->channels, ssh->mainchan);
8441         update_specials_menu(ssh->frontend);
8442         logevent("Opened channel for session");
8443         ssh->ncmode = FALSE;
8444     }
8445
8446     /*
8447      * Now we have a channel, make dispatch table entries for
8448      * general channel-based messages.
8449      */
8450     ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] =
8451     ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] =
8452         ssh2_msg_channel_data;
8453     ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_channel_eof;
8454     ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_channel_close;
8455     ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] =
8456         ssh2_msg_channel_open_confirmation;
8457     ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] =
8458         ssh2_msg_channel_open_failure;
8459     ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] =
8460         ssh2_msg_channel_request;
8461     ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] =
8462         ssh2_msg_channel_open;
8463
8464     if (ssh->cfg.ssh_simple) {
8465         /*
8466          * This message indicates to the server that we promise
8467          * not to try to run any other channel in parallel with
8468          * this one, so it's safe for it to advertise a very large
8469          * window and leave the flow control to TCP.
8470          */
8471         s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8472         ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
8473         ssh2_pkt_addstring(s->pktout, "simple@putty.projects.tartarus.org");
8474         ssh2_pkt_addbool(s->pktout, 0); /* no reply */
8475         ssh2_pkt_send(ssh, s->pktout);
8476     }
8477
8478     /*
8479      * Potentially enable X11 forwarding.
8480      */
8481     if (ssh->mainchan && !ssh->ncmode && ssh->cfg.x11_forward) {
8482         char proto[20], data[64];
8483         logevent("Requesting X11 forwarding");
8484         ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
8485                                        data, sizeof(data), ssh->cfg.x11_auth);
8486         x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
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, proto);
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, data);
8502         end_log_omission(ssh, s->pktout);
8503         ssh2_pkt_adduint32(s->pktout, x11_get_screen_number(ssh->cfg.x11_display));
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->x11auth = 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->x11auth)
9133         x11_free_auth(ssh->x11auth);
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 };