Fix `puttygen-unix-perms': f_open(), PuTTY's wrapper on fopen, now
[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) {
aa63ab7e 4644 unsigned int l = min(4 - c->u.a.lensofar, 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,
4661 len);
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) {
aa63ab7e 6081 unsigned int l = min(4 - c->u.a.lensofar, length);
51df0ab5 6082 memcpy(c->u.a.msglen + c->u.a.lensofar,
6083 data, l);
6084 data += l;
6085 length -= l;
6086 c->u.a.lensofar += l;
6087 }
6088 if (c->u.a.lensofar == 4) {
6089 c->u.a.totallen =
6090 4 + GET_32BIT(c->u.a.msglen);
6091 c->u.a.message = snewn(c->u.a.totallen,
6092 unsigned char);
6093 memcpy(c->u.a.message, c->u.a.msglen, 4);
6094 }
6095 if (c->u.a.lensofar >= 4 && length > 0) {
aa63ab7e 6096 unsigned int l =
51df0ab5 6097 min(c->u.a.totallen - c->u.a.lensofar,
6098 length);
6099 memcpy(c->u.a.message + c->u.a.lensofar,
6100 data, l);
6101 data += l;
6102 length -= l;
6103 c->u.a.lensofar += l;
6104 }
6105 if (c->u.a.lensofar == c->u.a.totallen) {
6106 void *reply;
6107 int replylen;
6108 if (agent_query(c->u.a.message,
6109 c->u.a.totallen,
6110 &reply, &replylen,
6111 ssh_agentf_callback, c))
6112 ssh_agentf_callback(c, reply, replylen);
6113 sfree(c->u.a.message);
6114 c->u.a.lensofar = 0;
6115 }
6116 }
6117 bufsize = 0;
6118 break;
6119 }
6120 /*
6121 * If we are not buffering too much data,
6122 * enlarge the window again at the remote side.
6123 */
6124 if (bufsize < OUR_V2_WINSIZE)
6125 ssh2_set_window(c, OUR_V2_WINSIZE - bufsize);
6126 }
6127}
6128
6129static void ssh2_msg_channel_eof(Ssh ssh, struct Packet *pktin)
6130{
6131 unsigned i = ssh_pkt_getuint32(pktin);
6132 struct ssh_channel *c;
6133
6134 c = find234(ssh->channels, &i, ssh_channelfind);
6135 if (!c)
6136 return; /* nonexistent channel */
6137
6138 if (c->type == CHAN_X11) {
6139 /*
6140 * Remote EOF on an X11 channel means we should
6141 * wrap up and close the channel ourselves.
6142 */
6143 x11_close(c->u.x11.s);
6144 sshfwd_close(c);
6145 } else if (c->type == CHAN_AGENT) {
6146 sshfwd_close(c);
6147 } else if (c->type == CHAN_SOCKDATA) {
6148 pfd_close(c->u.pfd.s);
6149 sshfwd_close(c);
6150 }
6151}
6152
6153static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
6154{
6155 unsigned i = ssh_pkt_getuint32(pktin);
6156 struct ssh_channel *c;
6157 struct Packet *pktout;
6158
6159 c = find234(ssh->channels, &i, ssh_channelfind);
64d6ff88 6160 if (!c || c->halfopen) {
51df0ab5 6161 bombout(("Received CHANNEL_CLOSE for %s channel %d\n",
6162 c ? "half-open" : "nonexistent", i));
6163 return;
6164 }
6165 /* Do pre-close processing on the channel. */
6166 switch (c->type) {
6167 case CHAN_MAINSESSION:
6168 ssh->mainchan = NULL;
6169 update_specials_menu(ssh->frontend);
6170 break;
6171 case CHAN_X11:
6172 if (c->u.x11.s != NULL)
6173 x11_close(c->u.x11.s);
6174 sshfwd_close(c);
6175 break;
6176 case CHAN_AGENT:
6177 sshfwd_close(c);
6178 break;
6179 case CHAN_SOCKDATA:
6180 if (c->u.pfd.s != NULL)
6181 pfd_close(c->u.pfd.s);
6182 sshfwd_close(c);
6183 break;
6184 }
6185 if (c->closes == 0) {
6186 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6187 ssh2_pkt_adduint32(pktout, c->remoteid);
6188 ssh2_pkt_send(ssh, pktout);
6189 }
6190 del234(ssh->channels, c);
6191 bufchain_clear(&c->v.v2.outbuffer);
6192 sfree(c);
6193
6194 /*
6195 * See if that was the last channel left open.
6196 * (This is only our termination condition if we're
6197 * not running in -N mode.)
6198 */
6199 if (!ssh->cfg.ssh_no_shell && count234(ssh->channels) == 0) {
51df0ab5 6200 /*
6201 * We used to send SSH_MSG_DISCONNECT here,
6202 * because I'd believed that _every_ conforming
2e85c969 6203 * SSH-2 connection had to end with a disconnect
51df0ab5 6204 * being sent by at least one side; apparently
6205 * I was wrong and it's perfectly OK to
6206 * unceremoniously slam the connection shut
6207 * when you're done, and indeed OpenSSH feels
6208 * this is more polite than sending a
6209 * DISCONNECT. So now we don't.
6210 */
9e296bfa 6211 ssh_disconnect(ssh, "All channels closed", NULL, 0, TRUE);
51df0ab5 6212 }
6213}
6214
6215static void ssh2_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
6216{
6217 unsigned i = ssh_pkt_getuint32(pktin);
6218 struct ssh_channel *c;
6219 struct Packet *pktout;
6220
6221 c = find234(ssh->channels, &i, ssh_channelfind);
6222 if (!c)
6223 return; /* nonexistent channel */
6224 if (c->type != CHAN_SOCKDATA_DORMANT)
6225 return; /* dunno why they're confirming this */
6226 c->remoteid = ssh_pkt_getuint32(pktin);
64d6ff88 6227 c->halfopen = FALSE;
51df0ab5 6228 c->type = CHAN_SOCKDATA;
6229 c->v.v2.remwindow = ssh_pkt_getuint32(pktin);
6230 c->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
6231 if (c->u.pfd.s)
6232 pfd_confirm(c->u.pfd.s);
6233 if (c->closes) {
6234 /*
6235 * We have a pending close on this channel,
6236 * which we decided on before the server acked
6237 * the channel open. So now we know the
6238 * remoteid, we can close it again.
6239 */
6240 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6241 ssh2_pkt_adduint32(pktout, c->remoteid);
6242 ssh2_pkt_send(ssh, pktout);
6243 }
6244}
6245
6246static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
6247{
6248 static const char *const reasons[] = {
6249 "<unknown reason code>",
6250 "Administratively prohibited",
6251 "Connect failed",
6252 "Unknown channel type",
6253 "Resource shortage",
6254 };
6255 unsigned i = ssh_pkt_getuint32(pktin);
6256 unsigned reason_code;
6257 char *reason_string;
6258 int reason_length;
51df0ab5 6259 struct ssh_channel *c;
6260 c = find234(ssh->channels, &i, ssh_channelfind);
6261 if (!c)
6262 return; /* nonexistent channel */
6263 if (c->type != CHAN_SOCKDATA_DORMANT)
6264 return; /* dunno why they're failing this */
6265
6266 reason_code = ssh_pkt_getuint32(pktin);
6267 if (reason_code >= lenof(reasons))
6268 reason_code = 0; /* ensure reasons[reason_code] in range */
6269 ssh_pkt_getstring(pktin, &reason_string, &reason_length);
fb983202 6270 logeventf(ssh, "Forwarded connection refused by server: %s [%.*s]",
6271 reasons[reason_code], reason_length, reason_string);
51df0ab5 6272
6273 pfd_close(c->u.pfd.s);
6274
6275 del234(ssh->channels, c);
6276 sfree(c);
6277}
6278
6279static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin)
6280{
6281 unsigned localid;
6282 char *type;
6283 int typelen, want_reply;
6284 int reply = SSH2_MSG_CHANNEL_FAILURE; /* default */
6285 struct ssh_channel *c;
6286 struct Packet *pktout;
6287
6288 localid = ssh_pkt_getuint32(pktin);
6289 ssh_pkt_getstring(pktin, &type, &typelen);
6290 want_reply = ssh2_pkt_getbool(pktin);
6291
6292 /*
6293 * First, check that the channel exists. Otherwise,
6294 * we can instantly disconnect with a rude message.
6295 */
6296 c = find234(ssh->channels, &localid, ssh_channelfind);
6297 if (!c) {
9e296bfa 6298 char *buf = dupprintf("Received channel request for nonexistent"
6299 " channel %d", localid);
6300 ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6301 sfree(buf);
51df0ab5 6302 return;
6303 }
6304
6305 /*
6306 * Having got the channel number, we now look at
6307 * the request type string to see if it's something
6308 * we recognise.
6309 */
6310 if (c == ssh->mainchan) {
6311 /*
6312 * We recognise "exit-status" and "exit-signal" on
6313 * the primary channel.
6314 */
6315 if (typelen == 11 &&
6316 !memcmp(type, "exit-status", 11)) {
6317
6318 ssh->exitcode = ssh_pkt_getuint32(pktin);
6319 logeventf(ssh, "Server sent command exit status %d",
6320 ssh->exitcode);
6321 reply = SSH2_MSG_CHANNEL_SUCCESS;
6322
6323 } else if (typelen == 11 &&
6324 !memcmp(type, "exit-signal", 11)) {
6325
6326 int is_plausible = TRUE, is_int = FALSE;
6327 char *fmt_sig = "", *fmt_msg = "";
6328 char *msg;
6329 int msglen = 0, core = FALSE;
6330 /* ICK: older versions of OpenSSH (e.g. 3.4p1)
6331 * provide an `int' for the signal, despite its
6332 * having been a `string' in the drafts since at
6333 * least 2001. (Fixed in session.c 1.147.) Try to
6334 * infer which we can safely parse it as. */
6335 {
6336 unsigned char *p = pktin->body +
6337 pktin->savedpos;
6338 long len = pktin->length - pktin->savedpos;
6339 unsigned long num = GET_32BIT(p); /* what is it? */
6340 /* If it's 0, it hardly matters; assume string */
6341 if (num == 0) {
6342 is_int = FALSE;
6343 } else {
6344 int maybe_int = FALSE, maybe_str = FALSE;
6345#define CHECK_HYPOTHESIS(offset, result) \
6346 do { \
6347 long q = offset; \
6348 if (q >= 0 && q+4 <= len) { \
6349 q = q + 4 + GET_32BIT(p+q); \
6350 if (q >= 0 && q+4 <= len && \
c849ff23 6351 ((q = q + 4 + GET_32BIT(p+q))!= 0) && q == len) \
51df0ab5 6352 result = TRUE; \
6353 } \
6354 } while(0)
6355 CHECK_HYPOTHESIS(4+1, maybe_int);
6356 CHECK_HYPOTHESIS(4+num+1, maybe_str);
6357#undef CHECK_HYPOTHESIS
6358 if (maybe_int && !maybe_str)
6359 is_int = TRUE;
6360 else if (!maybe_int && maybe_str)
6361 is_int = FALSE;
6362 else
6363 /* Crikey. Either or neither. Panic. */
6364 is_plausible = FALSE;
6365 }
6366 }
6367 if (is_plausible) {
6368 if (is_int) {
6369 /* Old non-standard OpenSSH. */
6370 int signum = ssh_pkt_getuint32(pktin);
6371 fmt_sig = dupprintf(" %d", signum);
6372 } else {
6373 /* As per the drafts. */
6374 char *sig;
6375 int siglen;
6376 ssh_pkt_getstring(pktin, &sig, &siglen);
6377 /* Signal name isn't supposed to be blank, but
6378 * let's cope gracefully if it is. */
6379 if (siglen) {
6380 fmt_sig = dupprintf(" \"%.*s\"",
6381 siglen, sig);
6382 }
6383 }
6384 core = ssh2_pkt_getbool(pktin);
6385 ssh_pkt_getstring(pktin, &msg, &msglen);
6386 if (msglen) {
6387 fmt_msg = dupprintf(" (\"%.*s\")", msglen, msg);
6388 }
6389 /* ignore lang tag */
6390 } /* else don't attempt to parse */
6391 logeventf(ssh, "Server exited on signal%s%s%s",
6392 fmt_sig, core ? " (core dumped)" : "",
6393 fmt_msg);
6394 if (*fmt_sig) sfree(fmt_sig);
6395 if (*fmt_msg) sfree(fmt_msg);
6396 reply = SSH2_MSG_CHANNEL_SUCCESS;
6397
6398 }
6399 } else {
6400 /*
6401 * This is a channel request we don't know
6402 * about, so we now either ignore the request
6403 * or respond with CHANNEL_FAILURE, depending
6404 * on want_reply.
6405 */
6406 reply = SSH2_MSG_CHANNEL_FAILURE;
6407 }
6408 if (want_reply) {
6409 pktout = ssh2_pkt_init(reply);
6410 ssh2_pkt_adduint32(pktout, c->remoteid);
6411 ssh2_pkt_send(ssh, pktout);
6412 }
6413}
6414
6415static void ssh2_msg_global_request(Ssh ssh, struct Packet *pktin)
6416{
6417 char *type;
6418 int typelen, want_reply;
6419 struct Packet *pktout;
6420
6421 ssh_pkt_getstring(pktin, &type, &typelen);
6422 want_reply = ssh2_pkt_getbool(pktin);
6423
6424 /*
6425 * We currently don't support any global requests
6426 * at all, so we either ignore the request or
6427 * respond with REQUEST_FAILURE, depending on
6428 * want_reply.
6429 */
6430 if (want_reply) {
6431 pktout = ssh2_pkt_init(SSH2_MSG_REQUEST_FAILURE);
6432 ssh2_pkt_send(ssh, pktout);
6433 }
6434}
6435
6436static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin)
6437{
6438 char *type;
6439 int typelen;
6440 char *peeraddr;
6441 int peeraddrlen;
6442 int peerport;
6443 char *error = NULL;
6444 struct ssh_channel *c;
6445 unsigned remid, winsize, pktsize;
6446 struct Packet *pktout;
6447
6448 ssh_pkt_getstring(pktin, &type, &typelen);
6449 c = snew(struct ssh_channel);
6450 c->ssh = ssh;
6451
6452 remid = ssh_pkt_getuint32(pktin);
6453 winsize = ssh_pkt_getuint32(pktin);
6454 pktsize = ssh_pkt_getuint32(pktin);
6455
6456 if (typelen == 3 && !memcmp(type, "x11", 3)) {
6457 char *addrstr;
6458
6459 ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
6460 addrstr = snewn(peeraddrlen+1, char);
6461 memcpy(addrstr, peeraddr, peeraddrlen);
6462 addrstr[peeraddrlen] = '\0';
6463 peerport = ssh_pkt_getuint32(pktin);
6464
6465 logeventf(ssh, "Received X11 connect request from %s:%d",
6466 addrstr, peerport);
6467
6468 if (!ssh->X11_fwd_enabled)
6469 error = "X11 forwarding is not enabled";
6470 else if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c,
6471 ssh->x11auth, addrstr, peerport,
6472 &ssh->cfg) != NULL) {
6473 error = "Unable to open an X11 connection";
6474 } else {
6475 logevent("Opening X11 forward connection succeeded");
6476 c->type = CHAN_X11;
6477 }
6478
6479 sfree(addrstr);
6480 } else if (typelen == 15 &&
6481 !memcmp(type, "forwarded-tcpip", 15)) {
6482 struct ssh_rportfwd pf, *realpf;
6483 char *dummy;
6484 int dummylen;
6485 ssh_pkt_getstring(pktin, &dummy, &dummylen);/* skip address */
6486 pf.sport = ssh_pkt_getuint32(pktin);
6487 ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
6488 peerport = ssh_pkt_getuint32(pktin);
6489 realpf = find234(ssh->rportfwds, &pf, NULL);
6490 logeventf(ssh, "Received remote port %d open request "
6491 "from %s:%d", pf.sport, peeraddr, peerport);
6492 if (realpf == NULL) {
6493 error = "Remote port is not recognised";
6494 } else {
6495 const char *e = pfd_newconnect(&c->u.pfd.s,
6496 realpf->dhost,
6497 realpf->dport, c,
05581745 6498 &ssh->cfg,
6499 realpf->pfrec->addressfamily);
51df0ab5 6500 logeventf(ssh, "Attempting to forward remote port to "
6501 "%s:%d", realpf->dhost, realpf->dport);
6502 if (e != NULL) {
6503 logeventf(ssh, "Port open failed: %s", e);
6504 error = "Port open failed";
6505 } else {
6506 logevent("Forwarded port opened successfully");
6507 c->type = CHAN_SOCKDATA;
6508 }
6509 }
6510 } else if (typelen == 22 &&
c49cf994 6511 !memcmp(type, "auth-agent@openssh.com", 22)) {
51df0ab5 6512 if (!ssh->agentfwd_enabled)
6513 error = "Agent forwarding is not enabled";
6514 else {
6515 c->type = CHAN_AGENT; /* identify channel type */
6516 c->u.a.lensofar = 0;
6517 }
6518 } else {
6519 error = "Unsupported channel type requested";
6520 }
6521
6522 c->remoteid = remid;
64d6ff88 6523 c->halfopen = FALSE;
51df0ab5 6524 if (error) {
6525 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_FAILURE);
6526 ssh2_pkt_adduint32(pktout, c->remoteid);
6527 ssh2_pkt_adduint32(pktout, SSH2_OPEN_CONNECT_FAILED);
6528 ssh2_pkt_addstring(pktout, error);
6529 ssh2_pkt_addstring(pktout, "en"); /* language tag */
6530 ssh2_pkt_send(ssh, pktout);
6531 logeventf(ssh, "Rejected channel open: %s", error);
6532 sfree(c);
6533 } else {
6534 c->localid = alloc_channel_id(ssh);
6535 c->closes = 0;
6536 c->v.v2.locwindow = OUR_V2_WINSIZE;
6537 c->v.v2.remwindow = winsize;
6538 c->v.v2.remmaxpkt = pktsize;
6539 bufchain_init(&c->v.v2.outbuffer);
6540 add234(ssh->channels, c);
6541 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
6542 ssh2_pkt_adduint32(pktout, c->remoteid);
6543 ssh2_pkt_adduint32(pktout, c->localid);
6544 ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);
954d5c5a 6545 ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
51df0ab5 6546 ssh2_pkt_send(ssh, pktout);
6547 }
6548}
6549
6bbce591 6550/*
6551 * Buffer banner messages for later display at some convenient point.
6552 */
6553static void ssh2_msg_userauth_banner(Ssh ssh, struct Packet *pktin)
6554{
6555 /* Arbitrary limit to prevent unbounded inflation of buffer */
6556 if (bufchain_size(&ssh->banner) <= 131072) {
6557 char *banner = NULL;
6558 int size = 0;
6559 ssh_pkt_getstring(pktin, &banner, &size);
6560 if (banner)
6561 bufchain_add(&ssh->banner, banner, size);
6562 }
6563}
6564
c6ccd5c2 6565/* Helper function to deal with sending tty modes for "pty-req" */
6566static void ssh2_send_ttymode(void *data, char *mode, char *val)
6567{
6568 struct Packet *pktout = (struct Packet *)data;
6569 int i = 0;
6570 unsigned int arg = 0;
6571 while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
6572 if (i == lenof(ssh_ttymodes)) return;
6573 switch (ssh_ttymodes[i].type) {
6574 case TTY_OP_CHAR:
6575 arg = ssh_tty_parse_specchar(val);
6576 break;
6577 case TTY_OP_BOOL:
6578 arg = ssh_tty_parse_boolean(val);
6579 break;
6580 }
6581 ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
6582 ssh2_pkt_adduint32(pktout, arg);
6583}
6584
783415f8 6585/*
2e85c969 6586 * Handle the SSH-2 userauth and connection layers.
7cca0d81 6587 */
ff3187f6 6588static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
6589 struct Packet *pktin)
7cca0d81 6590{
51470298 6591 struct do_ssh2_authconn_state {
6592 enum {
51470298 6593 AUTH_TYPE_NONE,
6594 AUTH_TYPE_PUBLICKEY,
6595 AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
6596 AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
6597 AUTH_TYPE_PASSWORD,
6598 AUTH_TYPE_KEYBOARD_INTERACTIVE,
6599 AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
6600 } type;
a1a1fae4 6601 int done_service_req;
51470298 6602 int gotit, need_pw, can_pubkey, can_passwd, can_keyb_inter;
94cd7c3a 6603 int tried_pubkey_config, done_agent;
edd0cb8a 6604 int kbd_inter_refused;
51470298 6605 int we_are_in;
edd0cb8a 6606 prompts_t *cur_prompt;
6607 int num_prompts;
51470298 6608 char username[100];
e955d348 6609 char *password;
51470298 6610 int got_username;
51470298 6611 void *publickey_blob;
6612 int publickey_bloblen;
edd0cb8a 6613 int publickey_encrypted;
6614 char *publickey_algorithm;
6615 char *publickey_comment;
94cd7c3a 6616 unsigned char agent_request[5], *agent_response, *agentp;
6617 int agent_responselen;
6618 unsigned char *pkblob_in_agent;
51470298 6619 int keyi, nkeys;
51470298 6620 char *pkblob, *alg, *commentp;
6621 int pklen, alglen, commentlen;
6622 int siglen, retlen, len;
6623 char *q, *agentreq, *ret;
6624 int try_send;
73feed4f 6625 int num_env, env_left, env_ok;
ff3187f6 6626 struct Packet *pktout;
51470298 6627 };
6628 crState(do_ssh2_authconn_state);
6629
6630 crBegin(ssh->do_ssh2_authconn_crstate);
e5574168 6631
a1a1fae4 6632 s->done_service_req = FALSE;
6633 s->we_are_in = FALSE;
6634 if (!ssh->cfg.ssh_no_userauth) {
6635 /*
6636 * Request userauth protocol, and await a response to it.
6637 */
6638 s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
6639 ssh2_pkt_addstring(s->pktout, "ssh-userauth");
6640 ssh2_pkt_send(ssh, s->pktout);
6641 crWaitUntilV(pktin);
6642 if (pktin->type == SSH2_MSG_SERVICE_ACCEPT)
6643 s->done_service_req = TRUE;
6644 }
6645 if (!s->done_service_req) {
6646 /*
6647 * Request connection protocol directly, without authentication.
6648 */
6649 s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
6650 ssh2_pkt_addstring(s->pktout, "ssh-connection");
6651 ssh2_pkt_send(ssh, s->pktout);
6652 crWaitUntilV(pktin);
6653 if (pktin->type == SSH2_MSG_SERVICE_ACCEPT) {
6654 s->we_are_in = TRUE; /* no auth required */
6655 } else {
6656 bombout(("Server refused service request"));
6657 crStopV;
6658 }
8d5de777 6659 }
7cca0d81 6660
94cd7c3a 6661 /* Arrange to be able to deal with any BANNERs that come in.
6662 * (We do this now as packets may come in during the next bit.) */
6663 bufchain_init(&ssh->banner);
6664 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] =
6665 ssh2_msg_userauth_banner;
6666
7cca0d81 6667 /*
edd0cb8a 6668 * Misc one-time setup for authentication.
6669 */
6670 s->publickey_blob = NULL;
6671 if (!s->we_are_in) {
6672
6673 /*
6674 * Load the public half of any configured public key file
6675 * for later use.
6676 */
6677 if (!filename_is_null(ssh->cfg.keyfile)) {
6678 int keytype;
6679 logeventf(ssh, "Reading private key file \"%.150s\"",
6680 filename_to_str(&ssh->cfg.keyfile));
6681 keytype = key_type(&ssh->cfg.keyfile);
6682 if (keytype == SSH_KEYTYPE_SSH2) {
6683 const char *error;
6684 s->publickey_blob =
6685 ssh2_userkey_loadpub(&ssh->cfg.keyfile,
6686 &s->publickey_algorithm,
6687 &s->publickey_bloblen,
6688 &s->publickey_comment, &error);
6689 if (s->publickey_blob) {
6690 s->publickey_encrypted =
6691 ssh2_userkey_encrypted(&ssh->cfg.keyfile, NULL);
6692 } else {
6693 char *msgbuf;
6694 logeventf(ssh, "Unable to load private key (%s)",
6695 error);
6696 msgbuf = dupprintf("Unable to load private key file "
6697 "\"%.150s\" (%s)\r\n",
6698 filename_to_str(&ssh->cfg.keyfile),
6699 error);
6700 c_write_str(ssh, msgbuf);
6701 sfree(msgbuf);
6702 }
6703 } else {
6704 char *msgbuf;
6705 logeventf(ssh, "Unable to use this key file (%s)",
6706 key_type_to_str(keytype));
6707 msgbuf = dupprintf("Unable to use key file \"%.150s\""
6708 " (%s)\r\n",
6709 filename_to_str(&ssh->cfg.keyfile),
6710 key_type_to_str(keytype));
6711 c_write_str(ssh, msgbuf);
6712 sfree(msgbuf);
6713 s->publickey_blob = NULL;
6714 }
6715 }
6716
94cd7c3a 6717 /*
6718 * Find out about any keys Pageant has (but if there's a
6719 * public key configured, filter out all others).
6720 */
6721 s->nkeys = 0;
6722 s->agent_response = NULL;
6723 s->pkblob_in_agent = NULL;
116f229d 6724 if (ssh->cfg.tryagent && agent_exists()) {
94cd7c3a 6725
6726 void *r;
6727
6728 logevent("Pageant is running. Requesting keys.");
6729
6730 /* Request the keys held by the agent. */
6731 PUT_32BIT(s->agent_request, 1);
6732 s->agent_request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
6733 if (!agent_query(s->agent_request, 5, &r, &s->agent_responselen,
6734 ssh_agent_callback, ssh)) {
6735 do {
6736 crReturnV;
6737 if (pktin) {
6738 bombout(("Unexpected data from server while"
6739 " waiting for agent response"));
6740 crStopV;
6741 }
6742 } while (pktin || inlen > 0);
6743 r = ssh->agent_response;
6744 s->agent_responselen = ssh->agent_response_len;
6745 }
6746 s->agent_response = (unsigned char *) r;
6747 if (s->agent_response && s->agent_responselen >= 5 &&
6748 s->agent_response[4] == SSH2_AGENT_IDENTITIES_ANSWER) {
6749 int keyi;
6750 unsigned char *p;
6751 p = s->agent_response + 5;
6752 s->nkeys = GET_32BIT(p);
6753 p += 4;
6754 logeventf(ssh, "Pageant has %d SSH-2 keys", s->nkeys);
6755 if (s->publickey_blob) {
6756 /* See if configured key is in agent. */
6757 for (keyi = 0; keyi < s->nkeys; keyi++) {
6758 s->pklen = GET_32BIT(p);
6759 if (s->pklen == s->publickey_bloblen &&
6760 !memcmp(p+4, s->publickey_blob,
6761 s->publickey_bloblen)) {
6762 logeventf(ssh, "Pageant key #%d matches "
6763 "configured key file", keyi);
6764 s->keyi = keyi;
6765 s->pkblob_in_agent = p;
6766 break;
6767 }
6768 p += 4 + s->pklen;
6769 p += GET_32BIT(p) + 4; /* comment */
6770 }
6771 if (!s->pkblob_in_agent) {
6772 logevent("Configured key file not in Pageant");
6773 s->nkeys = 0;
6774 }
6775 }
6776 }
6777 }
6778
edd0cb8a 6779 }
6780
6781 /*
1408a877 6782 * We repeat this whole loop, including the username prompt,
6783 * until we manage a successful authentication. If the user
51470298 6784 * types the wrong _password_, they can be sent back to the
6785 * beginning to try another username, if this is configured on.
6786 * (If they specify a username in the config, they are never
6787 * asked, even if they do give a wrong password.)
1408a877 6788 *
6789 * I think this best serves the needs of
6790 *
6791 * - the people who have no configuration, no keys, and just
6792 * want to try repeated (username,password) pairs until they
6793 * type both correctly
6794 *
6795 * - people who have keys and configuration but occasionally
6796 * need to fall back to passwords
6797 *
6798 * - people with a key held in Pageant, who might not have
6799 * logged in to a particular machine before; so they want to
6800 * type a username, and then _either_ their key will be
6801 * accepted, _or_ they will type a password. If they mistype
6802 * the username they will want to be able to get back and
6803 * retype it!
7cca0d81 6804 */
51470298 6805 s->username[0] = '\0';
6806 s->got_username = FALSE;
a1a1fae4 6807 while (!s->we_are_in) {
1408a877 6808 /*
6809 * Get a username.
6810 */
86916870 6811 if (s->got_username && !ssh->cfg.change_username) {
5bb641e1 6812 /*
6813 * We got a username last time round this loop, and
6814 * with change_username turned off we don't try to get
6815 * it again.
6816 */
aa09f7d0 6817 } else if (!*ssh->cfg.username) {
edd0cb8a 6818 int ret; /* need not be kept over crReturn */
6819 s->cur_prompt = new_prompts(ssh->frontend);
6820 s->cur_prompt->to_server = TRUE;
6821 s->cur_prompt->name = dupstr("SSH login name");
6822 add_prompt(s->cur_prompt, dupstr("login as: "), TRUE,
6823 lenof(s->username));
6824 ret = get_userpass_input(s->cur_prompt, NULL, 0);
6825 while (ret < 0) {
51470298 6826 ssh->send_ok = 1;
edd0cb8a 6827 crWaitUntilV(!pktin);
6828 ret = get_userpass_input(s->cur_prompt, in, inlen);
6829 ssh->send_ok = 0;
32874aea 6830 }
edd0cb8a 6831 if (!ret) {
6832 /*
6833 * get_userpass_input() failed to get a username.
6834 * Terminate.
6835 */
6836 free_prompts(s->cur_prompt);
6837 ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
6838 crStopV;
6839 }
6840 memcpy(s->username, s->cur_prompt->prompts[0]->result,
6841 lenof(s->username));
6842 free_prompts(s->cur_prompt);
7cca0d81 6843 } else {
57356d63 6844 char *stuff;
86916870 6845 strncpy(s->username, ssh->cfg.username, sizeof(s->username));
51470298 6846 s->username[sizeof(s->username)-1] = '\0';
65a22376 6847 if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
57356d63 6848 stuff = dupprintf("Using username \"%s\".\r\n", s->username);
51470298 6849 c_write_str(ssh, stuff);
57356d63 6850 sfree(stuff);
7cca0d81 6851 }
6852 }
51470298 6853 s->got_username = TRUE;
7cca0d81 6854
65a22376 6855 /*
1408a877 6856 * Send an authentication request using method "none": (a)
6857 * just in case it succeeds, and (b) so that we know what
6858 * authentication methods we can usefully try next.
65a22376 6859 */
51470298 6860 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
6861
ff3187f6 6862 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
6863 ssh2_pkt_addstring(s->pktout, s->username);
6864 ssh2_pkt_addstring(s->pktout, "ssh-connection");/* service requested */
6865 ssh2_pkt_addstring(s->pktout, "none"); /* method */
6866 ssh2_pkt_send(ssh, s->pktout);
51470298 6867 s->type = AUTH_TYPE_NONE;
6868 s->gotit = FALSE;
6869 s->we_are_in = FALSE;
6870
6871 s->tried_pubkey_config = FALSE;
6ac3a551 6872 s->kbd_inter_refused = FALSE;
65a22376 6873
94cd7c3a 6874 /* Reset agent request state. */
6875 s->done_agent = FALSE;
6876 if (s->agent_response) {
6877 if (s->pkblob_in_agent) {
6878 s->agentp = s->pkblob_in_agent;
6879 } else {
6880 s->agentp = s->agent_response + 5 + 4;
6881 s->keyi = 0;
6882 }
6883 }
6884
1408a877 6885 while (1) {
6886 /*
6887 * Wait for the result of the last authentication request.
6888 */
51470298 6889 if (!s->gotit)
ff3187f6 6890 crWaitUntilV(pktin);
6bbce591 6891 /*
6892 * Now is a convenient point to spew any banner material
6893 * that we've accumulated. (This should ensure that when
6894 * we exit the auth loop, we haven't any left to deal
6895 * with.)
6896 */
6897 {
6898 int size = bufchain_size(&ssh->banner);
32874aea 6899 /*
6900 * Don't show the banner if we're operating in
6901 * non-verbose non-interactive mode. (It's probably
6902 * a script, which means nobody will read the
6903 * banner _anyway_, and moreover the printing of
6904 * the banner will screw up processing on the
6905 * output of (say) plink.)
6906 */
6bbce591 6907 if (size && (flags & (FLAG_VERBOSE | FLAG_INTERACTIVE))) {
6908 char *banner = snewn(size, char);
6909 bufchain_fetch(&ssh->banner, banner, size);
6910 c_write_untrusted(ssh, banner, size);
6911 sfree(banner);
32874aea 6912 }
6bbce591 6913 bufchain_clear(&ssh->banner);
1408a877 6914 }
ff3187f6 6915 if (pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
1408a877 6916 logevent("Access granted");
51470298 6917 s->we_are_in = TRUE;
1408a877 6918 break;
6919 }
65a22376 6920
e955d348 6921 if (pktin->type != SSH2_MSG_USERAUTH_FAILURE) {
6922 bombout(("Strange packet received during authentication: "
6923 "type %d", pktin->type));
7ffdbc1a 6924 crStopV;
65a22376 6925 }
6926
51470298 6927 s->gotit = FALSE;
65a22376 6928
1408a877 6929 /*
6930 * OK, we're now sitting on a USERAUTH_FAILURE message, so
6931 * we can look at the string in it and know what we can
6932 * helpfully try next.
6933 */
ff3187f6 6934 if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
1408a877 6935 char *methods;
6936 int methlen;
ff3187f6 6937 ssh_pkt_getstring(pktin, &methods, &methlen);
ff3187f6 6938 if (!ssh2_pkt_getbool(pktin)) {
1408a877 6939 /*
6940 * We have received an unequivocal Access
6941 * Denied. This can translate to a variety of
6942 * messages:
6943 *
6944 * - if we'd just tried "none" authentication,
6945 * it's not worth printing anything at all
6946 *
6947 * - if we'd just tried a public key _offer_,
6948 * the message should be "Server refused our
6949 * key" (or no message at all if the key
6950 * came from Pageant)
6951 *
6952 * - if we'd just tried anything else, the
6953 * message really should be "Access denied".
6954 *
6955 * Additionally, if we'd just tried password
6956 * authentication, we should break out of this
6957 * whole loop so as to go back to the username
91f57d1f 6958 * prompt (iff we're configured to allow
6959 * username change attempts).
1408a877 6960 */
51470298 6961 if (s->type == AUTH_TYPE_NONE) {
1408a877 6962 /* do nothing */
51470298 6963 } else if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
6964 s->type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
6965 if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
6966 c_write_str(ssh, "Server refused our key\r\n");
1408a877 6967 logevent("Server refused public key");
51470298 6968 } else if (s->type==AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET) {
4bdf7c46 6969 /* server declined keyboard-interactive; ignore */
1408a877 6970 } else {
51470298 6971 c_write_str(ssh, "Access denied\r\n");
1408a877 6972 logevent("Access denied");
91f57d1f 6973 if (s->type == AUTH_TYPE_PASSWORD &&
6974 ssh->cfg.change_username) {
6c9dce7c 6975 /* XXX perhaps we should allow
6976 * keyboard-interactive to do this too? */
51470298 6977 s->we_are_in = FALSE;
1408a877 6978 break;
6979 }
6980 }
6981 } else {
51470298 6982 c_write_str(ssh, "Further authentication required\r\n");
1408a877 6983 logevent("Further authentication required");
6984 }
65a22376 6985
51470298 6986 s->can_pubkey =
32874aea 6987 in_commasep_string("publickey", methods, methlen);
51470298 6988 s->can_passwd =
32874aea 6989 in_commasep_string("password", methods, methlen);
86916870 6990 s->can_keyb_inter = ssh->cfg.try_ki_auth &&
761187b6 6991 in_commasep_string("keyboard-interactive", methods, methlen);
1408a877 6992 }
65a22376 6993
51470298 6994 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
65a22376 6995
94cd7c3a 6996 if (s->can_pubkey && !s->done_agent && s->nkeys) {
0405e71f 6997
1983e559 6998 /*
94cd7c3a 6999 * Attempt public-key authentication using a key from Pageant.
1983e559 7000 */
1983e559 7001
51470298 7002 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7003 ssh->pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
00db133f 7004
94cd7c3a 7005 logeventf(ssh, "Trying Pageant key #%d", s->keyi);
7006
7007 /* Unpack key from agent response */
7008 s->pklen = GET_32BIT(s->agentp);
7009 s->agentp += 4;
7010 s->pkblob = (char *)s->agentp;
7011 s->agentp += s->pklen;
7012 s->alglen = GET_32BIT(s->pkblob);
7013 s->alg = s->pkblob + 4;
7014 s->commentlen = GET_32BIT(s->agentp);
7015 s->agentp += 4;
7016 s->commentp = (char *)s->agentp;
7017 s->agentp += s->commentlen;
7018 /* s->agentp now points at next key, if any */
7019
7020 /* See if server will accept it */
7021 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7022 ssh2_pkt_addstring(s->pktout, s->username);
7023 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7024 /* service requested */
7025 ssh2_pkt_addstring(s->pktout, "publickey");
7026 /* method */
7027 ssh2_pkt_addbool(s->pktout, FALSE); /* no signature included */
7028 ssh2_pkt_addstring_start(s->pktout);
7029 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
7030 ssh2_pkt_addstring_start(s->pktout);
7031 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
7032 ssh2_pkt_send(ssh, s->pktout);
7033 s->type = AUTH_TYPE_PUBLICKEY_OFFER_QUIET;
1983e559 7034
94cd7c3a 7035 crWaitUntilV(pktin);
7036 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
1983e559 7037
94cd7c3a 7038 /* Offer of key refused. */
7039 s->gotit = TRUE;
1983e559 7040
94cd7c3a 7041 } else {
7042
7043 void *vret;
1983e559 7044
94cd7c3a 7045 if (flags & FLAG_VERBOSE) {
7046 c_write_str(ssh, "Authenticating with "
7047 "public key \"");
7048 c_write(ssh, s->commentp, s->commentlen);
7049 c_write_str(ssh, "\" from agent\r\n");
7050 }
1983e559 7051
94cd7c3a 7052 /*
7053 * Server is willing to accept the key.
7054 * Construct a SIGN_REQUEST.
7055 */
7056 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7057 ssh2_pkt_addstring(s->pktout, s->username);
7058 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7059 /* service requested */
7060 ssh2_pkt_addstring(s->pktout, "publickey");
7061 /* method */
7062 ssh2_pkt_addbool(s->pktout, TRUE); /* signature included */
7063 ssh2_pkt_addstring_start(s->pktout);
7064 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
7065 ssh2_pkt_addstring_start(s->pktout);
7066 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
7067
7068 /* Ask agent for signature. */
7069 s->siglen = s->pktout->length - 5 + 4 +
7070 ssh->v2_session_id_len;
7071 if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7072 s->siglen -= 4;
7073 s->len = 1; /* message type */
7074 s->len += 4 + s->pklen; /* key blob */
7075 s->len += 4 + s->siglen; /* data to sign */
7076 s->len += 4; /* flags */
7077 s->agentreq = snewn(4 + s->len, char);
7078 PUT_32BIT(s->agentreq, s->len);
7079 s->q = s->agentreq + 4;
7080 *s->q++ = SSH2_AGENTC_SIGN_REQUEST;
7081 PUT_32BIT(s->q, s->pklen);
7082 s->q += 4;
7083 memcpy(s->q, s->pkblob, s->pklen);
7084 s->q += s->pklen;
7085 PUT_32BIT(s->q, s->siglen);
7086 s->q += 4;
7087 /* Now the data to be signed... */
7088 if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7089 PUT_32BIT(s->q, ssh->v2_session_id_len);
51470298 7090 s->q += 4;
94cd7c3a 7091 }
7092 memcpy(s->q, ssh->v2_session_id,
7093 ssh->v2_session_id_len);
7094 s->q += ssh->v2_session_id_len;
7095 memcpy(s->q, s->pktout->data + 5,
7096 s->pktout->length - 5);
7097 s->q += s->pktout->length - 5;
7098 /* And finally the (zero) flags word. */
7099 PUT_32BIT(s->q, 0);
7100 if (!agent_query(s->agentreq, s->len + 4,
7101 &vret, &s->retlen,
7102 ssh_agent_callback, ssh)) {
7103 do {
7104 crReturnV;
7105 if (pktin) {
7106 bombout(("Unexpected data from server"
7107 " while waiting for agent"
7108 " response"));
7109 crStopV;
1983e559 7110 }
94cd7c3a 7111 } while (pktin || inlen > 0);
7112 vret = ssh->agent_response;
7113 s->retlen = ssh->agent_response_len;
7114 }
7115 s->ret = vret;
7116 sfree(s->agentreq);
7117 if (s->ret) {
7118 if (s->ret[4] == SSH2_AGENT_SIGN_RESPONSE) {
7119 logevent("Sending Pageant's response");
7120 ssh2_add_sigblob(ssh, s->pktout,
7121 s->pkblob, s->pklen,
7122 s->ret + 9,
7123 GET_32BIT(s->ret + 5));
7124 ssh2_pkt_send(ssh, s->pktout);
7125 s->type = AUTH_TYPE_PUBLICKEY;
7126 } else {
7127 /* FIXME: less drastic response */
7128 bombout(("Pageant failed to answer challenge"));
7129 crStopV;
1983e559 7130 }
7131 }
1983e559 7132 }
94cd7c3a 7133
7134 /* Do we have any keys left to try? */
7135 if (s->pkblob_in_agent) {
7136 s->done_agent = TRUE;
7137 s->tried_pubkey_config = TRUE;
7138 } else {
7139 s->keyi++;
7140 if (s->keyi >= s->nkeys)
7141 s->done_agent = TRUE;
7142 }
1983e559 7143
edd0cb8a 7144 } else if (s->can_pubkey && s->publickey_blob &&
7145 !s->tried_pubkey_config) {
65a22376 7146
edd0cb8a 7147 struct ssh2_userkey *key; /* not live over crReturn */
7148 char *passphrase; /* not live over crReturn */
65a22376 7149
51470298 7150 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7151 ssh->pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
00db133f 7152
edd0cb8a 7153 s->tried_pubkey_config = TRUE;
7154
65a22376 7155 /*
1408a877 7156 * Try the public key supplied in the configuration.
7157 *
7158 * First, offer the public blob to see if the server is
7159 * willing to accept it.
65a22376 7160 */
ff3187f6 7161 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7162 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7163 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7164 /* service requested */
7165 ssh2_pkt_addstring(s->pktout, "publickey"); /* method */
7166 ssh2_pkt_addbool(s->pktout, FALSE);
7167 /* no signature included */
7168 ssh2_pkt_addstring(s->pktout, s->publickey_algorithm);
7169 ssh2_pkt_addstring_start(s->pktout);
7170 ssh2_pkt_addstring_data(s->pktout,
7171 (char *)s->publickey_blob,
7172 s->publickey_bloblen);
ff3187f6 7173 ssh2_pkt_send(ssh, s->pktout);
edd0cb8a 7174 logevent("Offered public key");
ff3187f6 7175
7176 crWaitUntilV(pktin);
edd0cb8a 7177 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
7178 /* Key refused. Give up. */
7179 s->gotit = TRUE; /* reconsider message next loop */
7180 s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
7181 continue; /* process this new message */
45068b27 7182 }
edd0cb8a 7183 logevent("Offer of public key accepted");
af659722 7184
45068b27 7185 /*
edd0cb8a 7186 * Actually attempt a serious authentication using
7187 * the key.
45068b27 7188 */
edd0cb8a 7189 if (flags & FLAG_VERBOSE) {
7190 c_write_str(ssh, "Authenticating with public key \"");
7191 c_write_str(ssh, s->publickey_comment);
7192 c_write_str(ssh, "\"\r\n");
7193 }
7194 key = NULL;
7195 while (!key) {
7196 const char *error; /* not live over crReturn */
7197 if (s->publickey_encrypted) {
7198 /*
7199 * Get a passphrase from the user.
7200 */
7201 int ret; /* need not be kept over crReturn */
7202 s->cur_prompt = new_prompts(ssh->frontend);
7203 s->cur_prompt->to_server = FALSE;
7204 s->cur_prompt->name = dupstr("SSH key passphrase");
7205 add_prompt(s->cur_prompt,
7206 dupprintf("Passphrase for key \"%.100s\": ",
7207 s->publickey_comment),
7208 FALSE, SSH_MAX_PASSWORD_LEN);
7209 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7210 while (ret < 0) {
7211 ssh->send_ok = 1;
7212 crWaitUntilV(!pktin);
7213 ret = get_userpass_input(s->cur_prompt,
7214 in, inlen);
7215 ssh->send_ok = 0;
7216 }
7217 if (!ret) {
7218 /* Failed to get a passphrase. Terminate. */
7219 free_prompts(s->cur_prompt);
7220 ssh_disconnect(ssh, NULL,
7221 "Unable to authenticate",
7222 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7223 TRUE);
7224 crStopV;
85fdbe25 7225 }
edd0cb8a 7226 passphrase =
7227 dupstr(s->cur_prompt->prompts[0]->result);
7228 free_prompts(s->cur_prompt);
45068b27 7229 } else {
edd0cb8a 7230 passphrase = NULL; /* no passphrase needed */
45068b27 7231 }
1408a877 7232
edd0cb8a 7233 /*
7234 * Try decrypting the key.
7235 */
7236 key = ssh2_load_userkey(&ssh->cfg.keyfile, passphrase,
7237 &error);
7238 if (passphrase) {
7239 /* burn the evidence */
7240 memset(passphrase, 0, strlen(passphrase));
7241 sfree(passphrase);
7242 }
7243 if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
7244 if (passphrase &&
7245 (key == SSH2_WRONG_PASSPHRASE)) {
7246 c_write_str(ssh, "Wrong passphrase\r\n");
7247 key = NULL;
7248 /* and loop again */
7249 } else {
7250 c_write_str(ssh, "Unable to load private key (");
7251 c_write_str(ssh, error);
7252 c_write_str(ssh, ")\r\n");
7253 key = NULL;
7254 break; /* try something else */
7255 }
1408a877 7256 }
65a22376 7257 }
65a22376 7258
edd0cb8a 7259 if (key) {
1dd353b5 7260 unsigned char *pkblob, *sigblob, *sigdata;
7261 int pkblob_len, sigblob_len, sigdata_len;
edd0cb8a 7262 int p;
65a22376 7263
1408a877 7264 /*
7265 * We have loaded the private key and the server
7266 * has announced that it's willing to accept it.
7267 * Hallelujah. Generate a signature and send it.
7268 */
ff3187f6 7269 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7270 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7271 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7272 /* service requested */
7273 ssh2_pkt_addstring(s->pktout, "publickey");
7274 /* method */
ff3187f6 7275 ssh2_pkt_addbool(s->pktout, TRUE);
edd0cb8a 7276 /* signature follows */
ff3187f6 7277 ssh2_pkt_addstring(s->pktout, key->alg->name);
edd0cb8a 7278 pkblob = key->alg->public_blob(key->data,
7279 &pkblob_len);
ff3187f6 7280 ssh2_pkt_addstring_start(s->pktout);
edd0cb8a 7281 ssh2_pkt_addstring_data(s->pktout, (char *)pkblob,
7282 pkblob_len);
1408a877 7283
7284 /*
7285 * The data to be signed is:
7286 *
7287 * string session-id
7288 *
7289 * followed by everything so far placed in the
7290 * outgoing packet.
7291 */
b672f405 7292 sigdata_len = s->pktout->length - 5 + 4 +
7293 ssh->v2_session_id_len;
edd0cb8a 7294 if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7295 sigdata_len -= 4;
92d60585 7296 sigdata = snewn(sigdata_len, unsigned char);
edd0cb8a 7297 p = 0;
7298 if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7299 PUT_32BIT(sigdata+p, ssh->v2_session_id_len);
7300 p += 4;
7301 }
b672f405 7302 memcpy(sigdata+p, ssh->v2_session_id,
7303 ssh->v2_session_id_len);
7304 p += ssh->v2_session_id_len;
ff3187f6 7305 memcpy(sigdata+p, s->pktout->data + 5,
7306 s->pktout->length - 5);
edd0cb8a 7307 p += s->pktout->length - 5;
7308 assert(p == sigdata_len);
d8baa528 7309 sigblob = key->alg->sign(key->data, (char *)sigdata,
1dd353b5 7310 sigdata_len, &sigblob_len);
ff3187f6 7311 ssh2_add_sigblob(ssh, s->pktout, pkblob, pkblob_len,
1dd353b5 7312 sigblob, sigblob_len);
7313 sfree(pkblob);
7314 sfree(sigblob);
1408a877 7315 sfree(sigdata);
7316
ff3187f6 7317 ssh2_pkt_send(ssh, s->pktout);
51470298 7318 s->type = AUTH_TYPE_PUBLICKEY;
75374b2f 7319 key->alg->freekey(key->data);
1408a877 7320 }
edd0cb8a 7321
7322 } else if (s->can_keyb_inter && !s->kbd_inter_refused) {
7323
7324 /*
7325 * Keyboard-interactive authentication.
7326 */
edd0cb8a 7327
edd0cb8a 7328 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
7329
7330 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7331 ssh->pkt_ctx |= SSH2_PKTCTX_KBDINTER;
7332
7333 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7334 ssh2_pkt_addstring(s->pktout, s->username);
7335 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7336 /* service requested */
7337 ssh2_pkt_addstring(s->pktout, "keyboard-interactive");
7338 /* method */
7339 ssh2_pkt_addstring(s->pktout, ""); /* lang */
7340 ssh2_pkt_addstring(s->pktout, ""); /* submethods */
7341 ssh2_pkt_send(ssh, s->pktout);
7342
7343 crWaitUntilV(pktin);
7344 if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
7345 /* Server is not willing to do keyboard-interactive
b8e3173d 7346 * at all (or, bizarrely but legally, accepts the
7347 * user without actually issuing any prompts).
7348 * Give up on it entirely. */
edd0cb8a 7349 s->gotit = TRUE;
7350 if (pktin->type == SSH2_MSG_USERAUTH_FAILURE)
7351 logevent("Keyboard-interactive authentication refused");
7352 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
7353 s->kbd_inter_refused = TRUE; /* don't try it again */
7354 continue;
7355 }
7356
7357 /*
b8e3173d 7358 * Loop while the server continues to send INFO_REQUESTs.
edd0cb8a 7359 */
b8e3173d 7360 while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
edd0cb8a 7361
b8e3173d 7362 char *name, *inst, *lang;
7363 int name_len, inst_len, lang_len;
7364 int i;
7365
7366 /*
7367 * We've got a fresh USERAUTH_INFO_REQUEST.
7368 * Get the preamble and start building a prompt.
7369 */
7370 ssh_pkt_getstring(pktin, &name, &name_len);
7371 ssh_pkt_getstring(pktin, &inst, &inst_len);
7372 ssh_pkt_getstring(pktin, &lang, &lang_len);
7373 s->cur_prompt = new_prompts(ssh->frontend);
7374 s->cur_prompt->to_server = TRUE;
7375 if (name_len) {
7376 /* FIXME: better prefix to distinguish from
7377 * local prompts? */
7378 s->cur_prompt->name =
7379 dupprintf("SSH server: %.*s", name_len, name);
7380 s->cur_prompt->name_reqd = TRUE;
7381 } else {
7382 s->cur_prompt->name =
7383 dupstr("SSH server authentication");
7384 s->cur_prompt->name_reqd = FALSE;
edd0cb8a 7385 }
b8e3173d 7386 /* FIXME: ugly to print "Using..." in prompt _every_
7387 * time round. Can this be done more subtly? */
7388 s->cur_prompt->instruction =
7389 dupprintf("Using keyboard-interactive authentication.%s%.*s",
7390 inst_len ? "\n" : "", inst_len, inst);
7391 s->cur_prompt->instr_reqd = TRUE;
edd0cb8a 7392
b8e3173d 7393 /*
7394 * Get the prompts from the packet.
7395 */
7396 s->num_prompts = ssh_pkt_getuint32(pktin);
7397 for (i = 0; i < s->num_prompts; i++) {
7398 char *prompt;
7399 int prompt_len;
7400 int echo;
7401 static char noprompt[] =
7402 "<server failed to send prompt>: ";
7403
7404 ssh_pkt_getstring(pktin, &prompt, &prompt_len);
7405 echo = ssh2_pkt_getbool(pktin);
7406 if (!prompt_len) {
7407 prompt = noprompt;
7408 prompt_len = lenof(noprompt)-1;
7409 }
7410 add_prompt(s->cur_prompt,
7411 dupprintf("%.*s", prompt_len, prompt),
7412 echo, SSH_MAX_PASSWORD_LEN);
edd0cb8a 7413 }
b8e3173d 7414
7415 /*
7416 * Get the user's responses.
7417 */
7418 if (s->num_prompts) {
7419 int ret; /* not live over crReturn */
7420 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7421 while (ret < 0) {
7422 ssh->send_ok = 1;
7423 crWaitUntilV(!pktin);
7424 ret = get_userpass_input(s->cur_prompt, in, inlen);
7425 ssh->send_ok = 0;
7426 }
7427 if (!ret) {
7428 /*
7429 * Failed to get responses. Terminate.
7430 */
7431 free_prompts(s->cur_prompt);
7432 ssh_disconnect(ssh, NULL, "Unable to authenticate",
7433 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7434 TRUE);
7435 crStopV;
7436 }
edd0cb8a 7437 }
b8e3173d 7438
7439 /*
7440 * Send the responses to the server.
7441 */
7442 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_INFO_RESPONSE);
b8e3173d 7443 ssh2_pkt_adduint32(s->pktout, s->num_prompts);
7444 for (i=0; i < s->num_prompts; i++) {
7445 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
7446 ssh2_pkt_addstring(s->pktout,
7447 s->cur_prompt->prompts[i]->result);
7448 end_log_omission(ssh, s->pktout);
7449 }
18524056 7450 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
b8e3173d 7451
7452 /*
7453 * Get the next packet in case it's another
7454 * INFO_REQUEST.
7455 */
7456 crWaitUntilV(pktin);
7457
edd0cb8a 7458 }
7459
7460 /*
b8e3173d 7461 * We should have SUCCESS or FAILURE now.
edd0cb8a 7462 */
b8e3173d 7463 s->gotit = TRUE;
edd0cb8a 7464
7465 } else if (s->can_passwd) {
7466
7467 /*
7468 * Plain old password authentication.
7469 */
7470 int ret; /* not live over crReturn */
e955d348 7471 int changereq_first_time; /* not live over crReturn */
edd0cb8a 7472
edd0cb8a 7473 ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
7474 ssh->pkt_ctx |= SSH2_PKTCTX_PASSWORD;
7475
7476 s->cur_prompt = new_prompts(ssh->frontend);
7477 s->cur_prompt->to_server = TRUE;
7478 s->cur_prompt->name = dupstr("SSH password");
7479 add_prompt(s->cur_prompt, dupprintf("%.90s@%.90s's password: ",
7480 s->username,
7481 ssh->savedhost),
7482 FALSE, SSH_MAX_PASSWORD_LEN);
7483
7484 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7485 while (ret < 0) {
7486 ssh->send_ok = 1;
7487 crWaitUntilV(!pktin);
7488 ret = get_userpass_input(s->cur_prompt, in, inlen);
7489 ssh->send_ok = 0;
7490 }
7491 if (!ret) {
7492 /*
7493 * Failed to get responses. Terminate.
7494 */
7495 free_prompts(s->cur_prompt);
7496 ssh_disconnect(ssh, NULL, "Unable to authenticate",
7497 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7498 TRUE);
7499 crStopV;
7500 }
e955d348 7501 /*
7502 * Squirrel away the password. (We may need it later if
7503 * asked to change it.)
7504 */
7505 s->password = dupstr(s->cur_prompt->prompts[0]->result);
7506 free_prompts(s->cur_prompt);
edd0cb8a 7507
7508 /*
7509 * Send the password packet.
7510 *
95d2d262 7511 * We pad out the password packet to 256 bytes to make
7512 * it harder for an attacker to find the length of the
7513 * user's password.
1408a877 7514 *
95d2d262 7515 * Anyone using a password longer than 256 bytes
7516 * probably doesn't have much to worry about from
1408a877 7517 * people who find out how long their password is!
65a22376 7518 */
ff3187f6 7519 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7520 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7521 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7522 /* service requested */
ff3187f6 7523 ssh2_pkt_addstring(s->pktout, "password");
7524 ssh2_pkt_addbool(s->pktout, FALSE);
7525 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
e955d348 7526 ssh2_pkt_addstring(s->pktout, s->password);
ff3187f6 7527 end_log_omission(ssh, s->pktout);
18524056 7528 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
0d43337a 7529 logevent("Sent password");
28f4d4f0 7530 s->type = AUTH_TYPE_PASSWORD;
edd0cb8a 7531
e955d348 7532 /*
7533 * Wait for next packet, in case it's a password change
7534 * request.
7535 */
7536 crWaitUntilV(pktin);
7537 changereq_first_time = TRUE;
7538
7539 while (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
7540
7541 /*
7542 * We're being asked for a new password
7543 * (perhaps not for the first time).
7544 * Loop until the server accepts it.
7545 */
7546
7547 int got_new = FALSE; /* not live over crReturn */
7548 char *prompt; /* not live over crReturn */
7549 int prompt_len; /* not live over crReturn */
7550
7551 {
7552 char *msg;
7553 if (changereq_first_time)
7554 msg = "Server requested password change";
7555 else
7556 msg = "Server rejected new password";
7557 logevent(msg);
7558 c_write_str(ssh, msg);
7559 c_write_str(ssh, "\r\n");
7560 }
7561
7562 ssh_pkt_getstring(pktin, &prompt, &prompt_len);
7563
7564 s->cur_prompt = new_prompts(ssh->frontend);
7565 s->cur_prompt->to_server = TRUE;
7566 s->cur_prompt->name = dupstr("New SSH password");
7567 s->cur_prompt->instruction =
7568 dupprintf("%.*s", prompt_len, prompt);
7569 s->cur_prompt->instr_reqd = TRUE;
d9add7bc 7570 /*
7571 * There's no explicit requirement in the protocol
7572 * for the "old" passwords in the original and
7573 * password-change messages to be the same, and
7574 * apparently some Cisco kit supports password change
7575 * by the user entering a blank password originally
7576 * and the real password subsequently, so,
7577 * reluctantly, we prompt for the old password again.
7578 *
7579 * (On the other hand, some servers don't even bother
7580 * to check this field.)
7581 */
7582 add_prompt(s->cur_prompt,
7583 dupstr("Current password (blank for previously entered password): "),
7584 FALSE, SSH_MAX_PASSWORD_LEN);
e955d348 7585 add_prompt(s->cur_prompt, dupstr("Enter new password: "),
7586 FALSE, SSH_MAX_PASSWORD_LEN);
7587 add_prompt(s->cur_prompt, dupstr("Confirm new password: "),
7588 FALSE, SSH_MAX_PASSWORD_LEN);
7589
7590 /*
7591 * Loop until the user manages to enter the same
7592 * password twice.
7593 */
7594 while (!got_new) {
7595
7596 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7597 while (ret < 0) {
7598 ssh->send_ok = 1;
7599 crWaitUntilV(!pktin);
7600 ret = get_userpass_input(s->cur_prompt, in, inlen);
7601 ssh->send_ok = 0;
7602 }
7603 if (!ret) {
7604 /*
7605 * Failed to get responses. Terminate.
7606 */
7607 /* burn the evidence */
7608 free_prompts(s->cur_prompt);
7609 memset(s->password, 0, strlen(s->password));
7610 sfree(s->password);
7611 ssh_disconnect(ssh, NULL, "Unable to authenticate",
7612 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7613 TRUE);
7614 crStopV;
7615 }
7616
7617 /*
d9add7bc 7618 * If the user specified a new original password
7619 * (IYSWIM), overwrite any previously specified
7620 * one.
7621 * (A side effect is that the user doesn't have to
7622 * re-enter it if they louse up the new password.)
7623 */
7624 if (s->cur_prompt->prompts[0]->result[0]) {
7625 memset(s->password, 0, strlen(s->password));
7626 /* burn the evidence */
7627 sfree(s->password);
7628 s->password =
7629 dupstr(s->cur_prompt->prompts[0]->result);
7630 }
7631
7632 /*
7633 * Check the two new passwords match.
e955d348 7634 */
d9add7bc 7635 got_new = (strcmp(s->cur_prompt->prompts[1]->result,
7636 s->cur_prompt->prompts[2]->result)
e955d348 7637 == 0);
7638 if (!got_new)
7639 /* They don't. Silly user. */
7640 c_write_str(ssh, "Passwords do not match\r\n");
7641
7642 }
7643
7644 /*
7645 * Send the new password (along with the old one).
7646 * (see above for padding rationale)
7647 */
7648 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
e955d348 7649 ssh2_pkt_addstring(s->pktout, s->username);
7650 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7651 /* service requested */
7652 ssh2_pkt_addstring(s->pktout, "password");
7653 ssh2_pkt_addbool(s->pktout, TRUE);
7654 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
7655 ssh2_pkt_addstring(s->pktout, s->password);
7656 ssh2_pkt_addstring(s->pktout,
d9add7bc 7657 s->cur_prompt->prompts[1]->result);
e955d348 7658 free_prompts(s->cur_prompt);
7659 end_log_omission(ssh, s->pktout);
18524056 7660 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
e955d348 7661 logevent("Sent new password");
7662
7663 /*
7664 * Now see what the server has to say about it.
7665 * (If it's CHANGEREQ again, it's not happy with the
7666 * new password.)
7667 */
7668 crWaitUntilV(pktin);
7669 changereq_first_time = FALSE;
7670
7671 }
7672
7673 /*
7674 * We need to reexamine the current pktin at the top
7675 * of the loop. Either:
7676 * - we weren't asked to change password at all, in
7677 * which case it's a SUCCESS or FAILURE with the
7678 * usual meaning
7679 * - we sent a new password, and the server was
7680 * either OK with it (SUCCESS or FAILURE w/partial
7681 * success) or unhappy with the _old_ password
7682 * (FAILURE w/o partial success)
7683 * In any of these cases, we go back to the top of
7684 * the loop and start again.
7685 */
7686 s->gotit = TRUE;
7687
7688 /*
7689 * We don't need the old password any more, in any
7690 * case. Burn the evidence.
7691 */
7692 memset(s->password, 0, strlen(s->password));
7693 sfree(s->password);
7694
1408a877 7695 } else {
edd0cb8a 7696
9e296bfa 7697 ssh_disconnect(ssh, NULL,
7698 "No supported authentication methods available",
7699 SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
7700 FALSE);
7ffdbc1a 7701 crStopV;
edd0cb8a 7702
65a22376 7703 }
edd0cb8a 7704
65a22376 7705 }
a1a1fae4 7706 }
6bbce591 7707 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
7cca0d81 7708
edd0cb8a 7709 /* Clear up various bits and pieces from authentication. */
7710 if (s->publickey_blob) {
7711 sfree(s->publickey_blob);
7712 sfree(s->publickey_comment);
7713 }
94cd7c3a 7714 if (s->agent_response)
7715 sfree(s->agent_response);
edd0cb8a 7716
7cca0d81 7717 /*
a1a1fae4 7718 * Now the connection protocol has started, one way or another.
7cca0d81 7719 */
7720
0ed48730 7721 ssh->channels = newtree234(ssh_channelcmp);
7722
7cca0d81 7723 /*
b09eaa88 7724 * Set up handlers for some connection protocol messages, so we
7725 * don't have to handle them repeatedly in this coroutine.
7726 */
7727 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] =
7728 ssh2_msg_channel_window_adjust;
51df0ab5 7729 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] =
7730 ssh2_msg_global_request;
b09eaa88 7731
7732 /*
0ed48730 7733 * Create the main session channel.
7cca0d81 7734 */
feb02b4e 7735 if (ssh->cfg.ssh_no_shell) {
7736 ssh->mainchan = NULL;
7737 } else if (*ssh->cfg.ssh_nc_host) {
7738 /*
7739 * Just start a direct-tcpip channel and use it as the main
7740 * channel.
7741 */
7742 ssh->mainchan = snew(struct ssh_channel);
7743 ssh->mainchan->ssh = ssh;
7744 ssh->mainchan->localid = alloc_channel_id(ssh);
23828b7e 7745 logeventf(ssh,
7746 "Opening direct-tcpip channel to %s:%d in place of session",
7747 ssh->cfg.ssh_nc_host, ssh->cfg.ssh_nc_port);
feb02b4e 7748 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
7749 ssh2_pkt_addstring(s->pktout, "direct-tcpip");
7750 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
7751 ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
7752 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
7753 ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT); /* our max pkt size */
7754 ssh2_pkt_addstring(s->pktout, ssh->cfg.ssh_nc_host);
7755 ssh2_pkt_adduint32(s->pktout, ssh->cfg.ssh_nc_port);
7756 /*
23828b7e 7757 * There's nothing meaningful to put in the originator
7758 * fields, but some servers insist on syntactically correct
7759 * information.
feb02b4e 7760 */
7761 ssh2_pkt_addstring(s->pktout, "0.0.0.0");
7762 ssh2_pkt_adduint32(s->pktout, 0);
7763 ssh2_pkt_send(ssh, s->pktout);
7764
7765 crWaitUntilV(pktin);
7766 if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
7767 bombout(("Server refused to open a direct-tcpip channel"));
7768 crStopV;
7769 /* FIXME: error data comes back in FAILURE packet */
7770 }
7771 if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
7772 bombout(("Server's channel confirmation cited wrong channel"));
7773 crStopV;
7774 }
7775 ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
7776 ssh->mainchan->halfopen = FALSE;
7777 ssh->mainchan->type = CHAN_MAINSESSION;
7778 ssh->mainchan->closes = 0;
7779 ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
7780 ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
7781 bufchain_init(&ssh->mainchan->v.v2.outbuffer);
7782 add234(ssh->channels, ssh->mainchan);
7783 update_specials_menu(ssh->frontend);
23828b7e 7784 logevent("Opened direct-tcpip channel");
feb02b4e 7785 ssh->ncmode = TRUE;
7786 } else {
0ed48730 7787 ssh->mainchan = snew(struct ssh_channel);
7788 ssh->mainchan->ssh = ssh;
7789 ssh->mainchan->localid = alloc_channel_id(ssh);
ff3187f6 7790 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
7791 ssh2_pkt_addstring(s->pktout, "session");
7792 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
0ed48730 7793 ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
ff3187f6 7794 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
954d5c5a 7795 ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT); /* our max pkt size */
ff3187f6 7796 ssh2_pkt_send(ssh, s->pktout);
7797 crWaitUntilV(pktin);
7798 if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
0ed48730 7799 bombout(("Server refused to open a session"));
7800 crStopV;
7801 /* FIXME: error data comes back in FAILURE packet */
7802 }
ff3187f6 7803 if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
0ed48730 7804 bombout(("Server's channel confirmation cited wrong channel"));
7805 crStopV;
7806 }
ff3187f6 7807 ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
64d6ff88 7808 ssh->mainchan->halfopen = FALSE;
0ed48730 7809 ssh->mainchan->type = CHAN_MAINSESSION;
7810 ssh->mainchan->closes = 0;
ff3187f6 7811 ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
7812 ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
0ed48730 7813 bufchain_init(&ssh->mainchan->v.v2.outbuffer);
7814 add234(ssh->channels, ssh->mainchan);
62638676 7815 update_specials_menu(ssh->frontend);
0ed48730 7816 logevent("Opened channel for session");
feb02b4e 7817 ssh->ncmode = FALSE;
7818 }
7cca0d81 7819
7820 /*
51df0ab5 7821 * Now we have a channel, make dispatch table entries for
7822 * general channel-based messages.
7823 */
7824 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] =
7825 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] =
7826 ssh2_msg_channel_data;
7827 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_channel_eof;
7828 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_channel_close;
7829 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] =
7830 ssh2_msg_channel_open_confirmation;
7831 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] =
7832 ssh2_msg_channel_open_failure;
7833 ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] =
7834 ssh2_msg_channel_request;
7835 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] =
7836 ssh2_msg_channel_open;
7837
7838 /*
783415f8 7839 * Potentially enable X11 forwarding.
7840 */
feb02b4e 7841 if (ssh->mainchan && !ssh->ncmode && ssh->cfg.x11_forward) {
32874aea 7842 char proto[20], data[64];
7843 logevent("Requesting X11 forwarding");
302121de 7844 ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
86916870 7845 data, sizeof(data), ssh->cfg.x11_auth);
7846 x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
ff3187f6 7847 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7848 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
7849 ssh2_pkt_addstring(s->pktout, "x11-req");
7850 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
7851 ssh2_pkt_addbool(s->pktout, 0); /* many connections */
7852 ssh2_pkt_addstring(s->pktout, proto);
f68353be 7853 /*
7854 * Note that while we blank the X authentication data here, we don't
7855 * take any special action to blank the start of an X11 channel,
7856 * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
7857 * without having session blanking enabled is likely to leak your
7858 * cookie into the log.
7859 */
178c3872 7860 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
ff3187f6 7861 ssh2_pkt_addstring(s->pktout, data);
178c3872 7862 end_log_omission(ssh, s->pktout);
ff3187f6 7863 ssh2_pkt_adduint32(s->pktout, x11_get_screen_number(ssh->cfg.x11_display));
7864 ssh2_pkt_send(ssh, s->pktout);
32874aea 7865
b09eaa88 7866 crWaitUntilV(pktin);
32874aea 7867
ff3187f6 7868 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
7869 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 7870 bombout(("Unexpected response to X11 forwarding request:"
ff3187f6 7871 " packet type %d", pktin->type));
7ffdbc1a 7872 crStopV;
32874aea 7873 }
7874 logevent("X11 forwarding refused");
7875 } else {
7876 logevent("X11 forwarding enabled");
51470298 7877 ssh->X11_fwd_enabled = TRUE;
32874aea 7878 }
783415f8 7879 }
7880
7881 /*
bc240b21 7882 * Enable port forwardings.
7883 */
06fadff5 7884 ssh_setup_portfwd(ssh, &ssh->cfg);
bc240b21 7885
7886 /*
36c2a3e9 7887 * Potentially enable agent forwarding.
7888 */
feb02b4e 7889 if (ssh->mainchan && !ssh->ncmode && ssh->cfg.agentfwd && agent_exists()) {
32874aea 7890 logevent("Requesting OpenSSH-style agent forwarding");
ff3187f6 7891 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7892 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
7893 ssh2_pkt_addstring(s->pktout, "auth-agent-req@openssh.com");
7894 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
7895 ssh2_pkt_send(ssh, s->pktout);
32874aea 7896
b09eaa88 7897 crWaitUntilV(pktin);
32874aea 7898
ff3187f6 7899 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
7900 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 7901 bombout(("Unexpected response to agent forwarding request:"
ff3187f6 7902 " packet type %d", pktin->type));
7ffdbc1a 7903 crStopV;
32874aea 7904 }
7905 logevent("Agent forwarding refused");
7906 } else {
7907 logevent("Agent forwarding enabled");
51470298 7908 ssh->agentfwd_enabled = TRUE;
32874aea 7909 }
36c2a3e9 7910 }
7911
7912 /*
7cca0d81 7913 * Now allocate a pty for the session.
7914 */
feb02b4e 7915 if (ssh->mainchan && !ssh->ncmode && !ssh->cfg.nopty) {
a5dd8467 7916 /* Unpick the terminal-speed string. */
7917 /* XXX perhaps we should allow no speeds to be sent. */
db219738 7918 ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
7919 sscanf(ssh->cfg.termspeed, "%d,%d", &ssh->ospeed, &ssh->ispeed);
a5dd8467 7920 /* Build the pty request. */
ff3187f6 7921 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7922 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); /* recipient channel */
7923 ssh2_pkt_addstring(s->pktout, "pty-req");
7924 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
7925 ssh2_pkt_addstring(s->pktout, ssh->cfg.termtype);
7926 ssh2_pkt_adduint32(s->pktout, ssh->term_width);
7927 ssh2_pkt_adduint32(s->pktout, ssh->term_height);
7928 ssh2_pkt_adduint32(s->pktout, 0); /* pixel width */
7929 ssh2_pkt_adduint32(s->pktout, 0); /* pixel height */
7930 ssh2_pkt_addstring_start(s->pktout);
c6ccd5c2 7931 parse_ttymodes(ssh, ssh->cfg.ttymodes,
7932 ssh2_send_ttymode, (void *)s->pktout);
7933 ssh2_pkt_addbyte(s->pktout, SSH2_TTY_OP_ISPEED);
ff3187f6 7934 ssh2_pkt_adduint32(s->pktout, ssh->ispeed);
c6ccd5c2 7935 ssh2_pkt_addbyte(s->pktout, SSH2_TTY_OP_OSPEED);
ff3187f6 7936 ssh2_pkt_adduint32(s->pktout, ssh->ospeed);
7937 ssh2_pkt_addstring_data(s->pktout, "\0", 1); /* TTY_OP_END */
7938 ssh2_pkt_send(ssh, s->pktout);
51470298 7939 ssh->state = SSH_STATE_INTERMED;
32874aea 7940
b09eaa88 7941 crWaitUntilV(pktin);
32874aea 7942
ff3187f6 7943 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
7944 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 7945 bombout(("Unexpected response to pty request:"
ff3187f6 7946 " packet type %d", pktin->type));
7ffdbc1a 7947 crStopV;
32874aea 7948 }
51470298 7949 c_write_str(ssh, "Server refused to allocate pty\r\n");
7950 ssh->editing = ssh->echoing = 1;
32874aea 7951 } else {
a5dd8467 7952 logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
db219738 7953 ssh->ospeed, ssh->ispeed);
32874aea 7954 }
0965bee0 7955 } else {
51470298 7956 ssh->editing = ssh->echoing = 1;
7cca0d81 7957 }
7958
7959 /*
73feed4f 7960 * Send environment variables.
7961 *
7962 * Simplest thing here is to send all the requests at once, and
7963 * then wait for a whole bunch of successes or failures.
7964 */
feb02b4e 7965 if (ssh->mainchan && !ssh->ncmode && *ssh->cfg.environmt) {
73feed4f 7966 char *e = ssh->cfg.environmt;
7967 char *var, *varend, *val;
7968
7969 s->num_env = 0;
7970
7971 while (*e) {
7972 var = e;
7973 while (*e && *e != '\t') e++;
7974 varend = e;
7975 if (*e == '\t') e++;
7976 val = e;
7977 while (*e) e++;
7978 e++;
7979
ff3187f6 7980 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
7981 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
7982 ssh2_pkt_addstring(s->pktout, "env");
7983 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
7984 ssh2_pkt_addstring_start(s->pktout);
7985 ssh2_pkt_addstring_data(s->pktout, var, varend-var);
7986 ssh2_pkt_addstring(s->pktout, val);
7987 ssh2_pkt_send(ssh, s->pktout);
73feed4f 7988
7989 s->num_env++;
7990 }
7991
7992 logeventf(ssh, "Sent %d environment variables", s->num_env);
7993
7994 s->env_ok = 0;
7995 s->env_left = s->num_env;
7996
7997 while (s->env_left > 0) {
b09eaa88 7998 crWaitUntilV(pktin);
73feed4f 7999
ff3187f6 8000 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8001 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
73feed4f 8002 bombout(("Unexpected response to environment request:"
ff3187f6 8003 " packet type %d", pktin->type));
73feed4f 8004 crStopV;
8005 }
8006 } else {
8007 s->env_ok++;
8008 }
8009
8010 s->env_left--;
8011 }
8012
8013 if (s->env_ok == s->num_env) {
8014 logevent("All environment variables successfully set");
8015 } else if (s->env_ok == 0) {
8016 logevent("All environment variables refused");
8017 c_write_str(ssh, "Server refused to set environment variables\r\n");
8018 } else {
8019 logeventf(ssh, "%d environment variables refused",
8020 s->num_env - s->env_ok);
8021 c_write_str(ssh, "Server refused to set all environment variables\r\n");
8022 }
8023 }
8024
8025 /*
fd5e5847 8026 * Start a shell or a remote command. We may have to attempt
8027 * this twice if the config data has provided a second choice
8028 * of command.
7cca0d81 8029 */
feb02b4e 8030 if (ssh->mainchan && !ssh->ncmode) while (1) {
fd5e5847 8031 int subsys;
8032 char *cmd;
8033
51470298 8034 if (ssh->fallback_cmd) {
86916870 8035 subsys = ssh->cfg.ssh_subsys2;
8036 cmd = ssh->cfg.remote_cmd_ptr2;
fd5e5847 8037 } else {
86916870 8038 subsys = ssh->cfg.ssh_subsys;
8039 cmd = ssh->cfg.remote_cmd_ptr;
04c52f10 8040 if (!cmd) cmd = ssh->cfg.remote_cmd;
fd5e5847 8041 }
8042
ff3187f6 8043 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8044 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); /* recipient channel */
fd5e5847 8045 if (subsys) {
ff3187f6 8046 ssh2_pkt_addstring(s->pktout, "subsystem");
8047 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8048 ssh2_pkt_addstring(s->pktout, cmd);
fd5e5847 8049 } else if (*cmd) {
ff3187f6 8050 ssh2_pkt_addstring(s->pktout, "exec");
8051 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8052 ssh2_pkt_addstring(s->pktout, cmd);
fd5e5847 8053 } else {
ff3187f6 8054 ssh2_pkt_addstring(s->pktout, "shell");
8055 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
32874aea 8056 }
ff3187f6 8057 ssh2_pkt_send(ssh, s->pktout);
b09eaa88 8058
8059 crWaitUntilV(pktin);
8060
ff3187f6 8061 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8062 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8063 bombout(("Unexpected response to shell/command request:"
ff3187f6 8064 " packet type %d", pktin->type));
7ffdbc1a 8065 crStopV;
fd5e5847 8066 }
8067 /*
8068 * We failed to start the command. If this is the
8069 * fallback command, we really are finished; if it's
8070 * not, and if the fallback command exists, try falling
8071 * back to it before complaining.
8072 */
86916870 8073 if (!ssh->fallback_cmd && ssh->cfg.remote_cmd_ptr2 != NULL) {
fd5e5847 8074 logevent("Primary command failed; attempting fallback");
51470298 8075 ssh->fallback_cmd = TRUE;
fd5e5847 8076 continue;
8077 }
6b5cf8b4 8078 bombout(("Server refused to start a shell/command"));
7ffdbc1a 8079 crStopV;
fd5e5847 8080 } else {
8081 logevent("Started a shell/command");
32874aea 8082 }
fd5e5847 8083 break;
7cca0d81 8084 }
8085
51470298 8086 ssh->state = SSH_STATE_SESSION;
8087 if (ssh->size_needed)
8088 ssh_size(ssh, ssh->term_width, ssh->term_height);
8089 if (ssh->eof_needed)
8090 ssh_special(ssh, TS_EOF);
6e48c3fe 8091
7cca0d81 8092 /*
8093 * Transfer data!
8094 */
b9d7bcad 8095 if (ssh->ldisc)
8096 ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
0ed48730 8097 if (ssh->mainchan)
8098 ssh->send_ok = 1;
7cca0d81 8099 while (1) {
e5574168 8100 crReturnV;
51470298 8101 s->try_send = FALSE;
ff3187f6 8102 if (pktin) {
2b7540a7 8103
51df0ab5 8104 /*
8105 * _All_ the connection-layer packets we expect to
8106 * receive are now handled by the dispatch table.
8107 * Anything that reaches here must be bogus.
8108 */
32874aea 8109
51df0ab5 8110 bombout(("Strange packet received: type %d", pktin->type));
8111 crStopV;
0ed48730 8112 } else if (ssh->mainchan) {
32874aea 8113 /*
8114 * We have spare data. Add it to the channel buffer.
8115 */
d8baa528 8116 ssh2_add_channel_data(ssh->mainchan, (char *)in, inlen);
51470298 8117 s->try_send = TRUE;
32874aea 8118 }
51470298 8119 if (s->try_send) {
32874aea 8120 int i;
8121 struct ssh_channel *c;
8122 /*
8123 * Try to send data on all channels if we can.
8124 */
1bfc7e93 8125 for (i = 0; NULL != (c = index234(ssh->channels, i)); i++)
8126 ssh2_try_send_and_unthrottle(c);
7cca0d81 8127 }
e5574168 8128 }
8129
8130 crFinishV;
8131}
8132
8133/*
2e85c969 8134 * Handlers for SSH-2 messages that might arrive at any moment.
b09eaa88 8135 */
409bfa77 8136static void ssh2_msg_disconnect(Ssh ssh, struct Packet *pktin)
b09eaa88 8137{
8138 /* log reason code in disconnect message */
8139 char *buf, *msg;
8140 int nowlen, reason, msglen;
8141
8142 reason = ssh_pkt_getuint32(pktin);
8143 ssh_pkt_getstring(pktin, &msg, &msglen);
8144
8145 if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {
8146 buf = dupprintf("Received disconnect message (%s)",
8147 ssh2_disconnect_reasons[reason]);
8148 } else {
8149 buf = dupprintf("Received disconnect message (unknown"
8150 " type %d)", reason);
8151 }
8152 logevent(buf);
8153 sfree(buf);
8154 buf = dupprintf("Disconnection message text: %n%.*s",
8155 &nowlen, msglen, msg);
8156 logevent(buf);
8157 bombout(("Server sent disconnect message\ntype %d (%s):\n\"%s\"",
8158 reason,
8159 (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?
8160 ssh2_disconnect_reasons[reason] : "unknown",
8161 buf+nowlen));
8162 sfree(buf);
8163}
8164
409bfa77 8165static void ssh2_msg_debug(Ssh ssh, struct Packet *pktin)
b09eaa88 8166{
8167 /* log the debug message */
fb983202 8168 char *msg;
b09eaa88 8169 int msglen;
8170 int always_display;
8171
8172 /* XXX maybe we should actually take notice of this */
8173 always_display = ssh2_pkt_getbool(pktin);
8174 ssh_pkt_getstring(pktin, &msg, &msglen);
8175
fb983202 8176 logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
b09eaa88 8177}
8178
409bfa77 8179static void ssh2_msg_something_unimplemented(Ssh ssh, struct Packet *pktin)
b09eaa88 8180{
8181 struct Packet *pktout;
8182 pktout = ssh2_pkt_init(SSH2_MSG_UNIMPLEMENTED);
8183 ssh2_pkt_adduint32(pktout, pktin->sequence);
8184 /*
8185 * UNIMPLEMENTED messages MUST appear in the same order as the
8186 * messages they respond to. Hence, never queue them.
8187 */
8188 ssh2_pkt_send_noqueue(ssh, pktout);
8189}
8190
8191/*
2e85c969 8192 * Handle the top-level SSH-2 protocol.
7cca0d81 8193 */
b09eaa88 8194static void ssh2_protocol_setup(Ssh ssh)
8195{
8196 int i;
8197
8198 /*
8199 * Most messages cause SSH2_MSG_UNIMPLEMENTED.
8200 */
8201 for (i = 0; i < 256; i++)
8202 ssh->packet_dispatch[i] = ssh2_msg_something_unimplemented;
8203
8204 /*
8205 * Any message we actually understand, we set to NULL so that
8206 * the coroutines will get it.
8207 */
8208 ssh->packet_dispatch[SSH2_MSG_UNIMPLEMENTED] = NULL;
8209 ssh->packet_dispatch[SSH2_MSG_SERVICE_REQUEST] = NULL;
8210 ssh->packet_dispatch[SSH2_MSG_SERVICE_ACCEPT] = NULL;
8211 ssh->packet_dispatch[SSH2_MSG_KEXINIT] = NULL;
8212 ssh->packet_dispatch[SSH2_MSG_NEWKEYS] = NULL;
8213 ssh->packet_dispatch[SSH2_MSG_KEXDH_INIT] = NULL;
8214 ssh->packet_dispatch[SSH2_MSG_KEXDH_REPLY] = NULL;
8215 /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REQUEST] = NULL; duplicate case value */
8216 /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_GROUP] = NULL; duplicate case value */
8217 ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_INIT] = NULL;
8218 ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REPLY] = NULL;
8219 ssh->packet_dispatch[SSH2_MSG_USERAUTH_REQUEST] = NULL;
8220 ssh->packet_dispatch[SSH2_MSG_USERAUTH_FAILURE] = NULL;
8221 ssh->packet_dispatch[SSH2_MSG_USERAUTH_SUCCESS] = NULL;
8222 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
8223 ssh->packet_dispatch[SSH2_MSG_USERAUTH_PK_OK] = NULL;
8224 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ] = NULL; duplicate case value */
8225 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_REQUEST] = NULL; duplicate case value */
8226 ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_RESPONSE] = NULL;
8227 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] = NULL;
8228 ssh->packet_dispatch[SSH2_MSG_REQUEST_SUCCESS] = NULL;
8229 ssh->packet_dispatch[SSH2_MSG_REQUEST_FAILURE] = NULL;
8230 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = NULL;
8231 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] = NULL;
8232 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] = NULL;
8233 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] = NULL;
8234 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] = NULL;
8235 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] = NULL;
8236 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = NULL;
8237 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = NULL;
8238 ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] = NULL;
8239 ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = NULL;
8240 ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = NULL;
8241
8242 /*
8243 * These special message types we install handlers for.
8244 */
8245 ssh->packet_dispatch[SSH2_MSG_DISCONNECT] = ssh2_msg_disconnect;
2e85c969 8246 ssh->packet_dispatch[SSH2_MSG_IGNORE] = ssh_msg_ignore; /* shared with SSH-1 */
b09eaa88 8247 ssh->packet_dispatch[SSH2_MSG_DEBUG] = ssh2_msg_debug;
8248}
8249
9442dd57 8250static void ssh2_timer(void *ctx, long now)
8251{
8252 Ssh ssh = (Ssh)ctx;
8253
ecbb0000 8254 if (ssh->state == SSH_STATE_CLOSED)
8255 return;
8256
e6c1536e 8257 if (!ssh->kex_in_progress && ssh->cfg.ssh_rekey_time != 0 &&
9442dd57 8258 now - ssh->next_rekey >= 0) {
f382c87d 8259 do_ssh2_transport(ssh, "timeout", -1, NULL);
9442dd57 8260 }
8261}
8262
1c1a7262 8263static void ssh2_protocol(Ssh ssh, void *vin, int inlen,
ff3187f6 8264 struct Packet *pktin)
7cca0d81 8265{
1c1a7262 8266 unsigned char *in = (unsigned char *)vin;
b09eaa88 8267 if (ssh->state == SSH_STATE_CLOSED)
8268 return;
8269
9442dd57 8270 if (pktin) {
8271 ssh->incoming_data_size += pktin->encrypted_len;
8272 if (!ssh->kex_in_progress &&
d57f70af 8273 ssh->max_data_size != 0 &&
8274 ssh->incoming_data_size > ssh->max_data_size)
f382c87d 8275 do_ssh2_transport(ssh, "too much data received", -1, NULL);
9442dd57 8276 }
8277
b09eaa88 8278 if (pktin && ssh->packet_dispatch[pktin->type]) {
8279 ssh->packet_dispatch[pktin->type](ssh, pktin);
32874aea 8280 return;
b09eaa88 8281 }
8282
8283 if (!ssh->protocol_initial_phase_done ||
8284 (pktin && pktin->type >= 20 && pktin->type < 50)) {
8285 if (do_ssh2_transport(ssh, in, inlen, pktin) &&
8286 !ssh->protocol_initial_phase_done) {
8287 ssh->protocol_initial_phase_done = TRUE;
8288 /*
8289 * Allow authconn to initialise itself.
8290 */
8291 do_ssh2_authconn(ssh, NULL, 0, NULL);
8292 }
8293 } else {
8294 do_ssh2_authconn(ssh, in, inlen, pktin);
8295 }
7cca0d81 8296}
8297
8298/*
8df7a775 8299 * Called to set up the connection.
374330e2 8300 *
8301 * Returns an error message, or NULL on success.
374330e2 8302 */
cbe2d68f 8303static const char *ssh_init(void *frontend_handle, void **backend_handle,
8304 Config *cfg,
79bf227b 8305 char *host, int port, char **realhost, int nodelay,
8306 int keepalive)
32874aea 8307{
cbe2d68f 8308 const char *p;
51470298 8309 Ssh ssh;
8310
3d88e64d 8311 ssh = snew(struct ssh_tag);
86916870 8312 ssh->cfg = *cfg; /* STRUCTURE COPY */
125105d1 8313 ssh->version = 0; /* when not ready yet */
51470298 8314 ssh->s = NULL;
8315 ssh->cipher = NULL;
371e569c 8316 ssh->v1_cipher_ctx = NULL;
0183b242 8317 ssh->crcda_ctx = NULL;
51470298 8318 ssh->cscipher = NULL;
371e569c 8319 ssh->cs_cipher_ctx = NULL;
51470298 8320 ssh->sccipher = NULL;
371e569c 8321 ssh->sc_cipher_ctx = NULL;
51470298 8322 ssh->csmac = NULL;
a8327734 8323 ssh->cs_mac_ctx = NULL;
51470298 8324 ssh->scmac = NULL;
e0e1a00d 8325 ssh->sc_mac_ctx = NULL;
51470298 8326 ssh->cscomp = NULL;
5366aed8 8327 ssh->cs_comp_ctx = NULL;
51470298 8328 ssh->sccomp = NULL;
5366aed8 8329 ssh->sc_comp_ctx = NULL;
51470298 8330 ssh->kex = NULL;
389aa499 8331 ssh->kex_ctx = NULL;
51470298 8332 ssh->hostkey = NULL;
8333 ssh->exitcode = -1;
ac934965 8334 ssh->close_expected = FALSE;
9e296bfa 8335 ssh->clean_exit = FALSE;
51470298 8336 ssh->state = SSH_STATE_PREPACKET;
8337 ssh->size_needed = FALSE;
8338 ssh->eof_needed = FALSE;
b9d7bcad 8339 ssh->ldisc = NULL;
a8327734 8340 ssh->logctx = NULL;
51470298 8341 ssh->deferred_send_data = NULL;
8342 ssh->deferred_len = 0;
8343 ssh->deferred_size = 0;
8344 ssh->fallback_cmd = 0;
8345 ssh->pkt_ctx = 0;
302121de 8346 ssh->x11auth = NULL;
be738459 8347 ssh->v1_compressing = FALSE;
51470298 8348 ssh->v2_outgoing_sequence = 0;
8349 ssh->ssh1_rdpkt_crstate = 0;
8350 ssh->ssh2_rdpkt_crstate = 0;
8351 ssh->do_ssh_init_crstate = 0;
8352 ssh->ssh_gotdata_crstate = 0;
b09eaa88 8353 ssh->do_ssh1_connection_crstate = 0;
51470298 8354 ssh->do_ssh1_login_crstate = 0;
8355 ssh->do_ssh2_transport_crstate = 0;
8356 ssh->do_ssh2_authconn_crstate = 0;
8357 ssh->do_ssh_init_state = NULL;
8358 ssh->do_ssh1_login_state = NULL;
8359 ssh->do_ssh2_transport_state = NULL;
8360 ssh->do_ssh2_authconn_state = NULL;
4320baf7 8361 ssh->v_c = NULL;
8362 ssh->v_s = NULL;
6571dbfd 8363 ssh->mainchan = NULL;
968d2d92 8364 ssh->throttled_all = 0;
8365 ssh->v1_stdout_throttling = 0;
590f6a5f 8366 ssh->queue = NULL;
8367 ssh->queuelen = ssh->queuesize = 0;
8368 ssh->queueing = FALSE;
06fadff5 8369 ssh->qhead = ssh->qtail = NULL;
e13bba36 8370 ssh->deferred_rekey_reason = NULL;
3d9449a1 8371 bufchain_init(&ssh->queued_incoming_data);
8372 ssh->frozen = FALSE;
51470298 8373
8374 *backend_handle = ssh;
32874aea 8375
8f203108 8376#ifdef MSCRYPTOAPI
32874aea 8377 if (crypto_startup() == 0)
8f203108 8378 return "Microsoft high encryption pack not installed!";
8379#endif
374330e2 8380
51470298 8381 ssh->frontend = frontend_handle;
86916870 8382 ssh->term_width = ssh->cfg.width;
8383 ssh->term_height = ssh->cfg.height;
887035a5 8384
fabd1805 8385 ssh->channels = NULL;
8386 ssh->rportfwds = NULL;
f47a5ffb 8387 ssh->portfwds = NULL;
fabd1805 8388
51470298 8389 ssh->send_ok = 0;
8390 ssh->editing = 0;
8391 ssh->echoing = 0;
8392 ssh->v1_throttle_count = 0;
8393 ssh->overall_bufsize = 0;
8394 ssh->fallback_cmd = 0;
8df7a775 8395
3648d4c5 8396 ssh->protocol = NULL;
8397
b09eaa88 8398 ssh->protocol_initial_phase_done = FALSE;
8399
39934deb 8400 ssh->pinger = NULL;
8401
9442dd57 8402 ssh->incoming_data_size = ssh->outgoing_data_size =
8403 ssh->deferred_data_size = 0L;
d57f70af 8404 ssh->max_data_size = parse_blocksize(ssh->cfg.ssh_rekey_data);
9442dd57 8405 ssh->kex_in_progress = FALSE;
8406
79bf227b 8407 p = connect_to_host(ssh, host, port, realhost, nodelay, keepalive);
fb09bf1c 8408 if (p != NULL)
8409 return p;
374330e2 8410
5d17ccfc 8411 random_ref();
8412
374330e2 8413 return NULL;
8414}
8415
fabd1805 8416static void ssh_free(void *handle)
8417{
8418 Ssh ssh = (Ssh) handle;
8419 struct ssh_channel *c;
8420 struct ssh_rportfwd *pf;
8421
8422 if (ssh->v1_cipher_ctx)
8423 ssh->cipher->free_context(ssh->v1_cipher_ctx);
8424 if (ssh->cs_cipher_ctx)
8425 ssh->cscipher->free_context(ssh->cs_cipher_ctx);
8426 if (ssh->sc_cipher_ctx)
8427 ssh->sccipher->free_context(ssh->sc_cipher_ctx);
8428 if (ssh->cs_mac_ctx)
8429 ssh->csmac->free_context(ssh->cs_mac_ctx);
8430 if (ssh->sc_mac_ctx)
8431 ssh->scmac->free_context(ssh->sc_mac_ctx);
29b1d0b3 8432 if (ssh->cs_comp_ctx) {
8433 if (ssh->cscomp)
8434 ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
8435 else
8436 zlib_compress_cleanup(ssh->cs_comp_ctx);
8437 }
8438 if (ssh->sc_comp_ctx) {
8439 if (ssh->sccomp)
8440 ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
8441 else
8442 zlib_decompress_cleanup(ssh->sc_comp_ctx);
8443 }
fabd1805 8444 if (ssh->kex_ctx)
8445 dh_cleanup(ssh->kex_ctx);
8446 sfree(ssh->savedhost);
8447
590f6a5f 8448 while (ssh->queuelen-- > 0)
8449 ssh_free_packet(ssh->queue[ssh->queuelen]);
8450 sfree(ssh->queue);
8451
06fadff5 8452 while (ssh->qhead) {
8453 struct queued_handler *qh = ssh->qhead;
8454 ssh->qhead = qh->next;
8455 sfree(ssh->qhead);
8456 }
8457 ssh->qhead = ssh->qtail = NULL;
8458
fabd1805 8459 if (ssh->channels) {
8460 while ((c = delpos234(ssh->channels, 0)) != NULL) {
8461 switch (c->type) {
8462 case CHAN_X11:
8463 if (c->u.x11.s != NULL)
8464 x11_close(c->u.x11.s);
8465 break;
8466 case CHAN_SOCKDATA:
8467 if (c->u.pfd.s != NULL)
8468 pfd_close(c->u.pfd.s);
8469 break;
8470 }
8471 sfree(c);
8472 }
8473 freetree234(ssh->channels);
cdb52705 8474 ssh->channels = NULL;
fabd1805 8475 }
8476
8477 if (ssh->rportfwds) {
8478 while ((pf = delpos234(ssh->rportfwds, 0)) != NULL)
8479 sfree(pf);
8480 freetree234(ssh->rportfwds);
cdb52705 8481 ssh->rportfwds = NULL;
fabd1805 8482 }
8483 sfree(ssh->deferred_send_data);
8484 if (ssh->x11auth)
8485 x11_free_auth(ssh->x11auth);
8486 sfree(ssh->do_ssh_init_state);
8487 sfree(ssh->do_ssh1_login_state);
8488 sfree(ssh->do_ssh2_transport_state);
8489 sfree(ssh->do_ssh2_authconn_state);
4320baf7 8490 sfree(ssh->v_c);
8491 sfree(ssh->v_s);
679539d7 8492 if (ssh->crcda_ctx) {
8493 crcda_free_context(ssh->crcda_ctx);
8494 ssh->crcda_ctx = NULL;
8495 }
fabd1805 8496 if (ssh->s)
ac934965 8497 ssh_do_close(ssh, TRUE);
9442dd57 8498 expire_timer_context(ssh);
39934deb 8499 if (ssh->pinger)
8500 pinger_free(ssh->pinger);
3d9449a1 8501 bufchain_clear(&ssh->queued_incoming_data);
ee50e8b6 8502 sfree(ssh);
5d17ccfc 8503
8504 random_unref();
fabd1805 8505}
8506
374330e2 8507/*
86916870 8508 * Reconfigure the SSH backend.
86916870 8509 */
8510static void ssh_reconfig(void *handle, Config *cfg)
8511{
8512 Ssh ssh = (Ssh) handle;
e13bba36 8513 char *rekeying = NULL, rekey_mandatory = FALSE;
e6c1536e 8514 unsigned long old_max_data_size;
8515
39934deb 8516 pinger_reconfig(ssh->pinger, &ssh->cfg, cfg);
3b6606c7 8517 if (ssh->portfwds)
8518 ssh_setup_portfwd(ssh, cfg);
e6c1536e 8519
8520 if (ssh->cfg.ssh_rekey_time != cfg->ssh_rekey_time &&
8521 cfg->ssh_rekey_time != 0) {
8522 long new_next = ssh->last_rekey + cfg->ssh_rekey_time*60*TICKSPERSEC;
8523 long now = GETTICKCOUNT();
8524
8525 if (new_next - now < 0) {
f382c87d 8526 rekeying = "timeout shortened";
e6c1536e 8527 } else {
8528 ssh->next_rekey = schedule_timer(new_next - now, ssh2_timer, ssh);
8529 }
8530 }
8531
8532 old_max_data_size = ssh->max_data_size;
8533 ssh->max_data_size = parse_blocksize(cfg->ssh_rekey_data);
8534 if (old_max_data_size != ssh->max_data_size &&
8535 ssh->max_data_size != 0) {
8536 if (ssh->outgoing_data_size > ssh->max_data_size ||
8537 ssh->incoming_data_size > ssh->max_data_size)
f382c87d 8538 rekeying = "data limit lowered";
e6c1536e 8539 }
8540
e13bba36 8541 if (ssh->cfg.compression != cfg->compression) {
f382c87d 8542 rekeying = "compression setting changed";
e13bba36 8543 rekey_mandatory = TRUE;
8544 }
8545
8546 if (ssh->cfg.ssh2_des_cbc != cfg->ssh2_des_cbc ||
8547 memcmp(ssh->cfg.ssh_cipherlist, cfg->ssh_cipherlist,
8548 sizeof(ssh->cfg.ssh_cipherlist))) {
f382c87d 8549 rekeying = "cipher settings changed";
e13bba36 8550 rekey_mandatory = TRUE;
e6c1536e 8551 }
8552
86916870 8553 ssh->cfg = *cfg; /* STRUCTURE COPY */
e13bba36 8554
8555 if (rekeying) {
8556 if (!ssh->kex_in_progress) {
8557 do_ssh2_transport(ssh, rekeying, -1, NULL);
8558 } else if (rekey_mandatory) {
8559 ssh->deferred_rekey_reason = rekeying;
8560 }
8561 }
86916870 8562}
8563
8564/*
86dc445a 8565 * Called to send data down the SSH connection.
374330e2 8566 */
51470298 8567static int ssh_send(void *handle, char *buf, int len)
32874aea 8568{
51470298 8569 Ssh ssh = (Ssh) handle;
8570
8571 if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
5471d09a 8572 return 0;
374330e2 8573
d8baa528 8574 ssh->protocol(ssh, (unsigned char *)buf, len, 0);
5471d09a 8575
51470298 8576 return ssh_sendbuffer(ssh);
5471d09a 8577}
8578
8579/*
8580 * Called to query the current amount of buffered stdin data.
8581 */
51470298 8582static int ssh_sendbuffer(void *handle)
5471d09a 8583{
51470298 8584 Ssh ssh = (Ssh) handle;
5471d09a 8585 int override_value;
8586
51470298 8587 if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
5471d09a 8588 return 0;
8589
8590 /*
8591 * If the SSH socket itself has backed up, add the total backup
8592 * size on that to any individual buffer on the stdin channel.
8593 */
8594 override_value = 0;
51470298 8595 if (ssh->throttled_all)
8596 override_value = ssh->overall_bufsize;
5471d09a 8597
51470298 8598 if (ssh->version == 1) {
5471d09a 8599 return override_value;
51470298 8600 } else if (ssh->version == 2) {
8601 if (!ssh->mainchan || ssh->mainchan->closes > 0)
5471d09a 8602 return override_value;
8603 else
51470298 8604 return (override_value +
8605 bufchain_size(&ssh->mainchan->v.v2.outbuffer));
5471d09a 8606 }
8607
8608 return 0;
374330e2 8609}
8610
8611/*
6e48c3fe 8612 * Called to set the size of the window from SSH's POV.
374330e2 8613 */
51470298 8614static void ssh_size(void *handle, int width, int height)
32874aea 8615{
51470298 8616 Ssh ssh = (Ssh) handle;
ff3187f6 8617 struct Packet *pktout;
51470298 8618
8619 ssh->term_width = width;
8620 ssh->term_height = height;
f278d6f8 8621
51470298 8622 switch (ssh->state) {
374330e2 8623 case SSH_STATE_BEFORE_SIZE:
3687d221 8624 case SSH_STATE_PREPACKET:
21248260 8625 case SSH_STATE_CLOSED:
374330e2 8626 break; /* do nothing */
8627 case SSH_STATE_INTERMED:
51470298 8628 ssh->size_needed = TRUE; /* buffer for later */
374330e2 8629 break;
8630 case SSH_STATE_SESSION:
86916870 8631 if (!ssh->cfg.nopty) {
51470298 8632 if (ssh->version == 1) {
8633 send_packet(ssh, SSH1_CMSG_WINDOW_SIZE,
8634 PKT_INT, ssh->term_height,
8635 PKT_INT, ssh->term_width,
32874aea 8636 PKT_INT, 0, PKT_INT, 0, PKT_END);
0ed48730 8637 } else if (ssh->mainchan) {
ff3187f6 8638 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8639 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8640 ssh2_pkt_addstring(pktout, "window-change");
8641 ssh2_pkt_addbool(pktout, 0);
8642 ssh2_pkt_adduint32(pktout, ssh->term_width);
8643 ssh2_pkt_adduint32(pktout, ssh->term_height);
8644 ssh2_pkt_adduint32(pktout, 0);
8645 ssh2_pkt_adduint32(pktout, 0);
8646 ssh2_pkt_send(ssh, pktout);
32874aea 8647 }
8648 }
8649 break;
374330e2 8650 }
8651}
8652
8653/*
125105d1 8654 * Return a list of the special codes that make sense in this
8655 * protocol.
8656 */
8657static const struct telnet_special *ssh_get_specials(void *handle)
8658{
786ba75e 8659 static const struct telnet_special ssh1_ignore_special[] = {
8660 {"IGNORE message", TS_NOP}
8661 };
8662 static const struct telnet_special ssh2_transport_specials[] = {
62638676 8663 {"IGNORE message", TS_NOP},
9442dd57 8664 {"Repeat key exchange", TS_REKEY},
62638676 8665 };
8666 static const struct telnet_special ssh2_session_specials[] = {
6f2d0cde 8667 {NULL, TS_SEP},
8668 {"Break", TS_BRK},
786ba75e 8669 /* These are the signal names defined by draft-ietf-secsh-connect-23.
6f2d0cde 8670 * They include all the ISO C signals, but are a subset of the POSIX
8671 * required signals. */
8672 {"SIGINT (Interrupt)", TS_SIGINT},
8673 {"SIGTERM (Terminate)", TS_SIGTERM},
8674 {"SIGKILL (Kill)", TS_SIGKILL},
8675 {"SIGQUIT (Quit)", TS_SIGQUIT},
8676 {"SIGHUP (Hangup)", TS_SIGHUP},
8677 {"More signals", TS_SUBMENU},
8678 {"SIGABRT", TS_SIGABRT}, {"SIGALRM", TS_SIGALRM},
8679 {"SIGFPE", TS_SIGFPE}, {"SIGILL", TS_SIGILL},
8680 {"SIGPIPE", TS_SIGPIPE}, {"SIGSEGV", TS_SIGSEGV},
8681 {"SIGUSR1", TS_SIGUSR1}, {"SIGUSR2", TS_SIGUSR2},
8682 {NULL, TS_EXITMENU}
62638676 8683 };
8684 static const struct telnet_special specials_end[] = {
6f2d0cde 8685 {NULL, TS_EXITMENU}
62638676 8686 };
786ba75e 8687 /* XXX review this length for any changes: */
8688 static struct telnet_special ssh_specials[lenof(ssh2_transport_specials) +
62638676 8689 lenof(ssh2_session_specials) +
8690 lenof(specials_end)];
125105d1 8691 Ssh ssh = (Ssh) handle;
62638676 8692 int i = 0;
8693#define ADD_SPECIALS(name) \
8694 do { \
8695 assert((i + lenof(name)) <= lenof(ssh_specials)); \
8696 memcpy(&ssh_specials[i], name, sizeof name); \
8697 i += lenof(name); \
8698 } while(0)
125105d1 8699
8700 if (ssh->version == 1) {
62638676 8701 /* Don't bother offering IGNORE if we've decided the remote
8702 * won't cope with it, since we wouldn't bother sending it if
8703 * asked anyway. */
8704 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
786ba75e 8705 ADD_SPECIALS(ssh1_ignore_special);
125105d1 8706 } else if (ssh->version == 2) {
786ba75e 8707 ADD_SPECIALS(ssh2_transport_specials);
62638676 8708 if (ssh->mainchan)
8709 ADD_SPECIALS(ssh2_session_specials);
8710 } /* else we're not ready yet */
8711
8712 if (i) {
8713 ADD_SPECIALS(specials_end);
8714 return ssh_specials;
8715 } else {
125105d1 8716 return NULL;
62638676 8717 }
8718#undef ADD_SPECIALS
125105d1 8719}
8720
8721/*
86dc445a 8722 * Send special codes. TS_EOF is useful for `plink', so you
6abbf9e3 8723 * can send an EOF and collect resulting output (e.g. `plink
8724 * hostname sort').
374330e2 8725 */
51470298 8726static void ssh_special(void *handle, Telnet_Special code)
32874aea 8727{
51470298 8728 Ssh ssh = (Ssh) handle;
ff3187f6 8729 struct Packet *pktout;
51470298 8730
6abbf9e3 8731 if (code == TS_EOF) {
51470298 8732 if (ssh->state != SSH_STATE_SESSION) {
32874aea 8733 /*
8734 * Buffer the EOF in case we are pre-SESSION, so we can
8735 * send it as soon as we reach SESSION.
8736 */
8737 if (code == TS_EOF)
51470298 8738 ssh->eof_needed = TRUE;
32874aea 8739 return;
8740 }
51470298 8741 if (ssh->version == 1) {
8742 send_packet(ssh, SSH1_CMSG_EOF, PKT_END);
0ed48730 8743 } else if (ssh->mainchan) {
ff3187f6 8744 struct Packet *pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
8745 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8746 ssh2_pkt_send(ssh, pktout);
00a0b113 8747 ssh->send_ok = 0; /* now stop trying to read from stdin */
32874aea 8748 }
8749 logevent("Sent EOF message");
125105d1 8750 } else if (code == TS_PING || code == TS_NOP) {
51470298 8751 if (ssh->state == SSH_STATE_CLOSED
8752 || ssh->state == SSH_STATE_PREPACKET) return;
8753 if (ssh->version == 1) {
8754 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
8755 send_packet(ssh, SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
32874aea 8756 } else {
ff3187f6 8757 pktout = ssh2_pkt_init(SSH2_MSG_IGNORE);
8758 ssh2_pkt_addstring_start(pktout);
590f6a5f 8759 ssh2_pkt_send_noqueue(ssh, pktout);
32874aea 8760 }
9442dd57 8761 } else if (code == TS_REKEY) {
8762 if (!ssh->kex_in_progress && ssh->version == 2) {
f382c87d 8763 do_ssh2_transport(ssh, "at user request", -1, NULL);
9442dd57 8764 }
125105d1 8765 } else if (code == TS_BRK) {
8766 if (ssh->state == SSH_STATE_CLOSED
8767 || ssh->state == SSH_STATE_PREPACKET) return;
8768 if (ssh->version == 1) {
2e85c969 8769 logevent("Unable to send BREAK signal in SSH-1");
0ed48730 8770 } else if (ssh->mainchan) {
ff3187f6 8771 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8772 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8773 ssh2_pkt_addstring(pktout, "break");
8774 ssh2_pkt_addbool(pktout, 0);
8775 ssh2_pkt_adduint32(pktout, 0); /* default break length */
8776 ssh2_pkt_send(ssh, pktout);
125105d1 8777 }
6abbf9e3 8778 } else {
6f2d0cde 8779 /* Is is a POSIX signal? */
8780 char *signame = NULL;
8781 if (code == TS_SIGABRT) signame = "ABRT";
8782 if (code == TS_SIGALRM) signame = "ALRM";
8783 if (code == TS_SIGFPE) signame = "FPE";
8784 if (code == TS_SIGHUP) signame = "HUP";
8785 if (code == TS_SIGILL) signame = "ILL";
8786 if (code == TS_SIGINT) signame = "INT";
8787 if (code == TS_SIGKILL) signame = "KILL";
8788 if (code == TS_SIGPIPE) signame = "PIPE";
8789 if (code == TS_SIGQUIT) signame = "QUIT";
8790 if (code == TS_SIGSEGV) signame = "SEGV";
8791 if (code == TS_SIGTERM) signame = "TERM";
8792 if (code == TS_SIGUSR1) signame = "USR1";
8793 if (code == TS_SIGUSR2) signame = "USR2";
8794 /* The SSH-2 protocol does in principle support arbitrary named
8795 * signals, including signame@domain, but we don't support those. */
8796 if (signame) {
8797 /* It's a signal. */
8798 if (ssh->version == 2 && ssh->mainchan) {
ff3187f6 8799 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8800 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8801 ssh2_pkt_addstring(pktout, "signal");
8802 ssh2_pkt_addbool(pktout, 0);
8803 ssh2_pkt_addstring(pktout, signame);
8804 ssh2_pkt_send(ssh, pktout);
6f2d0cde 8805 logeventf(ssh, "Sent signal SIG%s", signame);
8806 }
8807 } else {
8808 /* Never heard of it. Do nothing */
8809 }
6abbf9e3 8810 }
374330e2 8811}
8812
51470298 8813void *new_sock_channel(void *handle, Socket s)
d74d141c 8814{
51470298 8815 Ssh ssh = (Ssh) handle;
d74d141c 8816 struct ssh_channel *c;
3d88e64d 8817 c = snew(struct ssh_channel);
51470298 8818 c->ssh = ssh;
d74d141c 8819
8820 if (c) {
64d6ff88 8821 c->halfopen = TRUE;
51470298 8822 c->localid = alloc_channel_id(ssh);
d74d141c 8823 c->closes = 0;
bc240b21 8824 c->type = CHAN_SOCKDATA_DORMANT;/* identify channel type */
d74d141c 8825 c->u.pfd.s = s;
013dd8c0 8826 bufchain_init(&c->v.v2.outbuffer);
51470298 8827 add234(ssh->channels, c);
d74d141c 8828 }
8829 return c;
8830}
8831
5471d09a 8832/*
8833 * This is called when stdout/stderr (the entity to which
8834 * from_backend sends data) manages to clear some backlog.
8835 */
ae9ae89f 8836static void ssh_unthrottle(void *handle, int bufsize)
5471d09a 8837{
51470298 8838 Ssh ssh = (Ssh) handle;
8839 if (ssh->version == 1) {
8840 if (ssh->v1_stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
8841 ssh->v1_stdout_throttling = 0;
8842 ssh1_throttle(ssh, -1);
5471d09a 8843 }
8844 } else {
51470298 8845 if (ssh->mainchan && ssh->mainchan->closes == 0)
8846 ssh2_set_window(ssh->mainchan, OUR_V2_WINSIZE - bufsize);
5471d09a 8847 }
8848}
8849
6b78788a 8850void ssh_send_port_open(void *channel, char *hostname, int port, char *org)
d74d141c 8851{
8852 struct ssh_channel *c = (struct ssh_channel *)channel;
6b78788a 8853 Ssh ssh = c->ssh;
ff3187f6 8854 struct Packet *pktout;
d74d141c 8855
57356d63 8856 logeventf(ssh, "Opening forwarded connection to %s:%d", hostname, port);
d74d141c 8857
51470298 8858 if (ssh->version == 1) {
8859 send_packet(ssh, SSH1_MSG_PORT_OPEN,
bc240b21 8860 PKT_INT, c->localid,
8861 PKT_STR, hostname,
8862 PKT_INT, port,
31fb1866 8863 /* PKT_STR, <org:orgport>, */
bc240b21 8864 PKT_END);
8865 } else {
ff3187f6 8866 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
8867 ssh2_pkt_addstring(pktout, "direct-tcpip");
8868 ssh2_pkt_adduint32(pktout, c->localid);
5471d09a 8869 c->v.v2.locwindow = OUR_V2_WINSIZE;
ff3187f6 8870 ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);/* our window size */
954d5c5a 8871 ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
ff3187f6 8872 ssh2_pkt_addstring(pktout, hostname);
8873 ssh2_pkt_adduint32(pktout, port);
bc240b21 8874 /*
8875 * We make up values for the originator data; partly it's
8876 * too much hassle to keep track, and partly I'm not
8877 * convinced the server should be told details like that
8878 * about my local network configuration.
1f182589 8879 * The "originator IP address" is syntactically a numeric
8880 * IP address, and some servers (e.g., Tectia) get upset
8881 * if it doesn't match this syntax.
bc240b21 8882 */
1f182589 8883 ssh2_pkt_addstring(pktout, "0.0.0.0");
ff3187f6 8884 ssh2_pkt_adduint32(pktout, 0);
8885 ssh2_pkt_send(ssh, pktout);
bc240b21 8886 }
d74d141c 8887}
8888
6226c939 8889static int ssh_connected(void *handle)
32874aea 8890{
51470298 8891 Ssh ssh = (Ssh) handle;
6226c939 8892 return ssh->s != NULL;
32874aea 8893}
8ccc75b0 8894
51470298 8895static int ssh_sendok(void *handle)
32874aea 8896{
51470298 8897 Ssh ssh = (Ssh) handle;
8898 return ssh->send_ok;
32874aea 8899}
fb09bf1c 8900
51470298 8901static int ssh_ldisc(void *handle, int option)
32874aea 8902{
51470298 8903 Ssh ssh = (Ssh) handle;
32874aea 8904 if (option == LD_ECHO)
51470298 8905 return ssh->echoing;
32874aea 8906 if (option == LD_EDIT)
51470298 8907 return ssh->editing;
0965bee0 8908 return FALSE;
8909}
8910
b9d7bcad 8911static void ssh_provide_ldisc(void *handle, void *ldisc)
8912{
8913 Ssh ssh = (Ssh) handle;
8914 ssh->ldisc = ldisc;
8915}
8916
a8327734 8917static void ssh_provide_logctx(void *handle, void *logctx)
8918{
8919 Ssh ssh = (Ssh) handle;
8920 ssh->logctx = logctx;
8921}
8922
51470298 8923static int ssh_return_exitcode(void *handle)
8924{
8925 Ssh ssh = (Ssh) handle;
3bb2f322 8926 if (ssh->s != NULL)
8927 return -1;
8928 else
3c112d53 8929 return (ssh->exitcode >= 0 ? ssh->exitcode : INT_MAX);
51470298 8930}
8931
8932/*
f89c3294 8933 * cfg_info for SSH is the currently running version of the
8934 * protocol. (1 for 1; 2 for 2; 0 for not-decided-yet.)
8935 */
8936static int ssh_cfg_info(void *handle)
8937{
8938 Ssh ssh = (Ssh) handle;
8939 return ssh->version;
8940}
8941
8942/*
51470298 8943 * Gross hack: pscp will try to start SFTP but fall back to scp1 if
8944 * that fails. This variable is the means by which scp.c can reach
8945 * into the SSH code and find out which one it got.
8946 */
8947extern int ssh_fallback_cmd(void *handle)
d8d6c7e5 8948{
51470298 8949 Ssh ssh = (Ssh) handle;
8950 return ssh->fallback_cmd;
d8d6c7e5 8951}
8952
374330e2 8953Backend ssh_backend = {
8954 ssh_init,
fabd1805 8955 ssh_free,
86916870 8956 ssh_reconfig,
374330e2 8957 ssh_send,
5471d09a 8958 ssh_sendbuffer,
374330e2 8959 ssh_size,
4017be6d 8960 ssh_special,
125105d1 8961 ssh_get_specials,
6226c939 8962 ssh_connected,
d8d6c7e5 8963 ssh_return_exitcode,
97db3be4 8964 ssh_sendok,
0965bee0 8965 ssh_ldisc,
b9d7bcad 8966 ssh_provide_ldisc,
a8327734 8967 ssh_provide_logctx,
5471d09a 8968 ssh_unthrottle,
f89c3294 8969 ssh_cfg_info,
97db3be4 8970 22
bc240b21 8971};