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