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