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