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