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