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