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