Mention more versions of Windows. (Not Vista, yet.)
[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()");
edd0cb8a 3567 }
3568 }
3569
3570 if (got_passphrase) {
3571
3572 /*
3573 * Send a public key attempt.
3574 */
3575 send_packet(ssh, SSH1_CMSG_AUTH_RSA,
3576 PKT_BIGNUM, s->key.modulus, PKT_END);
3577
3578 crWaitUntil(pktin);
3579 if (pktin->type == SSH1_SMSG_FAILURE) {
3580 c_write_str(ssh, "Server refused our public key.\r\n");
7b575324 3581 continue; /* go and try something else */
edd0cb8a 3582 }
3583 if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
3584 bombout(("Bizarre response to offer of public key"));
3585 crStop(0);
3586 }
3587
3588 {
3589 int i;
3590 unsigned char buffer[32];
3591 Bignum challenge, response;
3592
3593 if ((challenge = ssh1_pkt_getmp(pktin)) == NULL) {
3594 bombout(("Server's RSA challenge was badly formatted"));
3595 crStop(0);
3596 }
3597 response = rsadecrypt(challenge, &s->key);
3598 freebn(s->key.private_exponent);/* burn the evidence */
3599
3600 for (i = 0; i < 32; i++) {
3601 buffer[i] = bignum_byte(response, 31 - i);
3602 }
3603
3604 MD5Init(&md5c);
3605 MD5Update(&md5c, buffer, 32);
3606 MD5Update(&md5c, s->session_id, 16);
3607 MD5Final(buffer, &md5c);
3608
3609 send_packet(ssh, SSH1_CMSG_AUTH_RSA_RESPONSE,
3610 PKT_DATA, buffer, 16, PKT_END);
3611
3612 freebn(challenge);
3613 freebn(response);
3614 }
3615
3616 crWaitUntil(pktin);
3617 if (pktin->type == SSH1_SMSG_FAILURE) {
3618 if (flags & FLAG_VERBOSE)
3619 c_write_str(ssh, "Failed to authenticate with"
3620 " our public key.\r\n");
7b575324 3621 continue; /* go and try something else */
edd0cb8a 3622 } else if (pktin->type != SSH1_SMSG_SUCCESS) {
3623 bombout(("Bizarre response to RSA authentication response"));
3624 crStop(0);
3625 }
3626
3627 break; /* we're through! */
3628 }
3629
3630 }
3631
3632 /*
3633 * Otherwise, try various forms of password-like authentication.
3634 */
3635 s->cur_prompt = new_prompts(ssh->frontend);
32874aea 3636
86916870 3637 if (ssh->cfg.try_tis_auth &&
51470298 3638 (s->supported_auths_mask & (1 << SSH1_AUTH_TIS)) &&
3639 !s->tis_auth_refused) {
3640 s->pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
32874aea 3641 logevent("Requested TIS authentication");
51470298 3642 send_packet(ssh, SSH1_CMSG_AUTH_TIS, PKT_END);
ff3187f6 3643 crWaitUntil(pktin);
3644 if (pktin->type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
32874aea 3645 logevent("TIS authentication declined");
3646 if (flags & FLAG_INTERACTIVE)
51470298 3647 c_write_str(ssh, "TIS authentication refused.\r\n");
3648 s->tis_auth_refused = 1;
614a20a0 3649 continue;
32874aea 3650 } else {
0016d70b 3651 char *challenge;
3652 int challengelen;
edd0cb8a 3653 char *instr_suf, *prompt;
0016d70b 3654
ff3187f6 3655 ssh_pkt_getstring(pktin, &challenge, &challengelen);
0016d70b 3656 if (!challenge) {
3657 bombout(("TIS challenge packet was badly formed"));
3658 crStop(0);
3659 }
32874aea 3660 logevent("Received TIS challenge");
edd0cb8a 3661 s->cur_prompt->to_server = TRUE;
3662 s->cur_prompt->name = dupstr("SSH TIS authentication");
614a20a0 3663 /* Prompt heuristic comes from OpenSSH */
edd0cb8a 3664 if (memchr(challenge, '\n', challengelen)) {
3665 instr_suf = dupstr("");
3666 prompt = dupprintf("%.*s", challengelen, challenge);
3667 } else {
3668 instr_suf = dupprintf("%.*s", challengelen, challenge);
3669 prompt = dupstr("Response: ");
3670 }
3671 s->cur_prompt->instruction =
3672 dupprintf("Using TIS authentication.%s%s",
3673 (*instr_suf) ? "\n" : "",
3674 instr_suf);
3675 s->cur_prompt->instr_reqd = TRUE;
3676 add_prompt(s->cur_prompt, prompt, FALSE, SSH_MAX_PASSWORD_LEN);
3677 sfree(instr_suf);
32874aea 3678 }
3679 }
86916870 3680 if (ssh->cfg.try_tis_auth &&
51470298 3681 (s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
3682 !s->ccard_auth_refused) {
3683 s->pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
32874aea 3684 logevent("Requested CryptoCard authentication");
51470298 3685 send_packet(ssh, SSH1_CMSG_AUTH_CCARD, PKT_END);
ff3187f6 3686 crWaitUntil(pktin);
3687 if (pktin->type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
32874aea 3688 logevent("CryptoCard authentication declined");
51470298 3689 c_write_str(ssh, "CryptoCard authentication refused.\r\n");
3690 s->ccard_auth_refused = 1;
614a20a0 3691 continue;
32874aea 3692 } else {
0016d70b 3693 char *challenge;
3694 int challengelen;
edd0cb8a 3695 char *instr_suf, *prompt;
0016d70b 3696
ff3187f6 3697 ssh_pkt_getstring(pktin, &challenge, &challengelen);
0016d70b 3698 if (!challenge) {
3699 bombout(("CryptoCard challenge packet was badly formed"));
3700 crStop(0);
3701 }
32874aea 3702 logevent("Received CryptoCard challenge");
edd0cb8a 3703 s->cur_prompt->to_server = TRUE;
3704 s->cur_prompt->name = dupstr("SSH CryptoCard authentication");
3705 s->cur_prompt->name_reqd = FALSE;
3706 /* Prompt heuristic comes from OpenSSH */
3707 if (memchr(challenge, '\n', challengelen)) {
3708 instr_suf = dupstr("");
3709 prompt = dupprintf("%.*s", challengelen, challenge);
3710 } else {
3711 instr_suf = dupprintf("%.*s", challengelen, challenge);
3712 prompt = dupstr("Response: ");
3713 }
3714 s->cur_prompt->instruction =
3715 dupprintf("Using CryptoCard authentication.%s%s",
3716 (*instr_suf) ? "\n" : "",
3717 instr_suf);
3718 s->cur_prompt->instr_reqd = TRUE;
3719 add_prompt(s->cur_prompt, prompt, FALSE, SSH_MAX_PASSWORD_LEN);
3720 sfree(instr_suf);
32874aea 3721 }
3722 }
51470298 3723 if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
edd0cb8a 3724 s->cur_prompt->to_server = TRUE;
3725 s->cur_prompt->name = dupstr("SSH password");
3726 add_prompt(s->cur_prompt, dupprintf("%.90s@%.90s's password: ",
3727 s->username, ssh->savedhost),
3728 FALSE, SSH_MAX_PASSWORD_LEN);
32874aea 3729 }
a52f067e 3730
614a20a0 3731 /*
3732 * Show password prompt, having first obtained it via a TIS
3733 * or CryptoCard exchange if we're doing TIS or CryptoCard
3734 * authentication.
3735 */
edd0cb8a 3736 {
3737 int ret; /* need not be kept over crReturn */
3738 ret = get_userpass_input(s->cur_prompt, NULL, 0);
3739 while (ret < 0) {
3740 ssh->send_ok = 1;
3741 crWaitUntil(!pktin);
3742 ret = get_userpass_input(s->cur_prompt, in, inlen);
3743 ssh->send_ok = 0;
3744 }
3745 if (!ret) {
32874aea 3746 /*
edd0cb8a 3747 * Failed to get a password (for example
32874aea 3748 * because one was supplied on the command line
3749 * which has already failed to work). Terminate.
3750 */
edd0cb8a 3751 free_prompts(s->cur_prompt);
3752 ssh_disconnect(ssh, NULL, "Unable to authenticate", 0, TRUE);
3753 crStop(0);
32874aea 3754 }
32874aea 3755 }
3756
edd0cb8a 3757 if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
32874aea 3758 /*
edd0cb8a 3759 * Defence against traffic analysis: we send a
3760 * whole bunch of packets containing strings of
3761 * different lengths. One of these strings is the
3762 * password, in a SSH1_CMSG_AUTH_PASSWORD packet.
3763 * The others are all random data in
3764 * SSH1_MSG_IGNORE packets. This way a passive
3765 * listener can't tell which is the password, and
3766 * hence can't deduce the password length.
3767 *
3768 * Anybody with a password length greater than 16
3769 * bytes is going to have enough entropy in their
3770 * password that a listener won't find it _that_
3771 * much help to know how long it is. So what we'll
3772 * do is:
3773 *
3774 * - if password length < 16, we send 15 packets
3775 * containing string lengths 1 through 15
3776 *
3777 * - otherwise, we let N be the nearest multiple
3778 * of 8 below the password length, and send 8
3779 * packets containing string lengths N through
3780 * N+7. This won't obscure the order of
3781 * magnitude of the password length, but it will
3782 * introduce a bit of extra uncertainty.
3783 *
bf982899 3784 * A few servers can't deal with SSH1_MSG_IGNORE, at
3785 * least in this context. For these servers, we need
3786 * an alternative defence. We make use of the fact
3787 * that the password is interpreted as a C string:
3788 * so we can append a NUL, then some random data.
edd0cb8a 3789 *
bf982899 3790 * A few servers can deal with neither SSH1_MSG_IGNORE
3791 * here _nor_ a padded password string.
3792 * For these servers we are left with no defences
edd0cb8a 3793 * against password length sniffing.
32874aea 3794 */
bf982899 3795 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE) &&
3796 !(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
32874aea 3797 /*
edd0cb8a 3798 * The server can deal with SSH1_MSG_IGNORE, so
3799 * we can use the primary defence.
32874aea 3800 */
edd0cb8a 3801 int bottom, top, pwlen, i;
3802 char *randomstr;
32874aea 3803
edd0cb8a 3804 pwlen = strlen(s->cur_prompt->prompts[0]->result);
3805 if (pwlen < 16) {
3806 bottom = 0; /* zero length passwords are OK! :-) */
3807 top = 15;
3808 } else {
3809 bottom = pwlen & ~7;
3810 top = bottom + 7;
3811 }
32874aea 3812
edd0cb8a 3813 assert(pwlen >= bottom && pwlen <= top);
32874aea 3814
edd0cb8a 3815 randomstr = snewn(top + 1, char);
32874aea 3816
edd0cb8a 3817 for (i = bottom; i <= top; i++) {
3818 if (i == pwlen) {
3819 defer_packet(ssh, s->pwpkt_type,
3820 PKTT_PASSWORD, PKT_STR,
3821 s->cur_prompt->prompts[0]->result,
3822 PKTT_OTHER, PKT_END);
3823 } else {
3824 for (j = 0; j < i; j++) {
3825 do {
3826 randomstr[j] = random_byte();
3827 } while (randomstr[j] == '\0');
32874aea 3828 }
edd0cb8a 3829 randomstr[i] = '\0';
3830 defer_packet(ssh, SSH1_MSG_IGNORE,
3831 PKT_STR, randomstr, PKT_END);
32874aea 3832 }
edd0cb8a 3833 }
3834 logevent("Sending password with camouflage packets");
3835 ssh_pkt_defersend(ssh);
3836 sfree(randomstr);
3837 }
3838 else if (!(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
3839 /*
3840 * The server can't deal with SSH1_MSG_IGNORE
3841 * but can deal with padded passwords, so we
3842 * can use the secondary defence.
3843 */
3844 char string[64];
3845 char *ss;
3846 int len;
3847
3848 len = strlen(s->cur_prompt->prompts[0]->result);
3849 if (len < sizeof(string)) {
3850 ss = string;
3851 strcpy(string, s->cur_prompt->prompts[0]->result);
3852 len++; /* cover the zero byte */
3853 while (len < sizeof(string)) {
3854 string[len++] = (char) random_byte();
bd358db1 3855 }
bd358db1 3856 } else {
edd0cb8a 3857 ss = s->cur_prompt->prompts[0]->result;
32874aea 3858 }
edd0cb8a 3859 logevent("Sending length-padded password");
9a10ecf4 3860 send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
edd0cb8a 3861 PKT_INT, len, PKT_DATA, ss, len,
3862 PKTT_OTHER, PKT_END);
3863 } else {
3864 /*
bf982899 3865 * The server is believed unable to cope with
3866 * any of our password camouflage methods.
edd0cb8a 3867 */
3868 int len;
3869 len = strlen(s->cur_prompt->prompts[0]->result);
3870 logevent("Sending unpadded password");
3871 send_packet(ssh, s->pwpkt_type,
3872 PKTT_PASSWORD, PKT_INT, len,
3873 PKT_DATA, s->cur_prompt->prompts[0]->result, len,
3874 PKTT_OTHER, PKT_END);
32874aea 3875 }
edd0cb8a 3876 } else {
3877 send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
3878 PKT_STR, s->cur_prompt->prompts[0]->result,
3879 PKTT_OTHER, PKT_END);
32874aea 3880 }
c5e9c988 3881 logevent("Sent password");
edd0cb8a 3882 free_prompts(s->cur_prompt);
ff3187f6 3883 crWaitUntil(pktin);
3884 if (pktin->type == SSH1_SMSG_FAILURE) {
32874aea 3885 if (flags & FLAG_VERBOSE)
51470298 3886 c_write_str(ssh, "Access denied\r\n");
c5e9c988 3887 logevent("Authentication refused");
ff3187f6 3888 } else if (pktin->type != SSH1_SMSG_SUCCESS) {
3889 bombout(("Strange packet received, type %d", pktin->type));
7ffdbc1a 3890 crStop(0);
374330e2 3891 }
3892 }
3893
edd0cb8a 3894 /* Clear up */
3895 if (s->publickey_blob) {
3896 sfree(s->publickey_blob);
3897 sfree(s->publickey_comment);
3898 }
3899
c5e9c988 3900 logevent("Authentication successful");
3901
fb09bf1c 3902 crFinish(1);
3903}
3904
32874aea 3905void sshfwd_close(struct ssh_channel *c)
3906{
51470298 3907 Ssh ssh = c->ssh;
3908
1ef619ae 3909 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 3910 return;
36f94d1f 3911
80e48603 3912 if (c && !c->closes) {
4ed34d25 3913 /*
64d6ff88 3914 * If halfopen is true, we have sent
4ed34d25 3915 * CHANNEL_OPEN for this channel, but it hasn't even been
3916 * acknowledged by the server. So we must set a close flag
3917 * on it now, and then when the server acks the channel
3918 * open, we can close it then.
3919 */
64d6ff88 3920 if (!c->halfopen) {
51470298 3921 if (ssh->version == 1) {
3922 send_packet(ssh, SSH1_MSG_CHANNEL_CLOSE, PKT_INT, c->remoteid,
4ed34d25 3923 PKT_END);
3924 } else {
ff3187f6 3925 struct Packet *pktout;
3926 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
3927 ssh2_pkt_adduint32(pktout, c->remoteid);
3928 ssh2_pkt_send(ssh, pktout);
4ed34d25 3929 }
32874aea 3930 }
0357890f 3931 c->closes = 1; /* sent MSG_CLOSE */
32874aea 3932 if (c->type == CHAN_X11) {
3933 c->u.x11.s = NULL;
d74d141c 3934 logevent("Forwarded X11 connection terminated");
4ed34d25 3935 } else if (c->type == CHAN_SOCKDATA ||
3936 c->type == CHAN_SOCKDATA_DORMANT) {
d74d141c 3937 c->u.pfd.s = NULL;
3938 logevent("Forwarded port closed");
32874aea 3939 }
3940 }
3941}
3942
5471d09a 3943int sshfwd_write(struct ssh_channel *c, char *buf, int len)
32874aea 3944{
51470298 3945 Ssh ssh = c->ssh;
3946
1ef619ae 3947 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 3948 return 0;
36f94d1f 3949
51470298 3950 if (ssh->version == 1) {
3951 send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
32874aea 3952 PKT_INT, c->remoteid,
9a10ecf4 3953 PKTT_DATA,
3954 PKT_INT, len, PKT_DATA, buf, len,
3955 PKTT_OTHER, PKT_END);
5471d09a 3956 /*
2e85c969 3957 * In SSH-1 we can return 0 here - implying that forwarded
5471d09a 3958 * connections are never individually throttled - because
3959 * the only circumstance that can cause throttling will be
3960 * the whole SSH connection backing up, in which case
3961 * _everything_ will be throttled as a whole.
3962 */
3963 return 0;
783415f8 3964 } else {
32874aea 3965 ssh2_add_channel_data(c, buf, len);
5471d09a 3966 return ssh2_try_send(c);
3967 }
3968}
3969
3970void sshfwd_unthrottle(struct ssh_channel *c, int bufsize)
3971{
51470298 3972 Ssh ssh = c->ssh;
3973
1ef619ae 3974 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 3975 return;
36f94d1f 3976
51470298 3977 if (ssh->version == 1) {
5471d09a 3978 if (c->v.v1.throttling && bufsize < SSH1_BUFFER_LIMIT) {
3979 c->v.v1.throttling = 0;
51470298 3980 ssh1_throttle(ssh, -1);
5471d09a 3981 }
3982 } else {
3983 ssh2_set_window(c, OUR_V2_WINSIZE - bufsize);
783415f8 3984 }
9c964e85 3985}
3986
06fadff5 3987static void ssh_queueing_handler(Ssh ssh, struct Packet *pktin)
3988{
3989 struct queued_handler *qh = ssh->qhead;
3990
3991 assert(qh != NULL);
3992
3993 assert(pktin->type == qh->msg1 || pktin->type == qh->msg2);
3994
3995 if (qh->msg1 > 0) {
3996 assert(ssh->packet_dispatch[qh->msg1] == ssh_queueing_handler);
3997 ssh->packet_dispatch[qh->msg1] = NULL;
3998 }
3999 if (qh->msg2 > 0) {
4000 assert(ssh->packet_dispatch[qh->msg2] == ssh_queueing_handler);
4001 ssh->packet_dispatch[qh->msg2] = NULL;
4002 }
4003
4004 if (qh->next) {
4005 ssh->qhead = qh->next;
4006
4007 if (ssh->qhead->msg1 > 0) {
4008 assert(ssh->packet_dispatch[ssh->qhead->msg1] == NULL);
4009 ssh->packet_dispatch[ssh->qhead->msg1] = ssh_queueing_handler;
4010 }
4011 if (ssh->qhead->msg2 > 0) {
4012 assert(ssh->packet_dispatch[ssh->qhead->msg2] == NULL);
4013 ssh->packet_dispatch[ssh->qhead->msg2] = ssh_queueing_handler;
4014 }
4015 } else {
4016 ssh->qhead = ssh->qtail = NULL;
4017 ssh->packet_dispatch[pktin->type] = NULL;
4018 }
4019
4020 qh->handler(ssh, pktin, qh->ctx);
4021
4022 sfree(qh);
4023}
4024
4025static void ssh_queue_handler(Ssh ssh, int msg1, int msg2,
4026 chandler_fn_t handler, void *ctx)
4027{
4028 struct queued_handler *qh;
4029
4030 qh = snew(struct queued_handler);
4031 qh->msg1 = msg1;
4032 qh->msg2 = msg2;
4033 qh->handler = handler;
4034 qh->ctx = ctx;
4035 qh->next = NULL;
4036
4037 if (ssh->qtail == NULL) {
4038 ssh->qhead = qh;
4039
4040 if (qh->msg1 > 0) {
4041 assert(ssh->packet_dispatch[qh->msg1] == NULL);
4042 ssh->packet_dispatch[qh->msg1] = ssh_queueing_handler;
4043 }
4044 if (qh->msg2 > 0) {
4045 assert(ssh->packet_dispatch[qh->msg2] == NULL);
4046 ssh->packet_dispatch[qh->msg2] = ssh_queueing_handler;
4047 }
4048 } else {
4049 ssh->qtail->next = qh;
4050 }
4051 ssh->qtail = qh;
4052}
4053
4054static void ssh_rportfwd_succfail(Ssh ssh, struct Packet *pktin, void *ctx)
4055{
4056 struct ssh_rportfwd *rpf, *pf = (struct ssh_rportfwd *)ctx;
4057
4058 if (pktin->type == (ssh->version == 1 ? SSH1_SMSG_SUCCESS :
4059 SSH2_MSG_REQUEST_SUCCESS)) {
4060 logeventf(ssh, "Remote port forwarding from %s enabled",
4061 pf->sportdesc);
4062 } else {
4063 logeventf(ssh, "Remote port forwarding from %s refused",
4064 pf->sportdesc);
4065
4066 rpf = del234(ssh->rportfwds, pf);
4067 assert(rpf == pf);
fda2feb1 4068 free_rportfwd(pf);
06fadff5 4069 }
4070}
4071
4072static void ssh_setup_portfwd(Ssh ssh, const Config *cfg)
4073{
84328ddb 4074 const char *portfwd_strptr = cfg->portfwd;
4075 struct ssh_portfwd *epf;
4076 int i;
06fadff5 4077
fda2feb1 4078 if (!ssh->portfwds) {
4079 ssh->portfwds = newtree234(ssh_portcmp);
4080 } else {
4081 /*
4082 * Go through the existing port forwardings and tag them
84328ddb 4083 * with status==DESTROY. Any that we want to keep will be
4084 * re-enabled (status==KEEP) as we go through the
4085 * configuration and find out which bits are the same as
4086 * they were before.
fda2feb1 4087 */
4088 struct ssh_portfwd *epf;
4089 int i;
4090 for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
84328ddb 4091 epf->status = DESTROY;
fda2feb1 4092 }
4093
06fadff5 4094 while (*portfwd_strptr) {
84328ddb 4095 char address_family, type;
4096 int sport,dport,sserv,dserv;
4097 char sports[256], dports[256], saddr[256], host[256];
4098 int n;
4099
05581745 4100 address_family = 'A';
4101 type = 'L';
84328ddb 4102 if (*portfwd_strptr == 'A' ||
4103 *portfwd_strptr == '4' ||
4104 *portfwd_strptr == '6')
4105 address_family = *portfwd_strptr++;
4106 if (*portfwd_strptr == 'L' ||
4107 *portfwd_strptr == 'R' ||
4108 *portfwd_strptr == 'D')
4109 type = *portfwd_strptr++;
05581745 4110
06fadff5 4111 saddr[0] = '\0';
05581745 4112
06fadff5 4113 n = 0;
4114 while (*portfwd_strptr && *portfwd_strptr != '\t') {
4115 if (*portfwd_strptr == ':') {
4116 /*
4117 * We've seen a colon in the middle of the
4118 * source port number. This means that
4119 * everything we've seen until now is the
4120 * source _address_, so we'll move it into
4121 * saddr and start sports from the beginning
4122 * again.
4123 */
4124 portfwd_strptr++;
4125 sports[n] = '\0';
4126 if (ssh->version == 1 && type == 'R') {
2e85c969 4127 logeventf(ssh, "SSH-1 cannot handle remote source address "
06fadff5 4128 "spec \"%s\"; ignoring", sports);
4129 } else
4130 strcpy(saddr, sports);
4131 n = 0;
4132 }
019164b0 4133 if (n < lenof(sports)-1) sports[n++] = *portfwd_strptr++;
06fadff5 4134 }
4135 sports[n] = 0;
4136 if (type != 'D') {
4137 if (*portfwd_strptr == '\t')
4138 portfwd_strptr++;
4139 n = 0;
4140 while (*portfwd_strptr && *portfwd_strptr != ':') {
019164b0 4141 if (n < lenof(host)-1) host[n++] = *portfwd_strptr++;
06fadff5 4142 }
4143 host[n] = 0;
4144 if (*portfwd_strptr == ':')
4145 portfwd_strptr++;
4146 n = 0;
4147 while (*portfwd_strptr) {
019164b0 4148 if (n < lenof(dports)-1) dports[n++] = *portfwd_strptr++;
06fadff5 4149 }
4150 dports[n] = 0;
4151 portfwd_strptr++;
4152 dport = atoi(dports);
4153 dserv = 0;
4154 if (dport == 0) {
4155 dserv = 1;
4156 dport = net_service_lookup(dports);
4157 if (!dport) {
4158 logeventf(ssh, "Service lookup failed for destination"
4159 " port \"%s\"", dports);
4160 }
4161 }
4162 } else {
4163 while (*portfwd_strptr) portfwd_strptr++;
a9e72926 4164 host[0] = 0;
4165 dports[0] = 0;
06fadff5 4166 dport = dserv = -1;
4167 portfwd_strptr++; /* eat the NUL and move to next one */
4168 }
4169 sport = atoi(sports);
4170 sserv = 0;
4171 if (sport == 0) {
4172 sserv = 1;
4173 sport = net_service_lookup(sports);
4174 if (!sport) {
4175 logeventf(ssh, "Service lookup failed for source"
4176 " port \"%s\"", sports);
4177 }
4178 }
4179 if (sport && dport) {
4180 /* Set up a description of the source port. */
fda2feb1 4181 struct ssh_portfwd *pfrec, *epfrec;
fda2feb1 4182
4183 pfrec = snew(struct ssh_portfwd);
4184 pfrec->type = type;
4185 pfrec->saddr = *saddr ? dupstr(saddr) : NULL;
3fe92132 4186 pfrec->sserv = sserv ? dupstr(sports) : NULL;
fda2feb1 4187 pfrec->sport = sport;
84328ddb 4188 pfrec->daddr = *host ? dupstr(host) : NULL;
3fe92132 4189 pfrec->dserv = dserv ? dupstr(dports) : NULL;
fda2feb1 4190 pfrec->dport = dport;
4191 pfrec->local = NULL;
4192 pfrec->remote = NULL;
05581745 4193 pfrec->addressfamily = (address_family == '4' ? ADDRTYPE_IPV4 :
4194 address_family == '6' ? ADDRTYPE_IPV6 :
4195 ADDRTYPE_UNSPEC);
fda2feb1 4196
4197 epfrec = add234(ssh->portfwds, pfrec);
4198 if (epfrec != pfrec) {
4199 /*
4200 * We already have a port forwarding with precisely
4201 * these parameters. Hence, no need to do anything;
84328ddb 4202 * simply tag the existing one as KEEP.
fda2feb1 4203 */
84328ddb 4204 epfrec->status = KEEP;
fda2feb1 4205 free_portfwd(pfrec);
84328ddb 4206 } else {
4207 pfrec->status = CREATE;
4208 }
4209 }
4210 }
4211
4212 /*
4213 * Now go through and destroy any port forwardings which were
4214 * not re-enabled.
4215 */
4216 for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
4217 if (epf->status == DESTROY) {
4218 char *message;
4219
4220 message = dupprintf("%s port forwarding from %s%s%d",
4221 epf->type == 'L' ? "local" :
4222 epf->type == 'R' ? "remote" : "dynamic",
4223 epf->saddr ? epf->saddr : "",
4224 epf->saddr ? ":" : "",
4225 epf->sport);
4226
4227 if (epf->type != 'D') {
4228 char *msg2 = dupprintf("%s to %s:%d", message,
4229 epf->daddr, epf->dport);
4230 sfree(message);
4231 message = msg2;
4232 }
4233
4234 logeventf(ssh, "Cancelling %s", message);
4235 sfree(message);
4236
4237 if (epf->remote) {
4238 struct ssh_rportfwd *rpf = epf->remote;
4239 struct Packet *pktout;
4240
4241 /*
4242 * Cancel the port forwarding at the server
4243 * end.
4244 */
4245 if (ssh->version == 1) {
4246 /*
4247 * We cannot cancel listening ports on the
2e85c969 4248 * server side in SSH-1! There's no message
84328ddb 4249 * to support it. Instead, we simply remove
4250 * the rportfwd record from the local end
4251 * so that any connections the server tries
4252 * to make on it are rejected.
4253 */
4254 } else {
4255 pktout = ssh2_pkt_init(SSH2_MSG_GLOBAL_REQUEST);
4256 ssh2_pkt_addstring(pktout, "cancel-tcpip-forward");
4257 ssh2_pkt_addbool(pktout, 0);/* _don't_ want reply */
4258 if (epf->saddr) {
4259 ssh2_pkt_addstring(pktout, epf->saddr);
4260 } else if (ssh->cfg.rport_acceptall) {
5188540b 4261 /* XXX: ssh->cfg.rport_acceptall may not represent
4262 * what was used to open the original connection,
4263 * since it's reconfigurable. */
84328ddb 4264 ssh2_pkt_addstring(pktout, "0.0.0.0");
4265 } else {
4266 ssh2_pkt_addstring(pktout, "127.0.0.1");
4267 }
4268 ssh2_pkt_adduint32(pktout, epf->sport);
4269 ssh2_pkt_send(ssh, pktout);
4270 }
4271
4272 del234(ssh->rportfwds, rpf);
4273 free_rportfwd(rpf);
4274 } else if (epf->local) {
4275 pfd_terminate(epf->local);
4276 }
4277
4278 delpos234(ssh->portfwds, i);
4279 free_portfwd(epf);
4280 i--; /* so we don't skip one in the list */
4281 }
4282
4283 /*
4284 * And finally, set up any new port forwardings (status==CREATE).
4285 */
4286 for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
4287 if (epf->status == CREATE) {
4288 char *sportdesc, *dportdesc;
3fe92132 4289 sportdesc = dupprintf("%s%s%s%s%d%s",
84328ddb 4290 epf->saddr ? epf->saddr : "",
4291 epf->saddr ? ":" : "",
3fe92132 4292 epf->sserv ? epf->sserv : "",
4293 epf->sserv ? "(" : "",
4294 epf->sport,
4295 epf->sserv ? ")" : "");
84328ddb 4296 if (epf->type == 'D') {
4297 dportdesc = NULL;
4298 } else {
3fe92132 4299 dportdesc = dupprintf("%s:%s%s%d%s",
4300 epf->daddr,
4301 epf->dserv ? epf->dserv : "",
4302 epf->dserv ? "(" : "",
4303 epf->dport,
4304 epf->dserv ? ")" : "");
84328ddb 4305 }
05581745 4306
84328ddb 4307 if (epf->type == 'L') {
4308 const char *err = pfd_addforward(epf->daddr, epf->dport,
4309 epf->saddr, epf->sport,
5188540b 4310 ssh, cfg,
84328ddb 4311 &epf->local,
4312 epf->addressfamily);
4313
4314 logeventf(ssh, "Local %sport %s forwarding to %s%s%s",
4315 epf->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " :
4316 epf->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "",
4317 sportdesc, dportdesc,
4318 err ? " failed: " : "", err ? err : "");
4319 } else if (epf->type == 'D') {
06fadff5 4320 const char *err = pfd_addforward(NULL, -1,
84328ddb 4321 epf->saddr, epf->sport,
5188540b 4322 ssh, cfg,
84328ddb 4323 &epf->local,
4324 epf->addressfamily);
4325
4326 logeventf(ssh, "Local %sport %s SOCKS dynamic forwarding%s%s",
4327 epf->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " :
4328 epf->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "",
4329 sportdesc,
4330 err ? " failed: " : "", err ? err : "");
06fadff5 4331 } else {
4332 struct ssh_rportfwd *pf;
4333
4334 /*
4335 * Ensure the remote port forwardings tree exists.
4336 */
4337 if (!ssh->rportfwds) {
4338 if (ssh->version == 1)
4339 ssh->rportfwds = newtree234(ssh_rportcmp_ssh1);
4340 else
4341 ssh->rportfwds = newtree234(ssh_rportcmp_ssh2);
4342 }
4343
4344 pf = snew(struct ssh_rportfwd);
84328ddb 4345 strncpy(pf->dhost, epf->daddr, lenof(pf->dhost)-1);
4346 pf->dhost[lenof(pf->dhost)-1] = '\0';
4347 pf->dport = epf->dport;
4348 pf->sport = epf->sport;
06fadff5 4349 if (add234(ssh->rportfwds, pf) != pf) {
4350 logeventf(ssh, "Duplicate remote port forwarding to %s:%d",
84328ddb 4351 epf->daddr, epf->dport);
06fadff5 4352 sfree(pf);
4353 } else {
4354 logeventf(ssh, "Requesting remote port %s"
84328ddb 4355 " forward to %s", sportdesc, dportdesc);
06fadff5 4356
4357 pf->sportdesc = sportdesc;
4358 sportdesc = NULL;
84328ddb 4359 epf->remote = pf;
4360 pf->pfrec = epf;
06fadff5 4361
4362 if (ssh->version == 1) {
4363 send_packet(ssh, SSH1_CMSG_PORT_FORWARD_REQUEST,
84328ddb 4364 PKT_INT, epf->sport,
4365 PKT_STR, epf->daddr,
4366 PKT_INT, epf->dport,
06fadff5 4367 PKT_END);
4368 ssh_queue_handler(ssh, SSH1_SMSG_SUCCESS,
4369 SSH1_SMSG_FAILURE,
4370 ssh_rportfwd_succfail, pf);
4371 } else {
4372 struct Packet *pktout;
4373 pktout = ssh2_pkt_init(SSH2_MSG_GLOBAL_REQUEST);
4374 ssh2_pkt_addstring(pktout, "tcpip-forward");
4375 ssh2_pkt_addbool(pktout, 1);/* want reply */
84328ddb 4376 if (epf->saddr) {
4377 ssh2_pkt_addstring(pktout, epf->saddr);
5188540b 4378 } else if (cfg->rport_acceptall) {
06fadff5 4379 ssh2_pkt_addstring(pktout, "0.0.0.0");
4380 } else {
4381 ssh2_pkt_addstring(pktout, "127.0.0.1");
4382 }
84328ddb 4383 ssh2_pkt_adduint32(pktout, epf->sport);
06fadff5 4384 ssh2_pkt_send(ssh, pktout);
4385
4386 ssh_queue_handler(ssh, SSH2_MSG_REQUEST_SUCCESS,
4387 SSH2_MSG_REQUEST_FAILURE,
4388 ssh_rportfwd_succfail, pf);
4389 }
4390 }
4391 }
4392 sfree(sportdesc);
84328ddb 4393 sfree(dportdesc);
06fadff5 4394 }
06fadff5 4395}
4396
51df0ab5 4397static void ssh1_smsg_stdout_stderr_data(Ssh ssh, struct Packet *pktin)
4398{
4399 char *string;
4400 int stringlen, bufsize;
4401
4402 ssh_pkt_getstring(pktin, &string, &stringlen);
4403 if (string == NULL) {
4404 bombout(("Incoming terminal data packet was badly formed"));
4405 return;
4406 }
4407
4408 bufsize = from_backend(ssh->frontend, pktin->type == SSH1_SMSG_STDERR_DATA,
4409 string, stringlen);
4410 if (!ssh->v1_stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) {
4411 ssh->v1_stdout_throttling = 1;
4412 ssh1_throttle(ssh, +1);
4413 }
4414}
4415
4416static void ssh1_smsg_x11_open(Ssh ssh, struct Packet *pktin)
4417{
4418 /* Remote side is trying to open a channel to talk to our
4419 * X-Server. Give them back a local channel number. */
4420 struct ssh_channel *c;
4421 int remoteid = ssh_pkt_getuint32(pktin);
4422
4423 logevent("Received X11 connect request");
4424 /* Refuse if X11 forwarding is disabled. */
4425 if (!ssh->X11_fwd_enabled) {
4426 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4427 PKT_INT, remoteid, PKT_END);
4428 logevent("Rejected X11 connect request");
4429 } else {
4430 c = snew(struct ssh_channel);
4431 c->ssh = ssh;
4432
4433 if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c,
4434 ssh->x11auth, NULL, -1, &ssh->cfg) != NULL) {
4435 logevent("Opening X11 forward connection failed");
4436 sfree(c);
4437 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4438 PKT_INT, remoteid, PKT_END);
4439 } else {
4440 logevent
4441 ("Opening X11 forward connection succeeded");
4442 c->remoteid = remoteid;
64d6ff88 4443 c->halfopen = FALSE;
51df0ab5 4444 c->localid = alloc_channel_id(ssh);
4445 c->closes = 0;
4446 c->v.v1.throttling = 0;
4447 c->type = CHAN_X11; /* identify channel type */
4448 add234(ssh->channels, c);
4449 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4450 PKT_INT, c->remoteid, PKT_INT,
4451 c->localid, PKT_END);
4452 logevent("Opened X11 forward channel");
4453 }
4454 }
4455}
4456
4457static void ssh1_smsg_agent_open(Ssh ssh, struct Packet *pktin)
4458{
4459 /* Remote side is trying to open a channel to talk to our
4460 * agent. Give them back a local channel number. */
4461 struct ssh_channel *c;
4462 int remoteid = ssh_pkt_getuint32(pktin);
4463
4464 /* Refuse if agent forwarding is disabled. */
4465 if (!ssh->agentfwd_enabled) {
4466 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4467 PKT_INT, remoteid, PKT_END);
4468 } else {
4469 c = snew(struct ssh_channel);
4470 c->ssh = ssh;
4471 c->remoteid = remoteid;
64d6ff88 4472 c->halfopen = FALSE;
51df0ab5 4473 c->localid = alloc_channel_id(ssh);
4474 c->closes = 0;
4475 c->v.v1.throttling = 0;
4476 c->type = CHAN_AGENT; /* identify channel type */
4477 c->u.a.lensofar = 0;
4478 add234(ssh->channels, c);
4479 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4480 PKT_INT, c->remoteid, PKT_INT, c->localid,
4481 PKT_END);
4482 }
4483}
4484
4485static void ssh1_msg_port_open(Ssh ssh, struct Packet *pktin)
4486{
4487 /* Remote side is trying to open a channel to talk to a
4488 * forwarded port. Give them back a local channel number. */
4489 struct ssh_channel *c;
05581745 4490 struct ssh_rportfwd pf, *pfp;
51df0ab5 4491 int remoteid;
4492 int hostsize, port;
fb983202 4493 char *host;
51df0ab5 4494 const char *e;
4495 c = snew(struct ssh_channel);
4496 c->ssh = ssh;
4497
4498 remoteid = ssh_pkt_getuint32(pktin);
4499 ssh_pkt_getstring(pktin, &host, &hostsize);
4500 port = ssh_pkt_getuint32(pktin);
4501
4502 if (hostsize >= lenof(pf.dhost))
4503 hostsize = lenof(pf.dhost)-1;
4504 memcpy(pf.dhost, host, hostsize);
4505 pf.dhost[hostsize] = '\0';
4506 pf.dport = port;
05581745 4507 pfp = find234(ssh->rportfwds, &pf, NULL);
51df0ab5 4508
05581745 4509 if (pfp == NULL) {
fb983202 4510 logeventf(ssh, "Rejected remote port open request for %s:%d",
4511 pf.dhost, port);
51df0ab5 4512 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4513 PKT_INT, remoteid, PKT_END);
4514 } else {
fb983202 4515 logeventf(ssh, "Received remote port open request for %s:%d",
4516 pf.dhost, port);
51df0ab5 4517 e = pfd_newconnect(&c->u.pfd.s, pf.dhost, port,
05581745 4518 c, &ssh->cfg, pfp->pfrec->addressfamily);
51df0ab5 4519 if (e != NULL) {
fb983202 4520 logeventf(ssh, "Port open failed: %s", e);
51df0ab5 4521 sfree(c);
4522 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4523 PKT_INT, remoteid, PKT_END);
4524 } else {
4525 c->remoteid = remoteid;
64d6ff88 4526 c->halfopen = FALSE;
51df0ab5 4527 c->localid = alloc_channel_id(ssh);
4528 c->closes = 0;
4529 c->v.v1.throttling = 0;
4530 c->type = CHAN_SOCKDATA; /* identify channel type */
4531 add234(ssh->channels, c);
4532 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4533 PKT_INT, c->remoteid, PKT_INT,
4534 c->localid, PKT_END);
4535 logevent("Forwarded port opened successfully");
4536 }
4537 }
4538}
4539
4540static void ssh1_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
4541{
4542 unsigned int remoteid = ssh_pkt_getuint32(pktin);
4543 unsigned int localid = ssh_pkt_getuint32(pktin);
4544 struct ssh_channel *c;
4545
4546 c = find234(ssh->channels, &remoteid, ssh_channelfind);
4547 if (c && c->type == CHAN_SOCKDATA_DORMANT) {
4548 c->remoteid = localid;
64d6ff88 4549 c->halfopen = FALSE;
51df0ab5 4550 c->type = CHAN_SOCKDATA;
4551 c->v.v1.throttling = 0;
4552 pfd_confirm(c->u.pfd.s);
4553 }
4554
4555 if (c && c->closes) {
4556 /*
4557 * We have a pending close on this channel,
4558 * which we decided on before the server acked
4559 * the channel open. So now we know the
4560 * remoteid, we can close it again.
4561 */
4562 send_packet(ssh, SSH1_MSG_CHANNEL_CLOSE,
4563 PKT_INT, c->remoteid, PKT_END);
4564 }
4565}
4566
4567static void ssh1_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
4568{
4569 unsigned int remoteid = ssh_pkt_getuint32(pktin);
4570 struct ssh_channel *c;
4571
4572 c = find234(ssh->channels, &remoteid, ssh_channelfind);
4573 if (c && c->type == CHAN_SOCKDATA_DORMANT) {
4574 logevent("Forwarded connection refused by server");
4575 pfd_close(c->u.pfd.s);
4576 del234(ssh->channels, c);
4577 sfree(c);
4578 }
4579}
4580
4581static void ssh1_msg_channel_close(Ssh ssh, struct Packet *pktin)
4582{
4583 /* Remote side closes a channel. */
4584 unsigned i = ssh_pkt_getuint32(pktin);
4585 struct ssh_channel *c;
4586 c = find234(ssh->channels, &i, ssh_channelfind);
64d6ff88 4587 if (c && !c->halfopen) {
51df0ab5 4588 int closetype;
4589 closetype =
4590 (pktin->type == SSH1_MSG_CHANNEL_CLOSE ? 1 : 2);
4591
4592 if ((c->closes == 0) && (c->type == CHAN_X11)) {
4593 logevent("Forwarded X11 connection terminated");
4594 assert(c->u.x11.s != NULL);
4595 x11_close(c->u.x11.s);
4596 c->u.x11.s = NULL;
4597 }
4598 if ((c->closes == 0) && (c->type == CHAN_SOCKDATA)) {
4599 logevent("Forwarded port closed");
4600 assert(c->u.pfd.s != NULL);
4601 pfd_close(c->u.pfd.s);
4602 c->u.pfd.s = NULL;
4603 }
4604
4605 c->closes |= (closetype << 2); /* seen this message */
4606 if (!(c->closes & closetype)) {
4607 send_packet(ssh, pktin->type, PKT_INT, c->remoteid,
4608 PKT_END);
4609 c->closes |= closetype; /* sent it too */
4610 }
4611
4612 if (c->closes == 15) {
4613 del234(ssh->channels, c);
4614 sfree(c);
4615 }
4616 } else {
4617 bombout(("Received CHANNEL_CLOSE%s for %s channel %d\n",
4618 pktin->type == SSH1_MSG_CHANNEL_CLOSE ? "" :
4619 "_CONFIRMATION", c ? "half-open" : "nonexistent",
4620 i));
4621 }
4622}
4623
4624static void ssh1_msg_channel_data(Ssh ssh, struct Packet *pktin)
4625{
4626 /* Data sent down one of our channels. */
4627 int i = ssh_pkt_getuint32(pktin);
4628 char *p;
6d44acc9 4629 int len;
51df0ab5 4630 struct ssh_channel *c;
4631
4632 ssh_pkt_getstring(pktin, &p, &len);
4633
4634 c = find234(ssh->channels, &i, ssh_channelfind);
4635 if (c) {
4636 int bufsize = 0;
4637 switch (c->type) {
4638 case CHAN_X11:
4639 bufsize = x11_send(c->u.x11.s, p, len);
4640 break;
4641 case CHAN_SOCKDATA:
4642 bufsize = pfd_send(c->u.pfd.s, p, len);
4643 break;
4644 case CHAN_AGENT:
4645 /* Data for an agent message. Buffer it. */
4646 while (len > 0) {
4647 if (c->u.a.lensofar < 4) {
62ddb51e 4648 unsigned int l = min(4 - c->u.a.lensofar, (unsigned)len);
51df0ab5 4649 memcpy(c->u.a.msglen + c->u.a.lensofar, p,
4650 l);
4651 p += l;
4652 len -= l;
4653 c->u.a.lensofar += l;
4654 }
4655 if (c->u.a.lensofar == 4) {
4656 c->u.a.totallen =
4657 4 + GET_32BIT(c->u.a.msglen);
4658 c->u.a.message = snewn(c->u.a.totallen,
4659 unsigned char);
4660 memcpy(c->u.a.message, c->u.a.msglen, 4);
4661 }
4662 if (c->u.a.lensofar >= 4 && len > 0) {
aa63ab7e 4663 unsigned int l =
51df0ab5 4664 min(c->u.a.totallen - c->u.a.lensofar,
62ddb51e 4665 (unsigned)len);
51df0ab5 4666 memcpy(c->u.a.message + c->u.a.lensofar, p,
4667 l);
4668 p += l;
4669 len -= l;
4670 c->u.a.lensofar += l;
4671 }
4672 if (c->u.a.lensofar == c->u.a.totallen) {
4673 void *reply;
4674 int replylen;
4675 if (agent_query(c->u.a.message,
4676 c->u.a.totallen,
4677 &reply, &replylen,
4678 ssh_agentf_callback, c))
4679 ssh_agentf_callback(c, reply, replylen);
4680 sfree(c->u.a.message);
4681 c->u.a.lensofar = 0;
4682 }
4683 }
4684 bufsize = 0; /* agent channels never back up */
4685 break;
4686 }
4687 if (!c->v.v1.throttling && bufsize > SSH1_BUFFER_LIMIT) {
4688 c->v.v1.throttling = 1;
4689 ssh1_throttle(ssh, +1);
4690 }
4691 }
4692}
4693
4694static void ssh1_smsg_exit_status(Ssh ssh, struct Packet *pktin)
4695{
51df0ab5 4696 ssh->exitcode = ssh_pkt_getuint32(pktin);
fb983202 4697 logeventf(ssh, "Server sent command exit status %d", ssh->exitcode);
51df0ab5 4698 send_packet(ssh, SSH1_CMSG_EXIT_CONFIRMATION, PKT_END);
4699 /*
4700 * In case `helpful' firewalls or proxies tack
4701 * extra human-readable text on the end of the
4702 * session which we might mistake for another
4703 * encrypted packet, we close the session once
4704 * we've sent EXIT_CONFIRMATION.
4705 */
9e296bfa 4706 ssh_disconnect(ssh, NULL, NULL, 0, TRUE);
51df0ab5 4707}
4708
c6ccd5c2 4709/* Helper function to deal with sending tty modes for REQUEST_PTY */
4710static void ssh1_send_ttymode(void *data, char *mode, char *val)
4711{
4712 struct Packet *pktout = (struct Packet *)data;
4713 int i = 0;
4714 unsigned int arg = 0;
4715 while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
4716 if (i == lenof(ssh_ttymodes)) return;
4717 switch (ssh_ttymodes[i].type) {
4718 case TTY_OP_CHAR:
4719 arg = ssh_tty_parse_specchar(val);
4720 break;
4721 case TTY_OP_BOOL:
4722 arg = ssh_tty_parse_boolean(val);
4723 break;
4724 }
4725 ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
4726 ssh2_pkt_addbyte(pktout, arg);
4727}
4728
4729
b09eaa88 4730static void do_ssh1_connection(Ssh ssh, unsigned char *in, int inlen,
4731 struct Packet *pktin)
32874aea 4732{
b09eaa88 4733 crBegin(ssh->do_ssh1_connection_crstate);
fb09bf1c 4734
51df0ab5 4735 ssh->packet_dispatch[SSH1_SMSG_STDOUT_DATA] =
4736 ssh->packet_dispatch[SSH1_SMSG_STDERR_DATA] =
4737 ssh1_smsg_stdout_stderr_data;
4738
4739 ssh->packet_dispatch[SSH1_MSG_CHANNEL_OPEN_CONFIRMATION] =
4740 ssh1_msg_channel_open_confirmation;
4741 ssh->packet_dispatch[SSH1_MSG_CHANNEL_OPEN_FAILURE] =
4742 ssh1_msg_channel_open_failure;
4743 ssh->packet_dispatch[SSH1_MSG_CHANNEL_CLOSE] =
4744 ssh->packet_dispatch[SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION] =
4745 ssh1_msg_channel_close;
4746 ssh->packet_dispatch[SSH1_MSG_CHANNEL_DATA] = ssh1_msg_channel_data;
4747 ssh->packet_dispatch[SSH1_SMSG_EXIT_STATUS] = ssh1_smsg_exit_status;
4748
86916870 4749 if (ssh->cfg.agentfwd && agent_exists()) {
32874aea 4750 logevent("Requesting agent forwarding");
51470298 4751 send_packet(ssh, SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END);
32874aea 4752 do {
4753 crReturnV;
ff3187f6 4754 } while (!pktin);
4755 if (pktin->type != SSH1_SMSG_SUCCESS
4756 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 4757 bombout(("Protocol confusion"));
7ffdbc1a 4758 crStopV;
ff3187f6 4759 } else if (pktin->type == SSH1_SMSG_FAILURE) {
32874aea 4760 logevent("Agent forwarding refused");
4761 } else {
4762 logevent("Agent forwarding enabled");
51470298 4763 ssh->agentfwd_enabled = TRUE;
51df0ab5 4764 ssh->packet_dispatch[SSH1_SMSG_AGENT_OPEN] = ssh1_smsg_agent_open;
db7d555c 4765 }
dacbd0e8 4766 }
4767
86916870 4768 if (ssh->cfg.x11_forward) {
32874aea 4769 char proto[20], data[64];
4770 logevent("Requesting X11 forwarding");
302121de 4771 ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
86916870 4772 data, sizeof(data), ssh->cfg.x11_auth);
4773 x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
f68353be 4774 /*
4775 * Note that while we blank the X authentication data here, we don't
4776 * take any special action to blank the start of an X11 channel,
4777 * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
4778 * without having session blanking enabled is likely to leak your
4779 * cookie into the log.
4780 */
51470298 4781 if (ssh->v1_local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER) {
4782 send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
f68353be 4783 PKT_STR, proto,
4784 PKTT_PASSWORD, PKT_STR, data, PKTT_OTHER,
86916870 4785 PKT_INT, x11_get_screen_number(ssh->cfg.x11_display),
421d6835 4786 PKT_END);
32874aea 4787 } else {
51470298 4788 send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
f68353be 4789 PKT_STR, proto,
4790 PKTT_PASSWORD, PKT_STR, data, PKTT_OTHER, PKT_END);
32874aea 4791 }
4792 do {
4793 crReturnV;
ff3187f6 4794 } while (!pktin);
4795 if (pktin->type != SSH1_SMSG_SUCCESS
4796 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 4797 bombout(("Protocol confusion"));
7ffdbc1a 4798 crStopV;
ff3187f6 4799 } else if (pktin->type == SSH1_SMSG_FAILURE) {
32874aea 4800 logevent("X11 forwarding refused");
4801 } else {
4802 logevent("X11 forwarding enabled");
51470298 4803 ssh->X11_fwd_enabled = TRUE;
51df0ab5 4804 ssh->packet_dispatch[SSH1_SMSG_X11_OPEN] = ssh1_smsg_x11_open;
9c964e85 4805 }
4806 }
4807
06fadff5 4808 ssh_setup_portfwd(ssh, &ssh->cfg);
4809 ssh->packet_dispatch[SSH1_MSG_PORT_OPEN] = ssh1_msg_port_open;
d74d141c 4810
86916870 4811 if (!ssh->cfg.nopty) {
c6ccd5c2 4812 struct Packet *pkt;
a5dd8467 4813 /* Unpick the terminal-speed string. */
4814 /* XXX perhaps we should allow no speeds to be sent. */
db219738 4815 ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
4816 sscanf(ssh->cfg.termspeed, "%d,%d", &ssh->ospeed, &ssh->ispeed);
a5dd8467 4817 /* Send the pty request. */
c6ccd5c2 4818 pkt = ssh1_pkt_init(SSH1_CMSG_REQUEST_PTY);
4819 ssh_pkt_addstring(pkt, ssh->cfg.termtype);
4820 ssh_pkt_adduint32(pkt, ssh->term_height);
4821 ssh_pkt_adduint32(pkt, ssh->term_width);
4822 ssh_pkt_adduint32(pkt, 0); /* width in pixels */
4823 ssh_pkt_adduint32(pkt, 0); /* height in pixels */
4824 parse_ttymodes(ssh, ssh->cfg.ttymodes,
4825 ssh1_send_ttymode, (void *)pkt);
4826 ssh_pkt_addbyte(pkt, SSH1_TTY_OP_ISPEED);
4827 ssh_pkt_adduint32(pkt, ssh->ispeed);
4828 ssh_pkt_addbyte(pkt, SSH1_TTY_OP_OSPEED);
4829 ssh_pkt_adduint32(pkt, ssh->ospeed);
4830 ssh_pkt_addbyte(pkt, SSH_TTY_OP_END);
4831 s_wrpkt(ssh, pkt);
51470298 4832 ssh->state = SSH_STATE_INTERMED;
32874aea 4833 do {
4834 crReturnV;
ff3187f6 4835 } while (!pktin);
4836 if (pktin->type != SSH1_SMSG_SUCCESS
4837 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 4838 bombout(("Protocol confusion"));
7ffdbc1a 4839 crStopV;
ff3187f6 4840 } else if (pktin->type == SSH1_SMSG_FAILURE) {
51470298 4841 c_write_str(ssh, "Server refused to allocate pty\r\n");
4842 ssh->editing = ssh->echoing = 1;
32874aea 4843 }
a5dd8467 4844 logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
db219738 4845 ssh->ospeed, ssh->ispeed);
0965bee0 4846 } else {
51470298 4847 ssh->editing = ssh->echoing = 1;
374330e2 4848 }
4849
86916870 4850 if (ssh->cfg.compression) {
51470298 4851 send_packet(ssh, SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);
32874aea 4852 do {
4853 crReturnV;
ff3187f6 4854 } while (!pktin);
4855 if (pktin->type != SSH1_SMSG_SUCCESS
4856 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 4857 bombout(("Protocol confusion"));
7ffdbc1a 4858 crStopV;
ff3187f6 4859 } else if (pktin->type == SSH1_SMSG_FAILURE) {
51470298 4860 c_write_str(ssh, "Server refused to compress\r\n");
32874aea 4861 }
4ba9b64b 4862 logevent("Started compression");
51470298 4863 ssh->v1_compressing = TRUE;
5366aed8 4864 ssh->cs_comp_ctx = zlib_compress_init();
4865 logevent("Initialised zlib (RFC1950) compression");
4866 ssh->sc_comp_ctx = zlib_decompress_init();
4867 logevent("Initialised zlib (RFC1950) decompression");
4ba9b64b 4868 }
4869
fd5e5847 4870 /*
4871 * Start the shell or command.
4872 *
2e85c969 4873 * Special case: if the first-choice command is an SSH-2
fd5e5847 4874 * subsystem (hence not usable here) and the second choice
4875 * exists, we fall straight back to that.
4876 */
4877 {
86916870 4878 char *cmd = ssh->cfg.remote_cmd_ptr;
04c52f10 4879
4880 if (!cmd) cmd = ssh->cfg.remote_cmd;
fd5e5847 4881
86916870 4882 if (ssh->cfg.ssh_subsys && ssh->cfg.remote_cmd_ptr2) {
4883 cmd = ssh->cfg.remote_cmd_ptr2;
51470298 4884 ssh->fallback_cmd = TRUE;
fd5e5847 4885 }
4886 if (*cmd)
51470298 4887 send_packet(ssh, SSH1_CMSG_EXEC_CMD, PKT_STR, cmd, PKT_END);
fd5e5847 4888 else
51470298 4889 send_packet(ssh, SSH1_CMSG_EXEC_SHELL, PKT_END);
fd5e5847 4890 logevent("Started session");
4891 }
374330e2 4892
51470298 4893 ssh->state = SSH_STATE_SESSION;
4894 if (ssh->size_needed)
4895 ssh_size(ssh, ssh->term_width, ssh->term_height);
4896 if (ssh->eof_needed)
4897 ssh_special(ssh, TS_EOF);
374330e2 4898
b9d7bcad 4899 if (ssh->ldisc)
4900 ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
51470298 4901 ssh->send_ok = 1;
4902 ssh->channels = newtree234(ssh_channelcmp);
374330e2 4903 while (1) {
d74d141c 4904
51df0ab5 4905 /*
4906 * By this point, most incoming packets are already being
4907 * handled by the dispatch table, and we need only pay
4908 * attention to the unusual ones.
4909 */
0357890f 4910
51df0ab5 4911 crReturnV;
4912 if (pktin) {
4913 if (pktin->type == SSH1_SMSG_SUCCESS) {
972a41c8 4914 /* may be from EXEC_SHELL on some servers */
ff3187f6 4915 } else if (pktin->type == SSH1_SMSG_FAILURE) {
972a41c8 4916 /* may be from EXEC_SHELL on some servers
374330e2 4917 * if no pty is available or in other odd cases. Ignore */
374330e2 4918 } else {
ff3187f6 4919 bombout(("Strange packet received: type %d", pktin->type));
7ffdbc1a 4920 crStopV;
374330e2 4921 }
4922 } else {
8df7a775 4923 while (inlen > 0) {
4924 int len = min(inlen, 512);
9a10ecf4 4925 send_packet(ssh, SSH1_CMSG_STDIN_DATA, PKTT_DATA,
4926 PKT_INT, len, PKT_DATA, in, len,
4927 PKTT_OTHER, PKT_END);
8df7a775 4928 in += len;
4929 inlen -= len;
4930 }
374330e2 4931 }
4932 }
4933
4934 crFinishV;
4935}
4936
4937/*
2e85c969 4938 * Handle the top-level SSH-2 protocol.
b09eaa88 4939 */
4940static void ssh1_msg_debug(Ssh ssh, struct Packet *pktin)
4941{
fb983202 4942 char *msg;
b09eaa88 4943 int msglen;
4944
4945 ssh_pkt_getstring(pktin, &msg, &msglen);
fb983202 4946 logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
b09eaa88 4947}
4948
4949static void ssh1_msg_disconnect(Ssh ssh, struct Packet *pktin)
4950{
4951 /* log reason code in disconnect message */
4952 char *msg;
4953 int msglen;
4954
4955 ssh_pkt_getstring(pktin, &msg, &msglen);
4956 bombout(("Server sent disconnect message:\n\"%.*s\"", msglen, msg));
4957}
4958
409bfa77 4959static void ssh_msg_ignore(Ssh ssh, struct Packet *pktin)
b09eaa88 4960{
4961 /* Do nothing, because we're ignoring it! Duhh. */
4962}
4963
4964static void ssh1_protocol_setup(Ssh ssh)
4965{
4966 int i;
4967
4968 /*
4969 * Most messages are handled by the coroutines.
4970 */
4971 for (i = 0; i < 256; i++)
4972 ssh->packet_dispatch[i] = NULL;
4973
4974 /*
4975 * These special message types we install handlers for.
4976 */
4977 ssh->packet_dispatch[SSH1_MSG_DISCONNECT] = ssh1_msg_disconnect;
4978 ssh->packet_dispatch[SSH1_MSG_IGNORE] = ssh_msg_ignore;
4979 ssh->packet_dispatch[SSH1_MSG_DEBUG] = ssh1_msg_debug;
4980}
4981
1c1a7262 4982static void ssh1_protocol(Ssh ssh, void *vin, int inlen,
b09eaa88 4983 struct Packet *pktin)
4984{
1c1a7262 4985 unsigned char *in=(unsigned char*)vin;
b09eaa88 4986 if (ssh->state == SSH_STATE_CLOSED)
4987 return;
4988
4989 if (pktin && ssh->packet_dispatch[pktin->type]) {
4990 ssh->packet_dispatch[pktin->type](ssh, pktin);
4991 return;
4992 }
4993
4994 if (!ssh->protocol_initial_phase_done) {
4995 if (do_ssh1_login(ssh, in, inlen, pktin))
4996 ssh->protocol_initial_phase_done = TRUE;
4997 else
4998 return;
4999 }
5000
5001 do_ssh1_connection(ssh, in, inlen, pktin);
5002}
5003
5004/*
e5574168 5005 * Utility routine for decoding comma-separated strings in KEXINIT.
5006 */
32874aea 5007static int in_commasep_string(char *needle, char *haystack, int haylen)
5008{
57356d63 5009 int needlen;
5010 if (!needle || !haystack) /* protect against null pointers */
5011 return 0;
5012 needlen = strlen(needle);
e5574168 5013 while (1) {
32874aea 5014 /*
5015 * Is it at the start of the string?
5016 */
5017 if (haylen >= needlen && /* haystack is long enough */
5018 !memcmp(needle, haystack, needlen) && /* initial match */
5019 (haylen == needlen || haystack[needlen] == ',')
5020 /* either , or EOS follows */
5021 )
5022 return 1;
5023 /*
5024 * If not, search for the next comma and resume after that.
5025 * If no comma found, terminate.
5026 */
5027 while (haylen > 0 && *haystack != ',')
5028 haylen--, haystack++;
5029 if (haylen == 0)
5030 return 0;
5031 haylen--, haystack++; /* skip over comma itself */
e5574168 5032 }
5033}
5034
5035/*
b59743d5 5036 * Similar routine for checking whether we have the first string in a list.
5037 */
5038static int first_in_commasep_string(char *needle, char *haystack, int haylen)
5039{
5040 int needlen;
5041 if (!needle || !haystack) /* protect against null pointers */
5042 return 0;
5043 needlen = strlen(needle);
5044 /*
5045 * Is it at the start of the string?
5046 */
5047 if (haylen >= needlen && /* haystack is long enough */
5048 !memcmp(needle, haystack, needlen) && /* initial match */
5049 (haylen == needlen || haystack[needlen] == ',')
5050 /* either , or EOS follows */
5051 )
5052 return 1;
5053 return 0;
5054}
5055
5056
5057/*
2e85c969 5058 * SSH-2 key creation method.
754c0df9 5059 * (Currently assumes 2 lots of any hash are sufficient to generate
5060 * keys/IVs for any cipher/MAC. SSH2_MKKEY_ITERS documents this assumption.)
d39f364a 5061 */
754c0df9 5062#define SSH2_MKKEY_ITERS (2)
b672f405 5063static void ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, char chr,
d8baa528 5064 unsigned char *keyspace)
32874aea 5065{
b672f405 5066 const struct ssh_hash *h = ssh->kex->hash;
5067 void *s;
5068 /* First hlen bytes. */
5069 s = h->init();
51470298 5070 if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
b672f405 5071 hash_mpint(h, s, K);
5072 h->bytes(s, H, h->hlen);
5073 h->bytes(s, &chr, 1);
5074 h->bytes(s, ssh->v2_session_id, ssh->v2_session_id_len);
5075 h->final(s, keyspace);
5076 /* Next hlen bytes. */
5077 s = h->init();
51470298 5078 if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
b672f405 5079 hash_mpint(h, s, K);
5080 h->bytes(s, H, h->hlen);
5081 h->bytes(s, keyspace, h->hlen);
5082 h->final(s, keyspace + h->hlen);
d39f364a 5083}
5084
5085/*
2e85c969 5086 * Handle the SSH-2 transport layer.
e5574168 5087 */
1c1a7262 5088static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
ff3187f6 5089 struct Packet *pktin)
e5574168 5090{
1c1a7262 5091 unsigned char *in = (unsigned char *)vin;
51470298 5092 struct do_ssh2_transport_state {
4763c1c2 5093 int nbits, pbits, warn_kex, warn_cscipher, warn_sccipher;
51470298 5094 Bignum p, g, e, f, K;
3dc9a6a7 5095 void *our_kexinit;
5096 int our_kexinitlen;
51470298 5097 int kex_init_value, kex_reply_value;
5098 const struct ssh_mac **maclist;
5099 int nmacs;
5100 const struct ssh2_cipher *cscipher_tobe;
5101 const struct ssh2_cipher *sccipher_tobe;
5102 const struct ssh_mac *csmac_tobe;
5103 const struct ssh_mac *scmac_tobe;
5104 const struct ssh_compress *cscomp_tobe;
5105 const struct ssh_compress *sccomp_tobe;
5106 char *hostkeydata, *sigdata, *keystr, *fingerprint;
5107 int hostkeylen, siglen;
5108 void *hkey; /* actual host key */
754c0df9 5109 unsigned char exchange_hash[SSH2_KEX_MAX_HASH_LEN];
83e7d008 5110 int n_preferred_kex;
34557659 5111 const struct ssh_kexes *preferred_kex[KEX_MAX];
51470298 5112 int n_preferred_ciphers;
5113 const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX];
5114 const struct ssh_compress *preferred_comp;
e13bba36 5115 int got_session_id, activated_authconn;
ff3187f6 5116 struct Packet *pktout;
3d9449a1 5117 int dlgret;
5118 int guessok;
4763c1c2 5119 int ignorepkt;
51470298 5120 };
5121 crState(do_ssh2_transport_state);
5122
5123 crBegin(ssh->do_ssh2_transport_crstate);
5124
5125 s->cscipher_tobe = s->sccipher_tobe = NULL;
5126 s->csmac_tobe = s->scmac_tobe = NULL;
5127 s->cscomp_tobe = s->sccomp_tobe = NULL;
5128
e13bba36 5129 s->got_session_id = s->activated_authconn = FALSE;
e5574168 5130
e13bba36 5131 /*
5132 * Be prepared to work around the buggy MAC problem.
5133 */
5134 if (ssh->remote_bugs & BUG_SSH2_HMAC)
5135 s->maclist = buggymacs, s->nmacs = lenof(buggymacs);
5136 else
5137 s->maclist = macs, s->nmacs = lenof(macs);
5138
5139 begin_key_exchange:
149d2abc 5140 ssh->pkt_ctx &= ~SSH2_PKTCTX_KEX_MASK;
51470298 5141 {
e13bba36 5142 int i, j, commalist_started;
5143
51470298 5144 /*
83e7d008 5145 * Set up the preferred key exchange. (NULL => warn below here)
5146 */
5147 s->n_preferred_kex = 0;
5148 for (i = 0; i < KEX_MAX; i++) {
5149 switch (ssh->cfg.ssh_kexlist[i]) {
5150 case KEX_DHGEX:
5151 s->preferred_kex[s->n_preferred_kex++] =
5152 &ssh_diffiehellman_gex;
5153 break;
5154 case KEX_DHGROUP14:
5155 s->preferred_kex[s->n_preferred_kex++] =
5156 &ssh_diffiehellman_group14;
5157 break;
5158 case KEX_DHGROUP1:
5159 s->preferred_kex[s->n_preferred_kex++] =
5160 &ssh_diffiehellman_group1;
5161 break;
754c0df9 5162 case KEX_WARN:
83e7d008 5163 /* Flag for later. Don't bother if it's the last in
5164 * the list. */
5165 if (i < KEX_MAX - 1) {
5166 s->preferred_kex[s->n_preferred_kex++] = NULL;
5167 }
5168 break;
5169 }
5170 }
83e7d008 5171
83e7d008 5172 /*
51470298 5173 * Set up the preferred ciphers. (NULL => warn below here)
5174 */
5175 s->n_preferred_ciphers = 0;
5176 for (i = 0; i < CIPHER_MAX; i++) {
86916870 5177 switch (ssh->cfg.ssh_cipherlist[i]) {
51470298 5178 case CIPHER_BLOWFISH:
5179 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_blowfish;
5180 break;
5181 case CIPHER_DES:
86916870 5182 if (ssh->cfg.ssh2_des_cbc) {
51470298 5183 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_des;
5184 }
5185 break;
5186 case CIPHER_3DES:
5187 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_3des;
5188 break;
5189 case CIPHER_AES:
5190 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_aes;
5191 break;
a2add208 5192 case CIPHER_ARCFOUR:
5193 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_arcfour;
5194 break;
51470298 5195 case CIPHER_WARN:
5196 /* Flag for later. Don't bother if it's the last in
5197 * the list. */
5198 if (i < CIPHER_MAX - 1) {
5199 s->preferred_ciphers[s->n_preferred_ciphers++] = NULL;
5200 }
5201 break;
ca20bfcf 5202 }
ca20bfcf 5203 }
7591b9ff 5204
e13bba36 5205 /*
5206 * Set up preferred compression.
5207 */
5208 if (ssh->cfg.compression)
5209 s->preferred_comp = &ssh_zlib;
5210 else
5211 s->preferred_comp = &ssh_comp_none;
51470298 5212
5213 /*
590f6a5f 5214 * Enable queueing of outgoing auth- or connection-layer
5215 * packets while we are in the middle of a key exchange.
5216 */
5217 ssh->queueing = TRUE;
5218
5219 /*
9442dd57 5220 * Flag that KEX is in progress.
5221 */
5222 ssh->kex_in_progress = TRUE;
5223
5224 /*
51470298 5225 * Construct and send our key exchange packet.
5226 */
ff3187f6 5227 s->pktout = ssh2_pkt_init(SSH2_MSG_KEXINIT);
51470298 5228 for (i = 0; i < 16; i++)
ff3187f6 5229 ssh2_pkt_addbyte(s->pktout, (unsigned char) random_byte());
51470298 5230 /* List key exchange algorithms. */
ff3187f6 5231 ssh2_pkt_addstring_start(s->pktout);
83e7d008 5232 commalist_started = 0;
5233 for (i = 0; i < s->n_preferred_kex; i++) {
34557659 5234 const struct ssh_kexes *k = s->preferred_kex[i];
83e7d008 5235 if (!k) continue; /* warning flag */
34557659 5236 for (j = 0; j < k->nkexes; j++) {
5237 if (commalist_started)
5238 ssh2_pkt_addstring_str(s->pktout, ",");
5239 ssh2_pkt_addstring_str(s->pktout, k->list[j]->name);
5240 commalist_started = 1;
5241 }
32874aea 5242 }
51470298 5243 /* List server host key algorithms. */
ff3187f6 5244 ssh2_pkt_addstring_start(s->pktout);
51470298 5245 for (i = 0; i < lenof(hostkey_algs); i++) {
ff3187f6 5246 ssh2_pkt_addstring_str(s->pktout, hostkey_algs[i]->name);
51470298 5247 if (i < lenof(hostkey_algs) - 1)
ff3187f6 5248 ssh2_pkt_addstring_str(s->pktout, ",");
32874aea 5249 }
51470298 5250 /* List client->server encryption algorithms. */
ff3187f6 5251 ssh2_pkt_addstring_start(s->pktout);
83e7d008 5252 commalist_started = 0;
51470298 5253 for (i = 0; i < s->n_preferred_ciphers; i++) {
5254 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5255 if (!c) continue; /* warning flag */
5256 for (j = 0; j < c->nciphers; j++) {
83e7d008 5257 if (commalist_started)
ff3187f6 5258 ssh2_pkt_addstring_str(s->pktout, ",");
5259 ssh2_pkt_addstring_str(s->pktout, c->list[j]->name);
83e7d008 5260 commalist_started = 1;
51470298 5261 }
5262 }
5263 /* List server->client encryption algorithms. */
ff3187f6 5264 ssh2_pkt_addstring_start(s->pktout);
83e7d008 5265 commalist_started = 0;
51470298 5266 for (i = 0; i < s->n_preferred_ciphers; i++) {
5267 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5268 if (!c) continue; /* warning flag */
5269 for (j = 0; j < c->nciphers; j++) {
83e7d008 5270 if (commalist_started)
ff3187f6 5271 ssh2_pkt_addstring_str(s->pktout, ",");
5272 ssh2_pkt_addstring_str(s->pktout, c->list[j]->name);
83e7d008 5273 commalist_started = 1;
51470298 5274 }
5275 }
5276 /* List client->server MAC algorithms. */
ff3187f6 5277 ssh2_pkt_addstring_start(s->pktout);
51470298 5278 for (i = 0; i < s->nmacs; i++) {
ff3187f6 5279 ssh2_pkt_addstring_str(s->pktout, s->maclist[i]->name);
51470298 5280 if (i < s->nmacs - 1)
ff3187f6 5281 ssh2_pkt_addstring_str(s->pktout, ",");
51470298 5282 }
5283 /* List server->client MAC algorithms. */
ff3187f6 5284 ssh2_pkt_addstring_start(s->pktout);
51470298 5285 for (i = 0; i < s->nmacs; i++) {
ff3187f6 5286 ssh2_pkt_addstring_str(s->pktout, s->maclist[i]->name);
51470298 5287 if (i < s->nmacs - 1)
ff3187f6 5288 ssh2_pkt_addstring_str(s->pktout, ",");
51470298 5289 }
5290 /* List client->server compression algorithms. */
ff3187f6 5291 ssh2_pkt_addstring_start(s->pktout);
f6e0abe2 5292 assert(lenof(compressions) > 1);
ff3187f6 5293 ssh2_pkt_addstring_str(s->pktout, s->preferred_comp->name);
f6e0abe2 5294 for (i = 0; i < lenof(compressions); i++) {
5295 const struct ssh_compress *c = compressions[i];
5296 if (c != s->preferred_comp) {
ff3187f6 5297 ssh2_pkt_addstring_str(s->pktout, ",");
5298 ssh2_pkt_addstring_str(s->pktout, c->name);
f6e0abe2 5299 }
51470298 5300 }
5301 /* List server->client compression algorithms. */
ff3187f6 5302 ssh2_pkt_addstring_start(s->pktout);
f6e0abe2 5303 assert(lenof(compressions) > 1);
ff3187f6 5304 ssh2_pkt_addstring_str(s->pktout, s->preferred_comp->name);
f6e0abe2 5305 for (i = 0; i < lenof(compressions); i++) {
5306 const struct ssh_compress *c = compressions[i];
5307 if (c != s->preferred_comp) {
ff3187f6 5308 ssh2_pkt_addstring_str(s->pktout, ",");
5309 ssh2_pkt_addstring_str(s->pktout, c->name);
f6e0abe2 5310 }
51470298 5311 }
5312 /* List client->server languages. Empty list. */
ff3187f6 5313 ssh2_pkt_addstring_start(s->pktout);
51470298 5314 /* List server->client languages. Empty list. */
ff3187f6 5315 ssh2_pkt_addstring_start(s->pktout);
51470298 5316 /* First KEX packet does _not_ follow, because we're not that brave. */
ff3187f6 5317 ssh2_pkt_addbool(s->pktout, FALSE);
51470298 5318 /* Reserved. */
ff3187f6 5319 ssh2_pkt_adduint32(s->pktout, 0);
e5574168 5320 }
0db56f73 5321
3dc9a6a7 5322 s->our_kexinitlen = s->pktout->length - 5;
5323 s->our_kexinit = snewn(s->our_kexinitlen, unsigned char);
5324 memcpy(s->our_kexinit, s->pktout->data + 5, s->our_kexinitlen);
0db56f73 5325
590f6a5f 5326 ssh2_pkt_send_noqueue(ssh, s->pktout);
e5574168 5327
ff3187f6 5328 if (!pktin)
5329 crWaitUntil(pktin);
e5574168 5330
5331 /*
5332 * Now examine the other side's KEXINIT to see what we're up
5333 * to.
5334 */
51470298 5335 {
4763c1c2 5336 char *str, *preferred;
3d9449a1 5337 int i, j, len;
51470298 5338
ff3187f6 5339 if (pktin->type != SSH2_MSG_KEXINIT) {
6b5cf8b4 5340 bombout(("expected key exchange packet from server"));
7ffdbc1a 5341 crStop(0);
32874aea 5342 }
51470298 5343 ssh->kex = NULL;
5344 ssh->hostkey = NULL;
5345 s->cscipher_tobe = NULL;
5346 s->sccipher_tobe = NULL;
5347 s->csmac_tobe = NULL;
5348 s->scmac_tobe = NULL;
5349 s->cscomp_tobe = NULL;
5350 s->sccomp_tobe = NULL;
4763c1c2 5351 s->warn_kex = s->warn_cscipher = s->warn_sccipher = FALSE;
5352
ff3187f6 5353 pktin->savedpos += 16; /* skip garbage cookie */
5354 ssh_pkt_getstring(pktin, &str, &len); /* key exchange algorithms */
4763c1c2 5355
5356 preferred = NULL;
83e7d008 5357 for (i = 0; i < s->n_preferred_kex; i++) {
34557659 5358 const struct ssh_kexes *k = s->preferred_kex[i];
83e7d008 5359 if (!k) {
4763c1c2 5360 s->warn_kex = TRUE;
5361 } else {
34557659 5362 for (j = 0; j < k->nkexes; j++) {
5363 if (!preferred) preferred = k->list[j]->name;
5364 if (in_commasep_string(k->list[j]->name, str, len)) {
5365 ssh->kex = k->list[j];
5366 break;
5367 }
5368 }
83e7d008 5369 }
4763c1c2 5370 if (ssh->kex)
51470298 5371 break;
32874aea 5372 }
83e7d008 5373 if (!ssh->kex) {
5374 bombout(("Couldn't agree a key exchange algorithm (available: %s)",
5375 str ? str : "(null)"));
5376 crStop(0);
5377 }
b59743d5 5378 /*
5379 * Note that the server's guess is considered wrong if it doesn't match
5380 * the first algorithm in our list, even if it's still the algorithm
5381 * we end up using.
5382 */
4763c1c2 5383 s->guessok = first_in_commasep_string(preferred, str, len);
ff3187f6 5384 ssh_pkt_getstring(pktin, &str, &len); /* host key algorithms */
51470298 5385 for (i = 0; i < lenof(hostkey_algs); i++) {
5386 if (in_commasep_string(hostkey_algs[i]->name, str, len)) {
5387 ssh->hostkey = hostkey_algs[i];
5388 break;
5389 }
5390 }
3d9449a1 5391 s->guessok = s->guessok &&
b59743d5 5392 first_in_commasep_string(hostkey_algs[0]->name, str, len);
ff3187f6 5393 ssh_pkt_getstring(pktin, &str, &len); /* client->server cipher */
51470298 5394 for (i = 0; i < s->n_preferred_ciphers; i++) {
5395 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5396 if (!c) {
4763c1c2 5397 s->warn_cscipher = TRUE;
51470298 5398 } else {
5399 for (j = 0; j < c->nciphers; j++) {
5400 if (in_commasep_string(c->list[j]->name, str, len)) {
5401 s->cscipher_tobe = c->list[j];
5402 break;
5403 }
ca20bfcf 5404 }
32874aea 5405 }
4763c1c2 5406 if (s->cscipher_tobe)
51470298 5407 break;
32874aea 5408 }
51470298 5409 if (!s->cscipher_tobe) {
6b5cf8b4 5410 bombout(("Couldn't agree a client-to-server cipher (available: %s)",
57356d63 5411 str ? str : "(null)"));
7ffdbc1a 5412 crStop(0);
ca20bfcf 5413 }
0ef8f407 5414
ff3187f6 5415 ssh_pkt_getstring(pktin, &str, &len); /* server->client cipher */
51470298 5416 for (i = 0; i < s->n_preferred_ciphers; i++) {
5417 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5418 if (!c) {
4763c1c2 5419 s->warn_sccipher = TRUE;
51470298 5420 } else {
5421 for (j = 0; j < c->nciphers; j++) {
5422 if (in_commasep_string(c->list[j]->name, str, len)) {
5423 s->sccipher_tobe = c->list[j];
5424 break;
5425 }
ca20bfcf 5426 }
32874aea 5427 }
4763c1c2 5428 if (s->sccipher_tobe)
51470298 5429 break;
32874aea 5430 }
51470298 5431 if (!s->sccipher_tobe) {
6b5cf8b4 5432 bombout(("Couldn't agree a server-to-client cipher (available: %s)",
57356d63 5433 str ? str : "(null)"));
7ffdbc1a 5434 crStop(0);
ca20bfcf 5435 }
0ef8f407 5436
ff3187f6 5437 ssh_pkt_getstring(pktin, &str, &len); /* client->server mac */
51470298 5438 for (i = 0; i < s->nmacs; i++) {
5439 if (in_commasep_string(s->maclist[i]->name, str, len)) {
5440 s->csmac_tobe = s->maclist[i];
5441 break;
5442 }
32874aea 5443 }
ff3187f6 5444 ssh_pkt_getstring(pktin, &str, &len); /* server->client mac */
51470298 5445 for (i = 0; i < s->nmacs; i++) {
5446 if (in_commasep_string(s->maclist[i]->name, str, len)) {
5447 s->scmac_tobe = s->maclist[i];
5448 break;
5449 }
32874aea 5450 }
ff3187f6 5451 ssh_pkt_getstring(pktin, &str, &len); /* client->server compression */
51470298 5452 for (i = 0; i < lenof(compressions) + 1; i++) {
5453 const struct ssh_compress *c =
5454 i == 0 ? s->preferred_comp : compressions[i - 1];
5455 if (in_commasep_string(c->name, str, len)) {
5456 s->cscomp_tobe = c;
5457 break;
5458 }
32874aea 5459 }
ff3187f6 5460 ssh_pkt_getstring(pktin, &str, &len); /* server->client compression */
51470298 5461 for (i = 0; i < lenof(compressions) + 1; i++) {
5462 const struct ssh_compress *c =
5463 i == 0 ? s->preferred_comp : compressions[i - 1];
5464 if (in_commasep_string(c->name, str, len)) {
5465 s->sccomp_tobe = c;
5466 break;
5467 }
32874aea 5468 }
b59743d5 5469 ssh_pkt_getstring(pktin, &str, &len); /* client->server language */
5470 ssh_pkt_getstring(pktin, &str, &len); /* server->client language */
4763c1c2 5471 s->ignorepkt = ssh2_pkt_getbool(pktin) && !s->guessok;
5472
5473 if (s->warn_kex) {
5474 ssh_set_frozen(ssh, 1);
5475 s->dlgret = askalg(ssh->frontend, "key-exchange algorithm",
5476 ssh->kex->name,
5477 ssh_dialog_callback, ssh);
5478 if (s->dlgret < 0) {
5479 do {
5480 crReturn(0);
5481 if (pktin) {
5482 bombout(("Unexpected data from server while"
5483 " waiting for user response"));
5484 crStop(0);
5485 }
5486 } while (pktin || inlen > 0);
5487 s->dlgret = ssh->user_response;
5488 }
5489 ssh_set_frozen(ssh, 0);
5490 if (s->dlgret == 0) {
9e296bfa 5491 ssh_disconnect(ssh, "User aborted at kex warning", NULL,
5492 0, TRUE);
a5a6f839 5493 crStop(0);
4763c1c2 5494 }
5495 }
5496
5497 if (s->warn_cscipher) {
5498 ssh_set_frozen(ssh, 1);
5499 s->dlgret = askalg(ssh->frontend,
5500 "client-to-server cipher",
5501 s->cscipher_tobe->name,
5502 ssh_dialog_callback, ssh);
5503 if (s->dlgret < 0) {
5504 do {
5505 crReturn(0);
5506 if (pktin) {
5507 bombout(("Unexpected data from server while"
5508 " waiting for user response"));
5509 crStop(0);
5510 }
5511 } while (pktin || inlen > 0);
5512 s->dlgret = ssh->user_response;
5513 }
5514 ssh_set_frozen(ssh, 0);
5515 if (s->dlgret == 0) {
9e296bfa 5516 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
5517 0, TRUE);
a5a6f839 5518 crStop(0);
4763c1c2 5519 }
5520 }
5521
5522 if (s->warn_sccipher) {
5523 ssh_set_frozen(ssh, 1);
5524 s->dlgret = askalg(ssh->frontend,
5525 "server-to-client cipher",
5526 s->sccipher_tobe->name,
5527 ssh_dialog_callback, ssh);
5528 if (s->dlgret < 0) {
5529 do {
5530 crReturn(0);
5531 if (pktin) {
5532 bombout(("Unexpected data from server while"
5533 " waiting for user response"));
5534 crStop(0);
5535 }
5536 } while (pktin || inlen > 0);
5537 s->dlgret = ssh->user_response;
5538 }
5539 ssh_set_frozen(ssh, 0);
5540 if (s->dlgret == 0) {
9e296bfa 5541 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
5542 0, TRUE);
a5a6f839 5543 crStop(0);
4763c1c2 5544 }
5545 }
5546
b672f405 5547 ssh->exhash = ssh->kex->hash->init();
5548 hash_string(ssh->kex->hash, ssh->exhash, ssh->v_c, strlen(ssh->v_c));
5549 hash_string(ssh->kex->hash, ssh->exhash, ssh->v_s, strlen(ssh->v_s));
5550 hash_string(ssh->kex->hash, ssh->exhash,
5551 s->our_kexinit, s->our_kexinitlen);
3dc9a6a7 5552 sfree(s->our_kexinit);
5553 if (pktin->length > 5)
b672f405 5554 hash_string(ssh->kex->hash, ssh->exhash,
5555 pktin->data + 5, pktin->length - 5);
3dc9a6a7 5556
4763c1c2 5557 if (s->ignorepkt) /* first_kex_packet_follows */
b59743d5 5558 crWaitUntil(pktin); /* Ignore packet */
e5574168 5559 }
e5574168 5560
5561 /*
7bd5a860 5562 * Work out the number of bits of key we will need from the key
5563 * exchange. We start with the maximum key length of either
5564 * cipher...
5565 */
5566 {
32874aea 5567 int csbits, scbits;
7bd5a860 5568
51470298 5569 csbits = s->cscipher_tobe->keylen;
5570 scbits = s->sccipher_tobe->keylen;
5571 s->nbits = (csbits > scbits ? csbits : scbits);
7bd5a860 5572 }
b672f405 5573 /* The keys only have hlen-bit entropy, since they're based on
5574 * a hash. So cap the key size at hlen bits. */
5575 if (s->nbits > ssh->kex->hash->hlen * 8)
5576 s->nbits = ssh->kex->hash->hlen * 8;
7bd5a860 5577
5578 /*
a92dd380 5579 * If we're doing Diffie-Hellman group exchange, start by
5580 * requesting a group.
e5574168 5581 */
d1aaf71d 5582 if (!ssh->kex->pdata) {
32874aea 5583 logevent("Doing Diffie-Hellman group exchange");
51470298 5584 ssh->pkt_ctx |= SSH2_PKTCTX_DHGEX;
32874aea 5585 /*
5586 * Work out how big a DH group we will need to allow that
5587 * much data.
7bd5a860 5588 */
51470298 5589 s->pbits = 512 << ((s->nbits - 1) / 64);
ff3187f6 5590 s->pktout = ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
5591 ssh2_pkt_adduint32(s->pktout, s->pbits);
590f6a5f 5592 ssh2_pkt_send_noqueue(ssh, s->pktout);
32874aea 5593
ff3187f6 5594 crWaitUntil(pktin);
5595 if (pktin->type != SSH2_MSG_KEX_DH_GEX_GROUP) {
6b5cf8b4 5596 bombout(("expected key exchange group packet from server"));
7ffdbc1a 5597 crStop(0);
32874aea 5598 }
ff3187f6 5599 s->p = ssh2_pkt_getmp(pktin);
5600 s->g = ssh2_pkt_getmp(pktin);
5601 if (!s->p || !s->g) {
5602 bombout(("unable to read mp-ints from incoming group packet"));
5603 crStop(0);
5604 }
d1aaf71d 5605 ssh->kex_ctx = dh_setup_gex(s->p, s->g);
51470298 5606 s->kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
5607 s->kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
a92dd380 5608 } else {
d1aaf71d 5609 ssh->pkt_ctx |= SSH2_PKTCTX_DHGROUP;
5610 ssh->kex_ctx = dh_setup_group(ssh->kex);
51470298 5611 s->kex_init_value = SSH2_MSG_KEXDH_INIT;
5612 s->kex_reply_value = SSH2_MSG_KEXDH_REPLY;
d1aaf71d 5613 logeventf(ssh, "Using Diffie-Hellman with standard group \"%s\"",
5614 ssh->kex->groupname);
8d5de777 5615 }
e5574168 5616
c6daaa1a 5617 logeventf(ssh, "Doing Diffie-Hellman key exchange with hash %s",
5618 ssh->kex->hash->text_name);
e5574168 5619 /*
a92dd380 5620 * Now generate and send e for Diffie-Hellman.
e5574168 5621 */
755e0524 5622 set_busy_status(ssh->frontend, BUSY_CPU); /* this can take a while */
27cd7fc2 5623 s->e = dh_create_e(ssh->kex_ctx, s->nbits * 2);
ff3187f6 5624 s->pktout = ssh2_pkt_init(s->kex_init_value);
5625 ssh2_pkt_addmp(s->pktout, s->e);
590f6a5f 5626 ssh2_pkt_send_noqueue(ssh, s->pktout);
e5574168 5627
755e0524 5628 set_busy_status(ssh->frontend, BUSY_WAITING); /* wait for server */
ff3187f6 5629 crWaitUntil(pktin);
5630 if (pktin->type != s->kex_reply_value) {
6b5cf8b4 5631 bombout(("expected key exchange reply packet from server"));
7ffdbc1a 5632 crStop(0);
7cca0d81 5633 }
755e0524 5634 set_busy_status(ssh->frontend, BUSY_CPU); /* cogitate */
ff3187f6 5635 ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
5636 s->f = ssh2_pkt_getmp(pktin);
5637 if (!s->f) {
5638 bombout(("unable to parse key exchange reply packet"));
5639 crStop(0);
5640 }
5641 ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
e5574168 5642
27cd7fc2 5643 s->K = dh_find_K(ssh->kex_ctx, s->f);
e5574168 5644
755e0524 5645 /* We assume everything from now on will be quick, and it might
5646 * involve user interaction. */
5647 set_busy_status(ssh->frontend, BUSY_NOT);
5648
b672f405 5649 hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen);
34557659 5650 if (!ssh->kex->pdata) {
b672f405 5651 hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits);
5652 hash_mpint(ssh->kex->hash, ssh->exhash, s->p);
5653 hash_mpint(ssh->kex->hash, ssh->exhash, s->g);
a92dd380 5654 }
b672f405 5655 hash_mpint(ssh->kex->hash, ssh->exhash, s->e);
5656 hash_mpint(ssh->kex->hash, ssh->exhash, s->f);
5657 hash_mpint(ssh->kex->hash, ssh->exhash, s->K);
5658 assert(ssh->kex->hash->hlen <= sizeof(s->exchange_hash));
5659 ssh->kex->hash->final(ssh->exhash, s->exchange_hash);
e5574168 5660
27cd7fc2 5661 dh_cleanup(ssh->kex_ctx);
fabd1805 5662 ssh->kex_ctx = NULL;
3709bfe9 5663
7cca0d81 5664#if 0
765c4200 5665 debug(("Exchange hash is:\n"));
b672f405 5666 dmemdump(s->exchange_hash, ssh->kex->hash->hlen);
7cca0d81 5667#endif
5668
51470298 5669 s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
5670 if (!s->hkey ||
5671 !ssh->hostkey->verifysig(s->hkey, s->sigdata, s->siglen,
b672f405 5672 (char *)s->exchange_hash,
5673 ssh->kex->hash->hlen)) {
6b5cf8b4 5674 bombout(("Server's host key did not match the signature supplied"));
7ffdbc1a 5675 crStop(0);
8d5de777 5676 }
e5574168 5677
5678 /*
7cca0d81 5679 * Authenticate remote host: verify host key. (We've already
5680 * checked the signature of the exchange hash.)
e5574168 5681 */
51470298 5682 s->keystr = ssh->hostkey->fmtkey(s->hkey);
5683 s->fingerprint = ssh->hostkey->fingerprint(s->hkey);
3d9449a1 5684 ssh_set_frozen(ssh, 1);
5685 s->dlgret = verify_ssh_host_key(ssh->frontend,
5686 ssh->savedhost, ssh->savedport,
5687 ssh->hostkey->keytype, s->keystr,
5688 s->fingerprint,
5689 ssh_dialog_callback, ssh);
5690 if (s->dlgret < 0) {
5691 do {
5692 crReturn(0);
5693 if (pktin) {
5694 bombout(("Unexpected data from server while waiting"
5695 " for user host key response"));
5696 crStop(0);
5697 }
5698 } while (pktin || inlen > 0);
5699 s->dlgret = ssh->user_response;
5700 }
5701 ssh_set_frozen(ssh, 0);
5702 if (s->dlgret == 0) {
9e296bfa 5703 ssh_disconnect(ssh, "User aborted at host key verification", NULL,
5704 0, TRUE);
3d9449a1 5705 crStop(0);
5706 }
e13bba36 5707 if (!s->got_session_id) { /* don't bother logging this in rekeys */
5e0d7cb8 5708 logevent("Host key fingerprint is:");
51470298 5709 logevent(s->fingerprint);
5e0d7cb8 5710 }
51470298 5711 sfree(s->fingerprint);
5712 sfree(s->keystr);
5713 ssh->hostkey->freekey(s->hkey);
d39f364a 5714
5715 /*
9442dd57 5716 * The exchange hash from the very first key exchange is also
5717 * the session id, used in session key construction and
5718 * authentication.
5719 */
e13bba36 5720 if (!s->got_session_id) {
b672f405 5721 assert(sizeof(s->exchange_hash) <= sizeof(ssh->v2_session_id));
9442dd57 5722 memcpy(ssh->v2_session_id, s->exchange_hash,
5723 sizeof(s->exchange_hash));
b672f405 5724 ssh->v2_session_id_len = ssh->kex->hash->hlen;
6052bb76 5725 assert(ssh->v2_session_id_len <= sizeof(ssh->v2_session_id));
e13bba36 5726 s->got_session_id = TRUE;
5727 }
9442dd57 5728
5729 /*
7cca0d81 5730 * Send SSH2_MSG_NEWKEYS.
d39f364a 5731 */
ff3187f6 5732 s->pktout = ssh2_pkt_init(SSH2_MSG_NEWKEYS);
590f6a5f 5733 ssh2_pkt_send_noqueue(ssh, s->pktout);
9442dd57 5734 ssh->outgoing_data_size = 0; /* start counting from here */
5735
5736 /*
5737 * We've sent client NEWKEYS, so create and initialise
c64fe7d4 5738 * client-to-server session keys.
9442dd57 5739 */
5740 if (ssh->cs_cipher_ctx)
5741 ssh->cscipher->free_context(ssh->cs_cipher_ctx);
5742 ssh->cscipher = s->cscipher_tobe;
5743 ssh->cs_cipher_ctx = ssh->cscipher->make_context();
5744
5745 if (ssh->cs_mac_ctx)
5746 ssh->csmac->free_context(ssh->cs_mac_ctx);
5747 ssh->csmac = s->csmac_tobe;
5748 ssh->cs_mac_ctx = ssh->csmac->make_context();
5749
5750 if (ssh->cs_comp_ctx)
5751 ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
5752 ssh->cscomp = s->cscomp_tobe;
5753 ssh->cs_comp_ctx = ssh->cscomp->compress_init();
5754
5755 /*
5756 * Set IVs on client-to-server keys. Here we use the exchange
5757 * hash from the _first_ key exchange.
5758 */
5759 {
754c0df9 5760 unsigned char keyspace[SSH2_KEX_MAX_HASH_LEN * SSH2_MKKEY_ITERS];
5761 assert(sizeof(keyspace) >= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
b672f405 5762 ssh2_mkkey(ssh,s->K,s->exchange_hash,'C',keyspace);
754c0df9 5763 assert((ssh->cscipher->keylen+7) / 8 <=
5764 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
9442dd57 5765 ssh->cscipher->setkey(ssh->cs_cipher_ctx, keyspace);
b672f405 5766 ssh2_mkkey(ssh,s->K,s->exchange_hash,'A',keyspace);
754c0df9 5767 assert(ssh->cscipher->blksize <=
5768 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
9442dd57 5769 ssh->cscipher->setiv(ssh->cs_cipher_ctx, keyspace);
b672f405 5770 ssh2_mkkey(ssh,s->K,s->exchange_hash,'E',keyspace);
754c0df9 5771 assert(ssh->csmac->len <=
5772 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
9442dd57 5773 ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace);
754c0df9 5774 memset(keyspace, 0, sizeof(keyspace));
9442dd57 5775 }
5776
5777 logeventf(ssh, "Initialised %.200s client->server encryption",
5778 ssh->cscipher->text_name);
5779 logeventf(ssh, "Initialised %.200s client->server MAC algorithm",
5780 ssh->csmac->text_name);
5781 if (ssh->cscomp->text_name)
5782 logeventf(ssh, "Initialised %s compression",
5783 ssh->cscomp->text_name);
590f6a5f 5784
5785 /*
5786 * Now our end of the key exchange is complete, we can send all
5787 * our queued higher-layer packets.
5788 */
5789 ssh->queueing = FALSE;
5790 ssh2_pkt_queuesend(ssh);
d39f364a 5791
5792 /*
8406eaf9 5793 * Expect SSH2_MSG_NEWKEYS from server.
5794 */
ff3187f6 5795 crWaitUntil(pktin);
5796 if (pktin->type != SSH2_MSG_NEWKEYS) {
6b5cf8b4 5797 bombout(("expected new-keys packet from server"));
7ffdbc1a 5798 crStop(0);
8406eaf9 5799 }
9442dd57 5800 ssh->incoming_data_size = 0; /* start counting from here */
8406eaf9 5801
5802 /*
9442dd57 5803 * We've seen server NEWKEYS, so create and initialise
5804 * server-to-client session keys.
d39f364a 5805 */
371e569c 5806 if (ssh->sc_cipher_ctx)
5807 ssh->sccipher->free_context(ssh->sc_cipher_ctx);
51470298 5808 ssh->sccipher = s->sccipher_tobe;
371e569c 5809 ssh->sc_cipher_ctx = ssh->sccipher->make_context();
e0e1a00d 5810
e0e1a00d 5811 if (ssh->sc_mac_ctx)
5812 ssh->scmac->free_context(ssh->sc_mac_ctx);
51470298 5813 ssh->scmac = s->scmac_tobe;
e0e1a00d 5814 ssh->sc_mac_ctx = ssh->scmac->make_context();
5815
5366aed8 5816 if (ssh->sc_comp_ctx)
5817 ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
51470298 5818 ssh->sccomp = s->sccomp_tobe;
5366aed8 5819 ssh->sc_comp_ctx = ssh->sccomp->decompress_init();
5820
d39f364a 5821 /*
9442dd57 5822 * Set IVs on server-to-client keys. Here we use the exchange
5823 * hash from the _first_ key exchange.
d39f364a 5824 */
51470298 5825 {
754c0df9 5826 unsigned char keyspace[SSH2_KEX_MAX_HASH_LEN * SSH2_MKKEY_ITERS];
5827 assert(sizeof(keyspace) >= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
b672f405 5828 ssh2_mkkey(ssh,s->K,s->exchange_hash,'D',keyspace);
754c0df9 5829 assert((ssh->sccipher->keylen+7) / 8 <=
5830 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
371e569c 5831 ssh->sccipher->setkey(ssh->sc_cipher_ctx, keyspace);
b672f405 5832 ssh2_mkkey(ssh,s->K,s->exchange_hash,'B',keyspace);
754c0df9 5833 assert(ssh->sccipher->blksize <=
5834 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
371e569c 5835 ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace);
b672f405 5836 ssh2_mkkey(ssh,s->K,s->exchange_hash,'F',keyspace);
754c0df9 5837 assert(ssh->scmac->len <=
5838 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
e0e1a00d 5839 ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace);
754c0df9 5840 memset(keyspace, 0, sizeof(keyspace));
51470298 5841 }
57356d63 5842 logeventf(ssh, "Initialised %.200s server->client encryption",
5843 ssh->sccipher->text_name);
6c135243 5844 logeventf(ssh, "Initialised %.200s server->client MAC algorithm",
5845 ssh->scmac->text_name);
57356d63 5846 if (ssh->sccomp->text_name)
5847 logeventf(ssh, "Initialised %s decompression",
5848 ssh->sccomp->text_name);
9442dd57 5849
5850 /*
5851 * Free key exchange data.
5852 */
679539d7 5853 freebn(s->f);
679539d7 5854 freebn(s->K);
34557659 5855 if (!ssh->kex->pdata) {
b3949e7e 5856 freebn(s->g);
5857 freebn(s->p);
5858 }
d39f364a 5859
033b4cef 5860 /*
e13bba36 5861 * Key exchange is over. Loop straight back round if we have a
5862 * deferred rekey reason.
5863 */
5864 if (ssh->deferred_rekey_reason) {
5865 logevent(ssh->deferred_rekey_reason);
5866 pktin = NULL;
5867 ssh->deferred_rekey_reason = NULL;
5868 goto begin_key_exchange;
5869 }
5870
5871 /*
5872 * Otherwise, schedule a timer for our next rekey.
9442dd57 5873 */
5874 ssh->kex_in_progress = FALSE;
e6c1536e 5875 ssh->last_rekey = GETTICKCOUNT();
d57f70af 5876 if (ssh->cfg.ssh_rekey_time != 0)
5877 ssh->next_rekey = schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
5878 ssh2_timer, ssh);
e13bba36 5879
9442dd57 5880 /*
0db56f73 5881 * If this is the first key exchange phase, we must pass the
5882 * SSH2_MSG_NEWKEYS packet to the next layer, not because it
5883 * wants to see it but because it will need time to initialise
5884 * itself before it sees an actual packet. In subsequent key
5885 * exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
5886 * it would only confuse the layer above.
5887 */
e13bba36 5888 if (s->activated_authconn) {
0e3607ed 5889 crReturn(0);
0db56f73 5890 }
e13bba36 5891 s->activated_authconn = TRUE;
0db56f73 5892
5893 /*
7cca0d81 5894 * Now we're encrypting. Begin returning 1 to the protocol main
5895 * function so that other things can run on top of the
5896 * transport. If we ever see a KEXINIT, we must go back to the
5897 * start.
9442dd57 5898 *
5899 * We _also_ go back to the start if we see pktin==NULL and
5900 * inlen==-1, because this is a special signal meaning
5901 * `initiate client-driven rekey', and `in' contains a message
5902 * giving the reason for the rekey.
033b4cef 5903 */
9442dd57 5904 while (!((pktin && pktin->type == SSH2_MSG_KEXINIT) ||
5905 (!pktin && inlen == -1))) {
f382c87d 5906 wait_for_rekey:
32874aea 5907 crReturn(1);
e96adf72 5908 }
9442dd57 5909 if (pktin) {
5910 logevent("Server initiated key re-exchange");
5911 } else {
f382c87d 5912 /*
5913 * Special case: if the server bug is set that doesn't
5914 * allow rekeying, we give a different log message and
5915 * continue waiting. (If such a server _initiates_ a rekey,
5916 * we process it anyway!)
5917 */
5918 if ((ssh->remote_bugs & BUG_SSH2_REKEY)) {
5919 logeventf(ssh, "Server bug prevents key re-exchange (%s)",
5920 (char *)in);
5921 /* Reset the counters, so that at least this message doesn't
5922 * hit the event log _too_ often. */
5923 ssh->outgoing_data_size = 0;
5924 ssh->incoming_data_size = 0;
5925 if (ssh->cfg.ssh_rekey_time != 0) {
5926 ssh->next_rekey =
5927 schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
5928 ssh2_timer, ssh);
5929 }
5930 goto wait_for_rekey; /* this is utterly horrid */
5931 } else {
5932 logeventf(ssh, "Initiating key re-exchange (%s)", (char *)in);
f382c87d 5933 }
9442dd57 5934 }
7cca0d81 5935 goto begin_key_exchange;
e5574168 5936
5937 crFinish(1);
5938}
5939
7cca0d81 5940/*
2e85c969 5941 * Add data to an SSH-2 channel output buffer.
783415f8 5942 */
32874aea 5943static void ssh2_add_channel_data(struct ssh_channel *c, char *buf,
5944 int len)
5945{
5471d09a 5946 bufchain_add(&c->v.v2.outbuffer, buf, len);
783415f8 5947}
5948
5949/*
2e85c969 5950 * Attempt to send data on an SSH-2 channel.
783415f8 5951 */
5471d09a 5952static int ssh2_try_send(struct ssh_channel *c)
32874aea 5953{
51470298 5954 Ssh ssh = c->ssh;
ff3187f6 5955 struct Packet *pktout;
51470298 5956
5471d09a 5957 while (c->v.v2.remwindow > 0 && bufchain_size(&c->v.v2.outbuffer) > 0) {
5958 int len;
5959 void *data;
5960 bufchain_prefix(&c->v.v2.outbuffer, &data, &len);
5961 if ((unsigned)len > c->v.v2.remwindow)
5962 len = c->v.v2.remwindow;
5963 if ((unsigned)len > c->v.v2.remmaxpkt)
5964 len = c->v.v2.remmaxpkt;
ff3187f6 5965 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
5966 ssh2_pkt_adduint32(pktout, c->remoteid);
5967 dont_log_data(ssh, pktout, PKTLOG_OMIT);
5968 ssh2_pkt_addstring_start(pktout);
5969 ssh2_pkt_addstring_data(pktout, data, len);
5970 end_log_omission(ssh, pktout);
5971 ssh2_pkt_send(ssh, pktout);
5471d09a 5972 bufchain_consume(&c->v.v2.outbuffer, len);
5973 c->v.v2.remwindow -= len;
5974 }
5975
5976 /*
5977 * After having sent as much data as we can, return the amount
5978 * still buffered.
5979 */
5980 return bufchain_size(&c->v.v2.outbuffer);
5981}
5982
1bfc7e93 5983static void ssh2_try_send_and_unthrottle(struct ssh_channel *c)
5984{
5985 int bufsize;
5986 if (c->closes)
5987 return; /* don't send on closing channels */
5988 bufsize = ssh2_try_send(c);
5989 if (bufsize == 0) {
5990 switch (c->type) {
5991 case CHAN_MAINSESSION:
5992 /* stdin need not receive an unthrottle
5993 * notification since it will be polled */
5994 break;
5995 case CHAN_X11:
5996 x11_unthrottle(c->u.x11.s);
5997 break;
5998 case CHAN_AGENT:
5999 /* agent sockets are request/response and need no
6000 * buffer management */
6001 break;
6002 case CHAN_SOCKDATA:
6003 pfd_unthrottle(c->u.pfd.s);
6004 break;
6005 }
6006 }
6007}
6008
5471d09a 6009/*
2e85c969 6010 * Potentially enlarge the window on an SSH-2 channel.
5471d09a 6011 */
6012static void ssh2_set_window(struct ssh_channel *c, unsigned newwin)
6013{
51470298 6014 Ssh ssh = c->ssh;
6015
6b69f42e 6016 /*
6017 * Never send WINDOW_ADJUST for a channel that the remote side
6018 * already thinks it's closed; there's no point, since it won't
6019 * be sending any more data anyway.
6020 */
6021 if (c->closes != 0)
6022 return;
6023
d252310a 6024 /*
6025 * Only send a WINDOW_ADJUST if there's significantly more window
6026 * available than the other end thinks there is. This saves us
6027 * sending a WINDOW_ADJUST for every character in a shell session.
6028 *
6029 * "Significant" is arbitrarily defined as half the window size.
6030 */
6031 if (newwin > c->v.v2.locwindow * 2) {
ff3187f6 6032 struct Packet *pktout;
6033
6034 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
6035 ssh2_pkt_adduint32(pktout, c->remoteid);
6036 ssh2_pkt_adduint32(pktout, newwin - c->v.v2.locwindow);
6037 ssh2_pkt_send(ssh, pktout);
5471d09a 6038 c->v.v2.locwindow = newwin;
783415f8 6039 }
6040}
6041
51df0ab5 6042static void ssh2_msg_channel_window_adjust(Ssh ssh, struct Packet *pktin)
b09eaa88 6043{
6044 unsigned i = ssh_pkt_getuint32(pktin);
6045 struct ssh_channel *c;
6046 c = find234(ssh->channels, &i, ssh_channelfind);
1bfc7e93 6047 if (c && !c->closes) {
b09eaa88 6048 c->v.v2.remwindow += ssh_pkt_getuint32(pktin);
1bfc7e93 6049 ssh2_try_send_and_unthrottle(c);
6050 }
b09eaa88 6051}
6052
51df0ab5 6053static void ssh2_msg_channel_data(Ssh ssh, struct Packet *pktin)
6054{
6055 char *data;
6d44acc9 6056 int length;
51df0ab5 6057 unsigned i = ssh_pkt_getuint32(pktin);
6058 struct ssh_channel *c;
6059 c = find234(ssh->channels, &i, ssh_channelfind);
6060 if (!c)
6061 return; /* nonexistent channel */
6062 if (pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
6063 ssh_pkt_getuint32(pktin) != SSH2_EXTENDED_DATA_STDERR)
6064 return; /* extended but not stderr */
6065 ssh_pkt_getstring(pktin, &data, &length);
6066 if (data) {
6067 int bufsize = 0;
6068 c->v.v2.locwindow -= length;
6069 switch (c->type) {
6070 case CHAN_MAINSESSION:
6071 bufsize =
6072 from_backend(ssh->frontend, pktin->type ==
6073 SSH2_MSG_CHANNEL_EXTENDED_DATA,
6074 data, length);
6075 break;
6076 case CHAN_X11:
6077 bufsize = x11_send(c->u.x11.s, data, length);
6078 break;
6079 case CHAN_SOCKDATA:
6080 bufsize = pfd_send(c->u.pfd.s, data, length);
6081 break;
6082 case CHAN_AGENT:
6083 while (length > 0) {
6084 if (c->u.a.lensofar < 4) {
62ddb51e 6085 unsigned int l = min(4 - c->u.a.lensofar,
6086 (unsigned)length);
51df0ab5 6087 memcpy(c->u.a.msglen + c->u.a.lensofar,
6088 data, l);
6089 data += l;
6090 length -= l;
6091 c->u.a.lensofar += l;
6092 }
6093 if (c->u.a.lensofar == 4) {
6094 c->u.a.totallen =
6095 4 + GET_32BIT(c->u.a.msglen);
6096 c->u.a.message = snewn(c->u.a.totallen,
6097 unsigned char);
6098 memcpy(c->u.a.message, c->u.a.msglen, 4);
6099 }
6100 if (c->u.a.lensofar >= 4 && length > 0) {
aa63ab7e 6101 unsigned int l =
51df0ab5 6102 min(c->u.a.totallen - c->u.a.lensofar,
62ddb51e 6103 (unsigned)length);
51df0ab5 6104 memcpy(c->u.a.message + c->u.a.lensofar,
6105 data, l);
6106 data += l;
6107 length -= l;
6108 c->u.a.lensofar += l;
6109 }
6110 if (c->u.a.lensofar == c->u.a.totallen) {
6111 void *reply;
6112 int replylen;
6113 if (agent_query(c->u.a.message,
6114 c->u.a.totallen,
6115 &reply, &replylen,
6116 ssh_agentf_callback, c))
6117 ssh_agentf_callback(c, reply, replylen);
6118 sfree(c->u.a.message);
6119 c->u.a.lensofar = 0;
6120 }
6121 }
6122 bufsize = 0;
6123 break;
6124 }
6125 /*
6126 * If we are not buffering too much data,
6127 * enlarge the window again at the remote side.
6128 */
6129 if (bufsize < OUR_V2_WINSIZE)
6130 ssh2_set_window(c, OUR_V2_WINSIZE - bufsize);
6131 }
6132}
6133
6134static void ssh2_msg_channel_eof(Ssh ssh, struct Packet *pktin)
6135{
6136 unsigned i = ssh_pkt_getuint32(pktin);
6137 struct ssh_channel *c;
6138
6139 c = find234(ssh->channels, &i, ssh_channelfind);
6140 if (!c)
6141 return; /* nonexistent channel */
6142
6143 if (c->type == CHAN_X11) {
6144 /*
6145 * Remote EOF on an X11 channel means we should
6146 * wrap up and close the channel ourselves.
6147 */
6148 x11_close(c->u.x11.s);
6149 sshfwd_close(c);
6150 } else if (c->type == CHAN_AGENT) {
6151 sshfwd_close(c);
6152 } else if (c->type == CHAN_SOCKDATA) {
6153 pfd_close(c->u.pfd.s);
6154 sshfwd_close(c);
6155 }
6156}
6157
6158static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
6159{
6160 unsigned i = ssh_pkt_getuint32(pktin);
6161 struct ssh_channel *c;
6162 struct Packet *pktout;
6163
6164 c = find234(ssh->channels, &i, ssh_channelfind);
64d6ff88 6165 if (!c || c->halfopen) {
51df0ab5 6166 bombout(("Received CHANNEL_CLOSE for %s channel %d\n",
6167 c ? "half-open" : "nonexistent", i));
6168 return;
6169 }
6170 /* Do pre-close processing on the channel. */
6171 switch (c->type) {
6172 case CHAN_MAINSESSION:
6173 ssh->mainchan = NULL;
6174 update_specials_menu(ssh->frontend);
6175 break;
6176 case CHAN_X11:
6177 if (c->u.x11.s != NULL)
6178 x11_close(c->u.x11.s);
6179 sshfwd_close(c);
6180 break;
6181 case CHAN_AGENT:
6182 sshfwd_close(c);
6183 break;
6184 case CHAN_SOCKDATA:
6185 if (c->u.pfd.s != NULL)
6186 pfd_close(c->u.pfd.s);
6187 sshfwd_close(c);
6188 break;
6189 }
6190 if (c->closes == 0) {
6191 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6192 ssh2_pkt_adduint32(pktout, c->remoteid);
6193 ssh2_pkt_send(ssh, pktout);
6194 }
6195 del234(ssh->channels, c);
6196 bufchain_clear(&c->v.v2.outbuffer);
6197 sfree(c);
6198
6199 /*
6200 * See if that was the last channel left open.
6201 * (This is only our termination condition if we're
6202 * not running in -N mode.)
6203 */
6204 if (!ssh->cfg.ssh_no_shell && count234(ssh->channels) == 0) {
51df0ab5 6205 /*
6206 * We used to send SSH_MSG_DISCONNECT here,
6207 * because I'd believed that _every_ conforming
2e85c969 6208 * SSH-2 connection had to end with a disconnect
51df0ab5 6209 * being sent by at least one side; apparently
6210 * I was wrong and it's perfectly OK to
6211 * unceremoniously slam the connection shut
6212 * when you're done, and indeed OpenSSH feels
6213 * this is more polite than sending a
6214 * DISCONNECT. So now we don't.
6215 */
9e296bfa 6216 ssh_disconnect(ssh, "All channels closed", NULL, 0, TRUE);
51df0ab5 6217 }
6218}
6219
6220static void ssh2_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
6221{
6222 unsigned i = ssh_pkt_getuint32(pktin);
6223 struct ssh_channel *c;
6224 struct Packet *pktout;
6225
6226 c = find234(ssh->channels, &i, ssh_channelfind);
6227 if (!c)
6228 return; /* nonexistent channel */
6229 if (c->type != CHAN_SOCKDATA_DORMANT)
6230 return; /* dunno why they're confirming this */
6231 c->remoteid = ssh_pkt_getuint32(pktin);
64d6ff88 6232 c->halfopen = FALSE;
51df0ab5 6233 c->type = CHAN_SOCKDATA;
6234 c->v.v2.remwindow = ssh_pkt_getuint32(pktin);
6235 c->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
6236 if (c->u.pfd.s)
6237 pfd_confirm(c->u.pfd.s);
6238 if (c->closes) {
6239 /*
6240 * We have a pending close on this channel,
6241 * which we decided on before the server acked
6242 * the channel open. So now we know the
6243 * remoteid, we can close it again.
6244 */
6245 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6246 ssh2_pkt_adduint32(pktout, c->remoteid);
6247 ssh2_pkt_send(ssh, pktout);
6248 }
6249}
6250
6251static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
6252{
6253 static const char *const reasons[] = {
6254 "<unknown reason code>",
6255 "Administratively prohibited",
6256 "Connect failed",
6257 "Unknown channel type",
6258 "Resource shortage",
6259 };
6260 unsigned i = ssh_pkt_getuint32(pktin);
6261 unsigned reason_code;
6262 char *reason_string;
6263 int reason_length;
51df0ab5 6264 struct ssh_channel *c;
6265 c = find234(ssh->channels, &i, ssh_channelfind);
6266 if (!c)
6267 return; /* nonexistent channel */
6268 if (c->type != CHAN_SOCKDATA_DORMANT)
6269 return; /* dunno why they're failing this */
6270
6271 reason_code = ssh_pkt_getuint32(pktin);
6272 if (reason_code >= lenof(reasons))
6273 reason_code = 0; /* ensure reasons[reason_code] in range */
6274 ssh_pkt_getstring(pktin, &reason_string, &reason_length);
fb983202 6275 logeventf(ssh, "Forwarded connection refused by server: %s [%.*s]",
6276 reasons[reason_code], reason_length, reason_string);
51df0ab5 6277
6278 pfd_close(c->u.pfd.s);
6279
6280 del234(ssh->channels, c);
6281 sfree(c);
6282}
6283
6284static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin)
6285{
6286 unsigned localid;
6287 char *type;
6288 int typelen, want_reply;
6289 int reply = SSH2_MSG_CHANNEL_FAILURE; /* default */
6290 struct ssh_channel *c;
6291 struct Packet *pktout;
6292
6293 localid = ssh_pkt_getuint32(pktin);
6294 ssh_pkt_getstring(pktin, &type, &typelen);
6295 want_reply = ssh2_pkt_getbool(pktin);
6296
6297 /*
6298 * First, check that the channel exists. Otherwise,
6299 * we can instantly disconnect with a rude message.
6300 */
6301 c = find234(ssh->channels, &localid, ssh_channelfind);
6302 if (!c) {
9e296bfa 6303 char *buf = dupprintf("Received channel request for nonexistent"
6304 " channel %d", localid);
6305 ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6306 sfree(buf);
51df0ab5 6307 return;
6308 }
6309
6310 /*
6311 * Having got the channel number, we now look at
6312 * the request type string to see if it's something
6313 * we recognise.
6314 */
6315 if (c == ssh->mainchan) {
6316 /*
6317 * We recognise "exit-status" and "exit-signal" on
6318 * the primary channel.
6319 */
6320 if (typelen == 11 &&
6321 !memcmp(type, "exit-status", 11)) {
6322
6323 ssh->exitcode = ssh_pkt_getuint32(pktin);
6324 logeventf(ssh, "Server sent command exit status %d",
6325 ssh->exitcode);
6326 reply = SSH2_MSG_CHANNEL_SUCCESS;
6327
6328 } else if (typelen == 11 &&
6329 !memcmp(type, "exit-signal", 11)) {
6330
6331 int is_plausible = TRUE, is_int = FALSE;
6332 char *fmt_sig = "", *fmt_msg = "";
6333 char *msg;
6334 int msglen = 0, core = FALSE;
6335 /* ICK: older versions of OpenSSH (e.g. 3.4p1)
6336 * provide an `int' for the signal, despite its
6337 * having been a `string' in the drafts since at
6338 * least 2001. (Fixed in session.c 1.147.) Try to
6339 * infer which we can safely parse it as. */
6340 {
6341 unsigned char *p = pktin->body +
6342 pktin->savedpos;
6343 long len = pktin->length - pktin->savedpos;
6344 unsigned long num = GET_32BIT(p); /* what is it? */
6345 /* If it's 0, it hardly matters; assume string */
6346 if (num == 0) {
6347 is_int = FALSE;
6348 } else {
6349 int maybe_int = FALSE, maybe_str = FALSE;
6350#define CHECK_HYPOTHESIS(offset, result) \
6351 do { \
6352 long q = offset; \
6353 if (q >= 0 && q+4 <= len) { \
6354 q = q + 4 + GET_32BIT(p+q); \
6355 if (q >= 0 && q+4 <= len && \
c849ff23 6356 ((q = q + 4 + GET_32BIT(p+q))!= 0) && q == len) \
51df0ab5 6357 result = TRUE; \
6358 } \
6359 } while(0)
6360 CHECK_HYPOTHESIS(4+1, maybe_int);
6361 CHECK_HYPOTHESIS(4+num+1, maybe_str);
6362#undef CHECK_HYPOTHESIS
6363 if (maybe_int && !maybe_str)
6364 is_int = TRUE;
6365 else if (!maybe_int && maybe_str)
6366 is_int = FALSE;
6367 else
6368 /* Crikey. Either or neither. Panic. */
6369 is_plausible = FALSE;
6370 }
6371 }
d051d1b4 6372 ssh->exitcode = 128; /* means `unknown signal' */
51df0ab5 6373 if (is_plausible) {
6374 if (is_int) {
6375 /* Old non-standard OpenSSH. */
6376 int signum = ssh_pkt_getuint32(pktin);
6377 fmt_sig = dupprintf(" %d", signum);
d051d1b4 6378 ssh->exitcode = 128 + signum;
51df0ab5 6379 } else {
6380 /* As per the drafts. */
6381 char *sig;
6382 int siglen;
6383 ssh_pkt_getstring(pktin, &sig, &siglen);
6384 /* Signal name isn't supposed to be blank, but
6385 * let's cope gracefully if it is. */
6386 if (siglen) {
6387 fmt_sig = dupprintf(" \"%.*s\"",
6388 siglen, sig);
6389 }
d051d1b4 6390
6391 /*
6392 * Really hideous method of translating the
6393 * signal description back into a locally
6394 * meaningful number.
6395 */
6396
6397 if (0)
6398 ;
6399#ifdef SIGABRT
6400 else if (siglen == lenof("ABRT")-1 &&
6401 !memcmp(sig, "ABRT", siglen))
6402 ssh->exitcode = 128 + SIGABRT;
6403#endif
6404#ifdef SIGALRM
6405 else if (siglen == lenof("ALRM")-1 &&
6406 !memcmp(sig, "ALRM", siglen))
6407 ssh->exitcode = 128 + SIGALRM;
6408#endif
6409#ifdef SIGFPE
6410 else if (siglen == lenof("FPE")-1 &&
6411 !memcmp(sig, "FPE", siglen))
6412 ssh->exitcode = 128 + SIGFPE;
6413#endif
6414#ifdef SIGHUP
6415 else if (siglen == lenof("HUP")-1 &&
6416 !memcmp(sig, "HUP", siglen))
6417 ssh->exitcode = 128 + SIGHUP;
6418#endif
6419#ifdef SIGILL
6420 else if (siglen == lenof("ILL")-1 &&
6421 !memcmp(sig, "ILL", siglen))
6422 ssh->exitcode = 128 + SIGILL;
6423#endif
6424#ifdef SIGINT
6425 else if (siglen == lenof("INT")-1 &&
6426 !memcmp(sig, "INT", siglen))
6427 ssh->exitcode = 128 + SIGINT;
6428#endif
6429#ifdef SIGKILL
6430 else if (siglen == lenof("KILL")-1 &&
6431 !memcmp(sig, "KILL", siglen))
6432 ssh->exitcode = 128 + SIGKILL;
6433#endif
6434#ifdef SIGPIPE
6435 else if (siglen == lenof("PIPE")-1 &&
6436 !memcmp(sig, "PIPE", siglen))
6437 ssh->exitcode = 128 + SIGPIPE;
6438#endif
6439#ifdef SIGQUIT
6440 else if (siglen == lenof("QUIT")-1 &&
6441 !memcmp(sig, "QUIT", siglen))
6442 ssh->exitcode = 128 + SIGQUIT;
6443#endif
6444#ifdef SIGSEGV
6445 else if (siglen == lenof("SEGV")-1 &&
6446 !memcmp(sig, "SEGV", siglen))
6447 ssh->exitcode = 128 + SIGSEGV;
6448#endif
6449#ifdef SIGTERM
6450 else if (siglen == lenof("TERM")-1 &&
6451 !memcmp(sig, "TERM", siglen))
6452 ssh->exitcode = 128 + SIGTERM;
6453#endif
6454#ifdef SIGUSR1
6455 else if (siglen == lenof("USR1")-1 &&
6456 !memcmp(sig, "USR1", siglen))
6457 ssh->exitcode = 128 + SIGUSR1;
6458#endif
6459#ifdef SIGUSR2
6460 else if (siglen == lenof("USR2")-1 &&
6461 !memcmp(sig, "USR2", siglen))
6462 ssh->exitcode = 128 + SIGUSR2;
6463#endif
6464 else
6465 ssh->exitcode = 128;
51df0ab5 6466 }
6467 core = ssh2_pkt_getbool(pktin);
6468 ssh_pkt_getstring(pktin, &msg, &msglen);
6469 if (msglen) {
6470 fmt_msg = dupprintf(" (\"%.*s\")", msglen, msg);
6471 }
6472 /* ignore lang tag */
6473 } /* else don't attempt to parse */
6474 logeventf(ssh, "Server exited on signal%s%s%s",
6475 fmt_sig, core ? " (core dumped)" : "",
6476 fmt_msg);
6477 if (*fmt_sig) sfree(fmt_sig);
6478 if (*fmt_msg) sfree(fmt_msg);
6479 reply = SSH2_MSG_CHANNEL_SUCCESS;
6480
6481 }
6482 } else {
6483 /*
6484 * This is a channel request we don't know
6485 * about, so we now either ignore the request
6486 * or respond with CHANNEL_FAILURE, depending
6487 * on want_reply.
6488 */
6489 reply = SSH2_MSG_CHANNEL_FAILURE;
6490 }
6491 if (want_reply) {
6492 pktout = ssh2_pkt_init(reply);
6493 ssh2_pkt_adduint32(pktout, c->remoteid);
6494 ssh2_pkt_send(ssh, pktout);
6495 }
6496}
6497
6498static void ssh2_msg_global_request(Ssh ssh, struct Packet *pktin)
6499{
6500 char *type;
6501 int typelen, want_reply;
6502 struct Packet *pktout;
6503
6504 ssh_pkt_getstring(pktin, &type, &typelen);
6505 want_reply = ssh2_pkt_getbool(pktin);
6506
6507 /*
6508 * We currently don't support any global requests
6509 * at all, so we either ignore the request or
6510 * respond with REQUEST_FAILURE, depending on
6511 * want_reply.
6512 */
6513 if (want_reply) {
6514 pktout = ssh2_pkt_init(SSH2_MSG_REQUEST_FAILURE);
6515 ssh2_pkt_send(ssh, pktout);
6516 }
6517}
6518
6519static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin)
6520{
6521 char *type;
6522 int typelen;
6523 char *peeraddr;
6524 int peeraddrlen;
6525 int peerport;
6526 char *error = NULL;
6527 struct ssh_channel *c;
6528 unsigned remid, winsize, pktsize;
6529 struct Packet *pktout;
6530
6531 ssh_pkt_getstring(pktin, &type, &typelen);
6532 c = snew(struct ssh_channel);
6533 c->ssh = ssh;
6534
6535 remid = ssh_pkt_getuint32(pktin);
6536 winsize = ssh_pkt_getuint32(pktin);
6537 pktsize = ssh_pkt_getuint32(pktin);
6538
6539 if (typelen == 3 && !memcmp(type, "x11", 3)) {
6540 char *addrstr;
6541
6542 ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
6543 addrstr = snewn(peeraddrlen+1, char);
6544 memcpy(addrstr, peeraddr, peeraddrlen);
6545 addrstr[peeraddrlen] = '\0';
6546 peerport = ssh_pkt_getuint32(pktin);
6547
6548 logeventf(ssh, "Received X11 connect request from %s:%d",
6549 addrstr, peerport);
6550
6551 if (!ssh->X11_fwd_enabled)
6552 error = "X11 forwarding is not enabled";
6553 else if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c,
6554 ssh->x11auth, addrstr, peerport,
6555 &ssh->cfg) != NULL) {
6556 error = "Unable to open an X11 connection";
6557 } else {
6558 logevent("Opening X11 forward connection succeeded");
6559 c->type = CHAN_X11;
6560 }
6561
6562 sfree(addrstr);
6563 } else if (typelen == 15 &&
6564 !memcmp(type, "forwarded-tcpip", 15)) {
6565 struct ssh_rportfwd pf, *realpf;
6566 char *dummy;
6567 int dummylen;
6568 ssh_pkt_getstring(pktin, &dummy, &dummylen);/* skip address */
6569 pf.sport = ssh_pkt_getuint32(pktin);
6570 ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
6571 peerport = ssh_pkt_getuint32(pktin);
6572 realpf = find234(ssh->rportfwds, &pf, NULL);
6573 logeventf(ssh, "Received remote port %d open request "
6574 "from %s:%d", pf.sport, peeraddr, peerport);
6575 if (realpf == NULL) {
6576 error = "Remote port is not recognised";
6577 } else {
6578 const char *e = pfd_newconnect(&c->u.pfd.s,
6579 realpf->dhost,
6580 realpf->dport, c,
05581745 6581 &ssh->cfg,
6582 realpf->pfrec->addressfamily);
51df0ab5 6583 logeventf(ssh, "Attempting to forward remote port to "
6584 "%s:%d", realpf->dhost, realpf->dport);
6585 if (e != NULL) {
6586 logeventf(ssh, "Port open failed: %s", e);
6587 error = "Port open failed";
6588 } else {
6589 logevent("Forwarded port opened successfully");
6590 c->type = CHAN_SOCKDATA;
6591 }
6592 }
6593 } else if (typelen == 22 &&
c49cf994 6594 !memcmp(type, "auth-agent@openssh.com", 22)) {
51df0ab5 6595 if (!ssh->agentfwd_enabled)
6596 error = "Agent forwarding is not enabled";
6597 else {
6598 c->type = CHAN_AGENT; /* identify channel type */
6599 c->u.a.lensofar = 0;
6600 }
6601 } else {
6602 error = "Unsupported channel type requested";
6603 }
6604
6605 c->remoteid = remid;
64d6ff88 6606 c->halfopen = FALSE;
51df0ab5 6607 if (error) {
6608 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_FAILURE);
6609 ssh2_pkt_adduint32(pktout, c->remoteid);
6610 ssh2_pkt_adduint32(pktout, SSH2_OPEN_CONNECT_FAILED);
6611 ssh2_pkt_addstring(pktout, error);
6612 ssh2_pkt_addstring(pktout, "en"); /* language tag */
6613 ssh2_pkt_send(ssh, pktout);
6614 logeventf(ssh, "Rejected channel open: %s", error);
6615 sfree(c);
6616 } else {
6617 c->localid = alloc_channel_id(ssh);
6618 c->closes = 0;
6619 c->v.v2.locwindow = OUR_V2_WINSIZE;
6620 c->v.v2.remwindow = winsize;
6621 c->v.v2.remmaxpkt = pktsize;
6622 bufchain_init(&c->v.v2.outbuffer);
6623 add234(ssh->channels, c);
6624 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
6625 ssh2_pkt_adduint32(pktout, c->remoteid);
6626 ssh2_pkt_adduint32(pktout, c->localid);
6627 ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);
954d5c5a 6628 ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
51df0ab5 6629 ssh2_pkt_send(ssh, pktout);
6630 }
6631}
6632
6bbce591 6633/*
6634 * Buffer banner messages for later display at some convenient point.
6635 */
6636static void ssh2_msg_userauth_banner(Ssh ssh, struct Packet *pktin)
6637{
6638 /* Arbitrary limit to prevent unbounded inflation of buffer */
6639 if (bufchain_size(&ssh->banner) <= 131072) {
6640 char *banner = NULL;
6641 int size = 0;
6642 ssh_pkt_getstring(pktin, &banner, &size);
6643 if (banner)
6644 bufchain_add(&ssh->banner, banner, size);
6645 }
6646}
6647
c6ccd5c2 6648/* Helper function to deal with sending tty modes for "pty-req" */
6649static void ssh2_send_ttymode(void *data, char *mode, char *val)
6650{
6651 struct Packet *pktout = (struct Packet *)data;
6652 int i = 0;
6653 unsigned int arg = 0;
6654 while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
6655 if (i == lenof(ssh_ttymodes)) return;
6656 switch (ssh_ttymodes[i].type) {
6657 case TTY_OP_CHAR:
6658 arg = ssh_tty_parse_specchar(val);
6659 break;
6660 case TTY_OP_BOOL:
6661 arg = ssh_tty_parse_boolean(val);
6662 break;
6663 }
6664 ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
6665 ssh2_pkt_adduint32(pktout, arg);
6666}
6667
783415f8 6668/*
2e85c969 6669 * Handle the SSH-2 userauth and connection layers.
7cca0d81 6670 */
ff3187f6 6671static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
6672 struct Packet *pktin)
7cca0d81 6673{
51470298 6674 struct do_ssh2_authconn_state {
6675 enum {
51470298 6676 AUTH_TYPE_NONE,
6677 AUTH_TYPE_PUBLICKEY,
6678 AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
6679 AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
6680 AUTH_TYPE_PASSWORD,
6681 AUTH_TYPE_KEYBOARD_INTERACTIVE,
6682 AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
6683 } type;
a1a1fae4 6684 int done_service_req;
51470298 6685 int gotit, need_pw, can_pubkey, can_passwd, can_keyb_inter;
94cd7c3a 6686 int tried_pubkey_config, done_agent;
edd0cb8a 6687 int kbd_inter_refused;
51470298 6688 int we_are_in;
edd0cb8a 6689 prompts_t *cur_prompt;
6690 int num_prompts;
51470298 6691 char username[100];
e955d348 6692 char *password;
51470298 6693 int got_username;
51470298 6694 void *publickey_blob;
6695 int publickey_bloblen;
edd0cb8a 6696 int publickey_encrypted;
6697 char *publickey_algorithm;
6698 char *publickey_comment;
94cd7c3a 6699 unsigned char agent_request[5], *agent_response, *agentp;
6700 int agent_responselen;
6701 unsigned char *pkblob_in_agent;
51470298 6702 int keyi, nkeys;
51470298 6703 char *pkblob, *alg, *commentp;
6704 int pklen, alglen, commentlen;
6705 int siglen, retlen, len;
6706 char *q, *agentreq, *ret;
6707 int try_send;
73feed4f 6708 int num_env, env_left, env_ok;
ff3187f6 6709 struct Packet *pktout;
51470298 6710 };
6711 crState(do_ssh2_authconn_state);
6712
6713 crBegin(ssh->do_ssh2_authconn_crstate);
e5574168 6714
a1a1fae4 6715 s->done_service_req = FALSE;
6716 s->we_are_in = FALSE;
6717 if (!ssh->cfg.ssh_no_userauth) {
6718 /*
6719 * Request userauth protocol, and await a response to it.
6720 */
6721 s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
6722 ssh2_pkt_addstring(s->pktout, "ssh-userauth");
6723 ssh2_pkt_send(ssh, s->pktout);
6724 crWaitUntilV(pktin);
6725 if (pktin->type == SSH2_MSG_SERVICE_ACCEPT)
6726 s->done_service_req = TRUE;
6727 }
6728 if (!s->done_service_req) {
6729 /*
6730 * Request connection protocol directly, without authentication.
6731 */
6732 s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
6733 ssh2_pkt_addstring(s->pktout, "ssh-connection");
6734 ssh2_pkt_send(ssh, s->pktout);
6735 crWaitUntilV(pktin);
6736 if (pktin->type == SSH2_MSG_SERVICE_ACCEPT) {
6737 s->we_are_in = TRUE; /* no auth required */
6738 } else {
6739 bombout(("Server refused service request"));
6740 crStopV;
6741 }
8d5de777 6742 }
7cca0d81 6743
94cd7c3a 6744 /* Arrange to be able to deal with any BANNERs that come in.
6745 * (We do this now as packets may come in during the next bit.) */
6746 bufchain_init(&ssh->banner);
6747 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] =
6748 ssh2_msg_userauth_banner;
6749
7cca0d81 6750 /*
edd0cb8a 6751 * Misc one-time setup for authentication.
6752 */
6753 s->publickey_blob = NULL;
6754 if (!s->we_are_in) {
6755
6756 /*
6757 * Load the public half of any configured public key file
6758 * for later use.
6759 */
6760 if (!filename_is_null(ssh->cfg.keyfile)) {
6761 int keytype;
6762 logeventf(ssh, "Reading private key file \"%.150s\"",
6763 filename_to_str(&ssh->cfg.keyfile));
6764 keytype = key_type(&ssh->cfg.keyfile);
6765 if (keytype == SSH_KEYTYPE_SSH2) {
6766 const char *error;
6767 s->publickey_blob =
6768 ssh2_userkey_loadpub(&ssh->cfg.keyfile,
6769 &s->publickey_algorithm,
6770 &s->publickey_bloblen,
6771 &s->publickey_comment, &error);
6772 if (s->publickey_blob) {
6773 s->publickey_encrypted =
6774 ssh2_userkey_encrypted(&ssh->cfg.keyfile, NULL);
6775 } else {
6776 char *msgbuf;
6777 logeventf(ssh, "Unable to load private key (%s)",
6778 error);
6779 msgbuf = dupprintf("Unable to load private key file "
6780 "\"%.150s\" (%s)\r\n",
6781 filename_to_str(&ssh->cfg.keyfile),
6782 error);
6783 c_write_str(ssh, msgbuf);
6784 sfree(msgbuf);
6785 }
6786 } else {
6787 char *msgbuf;
6788 logeventf(ssh, "Unable to use this key file (%s)",
6789 key_type_to_str(keytype));
6790 msgbuf = dupprintf("Unable to use key file \"%.150s\""
6791 " (%s)\r\n",
6792 filename_to_str(&ssh->cfg.keyfile),
6793 key_type_to_str(keytype));
6794 c_write_str(ssh, msgbuf);
6795 sfree(msgbuf);
6796 s->publickey_blob = NULL;
6797 }
6798 }
6799
94cd7c3a 6800 /*
6801 * Find out about any keys Pageant has (but if there's a
6802 * public key configured, filter out all others).
6803 */
6804 s->nkeys = 0;
6805 s->agent_response = NULL;
6806 s->pkblob_in_agent = NULL;
116f229d 6807 if (ssh->cfg.tryagent && agent_exists()) {
94cd7c3a 6808
6809 void *r;
6810
6811 logevent("Pageant is running. Requesting keys.");
6812
6813 /* Request the keys held by the agent. */
6814 PUT_32BIT(s->agent_request, 1);
6815 s->agent_request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
6816 if (!agent_query(s->agent_request, 5, &r, &s->agent_responselen,
6817 ssh_agent_callback, ssh)) {
6818 do {
6819 crReturnV;
6820 if (pktin) {
6821 bombout(("Unexpected data from server while"
6822 " waiting for agent response"));
6823 crStopV;
6824 }
6825 } while (pktin || inlen > 0);
6826 r = ssh->agent_response;
6827 s->agent_responselen = ssh->agent_response_len;
6828 }
6829 s->agent_response = (unsigned char *) r;
6830 if (s->agent_response && s->agent_responselen >= 5 &&
6831 s->agent_response[4] == SSH2_AGENT_IDENTITIES_ANSWER) {
6832 int keyi;
6833 unsigned char *p;
6834 p = s->agent_response + 5;
6835 s->nkeys = GET_32BIT(p);
6836 p += 4;
6837 logeventf(ssh, "Pageant has %d SSH-2 keys", s->nkeys);
6838 if (s->publickey_blob) {
6839 /* See if configured key is in agent. */
6840 for (keyi = 0; keyi < s->nkeys; keyi++) {
6841 s->pklen = GET_32BIT(p);
6842 if (s->pklen == s->publickey_bloblen &&
6843 !memcmp(p+4, s->publickey_blob,
6844 s->publickey_bloblen)) {
6845 logeventf(ssh, "Pageant key #%d matches "
6846 "configured key file", keyi);
6847 s->keyi = keyi;
6848 s->pkblob_in_agent = p;
6849 break;
6850 }
6851 p += 4 + s->pklen;
6852 p += GET_32BIT(p) + 4; /* comment */
6853 }
6854 if (!s->pkblob_in_agent) {
6855 logevent("Configured key file not in Pageant");
6856 s->nkeys = 0;
6857 }
6858 }
6859 }
6860 }
6861
edd0cb8a 6862 }
6863
6864 /*
1408a877 6865 * We repeat this whole loop, including the username prompt,
6866 * until we manage a successful authentication. If the user
51470298 6867 * types the wrong _password_, they can be sent back to the
6868 * beginning to try another username, if this is configured on.
6869 * (If they specify a username in the config, they are never
6870 * asked, even if they do give a wrong password.)
1408a877 6871 *
6872 * I think this best serves the needs of
6873 *
6874 * - the people who have no configuration, no keys, and just
6875 * want to try repeated (username,password) pairs until they
6876 * type both correctly
6877 *
6878 * - people who have keys and configuration but occasionally
6879 * need to fall back to passwords
6880 *
6881 * - people with a key held in Pageant, who might not have
6882 * logged in to a particular machine before; so they want to
6883 * type a username, and then _either_ their key will be
6884 * accepted, _or_ they will type a password. If they mistype
6885 * the username they will want to be able to get back and
6886 * retype it!
7cca0d81 6887 */
51470298 6888 s->username[0] = '\0';
6889 s->got_username = FALSE;
a1a1fae4 6890 while (!s->we_are_in) {
1408a877 6891 /*
6892 * Get a username.
6893 */
86916870 6894 if (s->got_username && !ssh->cfg.change_username) {
5bb641e1 6895 /*
6896 * We got a username last time round this loop, and
6897 * with change_username turned off we don't try to get
6898 * it again.
6899 */
aa09f7d0 6900 } else if (!*ssh->cfg.username) {
edd0cb8a 6901 int ret; /* need not be kept over crReturn */
6902 s->cur_prompt = new_prompts(ssh->frontend);
6903 s->cur_prompt->to_server = TRUE;
6904 s->cur_prompt->name = dupstr("SSH login name");
6905 add_prompt(s->cur_prompt, dupstr("login as: "), TRUE,
6906 lenof(s->username));
6907 ret = get_userpass_input(s->cur_prompt, NULL, 0);
6908 while (ret < 0) {
51470298 6909 ssh->send_ok = 1;
edd0cb8a 6910 crWaitUntilV(!pktin);
6911 ret = get_userpass_input(s->cur_prompt, in, inlen);
6912 ssh->send_ok = 0;
32874aea 6913 }
edd0cb8a 6914 if (!ret) {
6915 /*
6916 * get_userpass_input() failed to get a username.
6917 * Terminate.
6918 */
6919 free_prompts(s->cur_prompt);
6920 ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
6921 crStopV;
6922 }
6923 memcpy(s->username, s->cur_prompt->prompts[0]->result,
6924 lenof(s->username));
6925 free_prompts(s->cur_prompt);
7cca0d81 6926 } else {
57356d63 6927 char *stuff;
86916870 6928 strncpy(s->username, ssh->cfg.username, sizeof(s->username));
51470298 6929 s->username[sizeof(s->username)-1] = '\0';
65a22376 6930 if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
57356d63 6931 stuff = dupprintf("Using username \"%s\".\r\n", s->username);
51470298 6932 c_write_str(ssh, stuff);
57356d63 6933 sfree(stuff);
7cca0d81 6934 }
6935 }
51470298 6936 s->got_username = TRUE;
7cca0d81 6937
65a22376 6938 /*
1408a877 6939 * Send an authentication request using method "none": (a)
6940 * just in case it succeeds, and (b) so that we know what
6941 * authentication methods we can usefully try next.
65a22376 6942 */
51470298 6943 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
6944
ff3187f6 6945 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
6946 ssh2_pkt_addstring(s->pktout, s->username);
6947 ssh2_pkt_addstring(s->pktout, "ssh-connection");/* service requested */
6948 ssh2_pkt_addstring(s->pktout, "none"); /* method */
6949 ssh2_pkt_send(ssh, s->pktout);
51470298 6950 s->type = AUTH_TYPE_NONE;
6951 s->gotit = FALSE;
6952 s->we_are_in = FALSE;
6953
6954 s->tried_pubkey_config = FALSE;
6ac3a551 6955 s->kbd_inter_refused = FALSE;
65a22376 6956
94cd7c3a 6957 /* Reset agent request state. */
6958 s->done_agent = FALSE;
6959 if (s->agent_response) {
6960 if (s->pkblob_in_agent) {
6961 s->agentp = s->pkblob_in_agent;
6962 } else {
6963 s->agentp = s->agent_response + 5 + 4;
6964 s->keyi = 0;
6965 }
6966 }
6967
1408a877 6968 while (1) {
6969 /*
6970 * Wait for the result of the last authentication request.
6971 */
51470298 6972 if (!s->gotit)
ff3187f6 6973 crWaitUntilV(pktin);
6bbce591 6974 /*
6975 * Now is a convenient point to spew any banner material
6976 * that we've accumulated. (This should ensure that when
6977 * we exit the auth loop, we haven't any left to deal
6978 * with.)
6979 */
6980 {
6981 int size = bufchain_size(&ssh->banner);
32874aea 6982 /*
6983 * Don't show the banner if we're operating in
6984 * non-verbose non-interactive mode. (It's probably
6985 * a script, which means nobody will read the
6986 * banner _anyway_, and moreover the printing of
6987 * the banner will screw up processing on the
6988 * output of (say) plink.)
6989 */
6bbce591 6990 if (size && (flags & (FLAG_VERBOSE | FLAG_INTERACTIVE))) {
6991 char *banner = snewn(size, char);
6992 bufchain_fetch(&ssh->banner, banner, size);
6993 c_write_untrusted(ssh, banner, size);
6994 sfree(banner);
32874aea 6995 }
6bbce591 6996 bufchain_clear(&ssh->banner);
1408a877 6997 }
ff3187f6 6998 if (pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
1408a877 6999 logevent("Access granted");
51470298 7000 s->we_are_in = TRUE;
1408a877 7001 break;
7002 }
65a22376 7003
e955d348 7004 if (pktin->type != SSH2_MSG_USERAUTH_FAILURE) {
7005 bombout(("Strange packet received during authentication: "
7006 "type %d", pktin->type));
7ffdbc1a 7007 crStopV;
65a22376 7008 }
7009
51470298 7010 s->gotit = FALSE;
65a22376 7011
1408a877 7012 /*
7013 * OK, we're now sitting on a USERAUTH_FAILURE message, so
7014 * we can look at the string in it and know what we can
7015 * helpfully try next.
7016 */
ff3187f6 7017 if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
1408a877 7018 char *methods;
7019 int methlen;
ff3187f6 7020 ssh_pkt_getstring(pktin, &methods, &methlen);
ff3187f6 7021 if (!ssh2_pkt_getbool(pktin)) {
1408a877 7022 /*
7023 * We have received an unequivocal Access
7024 * Denied. This can translate to a variety of
7025 * messages:
7026 *
7027 * - if we'd just tried "none" authentication,
7028 * it's not worth printing anything at all
7029 *
7030 * - if we'd just tried a public key _offer_,
7031 * the message should be "Server refused our
7032 * key" (or no message at all if the key
7033 * came from Pageant)
7034 *
7035 * - if we'd just tried anything else, the
7036 * message really should be "Access denied".
7037 *
7038 * Additionally, if we'd just tried password
7039 * authentication, we should break out of this
7040 * whole loop so as to go back to the username
91f57d1f 7041 * prompt (iff we're configured to allow
7042 * username change attempts).
1408a877 7043 */
51470298 7044 if (s->type == AUTH_TYPE_NONE) {
1408a877 7045 /* do nothing */
51470298 7046 } else if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
7047 s->type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
7048 if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
7049 c_write_str(ssh, "Server refused our key\r\n");
1408a877 7050 logevent("Server refused public key");
51470298 7051 } else if (s->type==AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET) {
4bdf7c46 7052 /* server declined keyboard-interactive; ignore */
1408a877 7053 } else {
51470298 7054 c_write_str(ssh, "Access denied\r\n");
1408a877 7055 logevent("Access denied");
91f57d1f 7056 if (s->type == AUTH_TYPE_PASSWORD &&
7057 ssh->cfg.change_username) {
6c9dce7c 7058 /* XXX perhaps we should allow
7059 * keyboard-interactive to do this too? */
51470298 7060 s->we_are_in = FALSE;
1408a877 7061 break;
7062 }
7063 }
7064 } else {
51470298 7065 c_write_str(ssh, "Further authentication required\r\n");
1408a877 7066 logevent("Further authentication required");
7067 }
65a22376 7068
51470298 7069 s->can_pubkey =
32874aea 7070 in_commasep_string("publickey", methods, methlen);
51470298 7071 s->can_passwd =
32874aea 7072 in_commasep_string("password", methods, methlen);
86916870 7073 s->can_keyb_inter = ssh->cfg.try_ki_auth &&
761187b6 7074 in_commasep_string("keyboard-interactive", methods, methlen);
1408a877 7075 }
65a22376 7076
51470298 7077 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
65a22376 7078
94cd7c3a 7079 if (s->can_pubkey && !s->done_agent && s->nkeys) {
0405e71f 7080
1983e559 7081 /*
94cd7c3a 7082 * Attempt public-key authentication using a key from Pageant.
1983e559 7083 */
1983e559 7084
51470298 7085 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7086 ssh->pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
00db133f 7087
94cd7c3a 7088 logeventf(ssh, "Trying Pageant key #%d", s->keyi);
7089
7090 /* Unpack key from agent response */
7091 s->pklen = GET_32BIT(s->agentp);
7092 s->agentp += 4;
7093 s->pkblob = (char *)s->agentp;
7094 s->agentp += s->pklen;
7095 s->alglen = GET_32BIT(s->pkblob);
7096 s->alg = s->pkblob + 4;
7097 s->commentlen = GET_32BIT(s->agentp);
7098 s->agentp += 4;
7099 s->commentp = (char *)s->agentp;
7100 s->agentp += s->commentlen;
7101 /* s->agentp now points at next key, if any */
7102
7103 /* See if server will accept it */
7104 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7105 ssh2_pkt_addstring(s->pktout, s->username);
7106 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7107 /* service requested */
7108 ssh2_pkt_addstring(s->pktout, "publickey");
7109 /* method */
7110 ssh2_pkt_addbool(s->pktout, FALSE); /* no signature included */
7111 ssh2_pkt_addstring_start(s->pktout);
7112 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
7113 ssh2_pkt_addstring_start(s->pktout);
7114 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
7115 ssh2_pkt_send(ssh, s->pktout);
7116 s->type = AUTH_TYPE_PUBLICKEY_OFFER_QUIET;
1983e559 7117
94cd7c3a 7118 crWaitUntilV(pktin);
7119 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
1983e559 7120
94cd7c3a 7121 /* Offer of key refused. */
7122 s->gotit = TRUE;
1983e559 7123
94cd7c3a 7124 } else {
7125
7126 void *vret;
1983e559 7127
94cd7c3a 7128 if (flags & FLAG_VERBOSE) {
7129 c_write_str(ssh, "Authenticating with "
7130 "public key \"");
7131 c_write(ssh, s->commentp, s->commentlen);
7132 c_write_str(ssh, "\" from agent\r\n");
7133 }
1983e559 7134
94cd7c3a 7135 /*
7136 * Server is willing to accept the key.
7137 * Construct a SIGN_REQUEST.
7138 */
7139 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7140 ssh2_pkt_addstring(s->pktout, s->username);
7141 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7142 /* service requested */
7143 ssh2_pkt_addstring(s->pktout, "publickey");
7144 /* method */
7145 ssh2_pkt_addbool(s->pktout, TRUE); /* signature included */
7146 ssh2_pkt_addstring_start(s->pktout);
7147 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
7148 ssh2_pkt_addstring_start(s->pktout);
7149 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
7150
7151 /* Ask agent for signature. */
7152 s->siglen = s->pktout->length - 5 + 4 +
7153 ssh->v2_session_id_len;
7154 if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7155 s->siglen -= 4;
7156 s->len = 1; /* message type */
7157 s->len += 4 + s->pklen; /* key blob */
7158 s->len += 4 + s->siglen; /* data to sign */
7159 s->len += 4; /* flags */
7160 s->agentreq = snewn(4 + s->len, char);
7161 PUT_32BIT(s->agentreq, s->len);
7162 s->q = s->agentreq + 4;
7163 *s->q++ = SSH2_AGENTC_SIGN_REQUEST;
7164 PUT_32BIT(s->q, s->pklen);
7165 s->q += 4;
7166 memcpy(s->q, s->pkblob, s->pklen);
7167 s->q += s->pklen;
7168 PUT_32BIT(s->q, s->siglen);
7169 s->q += 4;
7170 /* Now the data to be signed... */
7171 if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7172 PUT_32BIT(s->q, ssh->v2_session_id_len);
51470298 7173 s->q += 4;
94cd7c3a 7174 }
7175 memcpy(s->q, ssh->v2_session_id,
7176 ssh->v2_session_id_len);
7177 s->q += ssh->v2_session_id_len;
7178 memcpy(s->q, s->pktout->data + 5,
7179 s->pktout->length - 5);
7180 s->q += s->pktout->length - 5;
7181 /* And finally the (zero) flags word. */
7182 PUT_32BIT(s->q, 0);
7183 if (!agent_query(s->agentreq, s->len + 4,
7184 &vret, &s->retlen,
7185 ssh_agent_callback, ssh)) {
7186 do {
7187 crReturnV;
7188 if (pktin) {
7189 bombout(("Unexpected data from server"
7190 " while waiting for agent"
7191 " response"));
7192 crStopV;
1983e559 7193 }
94cd7c3a 7194 } while (pktin || inlen > 0);
7195 vret = ssh->agent_response;
7196 s->retlen = ssh->agent_response_len;
7197 }
7198 s->ret = vret;
7199 sfree(s->agentreq);
7200 if (s->ret) {
7201 if (s->ret[4] == SSH2_AGENT_SIGN_RESPONSE) {
7202 logevent("Sending Pageant's response");
7203 ssh2_add_sigblob(ssh, s->pktout,
7204 s->pkblob, s->pklen,
7205 s->ret + 9,
7206 GET_32BIT(s->ret + 5));
7207 ssh2_pkt_send(ssh, s->pktout);
7208 s->type = AUTH_TYPE_PUBLICKEY;
7209 } else {
7210 /* FIXME: less drastic response */
7211 bombout(("Pageant failed to answer challenge"));
7212 crStopV;
1983e559 7213 }
7214 }
1983e559 7215 }
94cd7c3a 7216
7217 /* Do we have any keys left to try? */
7218 if (s->pkblob_in_agent) {
7219 s->done_agent = TRUE;
7220 s->tried_pubkey_config = TRUE;
7221 } else {
7222 s->keyi++;
7223 if (s->keyi >= s->nkeys)
7224 s->done_agent = TRUE;
7225 }
1983e559 7226
edd0cb8a 7227 } else if (s->can_pubkey && s->publickey_blob &&
7228 !s->tried_pubkey_config) {
65a22376 7229
edd0cb8a 7230 struct ssh2_userkey *key; /* not live over crReturn */
7231 char *passphrase; /* not live over crReturn */
65a22376 7232
51470298 7233 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7234 ssh->pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
00db133f 7235
edd0cb8a 7236 s->tried_pubkey_config = TRUE;
7237
65a22376 7238 /*
1408a877 7239 * Try the public key supplied in the configuration.
7240 *
7241 * First, offer the public blob to see if the server is
7242 * willing to accept it.
65a22376 7243 */
ff3187f6 7244 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7245 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7246 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7247 /* service requested */
7248 ssh2_pkt_addstring(s->pktout, "publickey"); /* method */
7249 ssh2_pkt_addbool(s->pktout, FALSE);
7250 /* no signature included */
7251 ssh2_pkt_addstring(s->pktout, s->publickey_algorithm);
7252 ssh2_pkt_addstring_start(s->pktout);
7253 ssh2_pkt_addstring_data(s->pktout,
7254 (char *)s->publickey_blob,
7255 s->publickey_bloblen);
ff3187f6 7256 ssh2_pkt_send(ssh, s->pktout);
edd0cb8a 7257 logevent("Offered public key");
ff3187f6 7258
7259 crWaitUntilV(pktin);
edd0cb8a 7260 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
7261 /* Key refused. Give up. */
7262 s->gotit = TRUE; /* reconsider message next loop */
7263 s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
7264 continue; /* process this new message */
45068b27 7265 }
edd0cb8a 7266 logevent("Offer of public key accepted");
af659722 7267
45068b27 7268 /*
edd0cb8a 7269 * Actually attempt a serious authentication using
7270 * the key.
45068b27 7271 */
edd0cb8a 7272 if (flags & FLAG_VERBOSE) {
7273 c_write_str(ssh, "Authenticating with public key \"");
7274 c_write_str(ssh, s->publickey_comment);
7275 c_write_str(ssh, "\"\r\n");
7276 }
7277 key = NULL;
7278 while (!key) {
7279 const char *error; /* not live over crReturn */
7280 if (s->publickey_encrypted) {
7281 /*
7282 * Get a passphrase from the user.
7283 */
7284 int ret; /* need not be kept over crReturn */
7285 s->cur_prompt = new_prompts(ssh->frontend);
7286 s->cur_prompt->to_server = FALSE;
7287 s->cur_prompt->name = dupstr("SSH key passphrase");
7288 add_prompt(s->cur_prompt,
7289 dupprintf("Passphrase for key \"%.100s\": ",
7290 s->publickey_comment),
7291 FALSE, SSH_MAX_PASSWORD_LEN);
7292 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7293 while (ret < 0) {
7294 ssh->send_ok = 1;
7295 crWaitUntilV(!pktin);
7296 ret = get_userpass_input(s->cur_prompt,
7297 in, inlen);
7298 ssh->send_ok = 0;
7299 }
7300 if (!ret) {
7301 /* Failed to get a passphrase. Terminate. */
7302 free_prompts(s->cur_prompt);
7303 ssh_disconnect(ssh, NULL,
7304 "Unable to authenticate",
7305 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7306 TRUE);
7307 crStopV;
85fdbe25 7308 }
edd0cb8a 7309 passphrase =
7310 dupstr(s->cur_prompt->prompts[0]->result);
7311 free_prompts(s->cur_prompt);
45068b27 7312 } else {
edd0cb8a 7313 passphrase = NULL; /* no passphrase needed */
45068b27 7314 }
1408a877 7315
edd0cb8a 7316 /*
7317 * Try decrypting the key.
7318 */
7319 key = ssh2_load_userkey(&ssh->cfg.keyfile, passphrase,
7320 &error);
7321 if (passphrase) {
7322 /* burn the evidence */
7323 memset(passphrase, 0, strlen(passphrase));
7324 sfree(passphrase);
7325 }
7326 if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
7327 if (passphrase &&
7328 (key == SSH2_WRONG_PASSPHRASE)) {
7329 c_write_str(ssh, "Wrong passphrase\r\n");
7330 key = NULL;
7331 /* and loop again */
7332 } else {
7333 c_write_str(ssh, "Unable to load private key (");
7334 c_write_str(ssh, error);
7335 c_write_str(ssh, ")\r\n");
7336 key = NULL;
7337 break; /* try something else */
7338 }
1408a877 7339 }
65a22376 7340 }
65a22376 7341
edd0cb8a 7342 if (key) {
1dd353b5 7343 unsigned char *pkblob, *sigblob, *sigdata;
7344 int pkblob_len, sigblob_len, sigdata_len;
edd0cb8a 7345 int p;
65a22376 7346
1408a877 7347 /*
7348 * We have loaded the private key and the server
7349 * has announced that it's willing to accept it.
7350 * Hallelujah. Generate a signature and send it.
7351 */
ff3187f6 7352 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7353 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7354 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7355 /* service requested */
7356 ssh2_pkt_addstring(s->pktout, "publickey");
7357 /* method */
ff3187f6 7358 ssh2_pkt_addbool(s->pktout, TRUE);
edd0cb8a 7359 /* signature follows */
ff3187f6 7360 ssh2_pkt_addstring(s->pktout, key->alg->name);
edd0cb8a 7361 pkblob = key->alg->public_blob(key->data,
7362 &pkblob_len);
ff3187f6 7363 ssh2_pkt_addstring_start(s->pktout);
edd0cb8a 7364 ssh2_pkt_addstring_data(s->pktout, (char *)pkblob,
7365 pkblob_len);
1408a877 7366
7367 /*
7368 * The data to be signed is:
7369 *
7370 * string session-id
7371 *
7372 * followed by everything so far placed in the
7373 * outgoing packet.
7374 */
b672f405 7375 sigdata_len = s->pktout->length - 5 + 4 +
7376 ssh->v2_session_id_len;
edd0cb8a 7377 if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7378 sigdata_len -= 4;
92d60585 7379 sigdata = snewn(sigdata_len, unsigned char);
edd0cb8a 7380 p = 0;
7381 if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7382 PUT_32BIT(sigdata+p, ssh->v2_session_id_len);
7383 p += 4;
7384 }
b672f405 7385 memcpy(sigdata+p, ssh->v2_session_id,
7386 ssh->v2_session_id_len);
7387 p += ssh->v2_session_id_len;
ff3187f6 7388 memcpy(sigdata+p, s->pktout->data + 5,
7389 s->pktout->length - 5);
edd0cb8a 7390 p += s->pktout->length - 5;
7391 assert(p == sigdata_len);
d8baa528 7392 sigblob = key->alg->sign(key->data, (char *)sigdata,
1dd353b5 7393 sigdata_len, &sigblob_len);
ff3187f6 7394 ssh2_add_sigblob(ssh, s->pktout, pkblob, pkblob_len,
1dd353b5 7395 sigblob, sigblob_len);
7396 sfree(pkblob);
7397 sfree(sigblob);
1408a877 7398 sfree(sigdata);
7399
ff3187f6 7400 ssh2_pkt_send(ssh, s->pktout);
51470298 7401 s->type = AUTH_TYPE_PUBLICKEY;
75374b2f 7402 key->alg->freekey(key->data);
1408a877 7403 }
edd0cb8a 7404
7405 } else if (s->can_keyb_inter && !s->kbd_inter_refused) {
7406
7407 /*
7408 * Keyboard-interactive authentication.
7409 */
edd0cb8a 7410
edd0cb8a 7411 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
7412
7413 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7414 ssh->pkt_ctx |= SSH2_PKTCTX_KBDINTER;
7415
7416 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7417 ssh2_pkt_addstring(s->pktout, s->username);
7418 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7419 /* service requested */
7420 ssh2_pkt_addstring(s->pktout, "keyboard-interactive");
7421 /* method */
7422 ssh2_pkt_addstring(s->pktout, ""); /* lang */
7423 ssh2_pkt_addstring(s->pktout, ""); /* submethods */
7424 ssh2_pkt_send(ssh, s->pktout);
7425
7426 crWaitUntilV(pktin);
7427 if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
7428 /* Server is not willing to do keyboard-interactive
b8e3173d 7429 * at all (or, bizarrely but legally, accepts the
7430 * user without actually issuing any prompts).
7431 * Give up on it entirely. */
edd0cb8a 7432 s->gotit = TRUE;
7433 if (pktin->type == SSH2_MSG_USERAUTH_FAILURE)
7434 logevent("Keyboard-interactive authentication refused");
7435 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
7436 s->kbd_inter_refused = TRUE; /* don't try it again */
7437 continue;
7438 }
7439
7440 /*
b8e3173d 7441 * Loop while the server continues to send INFO_REQUESTs.
edd0cb8a 7442 */
b8e3173d 7443 while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
edd0cb8a 7444
b8e3173d 7445 char *name, *inst, *lang;
7446 int name_len, inst_len, lang_len;
7447 int i;
7448
7449 /*
7450 * We've got a fresh USERAUTH_INFO_REQUEST.
7451 * Get the preamble and start building a prompt.
7452 */
7453 ssh_pkt_getstring(pktin, &name, &name_len);
7454 ssh_pkt_getstring(pktin, &inst, &inst_len);
7455 ssh_pkt_getstring(pktin, &lang, &lang_len);
7456 s->cur_prompt = new_prompts(ssh->frontend);
7457 s->cur_prompt->to_server = TRUE;
7458 if (name_len) {
7459 /* FIXME: better prefix to distinguish from
7460 * local prompts? */
7461 s->cur_prompt->name =
7462 dupprintf("SSH server: %.*s", name_len, name);
7463 s->cur_prompt->name_reqd = TRUE;
7464 } else {
7465 s->cur_prompt->name =
7466 dupstr("SSH server authentication");
7467 s->cur_prompt->name_reqd = FALSE;
edd0cb8a 7468 }
b8e3173d 7469 /* FIXME: ugly to print "Using..." in prompt _every_
7470 * time round. Can this be done more subtly? */
7471 s->cur_prompt->instruction =
7472 dupprintf("Using keyboard-interactive authentication.%s%.*s",
7473 inst_len ? "\n" : "", inst_len, inst);
7474 s->cur_prompt->instr_reqd = TRUE;
edd0cb8a 7475
b8e3173d 7476 /*
7477 * Get the prompts from the packet.
7478 */
7479 s->num_prompts = ssh_pkt_getuint32(pktin);
7480 for (i = 0; i < s->num_prompts; i++) {
7481 char *prompt;
7482 int prompt_len;
7483 int echo;
7484 static char noprompt[] =
7485 "<server failed to send prompt>: ";
7486
7487 ssh_pkt_getstring(pktin, &prompt, &prompt_len);
7488 echo = ssh2_pkt_getbool(pktin);
7489 if (!prompt_len) {
7490 prompt = noprompt;
7491 prompt_len = lenof(noprompt)-1;
7492 }
7493 add_prompt(s->cur_prompt,
7494 dupprintf("%.*s", prompt_len, prompt),
7495 echo, SSH_MAX_PASSWORD_LEN);
edd0cb8a 7496 }
b8e3173d 7497
7498 /*
7499 * Get the user's responses.
7500 */
7501 if (s->num_prompts) {
7502 int ret; /* not live over crReturn */
7503 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7504 while (ret < 0) {
7505 ssh->send_ok = 1;
7506 crWaitUntilV(!pktin);
7507 ret = get_userpass_input(s->cur_prompt, in, inlen);
7508 ssh->send_ok = 0;
7509 }
7510 if (!ret) {
7511 /*
7512 * Failed to get responses. Terminate.
7513 */
7514 free_prompts(s->cur_prompt);
7515 ssh_disconnect(ssh, NULL, "Unable to authenticate",
7516 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7517 TRUE);
7518 crStopV;
7519 }
edd0cb8a 7520 }
b8e3173d 7521
7522 /*
7523 * Send the responses to the server.
7524 */
7525 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_INFO_RESPONSE);
b8e3173d 7526 ssh2_pkt_adduint32(s->pktout, s->num_prompts);
7527 for (i=0; i < s->num_prompts; i++) {
7528 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
7529 ssh2_pkt_addstring(s->pktout,
7530 s->cur_prompt->prompts[i]->result);
7531 end_log_omission(ssh, s->pktout);
7532 }
18524056 7533 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
b8e3173d 7534
7535 /*
7536 * Get the next packet in case it's another
7537 * INFO_REQUEST.
7538 */
7539 crWaitUntilV(pktin);
7540
edd0cb8a 7541 }
7542
7543 /*
b8e3173d 7544 * We should have SUCCESS or FAILURE now.
edd0cb8a 7545 */
b8e3173d 7546 s->gotit = TRUE;
edd0cb8a 7547
7548 } else if (s->can_passwd) {
7549
7550 /*
7551 * Plain old password authentication.
7552 */
7553 int ret; /* not live over crReturn */
e955d348 7554 int changereq_first_time; /* not live over crReturn */
edd0cb8a 7555
edd0cb8a 7556 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7557 ssh->pkt_ctx |= SSH2_PKTCTX_PASSWORD;
7558
7559 s->cur_prompt = new_prompts(ssh->frontend);
7560 s->cur_prompt->to_server = TRUE;
7561 s->cur_prompt->name = dupstr("SSH password");
7562 add_prompt(s->cur_prompt, dupprintf("%.90s@%.90s's password: ",
7563 s->username,
7564 ssh->savedhost),
7565 FALSE, SSH_MAX_PASSWORD_LEN);
7566
7567 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7568 while (ret < 0) {
7569 ssh->send_ok = 1;
7570 crWaitUntilV(!pktin);
7571 ret = get_userpass_input(s->cur_prompt, in, inlen);
7572 ssh->send_ok = 0;
7573 }
7574 if (!ret) {
7575 /*
7576 * Failed to get responses. Terminate.
7577 */
7578 free_prompts(s->cur_prompt);
7579 ssh_disconnect(ssh, NULL, "Unable to authenticate",
7580 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7581 TRUE);
7582 crStopV;
7583 }
e955d348 7584 /*
7585 * Squirrel away the password. (We may need it later if
7586 * asked to change it.)
7587 */
7588 s->password = dupstr(s->cur_prompt->prompts[0]->result);
7589 free_prompts(s->cur_prompt);
edd0cb8a 7590
7591 /*
7592 * Send the password packet.
7593 *
95d2d262 7594 * We pad out the password packet to 256 bytes to make
7595 * it harder for an attacker to find the length of the
7596 * user's password.
1408a877 7597 *
95d2d262 7598 * Anyone using a password longer than 256 bytes
7599 * probably doesn't have much to worry about from
1408a877 7600 * people who find out how long their password is!
65a22376 7601 */
ff3187f6 7602 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7603 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7604 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7605 /* service requested */
ff3187f6 7606 ssh2_pkt_addstring(s->pktout, "password");
7607 ssh2_pkt_addbool(s->pktout, FALSE);
7608 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
e955d348 7609 ssh2_pkt_addstring(s->pktout, s->password);
ff3187f6 7610 end_log_omission(ssh, s->pktout);
18524056 7611 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
0d43337a 7612 logevent("Sent password");
28f4d4f0 7613 s->type = AUTH_TYPE_PASSWORD;
edd0cb8a 7614
e955d348 7615 /*
7616 * Wait for next packet, in case it's a password change
7617 * request.
7618 */
7619 crWaitUntilV(pktin);
7620 changereq_first_time = TRUE;
7621
7622 while (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
7623
7624 /*
7625 * We're being asked for a new password
7626 * (perhaps not for the first time).
7627 * Loop until the server accepts it.
7628 */
7629
7630 int got_new = FALSE; /* not live over crReturn */
7631 char *prompt; /* not live over crReturn */
7632 int prompt_len; /* not live over crReturn */
7633
7634 {
7635 char *msg;
7636 if (changereq_first_time)
7637 msg = "Server requested password change";
7638 else
7639 msg = "Server rejected new password";
7640 logevent(msg);
7641 c_write_str(ssh, msg);
7642 c_write_str(ssh, "\r\n");
7643 }
7644
7645 ssh_pkt_getstring(pktin, &prompt, &prompt_len);
7646
7647 s->cur_prompt = new_prompts(ssh->frontend);
7648 s->cur_prompt->to_server = TRUE;
7649 s->cur_prompt->name = dupstr("New SSH password");
7650 s->cur_prompt->instruction =
7651 dupprintf("%.*s", prompt_len, prompt);
7652 s->cur_prompt->instr_reqd = TRUE;
d9add7bc 7653 /*
7654 * There's no explicit requirement in the protocol
7655 * for the "old" passwords in the original and
7656 * password-change messages to be the same, and
7657 * apparently some Cisco kit supports password change
7658 * by the user entering a blank password originally
7659 * and the real password subsequently, so,
7660 * reluctantly, we prompt for the old password again.
7661 *
7662 * (On the other hand, some servers don't even bother
7663 * to check this field.)
7664 */
7665 add_prompt(s->cur_prompt,
7666 dupstr("Current password (blank for previously entered password): "),
7667 FALSE, SSH_MAX_PASSWORD_LEN);
e955d348 7668 add_prompt(s->cur_prompt, dupstr("Enter new password: "),
7669 FALSE, SSH_MAX_PASSWORD_LEN);
7670 add_prompt(s->cur_prompt, dupstr("Confirm new password: "),
7671 FALSE, SSH_MAX_PASSWORD_LEN);
7672
7673 /*
7674 * Loop until the user manages to enter the same
7675 * password twice.
7676 */
7677 while (!got_new) {
7678
7679 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7680 while (ret < 0) {
7681 ssh->send_ok = 1;
7682 crWaitUntilV(!pktin);
7683 ret = get_userpass_input(s->cur_prompt, in, inlen);
7684 ssh->send_ok = 0;
7685 }
7686 if (!ret) {
7687 /*
7688 * Failed to get responses. Terminate.
7689 */
7690 /* burn the evidence */
7691 free_prompts(s->cur_prompt);
7692 memset(s->password, 0, strlen(s->password));
7693 sfree(s->password);
7694 ssh_disconnect(ssh, NULL, "Unable to authenticate",
7695 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7696 TRUE);
7697 crStopV;
7698 }
7699
7700 /*
d9add7bc 7701 * If the user specified a new original password
7702 * (IYSWIM), overwrite any previously specified
7703 * one.
7704 * (A side effect is that the user doesn't have to
7705 * re-enter it if they louse up the new password.)
7706 */
7707 if (s->cur_prompt->prompts[0]->result[0]) {
7708 memset(s->password, 0, strlen(s->password));
7709 /* burn the evidence */
7710 sfree(s->password);
7711 s->password =
7712 dupstr(s->cur_prompt->prompts[0]->result);
7713 }
7714
7715 /*
7716 * Check the two new passwords match.
e955d348 7717 */
d9add7bc 7718 got_new = (strcmp(s->cur_prompt->prompts[1]->result,
7719 s->cur_prompt->prompts[2]->result)
e955d348 7720 == 0);
7721 if (!got_new)
7722 /* They don't. Silly user. */
7723 c_write_str(ssh, "Passwords do not match\r\n");
7724
7725 }
7726
7727 /*
7728 * Send the new password (along with the old one).
7729 * (see above for padding rationale)
7730 */
7731 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
e955d348 7732 ssh2_pkt_addstring(s->pktout, s->username);
7733 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7734 /* service requested */
7735 ssh2_pkt_addstring(s->pktout, "password");
7736 ssh2_pkt_addbool(s->pktout, TRUE);
7737 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
7738 ssh2_pkt_addstring(s->pktout, s->password);
7739 ssh2_pkt_addstring(s->pktout,
d9add7bc 7740 s->cur_prompt->prompts[1]->result);
e955d348 7741 free_prompts(s->cur_prompt);
7742 end_log_omission(ssh, s->pktout);
18524056 7743 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
e955d348 7744 logevent("Sent new password");
7745
7746 /*
7747 * Now see what the server has to say about it.
7748 * (If it's CHANGEREQ again, it's not happy with the
7749 * new password.)
7750 */
7751 crWaitUntilV(pktin);
7752 changereq_first_time = FALSE;
7753
7754 }
7755
7756 /*
7757 * We need to reexamine the current pktin at the top
7758 * of the loop. Either:
7759 * - we weren't asked to change password at all, in
7760 * which case it's a SUCCESS or FAILURE with the
7761 * usual meaning
7762 * - we sent a new password, and the server was
7763 * either OK with it (SUCCESS or FAILURE w/partial
7764 * success) or unhappy with the _old_ password
7765 * (FAILURE w/o partial success)
7766 * In any of these cases, we go back to the top of
7767 * the loop and start again.
7768 */
7769 s->gotit = TRUE;
7770
7771 /*
7772 * We don't need the old password any more, in any
7773 * case. Burn the evidence.
7774 */
7775 memset(s->password, 0, strlen(s->password));
7776 sfree(s->password);
7777
1408a877 7778 } else {
edd0cb8a 7779
9e296bfa 7780 ssh_disconnect(ssh, NULL,
7781 "No supported authentication methods available",
7782 SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
7783 FALSE);
7ffdbc1a 7784 crStopV;
edd0cb8a 7785
65a22376 7786 }
edd0cb8a 7787
65a22376 7788 }
a1a1fae4 7789 }
6bbce591 7790 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
7cca0d81 7791
edd0cb8a 7792 /* Clear up various bits and pieces from authentication. */
7793 if (s->publickey_blob) {
7794 sfree(s->publickey_blob);
7795 sfree(s->publickey_comment);
7796 }
94cd7c3a 7797 if (s->agent_response)
7798 sfree(s->agent_response);
edd0cb8a 7799
7cca0d81 7800 /*
a1a1fae4 7801 * Now the connection protocol has started, one way or another.
7cca0d81 7802 */
7803
0ed48730 7804 ssh->channels = newtree234(ssh_channelcmp);
7805
7cca0d81 7806 /*
b09eaa88 7807 * Set up handlers for some connection protocol messages, so we
7808 * don't have to handle them repeatedly in this coroutine.
7809 */
7810 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] =
7811 ssh2_msg_channel_window_adjust;
51df0ab5 7812 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] =
7813 ssh2_msg_global_request;
b09eaa88 7814
7815 /*
0ed48730 7816 * Create the main session channel.
7cca0d81 7817 */
feb02b4e 7818 if (ssh->cfg.ssh_no_shell) {
7819 ssh->mainchan = NULL;
7820 } else if (*ssh->cfg.ssh_nc_host) {
7821 /*
7822 * Just start a direct-tcpip channel and use it as the main
7823 * channel.
7824 */
7825 ssh->mainchan = snew(struct ssh_channel);
7826 ssh->mainchan->ssh = ssh;
7827 ssh->mainchan->localid = alloc_channel_id(ssh);
23828b7e 7828 logeventf(ssh,
7829 "Opening direct-tcpip channel to %s:%d in place of session",
7830 ssh->cfg.ssh_nc_host, ssh->cfg.ssh_nc_port);
feb02b4e 7831 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
7832 ssh2_pkt_addstring(s->pktout, "direct-tcpip");
7833 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
7834 ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
7835 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
7836 ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT); /* our max pkt size */
7837 ssh2_pkt_addstring(s->pktout, ssh->cfg.ssh_nc_host);
7838 ssh2_pkt_adduint32(s->pktout, ssh->cfg.ssh_nc_port);
7839 /*
23828b7e 7840 * There's nothing meaningful to put in the originator
7841 * fields, but some servers insist on syntactically correct
7842 * information.
feb02b4e 7843 */
7844 ssh2_pkt_addstring(s->pktout, "0.0.0.0");
7845 ssh2_pkt_adduint32(s->pktout, 0);
7846 ssh2_pkt_send(ssh, s->pktout);
7847
7848 crWaitUntilV(pktin);
7849 if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
7850 bombout(("Server refused to open a direct-tcpip channel"));
7851 crStopV;
7852 /* FIXME: error data comes back in FAILURE packet */
7853 }
7854 if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
7855 bombout(("Server's channel confirmation cited wrong channel"));
7856 crStopV;
7857 }
7858 ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
7859 ssh->mainchan->halfopen = FALSE;
7860 ssh->mainchan->type = CHAN_MAINSESSION;
7861 ssh->mainchan->closes = 0;
7862 ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
7863 ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
7864 bufchain_init(&ssh->mainchan->v.v2.outbuffer);
7865 add234(ssh->channels, ssh->mainchan);
7866 update_specials_menu(ssh->frontend);
23828b7e 7867 logevent("Opened direct-tcpip channel");
feb02b4e 7868 ssh->ncmode = TRUE;
7869 } else {
0ed48730 7870 ssh->mainchan = snew(struct ssh_channel);
7871 ssh->mainchan->ssh = ssh;
7872 ssh->mainchan->localid = alloc_channel_id(ssh);
ff3187f6 7873 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
7874 ssh2_pkt_addstring(s->pktout, "session");
7875 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
0ed48730 7876 ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
ff3187f6 7877 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
954d5c5a 7878 ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT); /* our max pkt size */
ff3187f6 7879 ssh2_pkt_send(ssh, s->pktout);
7880 crWaitUntilV(pktin);
7881 if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
0ed48730 7882 bombout(("Server refused to open a session"));
7883 crStopV;
7884 /* FIXME: error data comes back in FAILURE packet */
7885 }
ff3187f6 7886 if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
0ed48730 7887 bombout(("Server's channel confirmation cited wrong channel"));
7888 crStopV;
7889 }
ff3187f6 7890 ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
64d6ff88 7891 ssh->mainchan->halfopen = FALSE;
0ed48730 7892 ssh->mainchan->type = CHAN_MAINSESSION;
7893 ssh->mainchan->closes = 0;
ff3187f6 7894 ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
7895 ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
0ed48730 7896 bufchain_init(&ssh->mainchan->v.v2.outbuffer);
7897 add234(ssh->channels, ssh->mainchan);
62638676 7898 update_specials_menu(ssh->frontend);
0ed48730 7899 logevent("Opened channel for session");
feb02b4e 7900 ssh->ncmode = FALSE;
7901 }
7cca0d81 7902
7903 /*
51df0ab5 7904 * Now we have a channel, make dispatch table entries for
7905 * general channel-based messages.
7906 */
7907 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] =
7908 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] =
7909 ssh2_msg_channel_data;
7910 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_channel_eof;
7911 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_channel_close;
7912 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] =
7913 ssh2_msg_channel_open_confirmation;
7914 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] =
7915 ssh2_msg_channel_open_failure;
7916 ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] =
7917 ssh2_msg_channel_request;
7918 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] =
7919 ssh2_msg_channel_open;
7920
7921 /*
783415f8 7922 * Potentially enable X11 forwarding.
7923 */
feb02b4e 7924 if (ssh->mainchan && !ssh->ncmode && ssh->cfg.x11_forward) {
32874aea 7925 char proto[20], data[64];
7926 logevent("Requesting X11 forwarding");
302121de 7927 ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
86916870 7928 data, sizeof(data), ssh->cfg.x11_auth);
7929 x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
ff3187f6 7930 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7931 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
7932 ssh2_pkt_addstring(s->pktout, "x11-req");
7933 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
7934 ssh2_pkt_addbool(s->pktout, 0); /* many connections */
7935 ssh2_pkt_addstring(s->pktout, proto);
f68353be 7936 /*
7937 * Note that while we blank the X authentication data here, we don't
7938 * take any special action to blank the start of an X11 channel,
7939 * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
7940 * without having session blanking enabled is likely to leak your
7941 * cookie into the log.
7942 */
178c3872 7943 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
ff3187f6 7944 ssh2_pkt_addstring(s->pktout, data);
178c3872 7945 end_log_omission(ssh, s->pktout);
ff3187f6 7946 ssh2_pkt_adduint32(s->pktout, x11_get_screen_number(ssh->cfg.x11_display));
7947 ssh2_pkt_send(ssh, s->pktout);
32874aea 7948
b09eaa88 7949 crWaitUntilV(pktin);
32874aea 7950
ff3187f6 7951 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
7952 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 7953 bombout(("Unexpected response to X11 forwarding request:"
ff3187f6 7954 " packet type %d", pktin->type));
7ffdbc1a 7955 crStopV;
32874aea 7956 }
7957 logevent("X11 forwarding refused");
7958 } else {
7959 logevent("X11 forwarding enabled");
51470298 7960 ssh->X11_fwd_enabled = TRUE;
32874aea 7961 }
783415f8 7962 }
7963
7964 /*
bc240b21 7965 * Enable port forwardings.
7966 */
06fadff5 7967 ssh_setup_portfwd(ssh, &ssh->cfg);
bc240b21 7968
7969 /*
36c2a3e9 7970 * Potentially enable agent forwarding.
7971 */
feb02b4e 7972 if (ssh->mainchan && !ssh->ncmode && ssh->cfg.agentfwd && agent_exists()) {
32874aea 7973 logevent("Requesting OpenSSH-style agent forwarding");
ff3187f6 7974 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7975 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
7976 ssh2_pkt_addstring(s->pktout, "auth-agent-req@openssh.com");
7977 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
7978 ssh2_pkt_send(ssh, s->pktout);
32874aea 7979
b09eaa88 7980 crWaitUntilV(pktin);
32874aea 7981
ff3187f6 7982 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
7983 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 7984 bombout(("Unexpected response to agent forwarding request:"
ff3187f6 7985 " packet type %d", pktin->type));
7ffdbc1a 7986 crStopV;
32874aea 7987 }
7988 logevent("Agent forwarding refused");
7989 } else {
7990 logevent("Agent forwarding enabled");
51470298 7991 ssh->agentfwd_enabled = TRUE;
32874aea 7992 }
36c2a3e9 7993 }
7994
7995 /*
7cca0d81 7996 * Now allocate a pty for the session.
7997 */
feb02b4e 7998 if (ssh->mainchan && !ssh->ncmode && !ssh->cfg.nopty) {
a5dd8467 7999 /* Unpick the terminal-speed string. */
8000 /* XXX perhaps we should allow no speeds to be sent. */
db219738 8001 ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
8002 sscanf(ssh->cfg.termspeed, "%d,%d", &ssh->ospeed, &ssh->ispeed);
a5dd8467 8003 /* Build the pty request. */
ff3187f6 8004 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8005 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); /* recipient channel */
8006 ssh2_pkt_addstring(s->pktout, "pty-req");
8007 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8008 ssh2_pkt_addstring(s->pktout, ssh->cfg.termtype);
8009 ssh2_pkt_adduint32(s->pktout, ssh->term_width);
8010 ssh2_pkt_adduint32(s->pktout, ssh->term_height);
8011 ssh2_pkt_adduint32(s->pktout, 0); /* pixel width */
8012 ssh2_pkt_adduint32(s->pktout, 0); /* pixel height */
8013 ssh2_pkt_addstring_start(s->pktout);
c6ccd5c2 8014 parse_ttymodes(ssh, ssh->cfg.ttymodes,
8015 ssh2_send_ttymode, (void *)s->pktout);
8016 ssh2_pkt_addbyte(s->pktout, SSH2_TTY_OP_ISPEED);
ff3187f6 8017 ssh2_pkt_adduint32(s->pktout, ssh->ispeed);
c6ccd5c2 8018 ssh2_pkt_addbyte(s->pktout, SSH2_TTY_OP_OSPEED);
ff3187f6 8019 ssh2_pkt_adduint32(s->pktout, ssh->ospeed);
8020 ssh2_pkt_addstring_data(s->pktout, "\0", 1); /* TTY_OP_END */
8021 ssh2_pkt_send(ssh, s->pktout);
51470298 8022 ssh->state = SSH_STATE_INTERMED;
32874aea 8023
b09eaa88 8024 crWaitUntilV(pktin);
32874aea 8025
ff3187f6 8026 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8027 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8028 bombout(("Unexpected response to pty request:"
ff3187f6 8029 " packet type %d", pktin->type));
7ffdbc1a 8030 crStopV;
32874aea 8031 }
51470298 8032 c_write_str(ssh, "Server refused to allocate pty\r\n");
8033 ssh->editing = ssh->echoing = 1;
32874aea 8034 } else {
a5dd8467 8035 logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
db219738 8036 ssh->ospeed, ssh->ispeed);
32874aea 8037 }
0965bee0 8038 } else {
51470298 8039 ssh->editing = ssh->echoing = 1;
7cca0d81 8040 }
8041
8042 /*
73feed4f 8043 * Send environment variables.
8044 *
8045 * Simplest thing here is to send all the requests at once, and
8046 * then wait for a whole bunch of successes or failures.
8047 */
feb02b4e 8048 if (ssh->mainchan && !ssh->ncmode && *ssh->cfg.environmt) {
73feed4f 8049 char *e = ssh->cfg.environmt;
8050 char *var, *varend, *val;
8051
8052 s->num_env = 0;
8053
8054 while (*e) {
8055 var = e;
8056 while (*e && *e != '\t') e++;
8057 varend = e;
8058 if (*e == '\t') e++;
8059 val = e;
8060 while (*e) e++;
8061 e++;
8062
ff3187f6 8063 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8064 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
8065 ssh2_pkt_addstring(s->pktout, "env");
8066 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8067 ssh2_pkt_addstring_start(s->pktout);
8068 ssh2_pkt_addstring_data(s->pktout, var, varend-var);
8069 ssh2_pkt_addstring(s->pktout, val);
8070 ssh2_pkt_send(ssh, s->pktout);
73feed4f 8071
8072 s->num_env++;
8073 }
8074
8075 logeventf(ssh, "Sent %d environment variables", s->num_env);
8076
8077 s->env_ok = 0;
8078 s->env_left = s->num_env;
8079
8080 while (s->env_left > 0) {
b09eaa88 8081 crWaitUntilV(pktin);
73feed4f 8082
ff3187f6 8083 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8084 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
73feed4f 8085 bombout(("Unexpected response to environment request:"
ff3187f6 8086 " packet type %d", pktin->type));
73feed4f 8087 crStopV;
8088 }
8089 } else {
8090 s->env_ok++;
8091 }
8092
8093 s->env_left--;
8094 }
8095
8096 if (s->env_ok == s->num_env) {
8097 logevent("All environment variables successfully set");
8098 } else if (s->env_ok == 0) {
8099 logevent("All environment variables refused");
8100 c_write_str(ssh, "Server refused to set environment variables\r\n");
8101 } else {
8102 logeventf(ssh, "%d environment variables refused",
8103 s->num_env - s->env_ok);
8104 c_write_str(ssh, "Server refused to set all environment variables\r\n");
8105 }
8106 }
8107
8108 /*
fd5e5847 8109 * Start a shell or a remote command. We may have to attempt
8110 * this twice if the config data has provided a second choice
8111 * of command.
7cca0d81 8112 */
feb02b4e 8113 if (ssh->mainchan && !ssh->ncmode) while (1) {
fd5e5847 8114 int subsys;
8115 char *cmd;
8116
51470298 8117 if (ssh->fallback_cmd) {
86916870 8118 subsys = ssh->cfg.ssh_subsys2;
8119 cmd = ssh->cfg.remote_cmd_ptr2;
fd5e5847 8120 } else {
86916870 8121 subsys = ssh->cfg.ssh_subsys;
8122 cmd = ssh->cfg.remote_cmd_ptr;
04c52f10 8123 if (!cmd) cmd = ssh->cfg.remote_cmd;
fd5e5847 8124 }
8125
ff3187f6 8126 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8127 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); /* recipient channel */
fd5e5847 8128 if (subsys) {
ff3187f6 8129 ssh2_pkt_addstring(s->pktout, "subsystem");
8130 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8131 ssh2_pkt_addstring(s->pktout, cmd);
fd5e5847 8132 } else if (*cmd) {
ff3187f6 8133 ssh2_pkt_addstring(s->pktout, "exec");
8134 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8135 ssh2_pkt_addstring(s->pktout, cmd);
fd5e5847 8136 } else {
ff3187f6 8137 ssh2_pkt_addstring(s->pktout, "shell");
8138 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
32874aea 8139 }
ff3187f6 8140 ssh2_pkt_send(ssh, s->pktout);
b09eaa88 8141
8142 crWaitUntilV(pktin);
8143
ff3187f6 8144 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8145 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8146 bombout(("Unexpected response to shell/command request:"
ff3187f6 8147 " packet type %d", pktin->type));
7ffdbc1a 8148 crStopV;
fd5e5847 8149 }
8150 /*
8151 * We failed to start the command. If this is the
8152 * fallback command, we really are finished; if it's
8153 * not, and if the fallback command exists, try falling
8154 * back to it before complaining.
8155 */
86916870 8156 if (!ssh->fallback_cmd && ssh->cfg.remote_cmd_ptr2 != NULL) {
fd5e5847 8157 logevent("Primary command failed; attempting fallback");
51470298 8158 ssh->fallback_cmd = TRUE;
fd5e5847 8159 continue;
8160 }
6b5cf8b4 8161 bombout(("Server refused to start a shell/command"));
7ffdbc1a 8162 crStopV;
fd5e5847 8163 } else {
8164 logevent("Started a shell/command");
32874aea 8165 }
fd5e5847 8166 break;
7cca0d81 8167 }
8168
51470298 8169 ssh->state = SSH_STATE_SESSION;
8170 if (ssh->size_needed)
8171 ssh_size(ssh, ssh->term_width, ssh->term_height);
8172 if (ssh->eof_needed)
8173 ssh_special(ssh, TS_EOF);
6e48c3fe 8174
7cca0d81 8175 /*
8176 * Transfer data!
8177 */
b9d7bcad 8178 if (ssh->ldisc)
8179 ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
0ed48730 8180 if (ssh->mainchan)
8181 ssh->send_ok = 1;
7cca0d81 8182 while (1) {
e5574168 8183 crReturnV;
51470298 8184 s->try_send = FALSE;
ff3187f6 8185 if (pktin) {
2b7540a7 8186
51df0ab5 8187 /*
8188 * _All_ the connection-layer packets we expect to
8189 * receive are now handled by the dispatch table.
8190 * Anything that reaches here must be bogus.
8191 */
32874aea 8192
51df0ab5 8193 bombout(("Strange packet received: type %d", pktin->type));
8194 crStopV;
0ed48730 8195 } else if (ssh->mainchan) {
32874aea 8196 /*
8197 * We have spare data. Add it to the channel buffer.
8198 */
d8baa528 8199 ssh2_add_channel_data(ssh->mainchan, (char *)in, inlen);
51470298 8200 s->try_send = TRUE;
32874aea 8201 }
51470298 8202 if (s->try_send) {
32874aea 8203 int i;
8204 struct ssh_channel *c;
8205 /*
8206 * Try to send data on all channels if we can.
8207 */
1bfc7e93 8208 for (i = 0; NULL != (c = index234(ssh->channels, i)); i++)
8209 ssh2_try_send_and_unthrottle(c);
7cca0d81 8210 }
e5574168 8211 }
8212
8213 crFinishV;
8214}
8215
8216/*
2e85c969 8217 * Handlers for SSH-2 messages that might arrive at any moment.
b09eaa88 8218 */
409bfa77 8219static void ssh2_msg_disconnect(Ssh ssh, struct Packet *pktin)
b09eaa88 8220{
8221 /* log reason code in disconnect message */
8222 char *buf, *msg;
8223 int nowlen, reason, msglen;
8224
8225 reason = ssh_pkt_getuint32(pktin);
8226 ssh_pkt_getstring(pktin, &msg, &msglen);
8227
8228 if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {
8229 buf = dupprintf("Received disconnect message (%s)",
8230 ssh2_disconnect_reasons[reason]);
8231 } else {
8232 buf = dupprintf("Received disconnect message (unknown"
8233 " type %d)", reason);
8234 }
8235 logevent(buf);
8236 sfree(buf);
8237 buf = dupprintf("Disconnection message text: %n%.*s",
8238 &nowlen, msglen, msg);
8239 logevent(buf);
8240 bombout(("Server sent disconnect message\ntype %d (%s):\n\"%s\"",
8241 reason,
8242 (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?
8243 ssh2_disconnect_reasons[reason] : "unknown",
8244 buf+nowlen));
8245 sfree(buf);
8246}
8247
409bfa77 8248static void ssh2_msg_debug(Ssh ssh, struct Packet *pktin)
b09eaa88 8249{
8250 /* log the debug message */
fb983202 8251 char *msg;
b09eaa88 8252 int msglen;
8253 int always_display;
8254
8255 /* XXX maybe we should actually take notice of this */
8256 always_display = ssh2_pkt_getbool(pktin);
8257 ssh_pkt_getstring(pktin, &msg, &msglen);
8258
fb983202 8259 logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
b09eaa88 8260}
8261
409bfa77 8262static void ssh2_msg_something_unimplemented(Ssh ssh, struct Packet *pktin)
b09eaa88 8263{
8264 struct Packet *pktout;
8265 pktout = ssh2_pkt_init(SSH2_MSG_UNIMPLEMENTED);
8266 ssh2_pkt_adduint32(pktout, pktin->sequence);
8267 /*
8268 * UNIMPLEMENTED messages MUST appear in the same order as the
8269 * messages they respond to. Hence, never queue them.
8270 */
8271 ssh2_pkt_send_noqueue(ssh, pktout);
8272}
8273
8274/*
2e85c969 8275 * Handle the top-level SSH-2 protocol.
7cca0d81 8276 */
b09eaa88 8277static void ssh2_protocol_setup(Ssh ssh)
8278{
8279 int i;
8280
8281 /*
8282 * Most messages cause SSH2_MSG_UNIMPLEMENTED.
8283 */
8284 for (i = 0; i < 256; i++)
8285 ssh->packet_dispatch[i] = ssh2_msg_something_unimplemented;
8286
8287 /*
8288 * Any message we actually understand, we set to NULL so that
8289 * the coroutines will get it.
8290 */
8291 ssh->packet_dispatch[SSH2_MSG_UNIMPLEMENTED] = NULL;
8292 ssh->packet_dispatch[SSH2_MSG_SERVICE_REQUEST] = NULL;
8293 ssh->packet_dispatch[SSH2_MSG_SERVICE_ACCEPT] = NULL;
8294 ssh->packet_dispatch[SSH2_MSG_KEXINIT] = NULL;
8295 ssh->packet_dispatch[SSH2_MSG_NEWKEYS] = NULL;
8296 ssh->packet_dispatch[SSH2_MSG_KEXDH_INIT] = NULL;
8297 ssh->packet_dispatch[SSH2_MSG_KEXDH_REPLY] = NULL;
8298 /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REQUEST] = NULL; duplicate case value */
8299 /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_GROUP] = NULL; duplicate case value */
8300 ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_INIT] = NULL;
8301 ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REPLY] = NULL;
8302 ssh->packet_dispatch[SSH2_MSG_USERAUTH_REQUEST] = NULL;
8303 ssh->packet_dispatch[SSH2_MSG_USERAUTH_FAILURE] = NULL;
8304 ssh->packet_dispatch[SSH2_MSG_USERAUTH_SUCCESS] = NULL;
8305 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
8306 ssh->packet_dispatch[SSH2_MSG_USERAUTH_PK_OK] = NULL;
8307 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ] = NULL; duplicate case value */
8308 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_REQUEST] = NULL; duplicate case value */
8309 ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_RESPONSE] = NULL;
8310 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] = NULL;
8311 ssh->packet_dispatch[SSH2_MSG_REQUEST_SUCCESS] = NULL;
8312 ssh->packet_dispatch[SSH2_MSG_REQUEST_FAILURE] = NULL;
8313 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = NULL;
8314 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] = NULL;
8315 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] = NULL;
8316 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] = NULL;
8317 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] = NULL;
8318 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] = NULL;
8319 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = NULL;
8320 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = NULL;
8321 ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] = NULL;
8322 ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = NULL;
8323 ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = NULL;
8324
8325 /*
8326 * These special message types we install handlers for.
8327 */
8328 ssh->packet_dispatch[SSH2_MSG_DISCONNECT] = ssh2_msg_disconnect;
2e85c969 8329 ssh->packet_dispatch[SSH2_MSG_IGNORE] = ssh_msg_ignore; /* shared with SSH-1 */
b09eaa88 8330 ssh->packet_dispatch[SSH2_MSG_DEBUG] = ssh2_msg_debug;
8331}
8332
9442dd57 8333static void ssh2_timer(void *ctx, long now)
8334{
8335 Ssh ssh = (Ssh)ctx;
8336
ecbb0000 8337 if (ssh->state == SSH_STATE_CLOSED)
8338 return;
8339
e6c1536e 8340 if (!ssh->kex_in_progress && ssh->cfg.ssh_rekey_time != 0 &&
9442dd57 8341 now - ssh->next_rekey >= 0) {
f382c87d 8342 do_ssh2_transport(ssh, "timeout", -1, NULL);
9442dd57 8343 }
8344}
8345
1c1a7262 8346static void ssh2_protocol(Ssh ssh, void *vin, int inlen,
ff3187f6 8347 struct Packet *pktin)
7cca0d81 8348{
1c1a7262 8349 unsigned char *in = (unsigned char *)vin;
b09eaa88 8350 if (ssh->state == SSH_STATE_CLOSED)
8351 return;
8352
9442dd57 8353 if (pktin) {
8354 ssh->incoming_data_size += pktin->encrypted_len;
8355 if (!ssh->kex_in_progress &&
d57f70af 8356 ssh->max_data_size != 0 &&
8357 ssh->incoming_data_size > ssh->max_data_size)
f382c87d 8358 do_ssh2_transport(ssh, "too much data received", -1, NULL);
9442dd57 8359 }
8360
b09eaa88 8361 if (pktin && ssh->packet_dispatch[pktin->type]) {
8362 ssh->packet_dispatch[pktin->type](ssh, pktin);
32874aea 8363 return;
b09eaa88 8364 }
8365
8366 if (!ssh->protocol_initial_phase_done ||
8367 (pktin && pktin->type >= 20 && pktin->type < 50)) {
8368 if (do_ssh2_transport(ssh, in, inlen, pktin) &&
8369 !ssh->protocol_initial_phase_done) {
8370 ssh->protocol_initial_phase_done = TRUE;
8371 /*
8372 * Allow authconn to initialise itself.
8373 */
8374 do_ssh2_authconn(ssh, NULL, 0, NULL);
8375 }
8376 } else {
8377 do_ssh2_authconn(ssh, in, inlen, pktin);
8378 }
7cca0d81 8379}
8380
8381/*
8df7a775 8382 * Called to set up the connection.
374330e2 8383 *
8384 * Returns an error message, or NULL on success.
374330e2 8385 */
cbe2d68f 8386static const char *ssh_init(void *frontend_handle, void **backend_handle,
8387 Config *cfg,
79bf227b 8388 char *host, int port, char **realhost, int nodelay,
8389 int keepalive)
32874aea 8390{
cbe2d68f 8391 const char *p;
51470298 8392 Ssh ssh;
8393
3d88e64d 8394 ssh = snew(struct ssh_tag);
86916870 8395 ssh->cfg = *cfg; /* STRUCTURE COPY */
125105d1 8396 ssh->version = 0; /* when not ready yet */
51470298 8397 ssh->s = NULL;
8398 ssh->cipher = NULL;
371e569c 8399 ssh->v1_cipher_ctx = NULL;
0183b242 8400 ssh->crcda_ctx = NULL;
51470298 8401 ssh->cscipher = NULL;
371e569c 8402 ssh->cs_cipher_ctx = NULL;
51470298 8403 ssh->sccipher = NULL;
371e569c 8404 ssh->sc_cipher_ctx = NULL;
51470298 8405 ssh->csmac = NULL;
a8327734 8406 ssh->cs_mac_ctx = NULL;
51470298 8407 ssh->scmac = NULL;
e0e1a00d 8408 ssh->sc_mac_ctx = NULL;
51470298 8409 ssh->cscomp = NULL;
5366aed8 8410 ssh->cs_comp_ctx = NULL;
51470298 8411 ssh->sccomp = NULL;
5366aed8 8412 ssh->sc_comp_ctx = NULL;
51470298 8413 ssh->kex = NULL;
389aa499 8414 ssh->kex_ctx = NULL;
51470298 8415 ssh->hostkey = NULL;
8416 ssh->exitcode = -1;
ac934965 8417 ssh->close_expected = FALSE;
9e296bfa 8418 ssh->clean_exit = FALSE;
51470298 8419 ssh->state = SSH_STATE_PREPACKET;
8420 ssh->size_needed = FALSE;
8421 ssh->eof_needed = FALSE;
b9d7bcad 8422 ssh->ldisc = NULL;
a8327734 8423 ssh->logctx = NULL;
51470298 8424 ssh->deferred_send_data = NULL;
8425 ssh->deferred_len = 0;
8426 ssh->deferred_size = 0;
8427 ssh->fallback_cmd = 0;
8428 ssh->pkt_ctx = 0;
302121de 8429 ssh->x11auth = NULL;
be738459 8430 ssh->v1_compressing = FALSE;
51470298 8431 ssh->v2_outgoing_sequence = 0;
8432 ssh->ssh1_rdpkt_crstate = 0;
8433 ssh->ssh2_rdpkt_crstate = 0;
8434 ssh->do_ssh_init_crstate = 0;
8435 ssh->ssh_gotdata_crstate = 0;
b09eaa88 8436 ssh->do_ssh1_connection_crstate = 0;
51470298 8437 ssh->do_ssh1_login_crstate = 0;
8438 ssh->do_ssh2_transport_crstate = 0;
8439 ssh->do_ssh2_authconn_crstate = 0;
8440 ssh->do_ssh_init_state = NULL;
8441 ssh->do_ssh1_login_state = NULL;
8442 ssh->do_ssh2_transport_state = NULL;
8443 ssh->do_ssh2_authconn_state = NULL;
4320baf7 8444 ssh->v_c = NULL;
8445 ssh->v_s = NULL;
6571dbfd 8446 ssh->mainchan = NULL;
968d2d92 8447 ssh->throttled_all = 0;
8448 ssh->v1_stdout_throttling = 0;
590f6a5f 8449 ssh->queue = NULL;
8450 ssh->queuelen = ssh->queuesize = 0;
8451 ssh->queueing = FALSE;
06fadff5 8452 ssh->qhead = ssh->qtail = NULL;
e13bba36 8453 ssh->deferred_rekey_reason = NULL;
3d9449a1 8454 bufchain_init(&ssh->queued_incoming_data);
8455 ssh->frozen = FALSE;
51470298 8456
8457 *backend_handle = ssh;
32874aea 8458
8f203108 8459#ifdef MSCRYPTOAPI
32874aea 8460 if (crypto_startup() == 0)
8f203108 8461 return "Microsoft high encryption pack not installed!";
8462#endif
374330e2 8463
51470298 8464 ssh->frontend = frontend_handle;
86916870 8465 ssh->term_width = ssh->cfg.width;
8466 ssh->term_height = ssh->cfg.height;
887035a5 8467
fabd1805 8468 ssh->channels = NULL;
8469 ssh->rportfwds = NULL;
f47a5ffb 8470 ssh->portfwds = NULL;
fabd1805 8471
51470298 8472 ssh->send_ok = 0;
8473 ssh->editing = 0;
8474 ssh->echoing = 0;
8475 ssh->v1_throttle_count = 0;
8476 ssh->overall_bufsize = 0;
8477 ssh->fallback_cmd = 0;
8df7a775 8478
3648d4c5 8479 ssh->protocol = NULL;
8480
b09eaa88 8481 ssh->protocol_initial_phase_done = FALSE;
8482
39934deb 8483 ssh->pinger = NULL;
8484
9442dd57 8485 ssh->incoming_data_size = ssh->outgoing_data_size =
8486 ssh->deferred_data_size = 0L;
d57f70af 8487 ssh->max_data_size = parse_blocksize(ssh->cfg.ssh_rekey_data);
9442dd57 8488 ssh->kex_in_progress = FALSE;
8489
79bf227b 8490 p = connect_to_host(ssh, host, port, realhost, nodelay, keepalive);
fb09bf1c 8491 if (p != NULL)
8492 return p;
374330e2 8493
5d17ccfc 8494 random_ref();
8495
374330e2 8496 return NULL;
8497}
8498
fabd1805 8499static void ssh_free(void *handle)
8500{
8501 Ssh ssh = (Ssh) handle;
8502 struct ssh_channel *c;
8503 struct ssh_rportfwd *pf;
8504
8505 if (ssh->v1_cipher_ctx)
8506 ssh->cipher->free_context(ssh->v1_cipher_ctx);
8507 if (ssh->cs_cipher_ctx)
8508 ssh->cscipher->free_context(ssh->cs_cipher_ctx);
8509 if (ssh->sc_cipher_ctx)
8510 ssh->sccipher->free_context(ssh->sc_cipher_ctx);
8511 if (ssh->cs_mac_ctx)
8512 ssh->csmac->free_context(ssh->cs_mac_ctx);
8513 if (ssh->sc_mac_ctx)
8514 ssh->scmac->free_context(ssh->sc_mac_ctx);
29b1d0b3 8515 if (ssh->cs_comp_ctx) {
8516 if (ssh->cscomp)
8517 ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
8518 else
8519 zlib_compress_cleanup(ssh->cs_comp_ctx);
8520 }
8521 if (ssh->sc_comp_ctx) {
8522 if (ssh->sccomp)
8523 ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
8524 else
8525 zlib_decompress_cleanup(ssh->sc_comp_ctx);
8526 }
fabd1805 8527 if (ssh->kex_ctx)
8528 dh_cleanup(ssh->kex_ctx);
8529 sfree(ssh->savedhost);
8530
590f6a5f 8531 while (ssh->queuelen-- > 0)
8532 ssh_free_packet(ssh->queue[ssh->queuelen]);
8533 sfree(ssh->queue);
8534
06fadff5 8535 while (ssh->qhead) {
8536 struct queued_handler *qh = ssh->qhead;
8537 ssh->qhead = qh->next;
8538 sfree(ssh->qhead);
8539 }
8540 ssh->qhead = ssh->qtail = NULL;
8541
fabd1805 8542 if (ssh->channels) {
8543 while ((c = delpos234(ssh->channels, 0)) != NULL) {
8544 switch (c->type) {
8545 case CHAN_X11:
8546 if (c->u.x11.s != NULL)
8547 x11_close(c->u.x11.s);
8548 break;
8549 case CHAN_SOCKDATA:
8550 if (c->u.pfd.s != NULL)
8551 pfd_close(c->u.pfd.s);
8552 break;
8553 }
8554 sfree(c);
8555 }
8556 freetree234(ssh->channels);
cdb52705 8557 ssh->channels = NULL;
fabd1805 8558 }
8559
8560 if (ssh->rportfwds) {
8561 while ((pf = delpos234(ssh->rportfwds, 0)) != NULL)
8562 sfree(pf);
8563 freetree234(ssh->rportfwds);
cdb52705 8564 ssh->rportfwds = NULL;
fabd1805 8565 }
8566 sfree(ssh->deferred_send_data);
8567 if (ssh->x11auth)
8568 x11_free_auth(ssh->x11auth);
8569 sfree(ssh->do_ssh_init_state);
8570 sfree(ssh->do_ssh1_login_state);
8571 sfree(ssh->do_ssh2_transport_state);
8572 sfree(ssh->do_ssh2_authconn_state);
4320baf7 8573 sfree(ssh->v_c);
8574 sfree(ssh->v_s);
679539d7 8575 if (ssh->crcda_ctx) {
8576 crcda_free_context(ssh->crcda_ctx);
8577 ssh->crcda_ctx = NULL;
8578 }
fabd1805 8579 if (ssh->s)
ac934965 8580 ssh_do_close(ssh, TRUE);
9442dd57 8581 expire_timer_context(ssh);
39934deb 8582 if (ssh->pinger)
8583 pinger_free(ssh->pinger);
3d9449a1 8584 bufchain_clear(&ssh->queued_incoming_data);
ee50e8b6 8585 sfree(ssh);
5d17ccfc 8586
8587 random_unref();
fabd1805 8588}
8589
374330e2 8590/*
86916870 8591 * Reconfigure the SSH backend.
86916870 8592 */
8593static void ssh_reconfig(void *handle, Config *cfg)
8594{
8595 Ssh ssh = (Ssh) handle;
e13bba36 8596 char *rekeying = NULL, rekey_mandatory = FALSE;
e6c1536e 8597 unsigned long old_max_data_size;
8598
39934deb 8599 pinger_reconfig(ssh->pinger, &ssh->cfg, cfg);
3b6606c7 8600 if (ssh->portfwds)
8601 ssh_setup_portfwd(ssh, cfg);
e6c1536e 8602
8603 if (ssh->cfg.ssh_rekey_time != cfg->ssh_rekey_time &&
8604 cfg->ssh_rekey_time != 0) {
8605 long new_next = ssh->last_rekey + cfg->ssh_rekey_time*60*TICKSPERSEC;
8606 long now = GETTICKCOUNT();
8607
8608 if (new_next - now < 0) {
f382c87d 8609 rekeying = "timeout shortened";
e6c1536e 8610 } else {
8611 ssh->next_rekey = schedule_timer(new_next - now, ssh2_timer, ssh);
8612 }
8613 }
8614
8615 old_max_data_size = ssh->max_data_size;
8616 ssh->max_data_size = parse_blocksize(cfg->ssh_rekey_data);
8617 if (old_max_data_size != ssh->max_data_size &&
8618 ssh->max_data_size != 0) {
8619 if (ssh->outgoing_data_size > ssh->max_data_size ||
8620 ssh->incoming_data_size > ssh->max_data_size)
f382c87d 8621 rekeying = "data limit lowered";
e6c1536e 8622 }
8623
e13bba36 8624 if (ssh->cfg.compression != cfg->compression) {
f382c87d 8625 rekeying = "compression setting changed";
e13bba36 8626 rekey_mandatory = TRUE;
8627 }
8628
8629 if (ssh->cfg.ssh2_des_cbc != cfg->ssh2_des_cbc ||
8630 memcmp(ssh->cfg.ssh_cipherlist, cfg->ssh_cipherlist,
8631 sizeof(ssh->cfg.ssh_cipherlist))) {
f382c87d 8632 rekeying = "cipher settings changed";
e13bba36 8633 rekey_mandatory = TRUE;
e6c1536e 8634 }
8635
86916870 8636 ssh->cfg = *cfg; /* STRUCTURE COPY */
e13bba36 8637
8638 if (rekeying) {
8639 if (!ssh->kex_in_progress) {
8640 do_ssh2_transport(ssh, rekeying, -1, NULL);
8641 } else if (rekey_mandatory) {
8642 ssh->deferred_rekey_reason = rekeying;
8643 }
8644 }
86916870 8645}
8646
8647/*
86dc445a 8648 * Called to send data down the SSH connection.
374330e2 8649 */
51470298 8650static int ssh_send(void *handle, char *buf, int len)
32874aea 8651{
51470298 8652 Ssh ssh = (Ssh) handle;
8653
8654 if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
5471d09a 8655 return 0;
374330e2 8656
d8baa528 8657 ssh->protocol(ssh, (unsigned char *)buf, len, 0);
5471d09a 8658
51470298 8659 return ssh_sendbuffer(ssh);
5471d09a 8660}
8661
8662/*
8663 * Called to query the current amount of buffered stdin data.
8664 */
51470298 8665static int ssh_sendbuffer(void *handle)
5471d09a 8666{
51470298 8667 Ssh ssh = (Ssh) handle;
5471d09a 8668 int override_value;
8669
51470298 8670 if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
5471d09a 8671 return 0;
8672
8673 /*
8674 * If the SSH socket itself has backed up, add the total backup
8675 * size on that to any individual buffer on the stdin channel.
8676 */
8677 override_value = 0;
51470298 8678 if (ssh->throttled_all)
8679 override_value = ssh->overall_bufsize;
5471d09a 8680
51470298 8681 if (ssh->version == 1) {
5471d09a 8682 return override_value;
51470298 8683 } else if (ssh->version == 2) {
8684 if (!ssh->mainchan || ssh->mainchan->closes > 0)
5471d09a 8685 return override_value;
8686 else
51470298 8687 return (override_value +
8688 bufchain_size(&ssh->mainchan->v.v2.outbuffer));
5471d09a 8689 }
8690
8691 return 0;
374330e2 8692}
8693
8694/*
6e48c3fe 8695 * Called to set the size of the window from SSH's POV.
374330e2 8696 */
51470298 8697static void ssh_size(void *handle, int width, int height)
32874aea 8698{
51470298 8699 Ssh ssh = (Ssh) handle;
ff3187f6 8700 struct Packet *pktout;
51470298 8701
8702 ssh->term_width = width;
8703 ssh->term_height = height;
f278d6f8 8704
51470298 8705 switch (ssh->state) {
374330e2 8706 case SSH_STATE_BEFORE_SIZE:
3687d221 8707 case SSH_STATE_PREPACKET:
21248260 8708 case SSH_STATE_CLOSED:
374330e2 8709 break; /* do nothing */
8710 case SSH_STATE_INTERMED:
51470298 8711 ssh->size_needed = TRUE; /* buffer for later */
374330e2 8712 break;
8713 case SSH_STATE_SESSION:
86916870 8714 if (!ssh->cfg.nopty) {
51470298 8715 if (ssh->version == 1) {
8716 send_packet(ssh, SSH1_CMSG_WINDOW_SIZE,
8717 PKT_INT, ssh->term_height,
8718 PKT_INT, ssh->term_width,
32874aea 8719 PKT_INT, 0, PKT_INT, 0, PKT_END);
0ed48730 8720 } else if (ssh->mainchan) {
ff3187f6 8721 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8722 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8723 ssh2_pkt_addstring(pktout, "window-change");
8724 ssh2_pkt_addbool(pktout, 0);
8725 ssh2_pkt_adduint32(pktout, ssh->term_width);
8726 ssh2_pkt_adduint32(pktout, ssh->term_height);
8727 ssh2_pkt_adduint32(pktout, 0);
8728 ssh2_pkt_adduint32(pktout, 0);
8729 ssh2_pkt_send(ssh, pktout);
32874aea 8730 }
8731 }
8732 break;
374330e2 8733 }
8734}
8735
8736/*
125105d1 8737 * Return a list of the special codes that make sense in this
8738 * protocol.
8739 */
8740static const struct telnet_special *ssh_get_specials(void *handle)
8741{
786ba75e 8742 static const struct telnet_special ssh1_ignore_special[] = {
8743 {"IGNORE message", TS_NOP}
8744 };
8745 static const struct telnet_special ssh2_transport_specials[] = {
62638676 8746 {"IGNORE message", TS_NOP},
9442dd57 8747 {"Repeat key exchange", TS_REKEY},
62638676 8748 };
8749 static const struct telnet_special ssh2_session_specials[] = {
6f2d0cde 8750 {NULL, TS_SEP},
8751 {"Break", TS_BRK},
786ba75e 8752 /* These are the signal names defined by draft-ietf-secsh-connect-23.
6f2d0cde 8753 * They include all the ISO C signals, but are a subset of the POSIX
8754 * required signals. */
8755 {"SIGINT (Interrupt)", TS_SIGINT},
8756 {"SIGTERM (Terminate)", TS_SIGTERM},
8757 {"SIGKILL (Kill)", TS_SIGKILL},
8758 {"SIGQUIT (Quit)", TS_SIGQUIT},
8759 {"SIGHUP (Hangup)", TS_SIGHUP},
8760 {"More signals", TS_SUBMENU},
8761 {"SIGABRT", TS_SIGABRT}, {"SIGALRM", TS_SIGALRM},
8762 {"SIGFPE", TS_SIGFPE}, {"SIGILL", TS_SIGILL},
8763 {"SIGPIPE", TS_SIGPIPE}, {"SIGSEGV", TS_SIGSEGV},
8764 {"SIGUSR1", TS_SIGUSR1}, {"SIGUSR2", TS_SIGUSR2},
8765 {NULL, TS_EXITMENU}
62638676 8766 };
8767 static const struct telnet_special specials_end[] = {
6f2d0cde 8768 {NULL, TS_EXITMENU}
62638676 8769 };
786ba75e 8770 /* XXX review this length for any changes: */
8771 static struct telnet_special ssh_specials[lenof(ssh2_transport_specials) +
62638676 8772 lenof(ssh2_session_specials) +
8773 lenof(specials_end)];
125105d1 8774 Ssh ssh = (Ssh) handle;
62638676 8775 int i = 0;
8776#define ADD_SPECIALS(name) \
8777 do { \
8778 assert((i + lenof(name)) <= lenof(ssh_specials)); \
8779 memcpy(&ssh_specials[i], name, sizeof name); \
8780 i += lenof(name); \
8781 } while(0)
125105d1 8782
8783 if (ssh->version == 1) {
62638676 8784 /* Don't bother offering IGNORE if we've decided the remote
8785 * won't cope with it, since we wouldn't bother sending it if
8786 * asked anyway. */
8787 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
786ba75e 8788 ADD_SPECIALS(ssh1_ignore_special);
125105d1 8789 } else if (ssh->version == 2) {
786ba75e 8790 ADD_SPECIALS(ssh2_transport_specials);
62638676 8791 if (ssh->mainchan)
8792 ADD_SPECIALS(ssh2_session_specials);
8793 } /* else we're not ready yet */
8794
8795 if (i) {
8796 ADD_SPECIALS(specials_end);
8797 return ssh_specials;
8798 } else {
125105d1 8799 return NULL;
62638676 8800 }
8801#undef ADD_SPECIALS
125105d1 8802}
8803
8804/*
86dc445a 8805 * Send special codes. TS_EOF is useful for `plink', so you
6abbf9e3 8806 * can send an EOF and collect resulting output (e.g. `plink
8807 * hostname sort').
374330e2 8808 */
51470298 8809static void ssh_special(void *handle, Telnet_Special code)
32874aea 8810{
51470298 8811 Ssh ssh = (Ssh) handle;
ff3187f6 8812 struct Packet *pktout;
51470298 8813
6abbf9e3 8814 if (code == TS_EOF) {
51470298 8815 if (ssh->state != SSH_STATE_SESSION) {
32874aea 8816 /*
8817 * Buffer the EOF in case we are pre-SESSION, so we can
8818 * send it as soon as we reach SESSION.
8819 */
8820 if (code == TS_EOF)
51470298 8821 ssh->eof_needed = TRUE;
32874aea 8822 return;
8823 }
51470298 8824 if (ssh->version == 1) {
8825 send_packet(ssh, SSH1_CMSG_EOF, PKT_END);
0ed48730 8826 } else if (ssh->mainchan) {
ff3187f6 8827 struct Packet *pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
8828 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8829 ssh2_pkt_send(ssh, pktout);
00a0b113 8830 ssh->send_ok = 0; /* now stop trying to read from stdin */
32874aea 8831 }
8832 logevent("Sent EOF message");
125105d1 8833 } else if (code == TS_PING || code == TS_NOP) {
51470298 8834 if (ssh->state == SSH_STATE_CLOSED
8835 || ssh->state == SSH_STATE_PREPACKET) return;
8836 if (ssh->version == 1) {
8837 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
8838 send_packet(ssh, SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
32874aea 8839 } else {
ff3187f6 8840 pktout = ssh2_pkt_init(SSH2_MSG_IGNORE);
8841 ssh2_pkt_addstring_start(pktout);
590f6a5f 8842 ssh2_pkt_send_noqueue(ssh, pktout);
32874aea 8843 }
9442dd57 8844 } else if (code == TS_REKEY) {
8845 if (!ssh->kex_in_progress && ssh->version == 2) {
f382c87d 8846 do_ssh2_transport(ssh, "at user request", -1, NULL);
9442dd57 8847 }
125105d1 8848 } else if (code == TS_BRK) {
8849 if (ssh->state == SSH_STATE_CLOSED
8850 || ssh->state == SSH_STATE_PREPACKET) return;
8851 if (ssh->version == 1) {
2e85c969 8852 logevent("Unable to send BREAK signal in SSH-1");
0ed48730 8853 } else if (ssh->mainchan) {
ff3187f6 8854 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8855 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8856 ssh2_pkt_addstring(pktout, "break");
8857 ssh2_pkt_addbool(pktout, 0);
8858 ssh2_pkt_adduint32(pktout, 0); /* default break length */
8859 ssh2_pkt_send(ssh, pktout);
125105d1 8860 }
6abbf9e3 8861 } else {
6f2d0cde 8862 /* Is is a POSIX signal? */
8863 char *signame = NULL;
8864 if (code == TS_SIGABRT) signame = "ABRT";
8865 if (code == TS_SIGALRM) signame = "ALRM";
8866 if (code == TS_SIGFPE) signame = "FPE";
8867 if (code == TS_SIGHUP) signame = "HUP";
8868 if (code == TS_SIGILL) signame = "ILL";
8869 if (code == TS_SIGINT) signame = "INT";
8870 if (code == TS_SIGKILL) signame = "KILL";
8871 if (code == TS_SIGPIPE) signame = "PIPE";
8872 if (code == TS_SIGQUIT) signame = "QUIT";
8873 if (code == TS_SIGSEGV) signame = "SEGV";
8874 if (code == TS_SIGTERM) signame = "TERM";
8875 if (code == TS_SIGUSR1) signame = "USR1";
8876 if (code == TS_SIGUSR2) signame = "USR2";
8877 /* The SSH-2 protocol does in principle support arbitrary named
8878 * signals, including signame@domain, but we don't support those. */
8879 if (signame) {
8880 /* It's a signal. */
8881 if (ssh->version == 2 && ssh->mainchan) {
ff3187f6 8882 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8883 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8884 ssh2_pkt_addstring(pktout, "signal");
8885 ssh2_pkt_addbool(pktout, 0);
8886 ssh2_pkt_addstring(pktout, signame);
8887 ssh2_pkt_send(ssh, pktout);
6f2d0cde 8888 logeventf(ssh, "Sent signal SIG%s", signame);
8889 }
8890 } else {
8891 /* Never heard of it. Do nothing */
8892 }
6abbf9e3 8893 }
374330e2 8894}
8895
51470298 8896void *new_sock_channel(void *handle, Socket s)
d74d141c 8897{
51470298 8898 Ssh ssh = (Ssh) handle;
d74d141c 8899 struct ssh_channel *c;
3d88e64d 8900 c = snew(struct ssh_channel);
51470298 8901 c->ssh = ssh;
d74d141c 8902
8903 if (c) {
64d6ff88 8904 c->halfopen = TRUE;
51470298 8905 c->localid = alloc_channel_id(ssh);
d74d141c 8906 c->closes = 0;
bc240b21 8907 c->type = CHAN_SOCKDATA_DORMANT;/* identify channel type */
d74d141c 8908 c->u.pfd.s = s;
013dd8c0 8909 bufchain_init(&c->v.v2.outbuffer);
51470298 8910 add234(ssh->channels, c);
d74d141c 8911 }
8912 return c;
8913}
8914
5471d09a 8915/*
8916 * This is called when stdout/stderr (the entity to which
8917 * from_backend sends data) manages to clear some backlog.
8918 */
ae9ae89f 8919static void ssh_unthrottle(void *handle, int bufsize)
5471d09a 8920{
51470298 8921 Ssh ssh = (Ssh) handle;
8922 if (ssh->version == 1) {
8923 if (ssh->v1_stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
8924 ssh->v1_stdout_throttling = 0;
8925 ssh1_throttle(ssh, -1);
5471d09a 8926 }
8927 } else {
51470298 8928 if (ssh->mainchan && ssh->mainchan->closes == 0)
8929 ssh2_set_window(ssh->mainchan, OUR_V2_WINSIZE - bufsize);
5471d09a 8930 }
8931}
8932
6b78788a 8933void ssh_send_port_open(void *channel, char *hostname, int port, char *org)
d74d141c 8934{
8935 struct ssh_channel *c = (struct ssh_channel *)channel;
6b78788a 8936 Ssh ssh = c->ssh;
ff3187f6 8937 struct Packet *pktout;
d74d141c 8938
57356d63 8939 logeventf(ssh, "Opening forwarded connection to %s:%d", hostname, port);
d74d141c 8940
51470298 8941 if (ssh->version == 1) {
8942 send_packet(ssh, SSH1_MSG_PORT_OPEN,
bc240b21 8943 PKT_INT, c->localid,
8944 PKT_STR, hostname,
8945 PKT_INT, port,
31fb1866 8946 /* PKT_STR, <org:orgport>, */
bc240b21 8947 PKT_END);
8948 } else {
ff3187f6 8949 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
8950 ssh2_pkt_addstring(pktout, "direct-tcpip");
8951 ssh2_pkt_adduint32(pktout, c->localid);
5471d09a 8952 c->v.v2.locwindow = OUR_V2_WINSIZE;
ff3187f6 8953 ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);/* our window size */
954d5c5a 8954 ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
ff3187f6 8955 ssh2_pkt_addstring(pktout, hostname);
8956 ssh2_pkt_adduint32(pktout, port);
bc240b21 8957 /*
8958 * We make up values for the originator data; partly it's
8959 * too much hassle to keep track, and partly I'm not
8960 * convinced the server should be told details like that
8961 * about my local network configuration.
1f182589 8962 * The "originator IP address" is syntactically a numeric
8963 * IP address, and some servers (e.g., Tectia) get upset
8964 * if it doesn't match this syntax.
bc240b21 8965 */
1f182589 8966 ssh2_pkt_addstring(pktout, "0.0.0.0");
ff3187f6 8967 ssh2_pkt_adduint32(pktout, 0);
8968 ssh2_pkt_send(ssh, pktout);
bc240b21 8969 }
d74d141c 8970}
8971
6226c939 8972static int ssh_connected(void *handle)
32874aea 8973{
51470298 8974 Ssh ssh = (Ssh) handle;
6226c939 8975 return ssh->s != NULL;
32874aea 8976}
8ccc75b0 8977
51470298 8978static int ssh_sendok(void *handle)
32874aea 8979{
51470298 8980 Ssh ssh = (Ssh) handle;
8981 return ssh->send_ok;
32874aea 8982}
fb09bf1c 8983
51470298 8984static int ssh_ldisc(void *handle, int option)
32874aea 8985{
51470298 8986 Ssh ssh = (Ssh) handle;
32874aea 8987 if (option == LD_ECHO)
51470298 8988 return ssh->echoing;
32874aea 8989 if (option == LD_EDIT)
51470298 8990 return ssh->editing;
0965bee0 8991 return FALSE;
8992}
8993
b9d7bcad 8994static void ssh_provide_ldisc(void *handle, void *ldisc)
8995{
8996 Ssh ssh = (Ssh) handle;
8997 ssh->ldisc = ldisc;
8998}
8999
a8327734 9000static void ssh_provide_logctx(void *handle, void *logctx)
9001{
9002 Ssh ssh = (Ssh) handle;
9003 ssh->logctx = logctx;
9004}
9005
51470298 9006static int ssh_return_exitcode(void *handle)
9007{
9008 Ssh ssh = (Ssh) handle;
3bb2f322 9009 if (ssh->s != NULL)
9010 return -1;
9011 else
3c112d53 9012 return (ssh->exitcode >= 0 ? ssh->exitcode : INT_MAX);
51470298 9013}
9014
9015/*
f89c3294 9016 * cfg_info for SSH is the currently running version of the
9017 * protocol. (1 for 1; 2 for 2; 0 for not-decided-yet.)
9018 */
9019static int ssh_cfg_info(void *handle)
9020{
9021 Ssh ssh = (Ssh) handle;
9022 return ssh->version;
9023}
9024
9025/*
51470298 9026 * Gross hack: pscp will try to start SFTP but fall back to scp1 if
9027 * that fails. This variable is the means by which scp.c can reach
9028 * into the SSH code and find out which one it got.
9029 */
9030extern int ssh_fallback_cmd(void *handle)
d8d6c7e5 9031{
51470298 9032 Ssh ssh = (Ssh) handle;
9033 return ssh->fallback_cmd;
d8d6c7e5 9034}
9035
374330e2 9036Backend ssh_backend = {
9037 ssh_init,
fabd1805 9038 ssh_free,
86916870 9039 ssh_reconfig,
374330e2 9040 ssh_send,
5471d09a 9041 ssh_sendbuffer,
374330e2 9042 ssh_size,
4017be6d 9043 ssh_special,
125105d1 9044 ssh_get_specials,
6226c939 9045 ssh_connected,
d8d6c7e5 9046 ssh_return_exitcode,
97db3be4 9047 ssh_sendok,
0965bee0 9048 ssh_ldisc,
b9d7bcad 9049 ssh_provide_ldisc,
a8327734 9050 ssh_provide_logctx,
5471d09a 9051 ssh_unthrottle,
f89c3294 9052 ssh_cfg_info,
97db3be4 9053 22
bc240b21 9054};