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