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