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