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