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