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