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