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