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