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