When doing custom bob builds from a given SVN revision, include the
[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>
d051d1b4 10#include <signal.h>
374330e2 11
12#include "putty.h"
dacbd0e8 13#include "tree234.h"
fb09bf1c 14#include "ssh.h"
bf84a03a 15#ifndef NO_GSSAPI
42af6a67 16#include "sshgss.h"
bf84a03a 17#endif
374330e2 18
19#ifndef FALSE
20#define FALSE 0
21#endif
22#ifndef TRUE
23#define TRUE 1
24#endif
25
32874aea 26#define SSH1_MSG_DISCONNECT 1 /* 0x1 */
27#define SSH1_SMSG_PUBLIC_KEY 2 /* 0x2 */
28#define SSH1_CMSG_SESSION_KEY 3 /* 0x3 */
29#define SSH1_CMSG_USER 4 /* 0x4 */
30#define SSH1_CMSG_AUTH_RSA 6 /* 0x6 */
31#define SSH1_SMSG_AUTH_RSA_CHALLENGE 7 /* 0x7 */
32#define SSH1_CMSG_AUTH_RSA_RESPONSE 8 /* 0x8 */
33#define SSH1_CMSG_AUTH_PASSWORD 9 /* 0x9 */
34#define SSH1_CMSG_REQUEST_PTY 10 /* 0xa */
35#define SSH1_CMSG_WINDOW_SIZE 11 /* 0xb */
36#define SSH1_CMSG_EXEC_SHELL 12 /* 0xc */
37#define SSH1_CMSG_EXEC_CMD 13 /* 0xd */
38#define SSH1_SMSG_SUCCESS 14 /* 0xe */
39#define SSH1_SMSG_FAILURE 15 /* 0xf */
40#define SSH1_CMSG_STDIN_DATA 16 /* 0x10 */
41#define SSH1_SMSG_STDOUT_DATA 17 /* 0x11 */
42#define SSH1_SMSG_STDERR_DATA 18 /* 0x12 */
43#define SSH1_CMSG_EOF 19 /* 0x13 */
44#define SSH1_SMSG_EXIT_STATUS 20 /* 0x14 */
45#define SSH1_MSG_CHANNEL_OPEN_CONFIRMATION 21 /* 0x15 */
46#define SSH1_MSG_CHANNEL_OPEN_FAILURE 22 /* 0x16 */
47#define SSH1_MSG_CHANNEL_DATA 23 /* 0x17 */
48#define SSH1_MSG_CHANNEL_CLOSE 24 /* 0x18 */
49#define SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* 0x19 */
50#define SSH1_SMSG_X11_OPEN 27 /* 0x1b */
51#define SSH1_CMSG_PORT_FORWARD_REQUEST 28 /* 0x1c */
52#define SSH1_MSG_PORT_OPEN 29 /* 0x1d */
53#define SSH1_CMSG_AGENT_REQUEST_FORWARDING 30 /* 0x1e */
54#define SSH1_SMSG_AGENT_OPEN 31 /* 0x1f */
55#define SSH1_MSG_IGNORE 32 /* 0x20 */
56#define SSH1_CMSG_EXIT_CONFIRMATION 33 /* 0x21 */
57#define SSH1_CMSG_X11_REQUEST_FORWARDING 34 /* 0x22 */
58#define SSH1_CMSG_AUTH_RHOSTS_RSA 35 /* 0x23 */
59#define SSH1_MSG_DEBUG 36 /* 0x24 */
60#define SSH1_CMSG_REQUEST_COMPRESSION 37 /* 0x25 */
61#define SSH1_CMSG_AUTH_TIS 39 /* 0x27 */
62#define SSH1_SMSG_AUTH_TIS_CHALLENGE 40 /* 0x28 */
63#define SSH1_CMSG_AUTH_TIS_RESPONSE 41 /* 0x29 */
64#define SSH1_CMSG_AUTH_CCARD 70 /* 0x46 */
65#define SSH1_SMSG_AUTH_CCARD_CHALLENGE 71 /* 0x47 */
66#define SSH1_CMSG_AUTH_CCARD_RESPONSE 72 /* 0x48 */
67
8f9e3231 68#define SSH1_AUTH_RHOSTS 1 /* 0x1 */
69#define SSH1_AUTH_RSA 2 /* 0x2 */
70#define SSH1_AUTH_PASSWORD 3 /* 0x3 */
71#define SSH1_AUTH_RHOSTS_RSA 4 /* 0x4 */
32874aea 72#define SSH1_AUTH_TIS 5 /* 0x5 */
73#define SSH1_AUTH_CCARD 16 /* 0x10 */
74
75#define SSH1_PROTOFLAG_SCREEN_NUMBER 1 /* 0x1 */
b96dc54c 76/* Mask for protoflags we will echo back to server if seen */
32874aea 77#define SSH1_PROTOFLAGS_SUPPORTED 0 /* 0x1 */
78
79#define SSH2_MSG_DISCONNECT 1 /* 0x1 */
80#define SSH2_MSG_IGNORE 2 /* 0x2 */
81#define SSH2_MSG_UNIMPLEMENTED 3 /* 0x3 */
82#define SSH2_MSG_DEBUG 4 /* 0x4 */
83#define SSH2_MSG_SERVICE_REQUEST 5 /* 0x5 */
84#define SSH2_MSG_SERVICE_ACCEPT 6 /* 0x6 */
85#define SSH2_MSG_KEXINIT 20 /* 0x14 */
86#define SSH2_MSG_NEWKEYS 21 /* 0x15 */
87#define SSH2_MSG_KEXDH_INIT 30 /* 0x1e */
88#define SSH2_MSG_KEXDH_REPLY 31 /* 0x1f */
89#define SSH2_MSG_KEX_DH_GEX_REQUEST 30 /* 0x1e */
90#define SSH2_MSG_KEX_DH_GEX_GROUP 31 /* 0x1f */
91#define SSH2_MSG_KEX_DH_GEX_INIT 32 /* 0x20 */
92#define SSH2_MSG_KEX_DH_GEX_REPLY 33 /* 0x21 */
fae1a71b 93#define SSH2_MSG_KEXRSA_PUBKEY 30 /* 0x1e */
94#define SSH2_MSG_KEXRSA_SECRET 31 /* 0x1f */
95#define SSH2_MSG_KEXRSA_DONE 32 /* 0x20 */
32874aea 96#define SSH2_MSG_USERAUTH_REQUEST 50 /* 0x32 */
97#define SSH2_MSG_USERAUTH_FAILURE 51 /* 0x33 */
98#define SSH2_MSG_USERAUTH_SUCCESS 52 /* 0x34 */
99#define SSH2_MSG_USERAUTH_BANNER 53 /* 0x35 */
100#define SSH2_MSG_USERAUTH_PK_OK 60 /* 0x3c */
101#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 /* 0x3c */
761187b6 102#define SSH2_MSG_USERAUTH_INFO_REQUEST 60 /* 0x3c */
103#define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 /* 0x3d */
32874aea 104#define SSH2_MSG_GLOBAL_REQUEST 80 /* 0x50 */
105#define SSH2_MSG_REQUEST_SUCCESS 81 /* 0x51 */
106#define SSH2_MSG_REQUEST_FAILURE 82 /* 0x52 */
107#define SSH2_MSG_CHANNEL_OPEN 90 /* 0x5a */
108#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91 /* 0x5b */
109#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92 /* 0x5c */
110#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93 /* 0x5d */
111#define SSH2_MSG_CHANNEL_DATA 94 /* 0x5e */
112#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95 /* 0x5f */
113#define SSH2_MSG_CHANNEL_EOF 96 /* 0x60 */
114#define SSH2_MSG_CHANNEL_CLOSE 97 /* 0x61 */
115#define SSH2_MSG_CHANNEL_REQUEST 98 /* 0x62 */
116#define SSH2_MSG_CHANNEL_SUCCESS 99 /* 0x63 */
117#define SSH2_MSG_CHANNEL_FAILURE 100 /* 0x64 */
42af6a67 118#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60
119#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61
120#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63
121#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64
122#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65
123#define SSH2_MSG_USERAUTH_GSSAPI_MIC 66
32874aea 124
00db133f 125/*
126 * Packet type contexts, so that ssh2_pkt_type can correctly decode
127 * the ambiguous type numbers back into the correct type strings.
128 */
acab36bc 129typedef enum {
130 SSH2_PKTCTX_NOKEX,
131 SSH2_PKTCTX_DHGROUP,
132 SSH2_PKTCTX_DHGEX,
133 SSH2_PKTCTX_RSAKEX
134} Pkt_KCtx;
135typedef enum {
136 SSH2_PKTCTX_NOAUTH,
137 SSH2_PKTCTX_PUBLICKEY,
138 SSH2_PKTCTX_PASSWORD,
42af6a67 139 SSH2_PKTCTX_GSSAPI,
acab36bc 140 SSH2_PKTCTX_KBDINTER
141} Pkt_ACtx;
00db133f 142
32874aea 143#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 /* 0x1 */
144#define SSH2_DISCONNECT_PROTOCOL_ERROR 2 /* 0x2 */
145#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED 3 /* 0x3 */
146#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED 4 /* 0x4 */
147#define SSH2_DISCONNECT_MAC_ERROR 5 /* 0x5 */
148#define SSH2_DISCONNECT_COMPRESSION_ERROR 6 /* 0x6 */
149#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE 7 /* 0x7 */
150#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 /* 0x8 */
151#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 /* 0x9 */
152#define SSH2_DISCONNECT_CONNECTION_LOST 10 /* 0xa */
153#define SSH2_DISCONNECT_BY_APPLICATION 11 /* 0xb */
154#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS 12 /* 0xc */
155#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER 13 /* 0xd */
156#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 /* 0xe */
157#define SSH2_DISCONNECT_ILLEGAL_USER_NAME 15 /* 0xf */
38c4a8da 158
159static const char *const ssh2_disconnect_reasons[] = {
160 NULL,
afb4d0dc 161 "host not allowed to connect",
162 "protocol error",
163 "key exchange failed",
164 "host authentication failed",
1da38d29 165 "MAC error",
afb4d0dc 166 "compression error",
167 "service not available",
168 "protocol version not supported",
169 "host key not verifiable",
170 "connection lost",
171 "by application",
172 "too many connections",
173 "auth cancelled by user",
174 "no more auth methods available",
175 "illegal user name",
38c4a8da 176};
9005f3ba 177
32874aea 178#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 /* 0x1 */
179#define SSH2_OPEN_CONNECT_FAILED 2 /* 0x2 */
180#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 /* 0x3 */
181#define SSH2_OPEN_RESOURCE_SHORTAGE 4 /* 0x4 */
d211621f 182
32874aea 183#define SSH2_EXTENDED_DATA_STDERR 1 /* 0x1 */
fb09bf1c 184
7d503c31 185/*
186 * Various remote-bug flags.
187 */
188#define BUG_CHOKES_ON_SSH1_IGNORE 1
189#define BUG_SSH2_HMAC 2
bd358db1 190#define BUG_NEEDS_SSH1_PLAIN_PASSWORD 4
0df73905 191#define BUG_CHOKES_ON_RSA 8
1dd353b5 192#define BUG_SSH2_RSA_PADDING 16
088bde77 193#define BUG_SSH2_DERIVEKEY 32
f382c87d 194#define BUG_SSH2_REKEY 64
dda87a28 195#define BUG_SSH2_PK_SESSIONID 128
c9739dba 196#define BUG_SSH2_MAXPKT 256
cf6ddb95 197#define BUG_CHOKES_ON_SSH2_IGNORE 512
bd358db1 198
c6ccd5c2 199/*
200 * Codes for terminal modes.
201 * Most of these are the same in SSH-1 and SSH-2.
7646c432 202 * This list is derived from RFC 4254 and
c6ccd5c2 203 * SSH-1 RFC-1.2.31.
204 */
205static const struct {
206 const char* const mode;
207 int opcode;
208 enum { TTY_OP_CHAR, TTY_OP_BOOL } type;
209} ssh_ttymodes[] = {
210 /* "V" prefix discarded for special characters relative to SSH specs */
211 { "INTR", 1, TTY_OP_CHAR },
212 { "QUIT", 2, TTY_OP_CHAR },
213 { "ERASE", 3, TTY_OP_CHAR },
214 { "KILL", 4, TTY_OP_CHAR },
215 { "EOF", 5, TTY_OP_CHAR },
216 { "EOL", 6, TTY_OP_CHAR },
217 { "EOL2", 7, TTY_OP_CHAR },
218 { "START", 8, TTY_OP_CHAR },
219 { "STOP", 9, TTY_OP_CHAR },
220 { "SUSP", 10, TTY_OP_CHAR },
221 { "DSUSP", 11, TTY_OP_CHAR },
222 { "REPRINT", 12, TTY_OP_CHAR },
223 { "WERASE", 13, TTY_OP_CHAR },
224 { "LNEXT", 14, TTY_OP_CHAR },
225 { "FLUSH", 15, TTY_OP_CHAR },
226 { "SWTCH", 16, TTY_OP_CHAR },
227 { "STATUS", 17, TTY_OP_CHAR },
228 { "DISCARD", 18, TTY_OP_CHAR },
229 { "IGNPAR", 30, TTY_OP_BOOL },
230 { "PARMRK", 31, TTY_OP_BOOL },
231 { "INPCK", 32, TTY_OP_BOOL },
232 { "ISTRIP", 33, TTY_OP_BOOL },
233 { "INLCR", 34, TTY_OP_BOOL },
234 { "IGNCR", 35, TTY_OP_BOOL },
235 { "ICRNL", 36, TTY_OP_BOOL },
236 { "IUCLC", 37, TTY_OP_BOOL },
237 { "IXON", 38, TTY_OP_BOOL },
238 { "IXANY", 39, TTY_OP_BOOL },
239 { "IXOFF", 40, TTY_OP_BOOL },
240 { "IMAXBEL", 41, TTY_OP_BOOL },
241 { "ISIG", 50, TTY_OP_BOOL },
242 { "ICANON", 51, TTY_OP_BOOL },
243 { "XCASE", 52, TTY_OP_BOOL },
244 { "ECHO", 53, TTY_OP_BOOL },
245 { "ECHOE", 54, TTY_OP_BOOL },
246 { "ECHOK", 55, TTY_OP_BOOL },
247 { "ECHONL", 56, TTY_OP_BOOL },
248 { "NOFLSH", 57, TTY_OP_BOOL },
249 { "TOSTOP", 58, TTY_OP_BOOL },
250 { "IEXTEN", 59, TTY_OP_BOOL },
251 { "ECHOCTL", 60, TTY_OP_BOOL },
252 { "ECHOKE", 61, TTY_OP_BOOL },
253 { "PENDIN", 62, TTY_OP_BOOL }, /* XXX is this a real mode? */
254 { "OPOST", 70, TTY_OP_BOOL },
255 { "OLCUC", 71, TTY_OP_BOOL },
256 { "ONLCR", 72, TTY_OP_BOOL },
257 { "OCRNL", 73, TTY_OP_BOOL },
258 { "ONOCR", 74, TTY_OP_BOOL },
259 { "ONLRET", 75, TTY_OP_BOOL },
260 { "CS7", 90, TTY_OP_BOOL },
261 { "CS8", 91, TTY_OP_BOOL },
262 { "PARENB", 92, TTY_OP_BOOL },
263 { "PARODD", 93, TTY_OP_BOOL }
264};
265
266/* Miscellaneous other tty-related constants. */
267#define SSH_TTY_OP_END 0
268/* The opcodes for ISPEED/OSPEED differ between SSH-1 and SSH-2. */
269#define SSH1_TTY_OP_ISPEED 192
270#define SSH1_TTY_OP_OSPEED 193
271#define SSH2_TTY_OP_ISPEED 128
272#define SSH2_TTY_OP_OSPEED 129
273
274/* Helper functions for parsing tty-related config. */
275static unsigned int ssh_tty_parse_specchar(char *s)
276{
277 unsigned int ret;
278 if (*s) {
279 char *next = NULL;
280 ret = ctrlparse(s, &next);
281 if (!next) ret = s[0];
282 } else {
283 ret = 255; /* special value meaning "don't set" */
284 }
285 return ret;
286}
287static unsigned int ssh_tty_parse_boolean(char *s)
288{
289 if (stricmp(s, "yes") == 0 ||
290 stricmp(s, "on") == 0 ||
291 stricmp(s, "true") == 0 ||
292 stricmp(s, "+") == 0)
293 return 1; /* true */
294 else if (stricmp(s, "no") == 0 ||
295 stricmp(s, "off") == 0 ||
296 stricmp(s, "false") == 0 ||
297 stricmp(s, "-") == 0)
298 return 0; /* false */
299 else
300 return (atoi(s) != 0);
301}
302
00db133f 303#define translate(x) if (type == x) return #x
acab36bc 304#define translatek(x,ctx) if (type == x && (pkt_kctx == ctx)) return #x
305#define translatea(x,ctx) if (type == x && (pkt_actx == ctx)) return #x
ae9ae89f 306static char *ssh1_pkt_type(int type)
00db133f 307{
308 translate(SSH1_MSG_DISCONNECT);
309 translate(SSH1_SMSG_PUBLIC_KEY);
310 translate(SSH1_CMSG_SESSION_KEY);
311 translate(SSH1_CMSG_USER);
312 translate(SSH1_CMSG_AUTH_RSA);
313 translate(SSH1_SMSG_AUTH_RSA_CHALLENGE);
314 translate(SSH1_CMSG_AUTH_RSA_RESPONSE);
315 translate(SSH1_CMSG_AUTH_PASSWORD);
316 translate(SSH1_CMSG_REQUEST_PTY);
317 translate(SSH1_CMSG_WINDOW_SIZE);
318 translate(SSH1_CMSG_EXEC_SHELL);
319 translate(SSH1_CMSG_EXEC_CMD);
320 translate(SSH1_SMSG_SUCCESS);
321 translate(SSH1_SMSG_FAILURE);
322 translate(SSH1_CMSG_STDIN_DATA);
323 translate(SSH1_SMSG_STDOUT_DATA);
324 translate(SSH1_SMSG_STDERR_DATA);
325 translate(SSH1_CMSG_EOF);
326 translate(SSH1_SMSG_EXIT_STATUS);
327 translate(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION);
328 translate(SSH1_MSG_CHANNEL_OPEN_FAILURE);
329 translate(SSH1_MSG_CHANNEL_DATA);
330 translate(SSH1_MSG_CHANNEL_CLOSE);
331 translate(SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION);
332 translate(SSH1_SMSG_X11_OPEN);
333 translate(SSH1_CMSG_PORT_FORWARD_REQUEST);
334 translate(SSH1_MSG_PORT_OPEN);
335 translate(SSH1_CMSG_AGENT_REQUEST_FORWARDING);
336 translate(SSH1_SMSG_AGENT_OPEN);
337 translate(SSH1_MSG_IGNORE);
338 translate(SSH1_CMSG_EXIT_CONFIRMATION);
339 translate(SSH1_CMSG_X11_REQUEST_FORWARDING);
340 translate(SSH1_CMSG_AUTH_RHOSTS_RSA);
341 translate(SSH1_MSG_DEBUG);
342 translate(SSH1_CMSG_REQUEST_COMPRESSION);
343 translate(SSH1_CMSG_AUTH_TIS);
344 translate(SSH1_SMSG_AUTH_TIS_CHALLENGE);
345 translate(SSH1_CMSG_AUTH_TIS_RESPONSE);
346 translate(SSH1_CMSG_AUTH_CCARD);
347 translate(SSH1_SMSG_AUTH_CCARD_CHALLENGE);
348 translate(SSH1_CMSG_AUTH_CCARD_RESPONSE);
349 return "unknown";
350}
acab36bc 351static char *ssh2_pkt_type(Pkt_KCtx pkt_kctx, Pkt_ACtx pkt_actx, int type)
00db133f 352{
42af6a67 353 translatea(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE,SSH2_PKTCTX_GSSAPI);
354 translatea(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,SSH2_PKTCTX_GSSAPI);
355 translatea(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,SSH2_PKTCTX_GSSAPI);
356 translatea(SSH2_MSG_USERAUTH_GSSAPI_ERROR,SSH2_PKTCTX_GSSAPI);
357 translatea(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,SSH2_PKTCTX_GSSAPI);
358 translatea(SSH2_MSG_USERAUTH_GSSAPI_MIC, SSH2_PKTCTX_GSSAPI);
00db133f 359 translate(SSH2_MSG_DISCONNECT);
360 translate(SSH2_MSG_IGNORE);
361 translate(SSH2_MSG_UNIMPLEMENTED);
362 translate(SSH2_MSG_DEBUG);
363 translate(SSH2_MSG_SERVICE_REQUEST);
364 translate(SSH2_MSG_SERVICE_ACCEPT);
365 translate(SSH2_MSG_KEXINIT);
366 translate(SSH2_MSG_NEWKEYS);
acab36bc 367 translatek(SSH2_MSG_KEXDH_INIT, SSH2_PKTCTX_DHGROUP);
368 translatek(SSH2_MSG_KEXDH_REPLY, SSH2_PKTCTX_DHGROUP);
369 translatek(SSH2_MSG_KEX_DH_GEX_REQUEST, SSH2_PKTCTX_DHGEX);
370 translatek(SSH2_MSG_KEX_DH_GEX_GROUP, SSH2_PKTCTX_DHGEX);
371 translatek(SSH2_MSG_KEX_DH_GEX_INIT, SSH2_PKTCTX_DHGEX);
372 translatek(SSH2_MSG_KEX_DH_GEX_REPLY, SSH2_PKTCTX_DHGEX);
373 translatek(SSH2_MSG_KEXRSA_PUBKEY, SSH2_PKTCTX_RSAKEX);
374 translatek(SSH2_MSG_KEXRSA_SECRET, SSH2_PKTCTX_RSAKEX);
375 translatek(SSH2_MSG_KEXRSA_DONE, SSH2_PKTCTX_RSAKEX);
00db133f 376 translate(SSH2_MSG_USERAUTH_REQUEST);
377 translate(SSH2_MSG_USERAUTH_FAILURE);
378 translate(SSH2_MSG_USERAUTH_SUCCESS);
379 translate(SSH2_MSG_USERAUTH_BANNER);
acab36bc 380 translatea(SSH2_MSG_USERAUTH_PK_OK, SSH2_PKTCTX_PUBLICKEY);
381 translatea(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, SSH2_PKTCTX_PASSWORD);
382 translatea(SSH2_MSG_USERAUTH_INFO_REQUEST, SSH2_PKTCTX_KBDINTER);
383 translatea(SSH2_MSG_USERAUTH_INFO_RESPONSE, SSH2_PKTCTX_KBDINTER);
00db133f 384 translate(SSH2_MSG_GLOBAL_REQUEST);
385 translate(SSH2_MSG_REQUEST_SUCCESS);
386 translate(SSH2_MSG_REQUEST_FAILURE);
387 translate(SSH2_MSG_CHANNEL_OPEN);
388 translate(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
389 translate(SSH2_MSG_CHANNEL_OPEN_FAILURE);
390 translate(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
391 translate(SSH2_MSG_CHANNEL_DATA);
392 translate(SSH2_MSG_CHANNEL_EXTENDED_DATA);
393 translate(SSH2_MSG_CHANNEL_EOF);
394 translate(SSH2_MSG_CHANNEL_CLOSE);
395 translate(SSH2_MSG_CHANNEL_REQUEST);
396 translate(SSH2_MSG_CHANNEL_SUCCESS);
397 translate(SSH2_MSG_CHANNEL_FAILURE);
398 return "unknown";
399}
400#undef translate
401#undef translatec
7d503c31 402
9a10ecf4 403/* Enumeration values for fields in SSH-1 packets */
404enum {
405 PKT_END, PKT_INT, PKT_CHAR, PKT_DATA, PKT_STR, PKT_BIGNUM,
406 /* These values are for communicating relevant semantics of
407 * fields to the packet logging code. */
408 PKTT_OTHER, PKTT_PASSWORD, PKTT_DATA
409};
972a41c8 410
acddebd9 411/*
412 * Coroutine mechanics for the sillier bits of the code. If these
413 * macros look impenetrable to you, you might find it helpful to
414 * read
415 *
416 * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
417 *
418 * which explains the theory behind these macros.
b624d1e6 419 *
420 * In particular, if you are getting `case expression not constant'
421 * errors when building with MS Visual Studio, this is because MS's
422 * Edit and Continue debugging feature causes their compiler to
423 * violate ANSI C. To disable Edit and Continue debugging:
424 *
425 * - right-click ssh.c in the FileView
426 * - click Settings
427 * - select the C/C++ tab and the General category
428 * - under `Debug info:', select anything _other_ than `Program
429 * Database for Edit and Continue'.
acddebd9 430 */
51470298 431#define crBegin(v) { int *crLine = &v; switch(v) { case 0:;
432#define crState(t) \
433 struct t *s; \
3d88e64d 434 if (!ssh->t) ssh->t = snew(struct t); \
51470298 435 s = ssh->t;
436#define crFinish(z) } *crLine = 0; return (z); }
437#define crFinishV } *crLine = 0; return; }
374330e2 438#define crReturn(z) \
439 do {\
51470298 440 *crLine =__LINE__; return (z); case __LINE__:;\
374330e2 441 } while (0)
442#define crReturnV \
443 do {\
51470298 444 *crLine=__LINE__; return; case __LINE__:;\
374330e2 445 } while (0)
51470298 446#define crStop(z) do{ *crLine = 0; return (z); }while(0)
447#define crStopV do{ *crLine = 0; return; }while(0)
fb09bf1c 448#define crWaitUntil(c) do { crReturn(0); } while (!(c))
7cca0d81 449#define crWaitUntilV(c) do { crReturnV; } while (!(c))
374330e2 450
51470298 451typedef struct ssh_tag *Ssh;
ff3187f6 452struct Packet;
453
dacd8872 454static struct Packet *ssh1_pkt_init(int pkt_type);
ff3187f6 455static struct Packet *ssh2_pkt_init(int pkt_type);
dacd8872 456static void ssh_pkt_ensure(struct Packet *, int length);
457static void ssh_pkt_adddata(struct Packet *, void *data, int len);
458static void ssh_pkt_addbyte(struct Packet *, unsigned char value);
ff3187f6 459static void ssh2_pkt_addbool(struct Packet *, unsigned char value);
dacd8872 460static void ssh_pkt_adduint32(struct Packet *, unsigned long value);
461static void ssh_pkt_addstring_start(struct Packet *);
462static void ssh_pkt_addstring_str(struct Packet *, char *data);
463static void ssh_pkt_addstring_data(struct Packet *, char *data, int len);
464static void ssh_pkt_addstring(struct Packet *, char *data);
d8baa528 465static unsigned char *ssh2_mpint_fmt(Bignum b, int *len);
dacd8872 466static void ssh1_pkt_addmp(struct Packet *, Bignum b);
ff3187f6 467static void ssh2_pkt_addmp(struct Packet *, Bignum b);
468static int ssh2_pkt_construct(Ssh, struct Packet *);
469static void ssh2_pkt_send(Ssh, struct Packet *);
590f6a5f 470static void ssh2_pkt_send_noqueue(Ssh, struct Packet *);
ff3187f6 471static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
472 struct Packet *pktin);
473static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
474 struct Packet *pktin);
3d63ca2e 475
5471d09a 476/*
477 * Buffer management constants. There are several of these for
478 * various different purposes:
479 *
480 * - SSH1_BUFFER_LIMIT is the amount of backlog that must build up
481 * on a local data stream before we throttle the whole SSH
2e85c969 482 * connection (in SSH-1 only). Throttling the whole connection is
5471d09a 483 * pretty drastic so we set this high in the hope it won't
484 * happen very often.
485 *
486 * - SSH_MAX_BACKLOG is the amount of backlog that must build up
487 * on the SSH connection itself before we defensively throttle
488 * _all_ local data streams. This is pretty drastic too (though
2e85c969 489 * thankfully unlikely in SSH-2 since the window mechanism should
5471d09a 490 * ensure that the server never has any need to throttle its end
491 * of the connection), so we set this high as well.
492 *
2e85c969 493 * - OUR_V2_WINSIZE is the maximum window size we present on SSH-2
5471d09a 494 * channels.
9b53e9b8 495 *
496 * - OUR_V2_BIGWIN is the window size we advertise for the only
3361b80a 497 * channel in a simple connection. It must be <= INT_MAX.
9916cc1e 498 *
499 * - OUR_V2_MAXPKT is the official "maximum packet size" we send
500 * to the remote side. This actually has nothing to do with the
501 * size of the _packet_, but is instead a limit on the amount
502 * of data we're willing to receive in a single SSH2 channel
503 * data message.
504 *
505 * - OUR_V2_PACKETLIMIT is actually the maximum size of SSH
506 * _packet_ we're prepared to cope with. It must be a multiple
507 * of the cipher block size, and must be at least 35000.
5471d09a 508 */
509
510#define SSH1_BUFFER_LIMIT 32768
511#define SSH_MAX_BACKLOG 32768
512#define OUR_V2_WINSIZE 16384
3361b80a 513#define OUR_V2_BIGWIN 0x7fffffff
954d5c5a 514#define OUR_V2_MAXPKT 0x4000UL
9916cc1e 515#define OUR_V2_PACKETLIMIT 0x9000UL
d74d141c 516
edd0cb8a 517/* Maximum length of passwords/passphrases (arbitrary) */
518#define SSH_MAX_PASSWORD_LEN 100
519
85cc02bb 520const static struct ssh_signkey *hostkey_algs[] = { &ssh_rsa, &ssh_dss };
e5574168 521
8b2715b2 522const static struct ssh_mac *macs[] = {
6668a75e 523 &ssh_hmac_sha1, &ssh_hmac_sha1_96, &ssh_hmac_md5
32874aea 524};
8b2715b2 525const static struct ssh_mac *buggymacs[] = {
6668a75e 526 &ssh_hmac_sha1_buggy, &ssh_hmac_sha1_96_buggy, &ssh_hmac_md5
32874aea 527};
e5574168 528
5366aed8 529static void *ssh_comp_none_init(void)
530{
531 return NULL;
532}
533static void ssh_comp_none_cleanup(void *handle)
32874aea 534{
535}
5366aed8 536static int ssh_comp_none_block(void *handle, unsigned char *block, int len,
32874aea 537 unsigned char **outblock, int *outlen)
538{
539 return 0;
540}
5366aed8 541static int ssh_comp_none_disable(void *handle)
32874aea 542{
4ba9b64b 543 return 0;
544}
57476f6b 545const static struct ssh_compress ssh_comp_none = {
4ba9b64b 546 "none",
5366aed8 547 ssh_comp_none_init, ssh_comp_none_cleanup, ssh_comp_none_block,
548 ssh_comp_none_init, ssh_comp_none_cleanup, ssh_comp_none_block,
549 ssh_comp_none_disable, NULL
e5574168 550};
4ba9b64b 551extern const struct ssh_compress ssh_zlib;
552const static struct ssh_compress *compressions[] = {
32874aea 553 &ssh_zlib, &ssh_comp_none
554};
374330e2 555
32874aea 556enum { /* channel types */
783415f8 557 CHAN_MAINSESSION,
558 CHAN_X11,
559 CHAN_AGENT,
bc240b21 560 CHAN_SOCKDATA,
561 CHAN_SOCKDATA_DORMANT /* one the remote hasn't confirmed */
783415f8 562};
563
dacbd0e8 564/*
0e443c99 565 * little structure to keep track of outstanding WINDOW_ADJUSTs
566 */
567struct winadj {
568 struct winadj *next;
569 unsigned size;
570};
571
572/*
dacbd0e8 573 * 2-3-4 tree storing channels.
574 */
575struct ssh_channel {
51470298 576 Ssh ssh; /* pointer back to main context */
d211621f 577 unsigned remoteid, localid;
dacbd0e8 578 int type;
64d6ff88 579 /* True if we opened this channel but server hasn't confirmed. */
580 int halfopen;
0357890f 581 /*
2e85c969 582 * In SSH-1, this value contains four bits:
0357890f 583 *
584 * 1 We have sent SSH1_MSG_CHANNEL_CLOSE.
585 * 2 We have sent SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION.
586 * 4 We have received SSH1_MSG_CHANNEL_CLOSE.
587 * 8 We have received SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION.
588 *
589 * A channel is completely finished with when all four bits are set.
590 */
dacbd0e8 591 int closes;
ff68564b 592 /*
593 * True if this channel is causing the underlying connection to be
594 * throttled.
595 */
596 int throttling_conn;
5471d09a 597 union {
5471d09a 598 struct ssh2_data_channel {
599 bufchain outbuffer;
600 unsigned remwindow, remmaxpkt;
467e064d 601 /* locwindow is signed so we can cope with excess data. */
9b53e9b8 602 int locwindow, locmaxwin;
0e443c99 603 /*
604 * remlocwin is the amount of local window that we think
605 * the remote end had available to it after it sent the
606 * last data packet or window adjust ack.
607 */
608 int remlocwin;
609 /*
610 * These store the list of window adjusts that haven't
611 * been acked.
612 */
613 struct winadj *winadj_head, *winadj_tail;
614 enum { THROTTLED, UNTHROTTLING, UNTHROTTLED } throttle_state;
5471d09a 615 } v2;
616 } v;
dacbd0e8 617 union {
32874aea 618 struct ssh_agent_channel {
619 unsigned char *message;
620 unsigned char msglen[4];
a03c9f9c 621 unsigned lensofar, totallen;
32874aea 622 } a;
623 struct ssh_x11_channel {
624 Socket s;
625 } x11;
d74d141c 626 struct ssh_pfd_channel {
627 Socket s;
628 } pfd;
dacbd0e8 629 } u;
630};
57476f6b 631
d74d141c 632/*
2e85c969 633 * 2-3-4 tree storing remote->local port forwardings. SSH-1 and SSH-2
634 * use this structure in different ways, reflecting SSH-2's
bc240b21 635 * altogether saner approach to port forwarding.
636 *
2e85c969 637 * In SSH-1, you arrange a remote forwarding by sending the server
bc240b21 638 * the remote port number, and the local destination host:port.
639 * When a connection comes in, the server sends you back that
640 * host:port pair, and you connect to it. This is a ready-made
641 * security hole if you're not on the ball: a malicious server
642 * could send you back _any_ host:port pair, so if you trustingly
643 * connect to the address it gives you then you've just opened the
644 * entire inside of your corporate network just by connecting
645 * through it to a dodgy SSH server. Hence, we must store a list of
646 * host:port pairs we _are_ trying to forward to, and reject a
647 * connection request from the server if it's not in the list.
648 *
2e85c969 649 * In SSH-2, each side of the connection minds its own business and
bc240b21 650 * doesn't send unnecessary information to the other. You arrange a
651 * remote forwarding by sending the server just the remote port
652 * number. When a connection comes in, the server tells you which
653 * of its ports was connected to; and _you_ have to remember what
654 * local host:port pair went with that port number.
655 *
2e85c969 656 * Hence, in SSH-1 this structure is indexed by destination
657 * host:port pair, whereas in SSH-2 it is indexed by source port.
d74d141c 658 */
fda2feb1 659struct ssh_portfwd; /* forward declaration */
660
d74d141c 661struct ssh_rportfwd {
bc240b21 662 unsigned sport, dport;
663 char dhost[256];
06fadff5 664 char *sportdesc;
fda2feb1 665 struct ssh_portfwd *pfrec;
d74d141c 666};
fda2feb1 667#define free_rportfwd(pf) ( \
668 ((pf) ? (sfree((pf)->sportdesc)) : (void)0 ), sfree(pf) )
669
670/*
671 * Separately to the rportfwd tree (which is for looking up port
672 * open requests from the server), a tree of _these_ structures is
673 * used to keep track of all the currently open port forwardings,
674 * so that we can reconfigure in mid-session if the user requests
675 * it.
676 */
677struct ssh_portfwd {
84328ddb 678 enum { DESTROY, KEEP, CREATE } status;
fda2feb1 679 int type;
680 unsigned sport, dport;
681 char *saddr, *daddr;
3fe92132 682 char *sserv, *dserv;
fda2feb1 683 struct ssh_rportfwd *remote;
05581745 684 int addressfamily;
fda2feb1 685 void *local;
686};
687#define free_portfwd(pf) ( \
3fe92132 688 ((pf) ? (sfree((pf)->saddr), sfree((pf)->daddr), \
689 sfree((pf)->sserv), sfree((pf)->dserv)) : (void)0 ), sfree(pf) )
d74d141c 690
57476f6b 691struct Packet {
dacd8872 692 long length; /* length of `data' actually used */
693 long forcepad; /* SSH-2: force padding to at least this length */
694 int type; /* only used for incoming packets */
695 unsigned long sequence; /* SSH-2 incoming sequence number */
696 unsigned char *data; /* allocated storage */
697 unsigned char *body; /* offset of payload within `data' */
698 long savedpos; /* temporary index into `data' (for strings) */
699 long maxlen; /* amount of storage allocated for `data' */
700 long encrypted_len; /* for SSH-2 total-size counting */
ff3187f6 701
702 /*
703 * State associated with packet logging
704 */
705 int logmode;
706 int nblanks;
707 struct logblank_t *blanks;
57476f6b 708};
709
1c1a7262 710static void ssh1_protocol(Ssh ssh, void *vin, int inlen,
ff3187f6 711 struct Packet *pktin);
1c1a7262 712static void ssh2_protocol(Ssh ssh, void *vin, int inlen,
ff3187f6 713 struct Packet *pktin);
b09eaa88 714static void ssh1_protocol_setup(Ssh ssh);
715static void ssh2_protocol_setup(Ssh ssh);
51470298 716static void ssh_size(void *handle, int width, int height);
717static void ssh_special(void *handle, Telnet_Special);
5471d09a 718static int ssh2_try_send(struct ssh_channel *c);
51470298 719static void ssh2_add_channel_data(struct ssh_channel *c, char *buf, int len);
720static void ssh_throttle_all(Ssh ssh, int enable, int bufsize);
9fca3f8c 721static void ssh2_set_window(struct ssh_channel *c, int newwin);
51470298 722static int ssh_sendbuffer(void *handle);
ac934965 723static int ssh_do_close(Ssh ssh, int notify_exit);
ff3187f6 724static unsigned long ssh_pkt_getuint32(struct Packet *pkt);
725static int ssh2_pkt_getbool(struct Packet *pkt);
726static void ssh_pkt_getstring(struct Packet *pkt, char **p, int *length);
9442dd57 727static void ssh2_timer(void *ctx, long now);
1c1a7262 728static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
9442dd57 729 struct Packet *pktin);
57476f6b 730
51470298 731struct rdpkt1_state_tag {
57476f6b 732 long len, pad, biglen, to_read;
733 unsigned long realcrc, gotcrc;
734 unsigned char *p;
735 int i;
736 int chunk;
ff3187f6 737 struct Packet *pktin;
51470298 738};
57476f6b 739
51470298 740struct rdpkt2_state_tag {
960e736a 741 long len, pad, payload, packetlen, maclen;
742 int i;
743 int cipherblk;
744 unsigned long incoming_sequence;
ff3187f6 745 struct Packet *pktin;
51470298 746};
747
b09eaa88 748typedef void (*handler_fn_t)(Ssh ssh, struct Packet *pktin);
06fadff5 749typedef void (*chandler_fn_t)(Ssh ssh, struct Packet *pktin, void *ctx);
750
751struct queued_handler;
752struct queued_handler {
753 int msg1, msg2;
754 chandler_fn_t handler;
755 void *ctx;
756 struct queued_handler *next;
757};
b09eaa88 758
51470298 759struct ssh_tag {
760 const struct plug_function_table *fn;
761 /* the above field _must_ be first in the structure */
762
4320baf7 763 char *v_c, *v_s;
b672f405 764 void *exhash;
51470298 765
766 Socket s;
767
b9d7bcad 768 void *ldisc;
a8327734 769 void *logctx;
b9d7bcad 770
51470298 771 unsigned char session_key[32];
772 int v1_compressing;
773 int v1_remote_protoflags;
774 int v1_local_protoflags;
775 int agentfwd_enabled;
776 int X11_fwd_enabled;
777 int remote_bugs;
778 const struct ssh_cipher *cipher;
371e569c 779 void *v1_cipher_ctx;
0183b242 780 void *crcda_ctx;
51470298 781 const struct ssh2_cipher *cscipher, *sccipher;
371e569c 782 void *cs_cipher_ctx, *sc_cipher_ctx;
51470298 783 const struct ssh_mac *csmac, *scmac;
e0e1a00d 784 void *cs_mac_ctx, *sc_mac_ctx;
51470298 785 const struct ssh_compress *cscomp, *sccomp;
5366aed8 786 void *cs_comp_ctx, *sc_comp_ctx;
51470298 787 const struct ssh_kex *kex;
788 const struct ssh_signkey *hostkey;
754c0df9 789 unsigned char v2_session_id[SSH2_KEX_MAX_HASH_LEN];
b672f405 790 int v2_session_id_len;
27cd7fc2 791 void *kex_ctx;
51470298 792
793 char *savedhost;
794 int savedport;
795 int send_ok;
796 int echoing, editing;
797
798 void *frontend;
799
db219738 800 int ospeed, ispeed; /* temporaries */
51470298 801 int term_width, term_height;
802
803 tree234 *channels; /* indexed by local id */
804 struct ssh_channel *mainchan; /* primary session channel */
feb02b4e 805 int ncmode; /* is primary channel direct-tcpip? */
51470298 806 int exitcode;
ac934965 807 int close_expected;
9e296bfa 808 int clean_exit;
51470298 809
fda2feb1 810 tree234 *rportfwds, *portfwds;
51470298 811
812 enum {
813 SSH_STATE_PREPACKET,
814 SSH_STATE_BEFORE_SIZE,
815 SSH_STATE_INTERMED,
816 SSH_STATE_SESSION,
817 SSH_STATE_CLOSED
818 } state;
819
820 int size_needed, eof_needed;
821
590f6a5f 822 struct Packet **queue;
823 int queuelen, queuesize;
824 int queueing;
51470298 825 unsigned char *deferred_send_data;
826 int deferred_len, deferred_size;
827
828 /*
829 * Gross hack: pscp will try to start SFTP but fall back to
830 * scp1 if that fails. This variable is the means by which
831 * scp.c can reach into the SSH code and find out which one it
832 * got.
833 */
834 int fallback_cmd;
835
6bbce591 836 bufchain banner; /* accumulates banners during do_ssh2_authconn */
51470298 837
acab36bc 838 Pkt_KCtx pkt_kctx;
839 Pkt_ACtx pkt_actx;
51470298 840
8def70c3 841 struct X11Display *x11disp;
302121de 842
51470298 843 int version;
ff68564b 844 int conn_throttle_count;
51470298 845 int overall_bufsize;
846 int throttled_all;
847 int v1_stdout_throttling;
a8756193 848 unsigned long v2_outgoing_sequence;
51470298 849
850 int ssh1_rdpkt_crstate;
851 int ssh2_rdpkt_crstate;
852 int do_ssh_init_crstate;
853 int ssh_gotdata_crstate;
51470298 854 int do_ssh1_login_crstate;
b09eaa88 855 int do_ssh1_connection_crstate;
51470298 856 int do_ssh2_transport_crstate;
857 int do_ssh2_authconn_crstate;
858
859 void *do_ssh_init_state;
860 void *do_ssh1_login_state;
861 void *do_ssh2_transport_state;
862 void *do_ssh2_authconn_state;
863
864 struct rdpkt1_state_tag rdpkt1_state;
865 struct rdpkt2_state_tag rdpkt2_state;
866
2e85c969 867 /* SSH-1 and SSH-2 use this for different things, but both use it */
b09eaa88 868 int protocol_initial_phase_done;
869
1c1a7262 870 void (*protocol) (Ssh ssh, void *vin, int inlen,
ff3187f6 871 struct Packet *pkt);
872 struct Packet *(*s_rdpkt) (Ssh ssh, unsigned char **data, int *datalen);
86916870 873
874 /*
875 * We maintain a full _copy_ of a Config structure here, not
876 * merely a pointer to it. That way, when we're passed a new
877 * one for reconfiguration, we can check the differences and
878 * potentially reconfigure port forwardings etc in mid-session.
879 */
880 Config cfg;
839f10db 881
882 /*
3d9449a1 883 * Used to transfer data back from async callbacks.
839f10db 884 */
885 void *agent_response;
886 int agent_response_len;
3d9449a1 887 int user_response;
888
889 /*
890 * The SSH connection can be set as `frozen', meaning we are
891 * not currently accepting incoming data from the network. This
892 * is slightly more serious than setting the _socket_ as
893 * frozen, because we may already have had data passed to us
894 * from the network which we need to delay processing until
895 * after the freeze is lifted, so we also need a bufchain to
896 * store that data.
897 */
898 int frozen;
899 bufchain queued_incoming_data;
b09eaa88 900
901 /*
902 * Dispatch table for packet types that we may have to deal
903 * with at any time.
904 */
905 handler_fn_t packet_dispatch[256];
39934deb 906
907 /*
06fadff5 908 * Queues of one-off handler functions for success/failure
909 * indications from a request.
910 */
911 struct queued_handler *qhead, *qtail;
912
913 /*
39934deb 914 * This module deals with sending keepalives.
915 */
916 Pinger pinger;
9442dd57 917
918 /*
919 * Track incoming and outgoing data sizes and time, for
920 * size-based rekeys.
921 */
922 unsigned long incoming_data_size, outgoing_data_size, deferred_data_size;
d57f70af 923 unsigned long max_data_size;
9442dd57 924 int kex_in_progress;
e6c1536e 925 long next_rekey, last_rekey;
e13bba36 926 char *deferred_rekey_reason; /* points to STATIC string; don't free */
42af6a67 927
928 /*
929 * Fully qualified host name, which we need if doing GSSAPI.
930 */
931 char *fullhostname;
51470298 932};
960e736a 933
382908ad 934#define logevent(s) logevent(ssh->frontend, s)
a8327734 935
936/* logevent, only printf-formatted. */
cbe2d68f 937static void logeventf(Ssh ssh, const char *fmt, ...)
a8327734 938{
939 va_list ap;
57356d63 940 char *buf;
a8327734 941
942 va_start(ap, fmt);
57356d63 943 buf = dupvprintf(fmt, ap);
a8327734 944 va_end(ap);
57356d63 945 logevent(buf);
57356d63 946 sfree(buf);
a8327734 947}
948
6b5cf8b4 949#define bombout(msg) \
950 do { \
951 char *text = dupprintf msg; \
ac934965 952 ssh_do_close(ssh, FALSE); \
6b5cf8b4 953 logevent(text); \
954 connection_fatal(ssh->frontend, "%s", text); \
955 sfree(text); \
956 } while (0)
a8327734 957
9a10ecf4 958/* Functions to leave bits out of the SSH packet log file. */
959
ff3187f6 960static void dont_log_password(Ssh ssh, struct Packet *pkt, int blanktype)
9a10ecf4 961{
962 if (ssh->cfg.logomitpass)
ff3187f6 963 pkt->logmode = blanktype;
9a10ecf4 964}
965
ff3187f6 966static void dont_log_data(Ssh ssh, struct Packet *pkt, int blanktype)
9a10ecf4 967{
968 if (ssh->cfg.logomitdata)
ff3187f6 969 pkt->logmode = blanktype;
9a10ecf4 970}
971
ff3187f6 972static void end_log_omission(Ssh ssh, struct Packet *pkt)
9a10ecf4 973{
ff3187f6 974 pkt->logmode = PKTLOG_EMIT;
9a10ecf4 975}
976
c6ccd5c2 977/* Helper function for common bits of parsing cfg.ttymodes. */
978static void parse_ttymodes(Ssh ssh, char *modes,
979 void (*do_mode)(void *data, char *mode, char *val),
980 void *data)
981{
982 while (*modes) {
983 char *t = strchr(modes, '\t');
984 char *m = snewn(t-modes+1, char);
985 char *val;
986 strncpy(m, modes, t-modes);
987 m[t-modes] = '\0';
988 if (*(t+1) == 'A')
989 val = get_ttymode(ssh->frontend, m);
990 else
991 val = dupstr(t+2);
992 if (val)
993 do_mode(data, m, val);
994 sfree(m);
995 sfree(val);
996 modes += strlen(modes) + 1;
997 }
998}
999
32874aea 1000static int ssh_channelcmp(void *av, void *bv)
1001{
1002 struct ssh_channel *a = (struct ssh_channel *) av;
1003 struct ssh_channel *b = (struct ssh_channel *) bv;
1004 if (a->localid < b->localid)
1005 return -1;
1006 if (a->localid > b->localid)
1007 return +1;
dacbd0e8 1008 return 0;
1009}
32874aea 1010static int ssh_channelfind(void *av, void *bv)
1011{
1012 unsigned *a = (unsigned *) av;
1013 struct ssh_channel *b = (struct ssh_channel *) bv;
1014 if (*a < b->localid)
1015 return -1;
1016 if (*a > b->localid)
1017 return +1;
dacbd0e8 1018 return 0;
1019}
1020
bc240b21 1021static int ssh_rportcmp_ssh1(void *av, void *bv)
d74d141c 1022{
1023 struct ssh_rportfwd *a = (struct ssh_rportfwd *) av;
1024 struct ssh_rportfwd *b = (struct ssh_rportfwd *) bv;
1025 int i;
bc240b21 1026 if ( (i = strcmp(a->dhost, b->dhost)) != 0)
d74d141c 1027 return i < 0 ? -1 : +1;
bc240b21 1028 if (a->dport > b->dport)
1029 return +1;
1030 if (a->dport < b->dport)
1031 return -1;
1032 return 0;
1033}
1034
1035static int ssh_rportcmp_ssh2(void *av, void *bv)
1036{
1037 struct ssh_rportfwd *a = (struct ssh_rportfwd *) av;
1038 struct ssh_rportfwd *b = (struct ssh_rportfwd *) bv;
cdcbdf3b 1039
bc240b21 1040 if (a->sport > b->sport)
d74d141c 1041 return +1;
bc240b21 1042 if (a->sport < b->sport)
1043 return -1;
d74d141c 1044 return 0;
1045}
1046
fda2feb1 1047/*
1048 * Special form of strcmp which can cope with NULL inputs. NULL is
1049 * defined to sort before even the empty string.
1050 */
1051static int nullstrcmp(const char *a, const char *b)
1052{
1053 if (a == NULL && b == NULL)
1054 return 0;
1055 if (a == NULL)
1056 return -1;
1057 if (b == NULL)
1058 return +1;
1059 return strcmp(a, b);
1060}
1061
1062static int ssh_portcmp(void *av, void *bv)
1063{
1064 struct ssh_portfwd *a = (struct ssh_portfwd *) av;
1065 struct ssh_portfwd *b = (struct ssh_portfwd *) bv;
1066 int i;
1067 if (a->type > b->type)
1068 return +1;
1069 if (a->type < b->type)
1070 return -1;
84328ddb 1071 if (a->addressfamily > b->addressfamily)
1072 return +1;
1073 if (a->addressfamily < b->addressfamily)
1074 return -1;
fda2feb1 1075 if ( (i = nullstrcmp(a->saddr, b->saddr)) != 0)
1076 return i < 0 ? -1 : +1;
1077 if (a->sport > b->sport)
1078 return +1;
1079 if (a->sport < b->sport)
1080 return -1;
1081 if (a->type != 'D') {
1082 if ( (i = nullstrcmp(a->daddr, b->daddr)) != 0)
1083 return i < 0 ? -1 : +1;
1084 if (a->dport > b->dport)
1085 return +1;
1086 if (a->dport < b->dport)
1087 return -1;
1088 }
1089 return 0;
1090}
1091
51470298 1092static int alloc_channel_id(Ssh ssh)
32874aea 1093{
260f3dec 1094 const unsigned CHANNEL_NUMBER_OFFSET = 256;
1095 unsigned low, high, mid;
d2371c81 1096 int tsize;
1097 struct ssh_channel *c;
1098
1099 /*
1100 * First-fit allocation of channel numbers: always pick the
1101 * lowest unused one. To do this, binary-search using the
1102 * counted B-tree to find the largest channel ID which is in a
1103 * contiguous sequence from the beginning. (Precisely
1104 * everything in that sequence must have ID equal to its tree
1105 * index plus CHANNEL_NUMBER_OFFSET.)
1106 */
51470298 1107 tsize = count234(ssh->channels);
d2371c81 1108
32874aea 1109 low = -1;
1110 high = tsize;
d2371c81 1111 while (high - low > 1) {
1112 mid = (high + low) / 2;
51470298 1113 c = index234(ssh->channels, mid);
d2371c81 1114 if (c->localid == mid + CHANNEL_NUMBER_OFFSET)
1115 low = mid; /* this one is fine */
1116 else
1117 high = mid; /* this one is past it */
1118 }
1119 /*
1120 * Now low points to either -1, or the tree index of the
1121 * largest ID in the initial sequence.
1122 */
1123 {
1124 unsigned i = low + 1 + CHANNEL_NUMBER_OFFSET;
51470298 1125 assert(NULL == find234(ssh->channels, &i, ssh_channelfind));
d2371c81 1126 }
1127 return low + 1 + CHANNEL_NUMBER_OFFSET;
1128}
1129
edd0cb8a 1130static void c_write_stderr(int trusted, const char *buf, int len)
1131{
1132 int i;
1133 for (i = 0; i < len; i++)
667deca9 1134 if (buf[i] != '\r' && (trusted || buf[i] == '\n' || (buf[i] & 0x60)))
edd0cb8a 1135 fputc(buf[i], stderr);
1136}
1137
9fab77dc 1138static void c_write(Ssh ssh, const char *buf, int len)
32874aea 1139{
edd0cb8a 1140 if (flags & FLAG_STDERR)
1141 c_write_stderr(1, buf, len);
1142 else
1143 from_backend(ssh->frontend, 1, buf, len);
3bdaf79d 1144}
1145
9fab77dc 1146static void c_write_untrusted(Ssh ssh, const char *buf, int len)
32874aea 1147{
edd0cb8a 1148 if (flags & FLAG_STDERR)
1149 c_write_stderr(0, buf, len);
1150 else
1151 from_backend_untrusted(ssh->frontend, buf, len);
a209e957 1152}
1153
9fab77dc 1154static void c_write_str(Ssh ssh, const char *buf)
32874aea 1155{
51470298 1156 c_write(ssh, buf, strlen(buf));
1408a877 1157}
1158
ff3187f6 1159static void ssh_free_packet(struct Packet *pkt)
1160{
1161 sfree(pkt->data);
1162 sfree(pkt);
1163}
1164static struct Packet *ssh_new_packet(void)
1165{
1166 struct Packet *pkt = snew(struct Packet);
1167
dacd8872 1168 pkt->body = pkt->data = NULL;
ff3187f6 1169 pkt->maxlen = 0;
1170 pkt->logmode = PKTLOG_EMIT;
1171 pkt->nblanks = 0;
1172 pkt->blanks = NULL;
1173
1174 return pkt;
1175}
1176
fb09bf1c 1177/*
1178 * Collect incoming data in the incoming packet buffer.
e5574168 1179 * Decipher and verify the packet when it is completely read.
1180 * Drop SSH1_MSG_DEBUG and SSH1_MSG_IGNORE packets.
fb09bf1c 1181 * Update the *data and *datalen variables.
ff3187f6 1182 * Return a Packet structure when a packet is completed.
fb09bf1c 1183 */
ff3187f6 1184static struct Packet *ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen)
fb09bf1c 1185{
51470298 1186 struct rdpkt1_state_tag *st = &ssh->rdpkt1_state;
374330e2 1187
51470298 1188 crBegin(ssh->ssh1_rdpkt_crstate);
374330e2 1189
ff3187f6 1190 st->pktin = ssh_new_packet();
1191
1192 st->pktin->type = 0;
1193 st->pktin->length = 0;
374330e2 1194
57476f6b 1195 for (st->i = st->len = 0; st->i < 4; st->i++) {
fb09bf1c 1196 while ((*datalen) == 0)
ff3187f6 1197 crReturn(NULL);
57476f6b 1198 st->len = (st->len << 8) + **data;
fb09bf1c 1199 (*data)++, (*datalen)--;
1200 }
374330e2 1201
57476f6b 1202 st->pad = 8 - (st->len % 8);
1203 st->biglen = st->len + st->pad;
ff3187f6 1204 st->pktin->length = st->len - 5;
fb09bf1c 1205
ae0500e5 1206 if (st->biglen < 0) {
1207 bombout(("Extremely large packet length from server suggests"
1208 " data stream corruption"));
ff3187f6 1209 ssh_free_packet(st->pktin);
1210 crStop(NULL);
ae0500e5 1211 }
1212
ff3187f6 1213 st->pktin->maxlen = st->biglen;
1214 st->pktin->data = snewn(st->biglen + APIEXTRA, unsigned char);
374330e2 1215
57476f6b 1216 st->to_read = st->biglen;
ff3187f6 1217 st->p = st->pktin->data;
57476f6b 1218 while (st->to_read > 0) {
32874aea 1219 st->chunk = st->to_read;
fb09bf1c 1220 while ((*datalen) == 0)
ff3187f6 1221 crReturn(NULL);
57476f6b 1222 if (st->chunk > (*datalen))
1223 st->chunk = (*datalen);
1224 memcpy(st->p, *data, st->chunk);
1225 *data += st->chunk;
1226 *datalen -= st->chunk;
1227 st->p += st->chunk;
1228 st->to_read -= st->chunk;
fb09bf1c 1229 }
374330e2 1230
ff3187f6 1231 if (ssh->cipher && detect_attack(ssh->crcda_ctx, st->pktin->data,
0183b242 1232 st->biglen, NULL)) {
6b5cf8b4 1233 bombout(("Network attack (CRC compensation) detected!"));
ff3187f6 1234 ssh_free_packet(st->pktin);
1235 crStop(NULL);
9a3a93a5 1236 }
1237
51470298 1238 if (ssh->cipher)
ff3187f6 1239 ssh->cipher->decrypt(ssh->v1_cipher_ctx, st->pktin->data, st->biglen);
374330e2 1240
ff3187f6 1241 st->realcrc = crc32_compute(st->pktin->data, st->biglen - 4);
1242 st->gotcrc = GET_32BIT(st->pktin->data + st->biglen - 4);
57476f6b 1243 if (st->gotcrc != st->realcrc) {
6b5cf8b4 1244 bombout(("Incorrect CRC received on packet"));
ff3187f6 1245 ssh_free_packet(st->pktin);
1246 crStop(NULL);
fb09bf1c 1247 }
572f871e 1248
ff3187f6 1249 st->pktin->body = st->pktin->data + st->pad + 1;
1250 st->pktin->savedpos = 0;
4ba9b64b 1251
51470298 1252 if (ssh->v1_compressing) {
4ba9b64b 1253 unsigned char *decompblk;
1254 int decomplen;
36b8d9bb 1255 if (!zlib_decompress_block(ssh->sc_comp_ctx,
ff3187f6 1256 st->pktin->body - 1, st->pktin->length + 1,
36b8d9bb 1257 &decompblk, &decomplen)) {
1258 bombout(("Zlib decompression encountered invalid data"));
ff3187f6 1259 ssh_free_packet(st->pktin);
1260 crStop(NULL);
36b8d9bb 1261 }
4ba9b64b 1262
ff3187f6 1263 if (st->pktin->maxlen < st->pad + decomplen) {
1264 st->pktin->maxlen = st->pad + decomplen;
1265 st->pktin->data = sresize(st->pktin->data,
1266 st->pktin->maxlen + APIEXTRA,
3d88e64d 1267 unsigned char);
ff3187f6 1268 st->pktin->body = st->pktin->data + st->pad + 1;
4ba9b64b 1269 }
1270
ff3187f6 1271 memcpy(st->pktin->body - 1, decompblk, decomplen);
dcbde236 1272 sfree(decompblk);
ff3187f6 1273 st->pktin->length = decomplen - 1;
4ba9b64b 1274 }
1275
ff3187f6 1276 st->pktin->type = st->pktin->body[-1];
00db133f 1277
9a10ecf4 1278 /*
1279 * Log incoming packet, possibly omitting sensitive fields.
1280 */
1281 if (ssh->logctx) {
1282 int nblanks = 0;
1283 struct logblank_t blank;
1284 if (ssh->cfg.logomitdata) {
1285 int do_blank = FALSE, blank_prefix = 0;
1286 /* "Session data" packets - omit the data field */
ff3187f6 1287 if ((st->pktin->type == SSH1_SMSG_STDOUT_DATA) ||
1288 (st->pktin->type == SSH1_SMSG_STDERR_DATA)) {
9a10ecf4 1289 do_blank = TRUE; blank_prefix = 4;
a2724fba 1290 } else if (st->pktin->type == SSH1_MSG_CHANNEL_DATA) {
1291 do_blank = TRUE; blank_prefix = 8;
9a10ecf4 1292 }
1293 if (do_blank) {
1294 blank.offset = blank_prefix;
ff3187f6 1295 blank.len = st->pktin->length;
9a10ecf4 1296 blank.type = PKTLOG_OMIT;
1297 nblanks = 1;
1298 }
1299 }
a8327734 1300 log_packet(ssh->logctx,
ff3187f6 1301 PKT_INCOMING, st->pktin->type,
1302 ssh1_pkt_type(st->pktin->type),
1303 st->pktin->body, st->pktin->length,
0d13bfcd 1304 nblanks, &blank, NULL);
9a10ecf4 1305 }
00db133f 1306
ff3187f6 1307 crFinish(st->pktin);
fb09bf1c 1308}
1309
ff3187f6 1310static struct Packet *ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen)
e5574168 1311{
51470298 1312 struct rdpkt2_state_tag *st = &ssh->rdpkt2_state;
e5574168 1313
51470298 1314 crBegin(ssh->ssh2_rdpkt_crstate);
e5574168 1315
ff3187f6 1316 st->pktin = ssh_new_packet();
1317
1318 st->pktin->type = 0;
1319 st->pktin->length = 0;
51470298 1320 if (ssh->sccipher)
1321 st->cipherblk = ssh->sccipher->blksize;
e5574168 1322 else
32874aea 1323 st->cipherblk = 8;
960e736a 1324 if (st->cipherblk < 8)
32874aea 1325 st->cipherblk = 8;
9916cc1e 1326 st->maclen = ssh->scmac ? ssh->scmac->len : 0;
960e736a 1327
9916cc1e 1328 if (ssh->sccipher && (ssh->sccipher->flags & SSH_CIPHER_IS_CBC) &&
1329 ssh->scmac) {
1330 /*
1331 * When dealing with a CBC-mode cipher, we want to avoid the
1332 * possibility of an attacker's tweaking the ciphertext stream
1333 * so as to cause us to feed the same block to the block
1334 * cipher more than once and thus leak information
1335 * (VU#958563). The way we do this is not to take any
1336 * decisions on the basis of anything we've decrypted until
1337 * we've verified it with a MAC. That includes the packet
1338 * length, so we just read data and check the MAC repeatedly,
1339 * and when the MAC passes, see if the length we've got is
1340 * plausible.
1341 */
1342
1343 /* May as well allocate the whole lot now. */
1344 st->pktin->data = snewn(OUR_V2_PACKETLIMIT + st->maclen + APIEXTRA,
1345 unsigned char);
1346
1347 /* Read an amount corresponding to the MAC. */
1348 for (st->i = 0; st->i < st->maclen; st->i++) {
1349 while ((*datalen) == 0)
1350 crReturn(NULL);
1351 st->pktin->data[st->i] = *(*data)++;
1352 (*datalen)--;
1353 }
e5574168 1354
9916cc1e 1355 st->packetlen = 0;
1356 {
1357 unsigned char seq[4];
1358 ssh->scmac->start(ssh->sc_mac_ctx);
1359 PUT_32BIT(seq, st->incoming_sequence);
1360 ssh->scmac->bytes(ssh->sc_mac_ctx, seq, 4);
1361 }
4252c9cc 1362
9916cc1e 1363 for (;;) { /* Once around this loop per cipher block. */
1364 /* Read another cipher-block's worth, and tack it onto the end. */
1365 for (st->i = 0; st->i < st->cipherblk; st->i++) {
1366 while ((*datalen) == 0)
1367 crReturn(NULL);
1368 st->pktin->data[st->packetlen+st->maclen+st->i] = *(*data)++;
1369 (*datalen)--;
1370 }
1371 /* Decrypt one more block (a little further back in the stream). */
1372 ssh->sccipher->decrypt(ssh->sc_cipher_ctx,
1373 st->pktin->data + st->packetlen,
1374 st->cipherblk);
1375 /* Feed that block to the MAC. */
1376 ssh->scmac->bytes(ssh->sc_mac_ctx,
1377 st->pktin->data + st->packetlen, st->cipherblk);
1378 st->packetlen += st->cipherblk;
1379 /* See if that gives us a valid packet. */
1380 if (ssh->scmac->verresult(ssh->sc_mac_ctx,
1381 st->pktin->data + st->packetlen) &&
1382 (st->len = GET_32BIT(st->pktin->data)) + 4 == st->packetlen)
1383 break;
1384 if (st->packetlen >= OUR_V2_PACKETLIMIT) {
1385 bombout(("No valid incoming packet found"));
1386 ssh_free_packet(st->pktin);
1387 crStop(NULL);
1388 }
1389 }
1390 st->pktin->maxlen = st->packetlen + st->maclen;
1391 st->pktin->data = sresize(st->pktin->data,
1392 st->pktin->maxlen + APIEXTRA,
1393 unsigned char);
1394 } else {
1395 st->pktin->data = snewn(st->cipherblk + APIEXTRA, unsigned char);
1396
1397 /*
1398 * Acquire and decrypt the first block of the packet. This will
1399 * contain the length and padding details.
1400 */
1401 for (st->i = st->len = 0; st->i < st->cipherblk; st->i++) {
1402 while ((*datalen) == 0)
1403 crReturn(NULL);
1404 st->pktin->data[st->i] = *(*data)++;
1405 (*datalen)--;
1406 }
e5574168 1407
9916cc1e 1408 if (ssh->sccipher)
1409 ssh->sccipher->decrypt(ssh->sc_cipher_ctx,
1410 st->pktin->data, st->cipherblk);
1411
1412 /*
1413 * Now get the length figure.
1414 */
1415 st->len = GET_32BIT(st->pktin->data);
1416
1417 /*
1418 * _Completely_ silly lengths should be stomped on before they
1419 * do us any more damage.
1420 */
1421 if (st->len < 0 || st->len > OUR_V2_PACKETLIMIT ||
1422 (st->len + 4) % st->cipherblk != 0) {
1423 bombout(("Incoming packet was garbled on decryption"));
1424 ssh_free_packet(st->pktin);
1425 crStop(NULL);
1426 }
e5574168 1427
9916cc1e 1428 /*
1429 * So now we can work out the total packet length.
1430 */
1431 st->packetlen = st->len + 4;
1432
1433 /*
1434 * Allocate memory for the rest of the packet.
1435 */
1436 st->pktin->maxlen = st->packetlen + st->maclen;
1437 st->pktin->data = sresize(st->pktin->data,
1438 st->pktin->maxlen + APIEXTRA,
1439 unsigned char);
1440
1441 /*
1442 * Read and decrypt the remainder of the packet.
1443 */
1444 for (st->i = st->cipherblk; st->i < st->packetlen + st->maclen;
1445 st->i++) {
1446 while ((*datalen) == 0)
1447 crReturn(NULL);
1448 st->pktin->data[st->i] = *(*data)++;
1449 (*datalen)--;
1450 }
1451 /* Decrypt everything _except_ the MAC. */
1452 if (ssh->sccipher)
1453 ssh->sccipher->decrypt(ssh->sc_cipher_ctx,
1454 st->pktin->data + st->cipherblk,
1455 st->packetlen - st->cipherblk);
1456
1457 /*
1458 * Check the MAC.
1459 */
1460 if (ssh->scmac
1461 && !ssh->scmac->verify(ssh->sc_mac_ctx, st->pktin->data,
1462 st->len + 4, st->incoming_sequence)) {
1463 bombout(("Incorrect MAC received on packet"));
1464 ssh_free_packet(st->pktin);
1465 crStop(NULL);
1466 }
1467 }
1468 /* Get and sanity-check the amount of random padding. */
1469 st->pad = st->pktin->data[4];
1470 if (st->pad < 4 || st->len - st->pad < 1) {
1471 bombout(("Invalid padding length on received packet"));
ff3187f6 1472 ssh_free_packet(st->pktin);
1473 crStop(NULL);
717dc483 1474 }
717dc483 1475 /*
e5574168 1476 * This enables us to deduce the payload length.
1477 */
960e736a 1478 st->payload = st->len - st->pad - 1;
e5574168 1479
ff3187f6 1480 st->pktin->length = st->payload + 5;
9442dd57 1481 st->pktin->encrypted_len = st->packetlen;
1482
b09eaa88 1483 st->pktin->sequence = st->incoming_sequence++;
e5574168 1484
4ba9b64b 1485 /*
1486 * Decompress packet payload.
1487 */
1488 {
1489 unsigned char *newpayload;
1490 int newlen;
51470298 1491 if (ssh->sccomp &&
5366aed8 1492 ssh->sccomp->decompress(ssh->sc_comp_ctx,
ff3187f6 1493 st->pktin->data + 5, st->pktin->length - 5,
51470298 1494 &newpayload, &newlen)) {
ff3187f6 1495 if (st->pktin->maxlen < newlen + 5) {
1496 st->pktin->maxlen = newlen + 5;
1497 st->pktin->data = sresize(st->pktin->data,
1498 st->pktin->maxlen + APIEXTRA,
3d88e64d 1499 unsigned char);
4ba9b64b 1500 }
ff3187f6 1501 st->pktin->length = 5 + newlen;
1502 memcpy(st->pktin->data + 5, newpayload, newlen);
dcbde236 1503 sfree(newpayload);
4ba9b64b 1504 }
1505 }
1506
ff3187f6 1507 st->pktin->savedpos = 6;
1508 st->pktin->body = st->pktin->data;
1509 st->pktin->type = st->pktin->data[5];
e5574168 1510
9a10ecf4 1511 /*
1512 * Log incoming packet, possibly omitting sensitive fields.
1513 */
1514 if (ssh->logctx) {
1515 int nblanks = 0;
1516 struct logblank_t blank;
1517 if (ssh->cfg.logomitdata) {
1518 int do_blank = FALSE, blank_prefix = 0;
1519 /* "Session data" packets - omit the data field */
ff3187f6 1520 if (st->pktin->type == SSH2_MSG_CHANNEL_DATA) {
9a10ecf4 1521 do_blank = TRUE; blank_prefix = 8;
a2724fba 1522 } else if (st->pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
1523 do_blank = TRUE; blank_prefix = 12;
9a10ecf4 1524 }
1525 if (do_blank) {
1526 blank.offset = blank_prefix;
ff3187f6 1527 blank.len = (st->pktin->length-6) - blank_prefix;
9a10ecf4 1528 blank.type = PKTLOG_OMIT;
1529 nblanks = 1;
1530 }
1531 }
ff3187f6 1532 log_packet(ssh->logctx, PKT_INCOMING, st->pktin->type,
acab36bc 1533 ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx,
1534 st->pktin->type),
ff3187f6 1535 st->pktin->data+6, st->pktin->length-6,
0d13bfcd 1536 nblanks, &blank, &st->pktin->sequence);
9a10ecf4 1537 }
00db133f 1538
ff3187f6 1539 crFinish(st->pktin);
e5574168 1540}
1541
dacd8872 1542static int s_wrpkt_prepare(Ssh ssh, struct Packet *pkt, int *offset_p)
32874aea 1543{
dacd8872 1544 int pad, biglen, i, pktoffs;
374330e2 1545 unsigned long crc;
fd7a4aad 1546#ifdef __SC__
1547 /*
1548 * XXX various versions of SC (including 8.8.4) screw up the
1549 * register allocation in this function and use the same register
1550 * (D6) for len and as a temporary, with predictable results. The
1551 * following sledgehammer prevents this.
1552 */
1553 volatile
1554#endif
1555 int len;
374330e2 1556
a8327734 1557 if (ssh->logctx)
dacd8872 1558 log_packet(ssh->logctx, PKT_OUTGOING, pkt->data[12],
1559 ssh1_pkt_type(pkt->data[12]),
1560 pkt->body, pkt->length - (pkt->body - pkt->data),
0d13bfcd 1561 pkt->nblanks, pkt->blanks, NULL);
ff3187f6 1562 sfree(pkt->blanks); pkt->blanks = NULL;
1563 pkt->nblanks = 0;
00db133f 1564
51470298 1565 if (ssh->v1_compressing) {
4ba9b64b 1566 unsigned char *compblk;
1567 int complen;
5366aed8 1568 zlib_compress_block(ssh->cs_comp_ctx,
dacd8872 1569 pkt->data + 12, pkt->length - 12,
4ba9b64b 1570 &compblk, &complen);
48406e6b 1571 ssh_pkt_ensure(pkt, complen + 2); /* just in case it's got bigger */
dacd8872 1572 memcpy(pkt->data + 12, compblk, complen);
dcbde236 1573 sfree(compblk);
dacd8872 1574 pkt->length = complen + 12;
4ba9b64b 1575 }
1576
dacd8872 1577 ssh_pkt_ensure(pkt, pkt->length + 4); /* space for CRC */
1578 pkt->length += 4;
1579 len = pkt->length - 4 - 8; /* len(type+data+CRC) */
32874aea 1580 pad = 8 - (len % 8);
dacd8872 1581 pktoffs = 8 - pad;
1582 biglen = len + pad; /* len(padding+type+data+CRC) */
374330e2 1583
dacd8872 1584 for (i = pktoffs; i < 4+8; i++)
1585 pkt->data[i] = random_byte();
1586 crc = crc32_compute(pkt->data + pktoffs + 4, biglen - 4); /* all ex len */
1587 PUT_32BIT(pkt->data + pktoffs + 4 + biglen - 4, crc);
1588 PUT_32BIT(pkt->data + pktoffs, len);
374330e2 1589
51470298 1590 if (ssh->cipher)
dacd8872 1591 ssh->cipher->encrypt(ssh->v1_cipher_ctx,
1592 pkt->data + pktoffs + 4, biglen);
374330e2 1593
dacd8872 1594 if (offset_p) *offset_p = pktoffs;
1595 return biglen + 4; /* len(length+padding+type+data+CRC) */
39065bed 1596}
1597
bf8a49a1 1598static int s_write(Ssh ssh, void *data, int len)
1599{
ff05dfef 1600 if (ssh->logctx)
0d13bfcd 1601 log_packet(ssh->logctx, PKT_OUTGOING, -1, NULL, data, len,
1602 0, NULL, NULL);
bf8a49a1 1603 return sk_write(ssh->s, (char *)data, len);
1604}
1605
ff3187f6 1606static void s_wrpkt(Ssh ssh, struct Packet *pkt)
32874aea 1607{
dacd8872 1608 int len, backlog, offset;
1609 len = s_wrpkt_prepare(ssh, pkt, &offset);
bf8a49a1 1610 backlog = s_write(ssh, pkt->data + offset, len);
5471d09a 1611 if (backlog > SSH_MAX_BACKLOG)
51470298 1612 ssh_throttle_all(ssh, 1, backlog);
dacd8872 1613 ssh_free_packet(pkt);
39065bed 1614}
1615
ff3187f6 1616static void s_wrpkt_defer(Ssh ssh, struct Packet *pkt)
32874aea 1617{
dacd8872 1618 int len, offset;
1619 len = s_wrpkt_prepare(ssh, pkt, &offset);
51470298 1620 if (ssh->deferred_len + len > ssh->deferred_size) {
1621 ssh->deferred_size = ssh->deferred_len + len + 128;
3d88e64d 1622 ssh->deferred_send_data = sresize(ssh->deferred_send_data,
1623 ssh->deferred_size,
1624 unsigned char);
39065bed 1625 }
dacd8872 1626 memcpy(ssh->deferred_send_data + ssh->deferred_len,
1627 pkt->data + offset, len);
51470298 1628 ssh->deferred_len += len;
dacd8872 1629 ssh_free_packet(pkt);
374330e2 1630}
1631
fb09bf1c 1632/*
dacd8872 1633 * Construct a SSH-1 packet with the specified contents.
1634 * (This all-at-once interface used to be the only one, but now SSH-1
1635 * packets can also be constructed incrementally.)
fb09bf1c 1636 */
dacd8872 1637static struct Packet *construct_packet(Ssh ssh, int pkttype, va_list ap)
fb09bf1c 1638{
dacd8872 1639 int argtype;
7cca0d81 1640 Bignum bn;
ff3187f6 1641 struct Packet *pkt;
fb09bf1c 1642
dacd8872 1643 pkt = ssh1_pkt_init(pkttype);
fb09bf1c 1644
dacd8872 1645 while ((argtype = va_arg(ap, int)) != PKT_END) {
1646 unsigned char *argp, argchar;
8a9977e5 1647 char *sargp;
dacd8872 1648 unsigned long argint;
1649 int arglen;
fb09bf1c 1650 switch (argtype) {
9a10ecf4 1651 /* Actual fields in the packet */
fb09bf1c 1652 case PKT_INT:
dacd8872 1653 argint = va_arg(ap, int);
1654 ssh_pkt_adduint32(pkt, argint);
fb09bf1c 1655 break;
1656 case PKT_CHAR:
dacd8872 1657 argchar = (unsigned char) va_arg(ap, int);
1658 ssh_pkt_addbyte(pkt, argchar);
fb09bf1c 1659 break;
1660 case PKT_DATA:
dacd8872 1661 argp = va_arg(ap, unsigned char *);
1662 arglen = va_arg(ap, int);
1663 ssh_pkt_adddata(pkt, argp, arglen);
fb09bf1c 1664 break;
1665 case PKT_STR:
8a9977e5 1666 sargp = va_arg(ap, char *);
1667 ssh_pkt_addstring(pkt, sargp);
fb09bf1c 1668 break;
7cca0d81 1669 case PKT_BIGNUM:
dacd8872 1670 bn = va_arg(ap, Bignum);
1671 ssh1_pkt_addmp(pkt, bn);
9a10ecf4 1672 break;
1673 /* Tokens for modifications to packet logging */
1674 case PKTT_PASSWORD:
ff3187f6 1675 dont_log_password(ssh, pkt, PKTLOG_BLANK);
9a10ecf4 1676 break;
1677 case PKTT_DATA:
ff3187f6 1678 dont_log_data(ssh, pkt, PKTLOG_OMIT);
7cca0d81 1679 break;
9a10ecf4 1680 case PKTT_OTHER:
ff3187f6 1681 end_log_omission(ssh, pkt);
9a10ecf4 1682 break;
1683 }
fb09bf1c 1684 }
ff3187f6 1685
1686 return pkt;
39065bed 1687}
fb09bf1c 1688
51470298 1689static void send_packet(Ssh ssh, int pkttype, ...)
32874aea 1690{
ff3187f6 1691 struct Packet *pkt;
dacd8872 1692 va_list ap;
1693 va_start(ap, pkttype);
1694 pkt = construct_packet(ssh, pkttype, ap);
1695 va_end(ap);
ff3187f6 1696 s_wrpkt(ssh, pkt);
fb09bf1c 1697}
1698
51470298 1699static void defer_packet(Ssh ssh, int pkttype, ...)
32874aea 1700{
ff3187f6 1701 struct Packet *pkt;
dacd8872 1702 va_list ap;
1703 va_start(ap, pkttype);
1704 pkt = construct_packet(ssh, pkttype, ap);
1705 va_end(ap);
ff3187f6 1706 s_wrpkt_defer(ssh, pkt);
39065bed 1707}
1708
32874aea 1709static int ssh_versioncmp(char *a, char *b)
1710{
9697bfd2 1711 char *ae, *be;
1712 unsigned long av, bv;
1713
43aa02a7 1714 av = strtoul(a, &ae, 10);
1715 bv = strtoul(b, &be, 10);
32874aea 1716 if (av != bv)
1717 return (av < bv ? -1 : +1);
1718 if (*ae == '.')
1719 ae++;
1720 if (*be == '.')
1721 be++;
43aa02a7 1722 av = strtoul(ae, &ae, 10);
1723 bv = strtoul(be, &be, 10);
32874aea 1724 if (av != bv)
1725 return (av < bv ? -1 : +1);
9697bfd2 1726 return 0;
1727}
1728
e5574168 1729/*
a92dd380 1730 * Utility routines for putting an SSH-protocol `string' and
b672f405 1731 * `uint32' into a hash state.
e5574168 1732 */
b672f405 1733static void hash_string(const struct ssh_hash *h, void *s, void *str, int len)
32874aea 1734{
e5574168 1735 unsigned char lenblk[4];
e5574168 1736 PUT_32BIT(lenblk, len);
b672f405 1737 h->bytes(s, lenblk, 4);
1738 h->bytes(s, str, len);
e5574168 1739}
1740
b672f405 1741static void hash_uint32(const struct ssh_hash *h, void *s, unsigned i)
32874aea 1742{
a92dd380 1743 unsigned char intblk[4];
1744 PUT_32BIT(intblk, i);
b672f405 1745 h->bytes(s, intblk, 4);
a92dd380 1746}
1747
7cca0d81 1748/*
dacd8872 1749 * Packet construction functions. Mostly shared between SSH-1 and SSH-2.
7cca0d81 1750 */
dacd8872 1751static void ssh_pkt_ensure(struct Packet *pkt, int length)
32874aea 1752{
ff3187f6 1753 if (pkt->maxlen < length) {
dacd8872 1754 unsigned char *body = pkt->body;
3d71de0b 1755 int offset = body ? body - pkt->data : 0;
ff3187f6 1756 pkt->maxlen = length + 256;
1757 pkt->data = sresize(pkt->data, pkt->maxlen + APIEXTRA, unsigned char);
dacd8872 1758 if (body) pkt->body = pkt->data + offset;
7cca0d81 1759 }
783415f8 1760}
dacd8872 1761static void ssh_pkt_adddata(struct Packet *pkt, void *data, int len)
32874aea 1762{
ff3187f6 1763 if (pkt->logmode != PKTLOG_EMIT) {
1764 pkt->nblanks++;
1765 pkt->blanks = sresize(pkt->blanks, pkt->nblanks, struct logblank_t);
dacd8872 1766 assert(pkt->body);
1767 pkt->blanks[pkt->nblanks-1].offset = pkt->length -
1768 (pkt->body - pkt->data);
ff3187f6 1769 pkt->blanks[pkt->nblanks-1].len = len;
1770 pkt->blanks[pkt->nblanks-1].type = pkt->logmode;
1771 }
1772 pkt->length += len;
dacd8872 1773 ssh_pkt_ensure(pkt, pkt->length);
ff3187f6 1774 memcpy(pkt->data + pkt->length - len, data, len);
7cca0d81 1775}
dacd8872 1776static void ssh_pkt_addbyte(struct Packet *pkt, unsigned char byte)
32874aea 1777{
dacd8872 1778 ssh_pkt_adddata(pkt, &byte, 1);
7cca0d81 1779}
ff3187f6 1780static void ssh2_pkt_addbool(struct Packet *pkt, unsigned char value)
32874aea 1781{
dacd8872 1782 ssh_pkt_adddata(pkt, &value, 1);
7cca0d81 1783}
dacd8872 1784static void ssh_pkt_adduint32(struct Packet *pkt, unsigned long value)
32874aea 1785{
7cca0d81 1786 unsigned char x[4];
1787 PUT_32BIT(x, value);
dacd8872 1788 ssh_pkt_adddata(pkt, x, 4);
7cca0d81 1789}
dacd8872 1790static void ssh_pkt_addstring_start(struct Packet *pkt)
32874aea 1791{
dacd8872 1792 ssh_pkt_adduint32(pkt, 0);
ff3187f6 1793 pkt->savedpos = pkt->length;
7cca0d81 1794}
dacd8872 1795static void ssh_pkt_addstring_str(struct Packet *pkt, char *data)
32874aea 1796{
dacd8872 1797 ssh_pkt_adddata(pkt, data, strlen(data));
ff3187f6 1798 PUT_32BIT(pkt->data + pkt->savedpos - 4, pkt->length - pkt->savedpos);
7cca0d81 1799}
dacd8872 1800static void ssh_pkt_addstring_data(struct Packet *pkt, char *data, int len)
32874aea 1801{
dacd8872 1802 ssh_pkt_adddata(pkt, data, len);
ff3187f6 1803 PUT_32BIT(pkt->data + pkt->savedpos - 4, pkt->length - pkt->savedpos);
7cca0d81 1804}
dacd8872 1805static void ssh_pkt_addstring(struct Packet *pkt, char *data)
1806{
1807 ssh_pkt_addstring_start(pkt);
1808 ssh_pkt_addstring_str(pkt, data);
1809}
1810static void ssh1_pkt_addmp(struct Packet *pkt, Bignum b)
32874aea 1811{
dacd8872 1812 int len = ssh1_bignum_length(b);
8a9977e5 1813 unsigned char *data = snewn(len, unsigned char);
dacd8872 1814 (void) ssh1_write_bignum(data, b);
1815 ssh_pkt_adddata(pkt, data, len);
1816 sfree(data);
7cca0d81 1817}
d8baa528 1818static unsigned char *ssh2_mpint_fmt(Bignum b, int *len)
32874aea 1819{
7cca0d81 1820 unsigned char *p;
32874aea 1821 int i, n = (bignum_bitcount(b) + 7) / 8;
3d88e64d 1822 p = snewn(n + 1, unsigned char);
7cca0d81 1823 p[0] = 0;
3709bfe9 1824 for (i = 1; i <= n; i++)
32874aea 1825 p[i] = bignum_byte(b, n - i);
7cca0d81 1826 i = 0;
32874aea 1827 while (i <= n && p[i] == 0 && (p[i + 1] & 0x80) == 0)
1828 i++;
1829 memmove(p, p + i, n + 1 - i);
1830 *len = n + 1 - i;
7cca0d81 1831 return p;
1832}
ff3187f6 1833static void ssh2_pkt_addmp(struct Packet *pkt, Bignum b)
32874aea 1834{
7cca0d81 1835 unsigned char *p;
1836 int len;
1837 p = ssh2_mpint_fmt(b, &len);
dacd8872 1838 ssh_pkt_addstring_start(pkt);
1839 ssh_pkt_addstring_data(pkt, (char *)p, len);
dcbde236 1840 sfree(p);
7cca0d81 1841}
b185170a 1842
dacd8872 1843static struct Packet *ssh1_pkt_init(int pkt_type)
1844{
1845 struct Packet *pkt = ssh_new_packet();
1846 pkt->length = 4 + 8; /* space for length + max padding */
1847 ssh_pkt_addbyte(pkt, pkt_type);
1848 pkt->body = pkt->data + pkt->length;
1849 return pkt;
1850}
1851
1852/* For legacy code (SSH-1 and -2 packet construction used to be separate) */
1853#define ssh2_pkt_ensure(pkt, length) ssh_pkt_ensure(pkt, length)
1854#define ssh2_pkt_adddata(pkt, data, len) ssh_pkt_adddata(pkt, data, len)
1855#define ssh2_pkt_addbyte(pkt, byte) ssh_pkt_addbyte(pkt, byte)
1856#define ssh2_pkt_adduint32(pkt, value) ssh_pkt_adduint32(pkt, value)
1857#define ssh2_pkt_addstring_start(pkt) ssh_pkt_addstring_start(pkt)
1858#define ssh2_pkt_addstring_str(pkt, data) ssh_pkt_addstring_str(pkt, data)
1859#define ssh2_pkt_addstring_data(pkt, data, len) ssh_pkt_addstring_data(pkt, data, len)
1860#define ssh2_pkt_addstring(pkt, data) ssh_pkt_addstring(pkt, data)
1861
1862static struct Packet *ssh2_pkt_init(int pkt_type)
1863{
1864 struct Packet *pkt = ssh_new_packet();
3d71de0b 1865 pkt->length = 5; /* space for packet length + padding length */
dacd8872 1866 pkt->forcepad = 0;
1867 ssh_pkt_addbyte(pkt, (unsigned char) pkt_type);
3d71de0b 1868 pkt->body = pkt->data + pkt->length; /* after packet type */
dacd8872 1869 return pkt;
1870}
1871
b185170a 1872/*
2e85c969 1873 * Construct an SSH-2 final-form packet: compress it, encrypt it,
b185170a 1874 * put the MAC on it. Final packet, ready to be sent, is stored in
ff3187f6 1875 * pkt->data. Total length is returned.
b185170a 1876 */
ff3187f6 1877static int ssh2_pkt_construct(Ssh ssh, struct Packet *pkt)
32874aea 1878{
7cca0d81 1879 int cipherblk, maclen, padding, i;
7cca0d81 1880
a8327734 1881 if (ssh->logctx)
ff3187f6 1882 log_packet(ssh->logctx, PKT_OUTGOING, pkt->data[5],
acab36bc 1883 ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx, pkt->data[5]),
dacd8872 1884 pkt->body, pkt->length - (pkt->body - pkt->data),
0d13bfcd 1885 pkt->nblanks, pkt->blanks, &ssh->v2_outgoing_sequence);
ff3187f6 1886 sfree(pkt->blanks); pkt->blanks = NULL;
1887 pkt->nblanks = 0;
00db133f 1888
7cca0d81 1889 /*
4ba9b64b 1890 * Compress packet payload.
1891 */
4ba9b64b 1892 {
1893 unsigned char *newpayload;
1894 int newlen;
51470298 1895 if (ssh->cscomp &&
ff3187f6 1896 ssh->cscomp->compress(ssh->cs_comp_ctx, pkt->data + 5,
1897 pkt->length - 5,
51470298 1898 &newpayload, &newlen)) {
ff3187f6 1899 pkt->length = 5;
1900 ssh2_pkt_adddata(pkt, newpayload, newlen);
dcbde236 1901 sfree(newpayload);
4ba9b64b 1902 }
1903 }
1904
1905 /*
7cca0d81 1906 * Add padding. At least four bytes, and must also bring total
1907 * length (minus MAC) up to a multiple of the block size.
95d2d262 1908 * If pkt->forcepad is set, make sure the packet is at least that size
1909 * after padding.
7cca0d81 1910 */
51470298 1911 cipherblk = ssh->cscipher ? ssh->cscipher->blksize : 8; /* block size */
32874aea 1912 cipherblk = cipherblk < 8 ? 8 : cipherblk; /* or 8 if blksize < 8 */
7cca0d81 1913 padding = 4;
95d2d262 1914 if (pkt->length + padding < pkt->forcepad)
1915 padding = pkt->forcepad - pkt->length;
32874aea 1916 padding +=
ff3187f6 1917 (cipherblk - (pkt->length + padding) % cipherblk) % cipherblk;
95d2d262 1918 assert(padding <= 255);
51470298 1919 maclen = ssh->csmac ? ssh->csmac->len : 0;
ff3187f6 1920 ssh2_pkt_ensure(pkt, pkt->length + padding + maclen);
1921 pkt->data[4] = padding;
7cca0d81 1922 for (i = 0; i < padding; i++)
ff3187f6 1923 pkt->data[pkt->length + i] = random_byte();
1924 PUT_32BIT(pkt->data, pkt->length + padding - 4);
51470298 1925 if (ssh->csmac)
ff3187f6 1926 ssh->csmac->generate(ssh->cs_mac_ctx, pkt->data,
1927 pkt->length + padding,
51470298 1928 ssh->v2_outgoing_sequence);
1929 ssh->v2_outgoing_sequence++; /* whether or not we MACed */
1930
1931 if (ssh->cscipher)
371e569c 1932 ssh->cscipher->encrypt(ssh->cs_cipher_ctx,
ff3187f6 1933 pkt->data, pkt->length + padding);
51470298 1934
9442dd57 1935 pkt->encrypted_len = pkt->length + padding;
1936
ff3187f6 1937 /* Ready-to-send packet starts at pkt->data. We return length. */
1938 return pkt->length + padding + maclen;
b185170a 1939}
1940
1941/*
590f6a5f 1942 * Routines called from the main SSH code to send packets. There
1943 * are quite a few of these, because we have two separate
1944 * mechanisms for delaying the sending of packets:
1945 *
1946 * - In order to send an IGNORE message and a password message in
1947 * a single fixed-length blob, we require the ability to
1948 * concatenate the encrypted forms of those two packets _into_ a
1949 * single blob and then pass it to our <network.h> transport
1950 * layer in one go. Hence, there's a deferment mechanism which
1951 * works after packet encryption.
1952 *
1953 * - In order to avoid sending any connection-layer messages
1954 * during repeat key exchange, we have to queue up any such
1955 * outgoing messages _before_ they are encrypted (and in
1956 * particular before they're allocated sequence numbers), and
1957 * then send them once we've finished.
1958 *
1959 * I call these mechanisms `defer' and `queue' respectively, so as
1960 * to distinguish them reasonably easily.
1961 *
1962 * The functions send_noqueue() and defer_noqueue() free the packet
1963 * structure they are passed. Every outgoing packet goes through
1964 * precisely one of these functions in its life; packets passed to
1965 * ssh2_pkt_send() or ssh2_pkt_defer() either go straight to one of
1966 * these or get queued, and then when the queue is later emptied
1967 * the packets are all passed to defer_noqueue().
97ab28d7 1968 *
1969 * When using a CBC-mode cipher, it's necessary to ensure that an
1970 * attacker can't provide data to be encrypted using an IV that they
1971 * know. We ensure this by prefixing each packet that might contain
1972 * user data with an SSH_MSG_IGNORE. This is done using the deferral
1973 * mechanism, so in this case send_noqueue() ends up redirecting to
1974 * defer_noqueue(). If you don't like this inefficiency, don't use
1975 * CBC.
b185170a 1976 */
590f6a5f 1977
97ab28d7 1978static void ssh2_pkt_defer_noqueue(Ssh, struct Packet *, int);
1979static void ssh_pkt_defersend(Ssh);
1980
590f6a5f 1981/*
2e85c969 1982 * Send an SSH-2 packet immediately, without queuing or deferring.
590f6a5f 1983 */
1984static void ssh2_pkt_send_noqueue(Ssh ssh, struct Packet *pkt)
32874aea 1985{
5471d09a 1986 int len;
1987 int backlog;
97ab28d7 1988 if (ssh->cscipher != NULL && (ssh->cscipher->flags & SSH_CIPHER_IS_CBC)) {
1989 /* We need to send two packets, so use the deferral mechanism. */
1990 ssh2_pkt_defer_noqueue(ssh, pkt, FALSE);
1991 ssh_pkt_defersend(ssh);
1992 return;
1993 }
ff3187f6 1994 len = ssh2_pkt_construct(ssh, pkt);
bf8a49a1 1995 backlog = s_write(ssh, pkt->data, len);
5471d09a 1996 if (backlog > SSH_MAX_BACKLOG)
51470298 1997 ssh_throttle_all(ssh, 1, backlog);
9442dd57 1998
1999 ssh->outgoing_data_size += pkt->encrypted_len;
2000 if (!ssh->kex_in_progress &&
d57f70af 2001 ssh->max_data_size != 0 &&
2002 ssh->outgoing_data_size > ssh->max_data_size)
f382c87d 2003 do_ssh2_transport(ssh, "too much data sent", -1, NULL);
9442dd57 2004
ff3187f6 2005 ssh_free_packet(pkt);
b185170a 2006}
2007
2008/*
2e85c969 2009 * Defer an SSH-2 packet.
b185170a 2010 */
97ab28d7 2011static void ssh2_pkt_defer_noqueue(Ssh ssh, struct Packet *pkt, int noignore)
32874aea 2012{
97ab28d7 2013 int len;
2014 if (ssh->cscipher != NULL && (ssh->cscipher->flags & SSH_CIPHER_IS_CBC) &&
cf6ddb95 2015 ssh->deferred_len == 0 && !noignore &&
2016 !(ssh->remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE)) {
97ab28d7 2017 /*
2018 * Interpose an SSH_MSG_IGNORE to ensure that user data don't
2019 * get encrypted with a known IV.
2020 */
2021 struct Packet *ipkt = ssh2_pkt_init(SSH2_MSG_IGNORE);
27311cc7 2022 ssh2_pkt_addstring_start(ipkt);
97ab28d7 2023 ssh2_pkt_defer_noqueue(ssh, ipkt, TRUE);
2024 }
2025 len = ssh2_pkt_construct(ssh, pkt);
51470298 2026 if (ssh->deferred_len + len > ssh->deferred_size) {
2027 ssh->deferred_size = ssh->deferred_len + len + 128;
3d88e64d 2028 ssh->deferred_send_data = sresize(ssh->deferred_send_data,
2029 ssh->deferred_size,
2030 unsigned char);
b185170a 2031 }
ff3187f6 2032 memcpy(ssh->deferred_send_data + ssh->deferred_len, pkt->data, len);
51470298 2033 ssh->deferred_len += len;
9442dd57 2034 ssh->deferred_data_size += pkt->encrypted_len;
ff3187f6 2035 ssh_free_packet(pkt);
b185170a 2036}
2037
2038/*
2e85c969 2039 * Queue an SSH-2 packet.
590f6a5f 2040 */
2041static void ssh2_pkt_queue(Ssh ssh, struct Packet *pkt)
2042{
2043 assert(ssh->queueing);
2044
2045 if (ssh->queuelen >= ssh->queuesize) {
2046 ssh->queuesize = ssh->queuelen + 32;
2047 ssh->queue = sresize(ssh->queue, ssh->queuesize, struct Packet *);
2048 }
2049
2050 ssh->queue[ssh->queuelen++] = pkt;
2051}
2052
2053/*
2054 * Either queue or send a packet, depending on whether queueing is
2055 * set.
2056 */
2057static void ssh2_pkt_send(Ssh ssh, struct Packet *pkt)
2058{
2059 if (ssh->queueing)
2060 ssh2_pkt_queue(ssh, pkt);
2061 else
2062 ssh2_pkt_send_noqueue(ssh, pkt);
2063}
2064
2065/*
2066 * Either queue or defer a packet, depending on whether queueing is
2067 * set.
2068 */
2069static void ssh2_pkt_defer(Ssh ssh, struct Packet *pkt)
2070{
2071 if (ssh->queueing)
2072 ssh2_pkt_queue(ssh, pkt);
2073 else
97ab28d7 2074 ssh2_pkt_defer_noqueue(ssh, pkt, FALSE);
590f6a5f 2075}
2076
2077/*
b185170a 2078 * Send the whole deferred data block constructed by
2e85c969 2079 * ssh2_pkt_defer() or SSH-1's defer_packet().
590f6a5f 2080 *
2081 * The expected use of the defer mechanism is that you call
2082 * ssh2_pkt_defer() a few times, then call ssh_pkt_defersend(). If
2083 * not currently queueing, this simply sets up deferred_send_data
2084 * and then sends it. If we _are_ currently queueing, the calls to
2085 * ssh2_pkt_defer() put the deferred packets on to the queue
2086 * instead, and therefore ssh_pkt_defersend() has no deferred data
2087 * to send. Hence, there's no need to make it conditional on
2088 * ssh->queueing.
b185170a 2089 */
51470298 2090static void ssh_pkt_defersend(Ssh ssh)
32874aea 2091{
5471d09a 2092 int backlog;
bf8a49a1 2093 backlog = s_write(ssh, ssh->deferred_send_data, ssh->deferred_len);
51470298 2094 ssh->deferred_len = ssh->deferred_size = 0;
2095 sfree(ssh->deferred_send_data);
2096 ssh->deferred_send_data = NULL;
5471d09a 2097 if (backlog > SSH_MAX_BACKLOG)
51470298 2098 ssh_throttle_all(ssh, 1, backlog);
9442dd57 2099
2100 ssh->outgoing_data_size += ssh->deferred_data_size;
2101 if (!ssh->kex_in_progress &&
d57f70af 2102 ssh->max_data_size != 0 &&
2103 ssh->outgoing_data_size > ssh->max_data_size)
f382c87d 2104 do_ssh2_transport(ssh, "too much data sent", -1, NULL);
9442dd57 2105 ssh->deferred_data_size = 0;
7cca0d81 2106}
2107
590f6a5f 2108/*
18524056 2109 * Send a packet whose length needs to be disguised (typically
2110 * passwords or keyboard-interactive responses).
2111 */
2112static void ssh2_pkt_send_with_padding(Ssh ssh, struct Packet *pkt,
2113 int padsize)
2114{
2115#if 0
2116 if (0) {
2117 /*
2118 * The simplest way to do this is to adjust the
2119 * variable-length padding field in the outgoing packet.
2120 *
2121 * Currently compiled out, because some Cisco SSH servers
2122 * don't like excessively padded packets (bah, why's it
2123 * always Cisco?)
2124 */
2125 pkt->forcepad = padsize;
2126 ssh2_pkt_send(ssh, pkt);
2127 } else
2128#endif
2129 {
2130 /*
2131 * If we can't do that, however, an alternative approach is
2132 * to use the pkt_defer mechanism to bundle the packet
2133 * tightly together with an SSH_MSG_IGNORE such that their
2134 * combined length is a constant. So first we construct the
2135 * final form of this packet and defer its sending.
2136 */
2137 ssh2_pkt_defer(ssh, pkt);
2138
2139 /*
2140 * Now construct an SSH_MSG_IGNORE which includes a string
2141 * that's an exact multiple of the cipher block size. (If
2142 * the cipher is NULL so that the block size is
2143 * unavailable, we don't do this trick at all, because we
2144 * gain nothing by it.)
2145 */
cf6ddb95 2146 if (ssh->cscipher &&
2147 !(ssh->remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE)) {
18524056 2148 int stringlen, i;
2149
2150 stringlen = (256 - ssh->deferred_len);
2151 stringlen += ssh->cscipher->blksize - 1;
2152 stringlen -= (stringlen % ssh->cscipher->blksize);
2153 if (ssh->cscomp) {
2154 /*
2155 * Temporarily disable actual compression, so we
2156 * can guarantee to get this string exactly the
2157 * length we want it. The compression-disabling
2158 * routine should return an integer indicating how
2159 * many bytes we should adjust our string length
2160 * by.
2161 */
2162 stringlen -=
2163 ssh->cscomp->disable_compression(ssh->cs_comp_ctx);
2164 }
2165 pkt = ssh2_pkt_init(SSH2_MSG_IGNORE);
2166 ssh2_pkt_addstring_start(pkt);
2167 for (i = 0; i < stringlen; i++) {
2168 char c = (char) random_byte();
2169 ssh2_pkt_addstring_data(pkt, &c, 1);
2170 }
2171 ssh2_pkt_defer(ssh, pkt);
2172 }
2173 ssh_pkt_defersend(ssh);
2174 }
2175}
2176
2177/*
2e85c969 2178 * Send all queued SSH-2 packets. We send them by means of
590f6a5f 2179 * ssh2_pkt_defer_noqueue(), in case they included a pair of
2180 * packets that needed to be lumped together.
2181 */
2182static void ssh2_pkt_queuesend(Ssh ssh)
2183{
2184 int i;
2185
2186 assert(!ssh->queueing);
2187
2188 for (i = 0; i < ssh->queuelen; i++)
97ab28d7 2189 ssh2_pkt_defer_noqueue(ssh, ssh->queue[i], FALSE);
590f6a5f 2190 ssh->queuelen = 0;
2191
2192 ssh_pkt_defersend(ssh);
2193}
2194
7cca0d81 2195#if 0
32874aea 2196void bndebug(char *string, Bignum b)
2197{
7cca0d81 2198 unsigned char *p;
2199 int i, len;
2200 p = ssh2_mpint_fmt(b, &len);
2201 debug(("%s", string));
2202 for (i = 0; i < len; i++)
32874aea 2203 debug((" %02x", p[i]));
765c4200 2204 debug(("\n"));
dcbde236 2205 sfree(p);
7cca0d81 2206}
2207#endif
2208
b672f405 2209static void hash_mpint(const struct ssh_hash *h, void *s, Bignum b)
32874aea 2210{
7cca0d81 2211 unsigned char *p;
2212 int len;
2213 p = ssh2_mpint_fmt(b, &len);
b672f405 2214 hash_string(h, s, p, len);
dcbde236 2215 sfree(p);
7cca0d81 2216}
2217
2218/*
2e85c969 2219 * Packet decode functions for both SSH-1 and SSH-2.
7cca0d81 2220 */
ff3187f6 2221static unsigned long ssh_pkt_getuint32(struct Packet *pkt)
32874aea 2222{
7cca0d81 2223 unsigned long value;
ff3187f6 2224 if (pkt->length - pkt->savedpos < 4)
32874aea 2225 return 0; /* arrgh, no way to decline (FIXME?) */
ff3187f6 2226 value = GET_32BIT(pkt->body + pkt->savedpos);
2227 pkt->savedpos += 4;
7cca0d81 2228 return value;
2229}
ff3187f6 2230static int ssh2_pkt_getbool(struct Packet *pkt)
32874aea 2231{
65a22376 2232 unsigned long value;
ff3187f6 2233 if (pkt->length - pkt->savedpos < 1)
32874aea 2234 return 0; /* arrgh, no way to decline (FIXME?) */
ff3187f6 2235 value = pkt->body[pkt->savedpos] != 0;
2236 pkt->savedpos++;
65a22376 2237 return value;
2238}
ff3187f6 2239static void ssh_pkt_getstring(struct Packet *pkt, char **p, int *length)
32874aea 2240{
57356d63 2241 int len;
7cca0d81 2242 *p = NULL;
45068b27 2243 *length = 0;
ff3187f6 2244 if (pkt->length - pkt->savedpos < 4)
32874aea 2245 return;
ff3187f6 2246 len = GET_32BIT(pkt->body + pkt->savedpos);
57356d63 2247 if (len < 0)
2248 return;
2249 *length = len;
ff3187f6 2250 pkt->savedpos += 4;
2251 if (pkt->length - pkt->savedpos < *length)
32874aea 2252 return;
ff3187f6 2253 *p = (char *)(pkt->body + pkt->savedpos);
2254 pkt->savedpos += *length;
7cca0d81 2255}
ff3187f6 2256static void *ssh_pkt_getdata(struct Packet *pkt, int length)
0016d70b 2257{
ff3187f6 2258 if (pkt->length - pkt->savedpos < length)
0016d70b 2259 return NULL;
ff3187f6 2260 pkt->savedpos += length;
2261 return pkt->body + (pkt->savedpos - length);
0016d70b 2262}
ff3187f6 2263static int ssh1_pkt_getrsakey(struct Packet *pkt, struct RSAKey *key,
0016d70b 2264 unsigned char **keystr)
2265{
2266 int j;
2267
ff3187f6 2268 j = makekey(pkt->body + pkt->savedpos,
2269 pkt->length - pkt->savedpos,
0016d70b 2270 key, keystr, 0);
2271
2272 if (j < 0)
2273 return FALSE;
2274
ff3187f6 2275 pkt->savedpos += j;
2276 assert(pkt->savedpos < pkt->length);
0016d70b 2277
2278 return TRUE;
2279}
ff3187f6 2280static Bignum ssh1_pkt_getmp(struct Packet *pkt)
0016d70b 2281{
2282 int j;
2283 Bignum b;
2284
ff3187f6 2285 j = ssh1_read_bignum(pkt->body + pkt->savedpos,
2286 pkt->length - pkt->savedpos, &b);
0016d70b 2287
2288 if (j < 0)
2289 return NULL;
2290
ff3187f6 2291 pkt->savedpos += j;
0016d70b 2292 return b;
2293}
ff3187f6 2294static Bignum ssh2_pkt_getmp(struct Packet *pkt)
32874aea 2295{
7cca0d81 2296 char *p;
3709bfe9 2297 int length;
7cca0d81 2298 Bignum b;
2299
ff3187f6 2300 ssh_pkt_getstring(pkt, &p, &length);
7cca0d81 2301 if (!p)
32874aea 2302 return NULL;
ff3187f6 2303 if (p[0] & 0x80)
32874aea 2304 return NULL;
d8baa528 2305 b = bignum_from_bytes((unsigned char *)p, length);
7cca0d81 2306 return b;
2307}
2308
7d503c31 2309/*
2e85c969 2310 * Helper function to add an SSH-2 signature blob to a packet.
1dd353b5 2311 * Expects to be shown the public key blob as well as the signature
2312 * blob. Normally works just like ssh2_pkt_addstring, but will
2313 * fiddle with the signature packet if necessary for
2314 * BUG_SSH2_RSA_PADDING.
2315 */
ff3187f6 2316static void ssh2_add_sigblob(Ssh ssh, struct Packet *pkt,
2317 void *pkblob_v, int pkblob_len,
1dd353b5 2318 void *sigblob_v, int sigblob_len)
2319{
2320 unsigned char *pkblob = (unsigned char *)pkblob_v;
2321 unsigned char *sigblob = (unsigned char *)sigblob_v;
2322
2323 /* dmemdump(pkblob, pkblob_len); */
2324 /* dmemdump(sigblob, sigblob_len); */
2325
2326 /*
2327 * See if this is in fact an ssh-rsa signature and a buggy
2328 * server; otherwise we can just do this the easy way.
2329 */
51470298 2330 if ((ssh->remote_bugs & BUG_SSH2_RSA_PADDING) &&
1dd353b5 2331 (GET_32BIT(pkblob) == 7 && !memcmp(pkblob+4, "ssh-rsa", 7))) {
2332 int pos, len, siglen;
2333
2334 /*
2335 * Find the byte length of the modulus.
2336 */
2337
2338 pos = 4+7; /* skip over "ssh-rsa" */
2339 pos += 4 + GET_32BIT(pkblob+pos); /* skip over exponent */
2340 len = GET_32BIT(pkblob+pos); /* find length of modulus */
2341 pos += 4; /* find modulus itself */
2342 while (len > 0 && pkblob[pos] == 0)
2343 len--, pos++;
2344 /* debug(("modulus length is %d\n", len)); */
2345
2346 /*
2347 * Now find the signature integer.
2348 */
2349 pos = 4+7; /* skip over "ssh-rsa" */
2350 siglen = GET_32BIT(sigblob+pos);
2351 /* debug(("signature length is %d\n", siglen)); */
2352
2353 if (len != siglen) {
2354 unsigned char newlen[4];
ff3187f6 2355 ssh2_pkt_addstring_start(pkt);
2356 ssh2_pkt_addstring_data(pkt, (char *)sigblob, pos);
1dd353b5 2357 /* dmemdump(sigblob, pos); */
2358 pos += 4; /* point to start of actual sig */
2359 PUT_32BIT(newlen, len);
ff3187f6 2360 ssh2_pkt_addstring_data(pkt, (char *)newlen, 4);
1dd353b5 2361 /* dmemdump(newlen, 4); */
2362 newlen[0] = 0;
2363 while (len-- > siglen) {
ff3187f6 2364 ssh2_pkt_addstring_data(pkt, (char *)newlen, 1);
1dd353b5 2365 /* dmemdump(newlen, 1); */
2366 }
ff3187f6 2367 ssh2_pkt_addstring_data(pkt, (char *)(sigblob+pos), siglen);
1dd353b5 2368 /* dmemdump(sigblob+pos, siglen); */
2369 return;
2370 }
2371
2372 /* Otherwise fall through and do it the easy way. */
2373 }
2374
ff3187f6 2375 ssh2_pkt_addstring_start(pkt);
2376 ssh2_pkt_addstring_data(pkt, (char *)sigblob, sigblob_len);
1dd353b5 2377}
2378
2379/*
7d503c31 2380 * Examine the remote side's version string and compare it against
2381 * a list of known buggy implementations.
2382 */
51470298 2383static void ssh_detect_bugs(Ssh ssh, char *vstring)
32874aea 2384{
2385 char *imp; /* pointer to implementation part */
7d503c31 2386 imp = vstring;
2387 imp += strcspn(imp, "-");
bd358db1 2388 if (*imp) imp++;
7d503c31 2389 imp += strcspn(imp, "-");
bd358db1 2390 if (*imp) imp++;
7d503c31 2391
51470298 2392 ssh->remote_bugs = 0;
7d503c31 2393
bf982899 2394 /*
2395 * General notes on server version strings:
2396 * - Not all servers reporting "Cisco-1.25" have all the bugs listed
2397 * here -- in particular, we've heard of one that's perfectly happy
2398 * with SSH1_MSG_IGNOREs -- but this string never seems to change,
2399 * so we can't distinguish them.
2400 */
5ecd7ad0 2401 if (ssh->cfg.sshbug_ignore1 == FORCE_ON ||
2402 (ssh->cfg.sshbug_ignore1 == AUTO &&
2c9c6388 2403 (!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") ||
2404 !strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") ||
46ac09aa 2405 !strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25") ||
bd0b4caf 2406 !strcmp(imp, "OSU_1.4alpha3") || !strcmp(imp, "OSU_1.5alpha4")))) {
32874aea 2407 /*
2408 * These versions don't support SSH1_MSG_IGNORE, so we have
2409 * to use a different defence against password length
2410 * sniffing.
2411 */
51470298 2412 ssh->remote_bugs |= BUG_CHOKES_ON_SSH1_IGNORE;
2e85c969 2413 logevent("We believe remote version has SSH-1 ignore bug");
7d503c31 2414 }
2415
5ecd7ad0 2416 if (ssh->cfg.sshbug_plainpw1 == FORCE_ON ||
2417 (ssh->cfg.sshbug_plainpw1 == AUTO &&
46ac09aa 2418 (!strcmp(imp, "Cisco-1.25") || !strcmp(imp, "OSU_1.4alpha3")))) {
bd358db1 2419 /*
2420 * These versions need a plain password sent; they can't
2421 * handle having a null and a random length of data after
2422 * the password.
2423 */
51470298 2424 ssh->remote_bugs |= BUG_NEEDS_SSH1_PLAIN_PASSWORD;
2e85c969 2425 logevent("We believe remote version needs a plain SSH-1 password");
bd358db1 2426 }
2427
5ecd7ad0 2428 if (ssh->cfg.sshbug_rsa1 == FORCE_ON ||
2429 (ssh->cfg.sshbug_rsa1 == AUTO &&
2c9c6388 2430 (!strcmp(imp, "Cisco-1.25")))) {
0df73905 2431 /*
2432 * These versions apparently have no clue whatever about
2433 * RSA authentication and will panic and die if they see
2434 * an AUTH_RSA message.
2435 */
51470298 2436 ssh->remote_bugs |= BUG_CHOKES_ON_RSA;
19f47a7d 2437 logevent("We believe remote version can't handle SSH-1 RSA authentication");
0df73905 2438 }
2439
5ecd7ad0 2440 if (ssh->cfg.sshbug_hmac2 == FORCE_ON ||
2441 (ssh->cfg.sshbug_hmac2 == AUTO &&
b9f387af 2442 !wc_match("* VShell", imp) &&
831301f6 2443 (wc_match("2.1.0*", imp) || wc_match("2.0.*", imp) ||
2444 wc_match("2.2.0*", imp) || wc_match("2.3.0*", imp) ||
2445 wc_match("2.1 *", imp)))) {
32874aea 2446 /*
2447 * These versions have the HMAC bug.
2448 */
51470298 2449 ssh->remote_bugs |= BUG_SSH2_HMAC;
2e85c969 2450 logevent("We believe remote version has SSH-2 HMAC bug");
7d503c31 2451 }
1dd353b5 2452
5ecd7ad0 2453 if (ssh->cfg.sshbug_derivekey2 == FORCE_ON ||
2454 (ssh->cfg.sshbug_derivekey2 == AUTO &&
b9f387af 2455 !wc_match("* VShell", imp) &&
2856a1b9 2456 (wc_match("2.0.0*", imp) || wc_match("2.0.10*", imp) ))) {
088bde77 2457 /*
2458 * These versions have the key-derivation bug (failing to
2459 * include the literal shared secret in the hashes that
2460 * generate the keys).
2461 */
51470298 2462 ssh->remote_bugs |= BUG_SSH2_DERIVEKEY;
2e85c969 2463 logevent("We believe remote version has SSH-2 key-derivation bug");
088bde77 2464 }
2465
5ecd7ad0 2466 if (ssh->cfg.sshbug_rsapad2 == FORCE_ON ||
2467 (ssh->cfg.sshbug_rsapad2 == AUTO &&
831301f6 2468 (wc_match("OpenSSH_2.[5-9]*", imp) ||
2469 wc_match("OpenSSH_3.[0-2]*", imp)))) {
1dd353b5 2470 /*
2e85c969 2471 * These versions have the SSH-2 RSA padding bug.
1dd353b5 2472 */
51470298 2473 ssh->remote_bugs |= BUG_SSH2_RSA_PADDING;
2e85c969 2474 logevent("We believe remote version has SSH-2 RSA padding bug");
1dd353b5 2475 }
8e975795 2476
dda87a28 2477 if (ssh->cfg.sshbug_pksessid2 == FORCE_ON ||
2478 (ssh->cfg.sshbug_pksessid2 == AUTO &&
2479 wc_match("OpenSSH_2.[0-2]*", imp))) {
2480 /*
2e85c969 2481 * These versions have the SSH-2 session-ID bug in
dda87a28 2482 * public-key authentication.
2483 */
2484 ssh->remote_bugs |= BUG_SSH2_PK_SESSIONID;
2e85c969 2485 logevent("We believe remote version has SSH-2 public-key-session-ID bug");
dda87a28 2486 }
f382c87d 2487
2488 if (ssh->cfg.sshbug_rekey2 == FORCE_ON ||
2489 (ssh->cfg.sshbug_rekey2 == AUTO &&
39b8712f 2490 (wc_match("DigiSSH_2.0", imp) ||
2491 wc_match("OpenSSH_2.[0-4]*", imp) ||
e12d95a5 2492 wc_match("OpenSSH_2.5.[0-3]*", imp) ||
2493 wc_match("Sun_SSH_1.0", imp) ||
f4275b53 2494 wc_match("Sun_SSH_1.0.1", imp) ||
96bd26de 2495 /* All versions <= 1.2.6 (they changed their format in 1.2.7) */
2496 wc_match("WeOnlyDo-*", imp)))) {
f382c87d 2497 /*
2e85c969 2498 * These versions have the SSH-2 rekey bug.
f382c87d 2499 */
2500 ssh->remote_bugs |= BUG_SSH2_REKEY;
2e85c969 2501 logevent("We believe remote version has SSH-2 rekey bug");
f382c87d 2502 }
c9739dba 2503
2504 if (ssh->cfg.sshbug_maxpkt2 == FORCE_ON ||
2505 (ssh->cfg.sshbug_maxpkt2 == AUTO &&
5ca836f2 2506 (wc_match("1.36_sshlib GlobalSCAPE", imp) ||
2507 wc_match("1.36 sshlib: GlobalScape", imp)))) {
c9739dba 2508 /*
2509 * This version ignores our makpkt and needs to be throttled.
2510 */
2511 ssh->remote_bugs |= BUG_SSH2_MAXPKT;
2512 logevent("We believe remote version ignores SSH-2 maximum packet size");
2513 }
cf6ddb95 2514
2515 if (ssh->cfg.sshbug_ignore2 == FORCE_ON) {
2516 /*
2517 * Servers that don't support SSH2_MSG_IGNORE. Currently,
2518 * none detected automatically.
2519 */
2520 ssh->remote_bugs |= BUG_CHOKES_ON_SSH2_IGNORE;
2521 logevent("We believe remote version has SSH-2 ignore bug");
2522 }
7d503c31 2523}
2524
d38d6a1f 2525/*
2526 * The `software version' part of an SSH version string is required
2527 * to contain no spaces or minus signs.
2528 */
2529static void ssh_fix_verstring(char *str)
2530{
2531 /* Eat "SSH-<protoversion>-". */
2532 assert(*str == 'S'); str++;
2533 assert(*str == 'S'); str++;
2534 assert(*str == 'H'); str++;
2535 assert(*str == '-'); str++;
2536 while (*str && *str != '-') str++;
2537 assert(*str == '-'); str++;
2538
2539 /* Convert minus signs and spaces in the remaining string into
2540 * underscores. */
2541 while (*str) {
2542 if (*str == '-' || *str == ' ')
2543 *str = '_';
2544 str++;
2545 }
2546}
2547
1fcd0d98 2548/*
2549 * Send an appropriate SSH version string.
2550 */
2551static void ssh_send_verstring(Ssh ssh, char *svers)
2552{
2553 char *verstring;
2554
2555 if (ssh->version == 2) {
2556 /*
2557 * Construct a v2 version string.
2558 */
2559 verstring = dupprintf("SSH-2.0-%s\015\012", sshver);
2560 } else {
2561 /*
2562 * Construct a v1 version string.
2563 */
2564 verstring = dupprintf("SSH-%s-%s\012",
2565 (ssh_versioncmp(svers, "1.5") <= 0 ?
2566 svers : "1.5"),
2567 sshver);
2568 }
2569
2570 ssh_fix_verstring(verstring);
2571
2572 if (ssh->version == 2) {
2573 size_t len;
2574 /*
2575 * Record our version string.
2576 */
2577 len = strcspn(verstring, "\015\012");
2578 ssh->v_c = snewn(len + 1, char);
2579 memcpy(ssh->v_c, verstring, len);
2580 ssh->v_c[len] = 0;
2581 }
2582
2583 logeventf(ssh, "We claim version: %.*s",
2584 strcspn(verstring, "\015\012"), verstring);
2585 s_write(ssh, verstring, strlen(verstring));
2586 sfree(verstring);
2587}
2588
51470298 2589static int do_ssh_init(Ssh ssh, unsigned char c)
32874aea 2590{
51470298 2591 struct do_ssh_init_state {
2592 int vslen;
2593 char version[10];
2594 char *vstring;
2595 int vstrsize;
2596 int i;
2597 int proto1, proto2;
2598 };
2599 crState(do_ssh_init_state);
374330e2 2600
51470298 2601 crBegin(ssh->do_ssh_init_crstate);
8df7a775 2602
8c1835c0 2603 /* Search for a line beginning with the string "SSH-" in the input. */
2604 for (;;) {
2605 if (c != 'S') goto no;
2606 crReturn(1);
2607 if (c != 'S') goto no;
2608 crReturn(1);
2609 if (c != 'H') goto no;
2610 crReturn(1);
2611 if (c != '-') goto no;
2612 break;
2613 no:
2614 while (c != '\012')
2615 crReturn(1);
2616 crReturn(1);
374330e2 2617 }
8df7a775 2618
51470298 2619 s->vstrsize = 16;
3d88e64d 2620 s->vstring = snewn(s->vstrsize, char);
51470298 2621 strcpy(s->vstring, "SSH-");
2622 s->vslen = 4;
2623 s->i = 0;
374330e2 2624 while (1) {
8df7a775 2625 crReturn(1); /* get another char */
51470298 2626 if (s->vslen >= s->vstrsize - 1) {
2627 s->vstrsize += 16;
3d88e64d 2628 s->vstring = sresize(s->vstring, s->vstrsize, char);
32874aea 2629 }
51470298 2630 s->vstring[s->vslen++] = c;
2631 if (s->i >= 0) {
374330e2 2632 if (c == '-') {
51470298 2633 s->version[s->i] = '\0';
2634 s->i = -1;
2635 } else if (s->i < sizeof(s->version) - 1)
2636 s->version[s->i++] = c;
c4ffc4d0 2637 } else if (c == '\012')
374330e2 2638 break;
2639 }
2640
51470298 2641 ssh->agentfwd_enabled = FALSE;
2642 ssh->rdpkt2_state.incoming_sequence = 0;
960e736a 2643
51470298 2644 s->vstring[s->vslen] = 0;
a7d4653a 2645 s->vstring[strcspn(s->vstring, "\015\012")] = '\0';/* remove EOL chars */
fb983202 2646 logeventf(ssh, "Server version: %s", s->vstring);
51470298 2647 ssh_detect_bugs(ssh, s->vstring);
c5e9c988 2648
adf799dd 2649 /*
38d228a2 2650 * Decide which SSH protocol version to support.
adf799dd 2651 */
38d228a2 2652
2653 /* Anything strictly below "2.0" means protocol 1 is supported. */
51470298 2654 s->proto1 = ssh_versioncmp(s->version, "2.0") < 0;
38d228a2 2655 /* Anything greater or equal to "1.99" means protocol 2 is supported. */
51470298 2656 s->proto2 = ssh_versioncmp(s->version, "1.99") >= 0;
38d228a2 2657
86916870 2658 if (ssh->cfg.sshprot == 0 && !s->proto1) {
6b5cf8b4 2659 bombout(("SSH protocol version 1 required by user but not provided by server"));
7ffdbc1a 2660 crStop(0);
38d228a2 2661 }
86916870 2662 if (ssh->cfg.sshprot == 3 && !s->proto2) {
6b5cf8b4 2663 bombout(("SSH protocol version 2 required by user but not provided by server"));
7ffdbc1a 2664 crStop(0);
38d228a2 2665 }
2666
1fcd0d98 2667 if (s->proto2 && (ssh->cfg.sshprot >= 2 || !s->proto1))
2668 ssh->version = 2;
2669 else
2670 ssh->version = 1;
d38d6a1f 2671
2672 logeventf(ssh, "Using SSH protocol version %d", ssh->version);
2673
1fcd0d98 2674 /* Send the version string, if we haven't already */
2675 if (ssh->cfg.sshprot != 3)
2676 ssh_send_verstring(ssh, s->version);
2677
2678 if (ssh->version == 2) {
2679 size_t len;
2680 /*
2681 * Record their version string.
2682 */
2683 len = strcspn(s->vstring, "\015\012");
2684 ssh->v_s = snewn(len + 1, char);
2685 memcpy(ssh->v_s, s->vstring, len);
2686 ssh->v_s[len] = 0;
2687
2688 /*
2689 * Initialise SSH-2 protocol.
2690 */
2691 ssh->protocol = ssh2_protocol;
2692 ssh2_protocol_setup(ssh);
2693 ssh->s_rdpkt = ssh2_rdpkt;
2694 } else {
2695 /*
2696 * Initialise SSH-1 protocol.
2697 */
2698 ssh->protocol = ssh1_protocol;
2699 ssh1_protocol_setup(ssh);
2700 ssh->s_rdpkt = ssh1_rdpkt;
2701 }
2702 if (ssh->version == 2)
2703 do_ssh2_transport(ssh, NULL, -1, NULL);
2704
125105d1 2705 update_specials_menu(ssh->frontend);
51470298 2706 ssh->state = SSH_STATE_BEFORE_SIZE;
39934deb 2707 ssh->pinger = pinger_new(&ssh->cfg, &ssh_backend, ssh);
8df7a775 2708
51470298 2709 sfree(s->vstring);
50526e47 2710
8df7a775 2711 crFinish(0);
2712}
2713
3d9449a1 2714static void ssh_process_incoming_data(Ssh ssh,
2715 unsigned char **data, int *datalen)
2716{
bf8a49a1 2717 struct Packet *pktin;
2718
2719 pktin = ssh->s_rdpkt(ssh, data, datalen);
3d9449a1 2720 if (pktin) {
2721 ssh->protocol(ssh, NULL, 0, pktin);
2722 ssh_free_packet(pktin);
2723 }
2724}
2725
2726static void ssh_queue_incoming_data(Ssh ssh,
2727 unsigned char **data, int *datalen)
2728{
2729 bufchain_add(&ssh->queued_incoming_data, *data, *datalen);
2730 *data += *datalen;
2731 *datalen = 0;
2732}
2733
2734static void ssh_process_queued_incoming_data(Ssh ssh)
2735{
2736 void *vdata;
2737 unsigned char *data;
2738 int len, origlen;
2739
2740 while (!ssh->frozen && bufchain_size(&ssh->queued_incoming_data)) {
2741 bufchain_prefix(&ssh->queued_incoming_data, &vdata, &len);
2742 data = vdata;
2743 origlen = len;
2744
2745 while (!ssh->frozen && len > 0)
2746 ssh_process_incoming_data(ssh, &data, &len);
2747
2748 if (origlen > len)
2749 bufchain_consume(&ssh->queued_incoming_data, origlen - len);
2750 }
2751}
2752
2753static void ssh_set_frozen(Ssh ssh, int frozen)
2754{
a5a6f839 2755 if (ssh->s)
2756 sk_set_frozen(ssh->s, frozen);
3d9449a1 2757 ssh->frozen = frozen;
2758}
2759
51470298 2760static void ssh_gotdata(Ssh ssh, unsigned char *data, int datalen)
8df7a775 2761{
bf8a49a1 2762 /* Log raw data, if we're in that mode. */
ff05dfef 2763 if (ssh->logctx)
2764 log_packet(ssh->logctx, PKT_INCOMING, -1, NULL, data, datalen,
0d13bfcd 2765 0, NULL, NULL);
bf8a49a1 2766
51470298 2767 crBegin(ssh->ssh_gotdata_crstate);
8df7a775 2768
2769 /*
2770 * To begin with, feed the characters one by one to the
2771 * protocol initialisation / selection function do_ssh_init().
2772 * When that returns 0, we're done with the initial greeting
2773 * exchange and can move on to packet discipline.
2774 */
2775 while (1) {
51470298 2776 int ret; /* need not be kept across crReturn */
8df7a775 2777 if (datalen == 0)
2778 crReturnV; /* more data please */
51470298 2779 ret = do_ssh_init(ssh, *data);
32874aea 2780 data++;
2781 datalen--;
8df7a775 2782 if (ret == 0)
2783 break;
2784 }
2785
2786 /*
2787 * We emerge from that loop when the initial negotiation is
2788 * over and we have selected an s_rdpkt function. Now pass
2789 * everything to s_rdpkt, and then pass the resulting packets
2790 * to the proper protocol handler.
2791 */
3d9449a1 2792
8df7a775 2793 while (1) {
e375106c 2794 while (bufchain_size(&ssh->queued_incoming_data) > 0 || datalen > 0) {
2795 if (ssh->frozen) {
3d9449a1 2796 ssh_queue_incoming_data(ssh, &data, &datalen);
e375106c 2797 /* This uses up all data and cannot cause anything interesting
2798 * to happen; indeed, for anything to happen at all, we must
2799 * return, so break out. */
2800 break;
2801 } else if (bufchain_size(&ssh->queued_incoming_data) > 0) {
2802 /* This uses up some or all data, and may freeze the
2803 * session. */
2804 ssh_process_queued_incoming_data(ssh);
2805 } else {
2806 /* This uses up some or all data, and may freeze the
2807 * session. */
2808 ssh_process_incoming_data(ssh, &data, &datalen);
2809 }
2810 /* FIXME this is probably EBW. */
ff3187f6 2811 if (ssh->state == SSH_STATE_CLOSED)
2812 return;
8df7a775 2813 }
e375106c 2814 /* We're out of data. Go and get some more. */
8df7a775 2815 crReturnV;
2816 }
2817 crFinishV;
2818}
2819
ac934965 2820static int ssh_do_close(Ssh ssh, int notify_exit)
32874aea 2821{
80ffa58b 2822 int ret = 0;
36f94d1f 2823 struct ssh_channel *c;
2824
51470298 2825 ssh->state = SSH_STATE_CLOSED;
ecbb0000 2826 expire_timer_context(ssh);
51470298 2827 if (ssh->s) {
2828 sk_close(ssh->s);
2829 ssh->s = NULL;
ac934965 2830 if (notify_exit)
2831 notify_remote_exit(ssh->frontend);
2832 else
2833 ret = 1;
f3ab576e 2834 }
36f94d1f 2835 /*
80ffa58b 2836 * Now we must shut down any port- and X-forwarded channels going
36f94d1f 2837 * through this connection.
2838 */
74a98066 2839 if (ssh->channels) {
80ffa58b 2840 while (NULL != (c = index234(ssh->channels, 0))) {
74a98066 2841 switch (c->type) {
2842 case CHAN_X11:
2843 x11_close(c->u.x11.s);
2844 break;
2845 case CHAN_SOCKDATA:
2846 pfd_close(c->u.pfd.s);
2847 break;
2848 }
80ffa58b 2849 del234(ssh->channels, c); /* moving next one to index 0 */
74a98066 2850 if (ssh->version == 2)
2851 bufchain_clear(&c->v.v2.outbuffer);
2852 sfree(c);
36f94d1f 2853 }
36f94d1f 2854 }
f8c9f9df 2855 /*
2856 * Go through port-forwardings, and close any associated
2857 * listening sockets.
2858 */
2859 if (ssh->portfwds) {
2860 struct ssh_portfwd *pf;
2861 while (NULL != (pf = index234(ssh->portfwds, 0))) {
2862 /* Dispose of any listening socket. */
2863 if (pf->local)
2864 pfd_terminate(pf->local);
2865 del234(ssh->portfwds, pf); /* moving next one to index 0 */
2866 free_portfwd(pf);
2867 }
b72bdf11 2868 freetree234(ssh->portfwds);
2869 ssh->portfwds = NULL;
f8c9f9df 2870 }
ac934965 2871
2872 return ret;
36f94d1f 2873}
2874
7555d6a5 2875static void ssh_log(Plug plug, int type, SockAddr addr, int port,
2876 const char *error_msg, int error_code)
2877{
2878 Ssh ssh = (Ssh) plug;
2879 char addrbuf[256], *msg;
2880
2881 sk_getaddr(addr, addrbuf, lenof(addrbuf));
2882
2883 if (type == 0)
2884 msg = dupprintf("Connecting to %s port %d", addrbuf, port);
2885 else
2886 msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg);
2887
2888 logevent(msg);
fb983202 2889 sfree(msg);
7555d6a5 2890}
2891
cbe2d68f 2892static int ssh_closing(Plug plug, const char *error_msg, int error_code,
36f94d1f 2893 int calling_back)
2894{
2895 Ssh ssh = (Ssh) plug;
ac934965 2896 int need_notify = ssh_do_close(ssh, FALSE);
2897
9e296bfa 2898 if (!error_msg) {
2899 if (!ssh->close_expected)
2900 error_msg = "Server unexpectedly closed network connection";
2901 else
2902 error_msg = "Server closed network connection";
ac934965 2903 }
2904
d051d1b4 2905 if (ssh->close_expected && ssh->clean_exit && ssh->exitcode < 0)
2906 ssh->exitcode = 0;
2907
2425184b 2908 if (need_notify)
2909 notify_remote_exit(ssh->frontend);
2910
9e296bfa 2911 if (error_msg)
247308b5 2912 logevent(error_msg);
9e296bfa 2913 if (!ssh->close_expected || !ssh->clean_exit)
971bcc0a 2914 connection_fatal(ssh->frontend, "%s", error_msg);
7e78000d 2915 return 0;
2916}
2917
32874aea 2918static int ssh_receive(Plug plug, int urgent, char *data, int len)
2919{
51470298 2920 Ssh ssh = (Ssh) plug;
d8baa528 2921 ssh_gotdata(ssh, (unsigned char *)data, len);
51470298 2922 if (ssh->state == SSH_STATE_CLOSED) {
ac934965 2923 ssh_do_close(ssh, TRUE);
32874aea 2924 return 0;
3257deae 2925 }
fef97f43 2926 return 1;
374330e2 2927}
2928
5471d09a 2929static void ssh_sent(Plug plug, int bufsize)
2930{
51470298 2931 Ssh ssh = (Ssh) plug;
5471d09a 2932 /*
2933 * If the send backlog on the SSH socket itself clears, we
2934 * should unthrottle the whole world if it was throttled.
2935 */
2936 if (bufsize < SSH_MAX_BACKLOG)
51470298 2937 ssh_throttle_all(ssh, 0, bufsize);
5471d09a 2938}
2939
fb09bf1c 2940/*
8df7a775 2941 * Connect to specified host and port.
2942 * Returns an error message, or NULL on success.
6e1ebb76 2943 * Also places the canonical host name into `realhost'. It must be
2944 * freed by the caller.
8df7a775 2945 */
cbe2d68f 2946static const char *connect_to_host(Ssh ssh, char *host, int port,
79bf227b 2947 char **realhost, int nodelay, int keepalive)
8df7a775 2948{
51470298 2949 static const struct plug_function_table fn_table = {
7555d6a5 2950 ssh_log,
7e78000d 2951 ssh_closing,
5471d09a 2952 ssh_receive,
2953 ssh_sent,
2954 NULL
51470298 2955 };
7e78000d 2956
8df7a775 2957 SockAddr addr;
cbe2d68f 2958 const char *err;
8df7a775 2959
881da168 2960 if (*ssh->cfg.loghost) {
2961 char *colon;
8df7a775 2962
881da168 2963 ssh->savedhost = dupstr(ssh->cfg.loghost);
2964 ssh->savedport = 22; /* default ssh port */
2965
2966 /*
2967 * A colon suffix on savedhost also lets us affect
2968 * savedport.
2969 *
2970 * (FIXME: do something about IPv6 address literals here.)
2971 */
2972 colon = strrchr(ssh->savedhost, ':');
2973 if (colon) {
2974 *colon++ = '\0';
2975 if (*colon)
2976 ssh->savedport = atoi(colon);
2977 }
2978 } else {
2979 ssh->savedhost = dupstr(host);
2980 if (port < 0)
2981 port = 22; /* default ssh port */
2982 ssh->savedport = port;
2983 }
8df7a775 2984
2985 /*
2986 * Try to find host.
2987 */
05581745 2988 logeventf(ssh, "Looking up host \"%s\"%s", host,
2989 (ssh->cfg.addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
2990 (ssh->cfg.addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" : "")));
2991 addr = name_lookup(host, port, realhost, &ssh->cfg,
2992 ssh->cfg.addressfamily);
170c1e6e 2993 if ((err = sk_addr_error(addr)) != NULL) {
2994 sk_addr_free(addr);
8df7a775 2995 return err;
170c1e6e 2996 }
42af6a67 2997 ssh->fullhostname = dupstr(*realhost); /* save in case of GSSAPI */
8df7a775 2998
8df7a775 2999 /*
3000 * Open socket.
3001 */
51470298 3002 ssh->fn = &fn_table;
e8fa8f62 3003 ssh->s = new_connection(addr, *realhost, port,
79bf227b 3004 0, 1, nodelay, keepalive, (Plug) ssh, &ssh->cfg);
70e5d0fd 3005 if ((err = sk_socket_error(ssh->s)) != NULL) {
51470298 3006 ssh->s = NULL;
39934deb 3007 notify_remote_exit(ssh->frontend);
8df7a775 3008 return err;
67c4ba2e 3009 }
8df7a775 3010
ff05dfef 3011 /*
3012 * If the SSH version number's fixed, set it now, and if it's SSH-2,
3013 * send the version string too.
3014 */
3015 if (ssh->cfg.sshprot == 0)
3016 ssh->version = 1;
3017 if (ssh->cfg.sshprot == 3) {
3018 ssh->version = 2;
3019 ssh_send_verstring(ssh, NULL);
3020 }
3021
881da168 3022 /*
3023 * loghost, if configured, overrides realhost.
3024 */
3025 if (*ssh->cfg.loghost) {
3026 sfree(*realhost);
3027 *realhost = dupstr(ssh->cfg.loghost);
3028 }
3029
8df7a775 3030 return NULL;
3031}
3032
3033/*
5471d09a 3034 * Throttle or unthrottle the SSH connection.
3035 */
ff68564b 3036static void ssh_throttle_conn(Ssh ssh, int adjust)
5471d09a 3037{
ff68564b 3038 int old_count = ssh->conn_throttle_count;
3039 ssh->conn_throttle_count += adjust;
3040 assert(ssh->conn_throttle_count >= 0);
3041 if (ssh->conn_throttle_count && !old_count) {
3d9449a1 3042 ssh_set_frozen(ssh, 1);
ff68564b 3043 } else if (!ssh->conn_throttle_count && old_count) {
3d9449a1 3044 ssh_set_frozen(ssh, 0);
5471d09a 3045 }
3046}
3047
3048/*
3049 * Throttle or unthrottle _all_ local data streams (for when sends
3050 * on the SSH connection itself back up).
3051 */
51470298 3052static void ssh_throttle_all(Ssh ssh, int enable, int bufsize)
5471d09a 3053{
3054 int i;
3055 struct ssh_channel *c;
3056
51470298 3057 if (enable == ssh->throttled_all)
5471d09a 3058 return;
51470298 3059 ssh->throttled_all = enable;
3060 ssh->overall_bufsize = bufsize;
3061 if (!ssh->channels)
5471d09a 3062 return;
51470298 3063 for (i = 0; NULL != (c = index234(ssh->channels, i)); i++) {
5471d09a 3064 switch (c->type) {
3065 case CHAN_MAINSESSION:
3066 /*
3067 * This is treated separately, outside the switch.
3068 */
3069 break;
3070 case CHAN_X11:
3071 x11_override_throttle(c->u.x11.s, enable);
3072 break;
3073 case CHAN_AGENT:
3074 /* Agent channels require no buffer management. */
3075 break;
3076 case CHAN_SOCKDATA:
36f94d1f 3077 pfd_override_throttle(c->u.pfd.s, enable);
5471d09a 3078 break;
3079 }
3080 }
3081}
3082
f11d78f2 3083static void ssh_agent_callback(void *sshv, void *reply, int replylen)
839f10db 3084{
3085 Ssh ssh = (Ssh) sshv;
3086
3087 ssh->agent_response = reply;
3088 ssh->agent_response_len = replylen;
3089
3090 if (ssh->version == 1)
ff3187f6 3091 do_ssh1_login(ssh, NULL, -1, NULL);
839f10db 3092 else
ff3187f6 3093 do_ssh2_authconn(ssh, NULL, -1, NULL);
839f10db 3094}
3095
3d9449a1 3096static void ssh_dialog_callback(void *sshv, int ret)
3097{
3098 Ssh ssh = (Ssh) sshv;
3099
3100 ssh->user_response = ret;
3101
3102 if (ssh->version == 1)
3103 do_ssh1_login(ssh, NULL, -1, NULL);
3104 else
3105 do_ssh2_transport(ssh, NULL, -1, NULL);
3106
3107 /*
3108 * This may have unfrozen the SSH connection, so do a
3109 * queued-data run.
3110 */
3111 ssh_process_queued_incoming_data(ssh);
3112}
3113
f11d78f2 3114static void ssh_agentf_callback(void *cv, void *reply, int replylen)
839f10db 3115{
3116 struct ssh_channel *c = (struct ssh_channel *)cv;
3117 Ssh ssh = c->ssh;
3118 void *sentreply = reply;
3119
3120 if (!sentreply) {
3121 /* Fake SSH_AGENT_FAILURE. */
3122 sentreply = "\0\0\0\1\5";
3123 replylen = 5;
3124 }
3125 if (ssh->version == 2) {
3126 ssh2_add_channel_data(c, sentreply, replylen);
3127 ssh2_try_send(c);
3128 } else {
3129 send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
3130 PKT_INT, c->remoteid,
3131 PKT_INT, replylen,
a2724fba 3132 PKTT_DATA,
839f10db 3133 PKT_DATA, sentreply, replylen,
9a10ecf4 3134 PKTT_OTHER,
839f10db 3135 PKT_END);
3136 }
3137 if (reply)
3138 sfree(reply);
3139}
3140
0405e71f 3141/*
9e296bfa 3142 * Client-initiated disconnection. Send a DISCONNECT if `wire_reason'
3143 * non-NULL, otherwise just close the connection. `client_reason' == NULL
3144 * => log `wire_reason'.
3145 */
3146static void ssh_disconnect(Ssh ssh, char *client_reason, char *wire_reason,
3147 int code, int clean_exit)
3148{
3149 char *error;
3150 if (!client_reason)
3151 client_reason = wire_reason;
3152 if (client_reason)
3153 error = dupprintf("Disconnected: %s", client_reason);
3154 else
3155 error = dupstr("Disconnected");
3156 if (wire_reason) {
3157 if (ssh->version == 1) {
3158 send_packet(ssh, SSH1_MSG_DISCONNECT, PKT_STR, wire_reason,
3159 PKT_END);
3160 } else if (ssh->version == 2) {
3161 struct Packet *pktout = ssh2_pkt_init(SSH2_MSG_DISCONNECT);
3162 ssh2_pkt_adduint32(pktout, code);
3163 ssh2_pkt_addstring(pktout, wire_reason);
3164 ssh2_pkt_addstring(pktout, "en"); /* language tag */
3165 ssh2_pkt_send_noqueue(ssh, pktout);
3166 }
3167 }
3168 ssh->close_expected = TRUE;
3169 ssh->clean_exit = clean_exit;
3170 ssh_closing((Plug)ssh, error, 0, 0);
3171 sfree(error);
3172}
3173
3174/*
fb09bf1c 3175 * Handle the key exchange and user authentication phases.
3176 */
ff3187f6 3177static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
3178 struct Packet *pktin)
fb09bf1c 3179{
0016d70b 3180 int i, j, ret;
3181 unsigned char cookie[8], *ptr;
374330e2 3182 struct RSAKey servkey, hostkey;
3183 struct MD5Context md5c;
51470298 3184 struct do_ssh1_login_state {
3185 int len;
3186 unsigned char *rsabuf, *keystr1, *keystr2;
3187 unsigned long supported_ciphers_mask, supported_auths_mask;
3188 int tried_publickey, tried_agent;
3189 int tis_auth_refused, ccard_auth_refused;
3190 unsigned char session_id[16];
3191 int cipher_type;
3192 char username[100];
3193 void *publickey_blob;
3194 int publickey_bloblen;
edd0cb8a 3195 char *publickey_comment;
3196 int publickey_encrypted;
3197 prompts_t *cur_prompt;
51470298 3198 char c;
3199 int pwpkt_type;
3200 unsigned char request[5], *response, *p;
3201 int responselen;
3202 int keyi, nkeys;
3203 int authed;
3204 struct RSAKey key;
3205 Bignum challenge;
3206 char *commentp;
3207 int commentlen;
3d9449a1 3208 int dlgret;
51470298 3209 };
3210 crState(do_ssh1_login_state);
3211
3212 crBegin(ssh->do_ssh1_login_crstate);
374330e2 3213
ff3187f6 3214 if (!pktin)
3215 crWaitUntil(pktin);
374330e2 3216
ff3187f6 3217 if (pktin->type != SSH1_SMSG_PUBLIC_KEY) {
6b5cf8b4 3218 bombout(("Public key packet not received"));
7ffdbc1a 3219 crStop(0);
8d5de777 3220 }
374330e2 3221
c5e9c988 3222 logevent("Received public keys");
374330e2 3223
ff3187f6 3224 ptr = ssh_pkt_getdata(pktin, 8);
0016d70b 3225 if (!ptr) {
2e85c969 3226 bombout(("SSH-1 public key packet stopped before random cookie"));
0016d70b 3227 crStop(0);
3228 }
3229 memcpy(cookie, ptr, 8);
374330e2 3230
ff3187f6 3231 if (!ssh1_pkt_getrsakey(pktin, &servkey, &s->keystr1) ||
3232 !ssh1_pkt_getrsakey(pktin, &hostkey, &s->keystr2)) {
2e85c969 3233 bombout(("Failed to read SSH-1 public keys from public key packet"));
0016d70b 3234 crStop(0);
3235 }
374330e2 3236
c5e9c988 3237 /*
1c2a93c4 3238 * Log the host key fingerprint.
c5e9c988 3239 */
c5e9c988 3240 {
3241 char logmsg[80];
1c2a93c4 3242 logevent("Host key fingerprint is:");
c5e9c988 3243 strcpy(logmsg, " ");
32874aea 3244 hostkey.comment = NULL;
3245 rsa_fingerprint(logmsg + strlen(logmsg),
3246 sizeof(logmsg) - strlen(logmsg), &hostkey);
c5e9c988 3247 logevent(logmsg);
3248 }
3249
ff3187f6 3250 ssh->v1_remote_protoflags = ssh_pkt_getuint32(pktin);
3251 s->supported_ciphers_mask = ssh_pkt_getuint32(pktin);
3252 s->supported_auths_mask = ssh_pkt_getuint32(pktin);
d5b2c841 3253 if ((ssh->remote_bugs & BUG_CHOKES_ON_RSA))
3254 s->supported_auths_mask &= ~(1 << SSH1_AUTH_RSA);
bea1ef5f 3255
51470298 3256 ssh->v1_local_protoflags =
3257 ssh->v1_remote_protoflags & SSH1_PROTOFLAGS_SUPPORTED;
3258 ssh->v1_local_protoflags |= SSH1_PROTOFLAG_SCREEN_NUMBER;
b96dc54c 3259
c5e9c988 3260 MD5Init(&md5c);
51470298 3261 MD5Update(&md5c, s->keystr2, hostkey.bytes);
3262 MD5Update(&md5c, s->keystr1, servkey.bytes);
0016d70b 3263 MD5Update(&md5c, cookie, 8);
51470298 3264 MD5Final(s->session_id, &md5c);
374330e2 3265
32874aea 3266 for (i = 0; i < 32; i++)
51470298 3267 ssh->session_key[i] = random_byte();
374330e2 3268
0016d70b 3269 /*
3270 * Verify that the `bits' and `bytes' parameters match.
3271 */
3272 if (hostkey.bits > hostkey.bytes * 8 ||
3273 servkey.bits > servkey.bytes * 8) {
2e85c969 3274 bombout(("SSH-1 public keys were badly formatted"));
0016d70b 3275 crStop(0);
3276 }
3277
51470298 3278 s->len = (hostkey.bytes > servkey.bytes ? hostkey.bytes : servkey.bytes);
374330e2 3279
3d88e64d 3280 s->rsabuf = snewn(s->len, unsigned char);
374330e2 3281
89ee5268 3282 /*
3283 * Verify the host key.
3284 */
3285 {
32874aea 3286 /*
3287 * First format the key into a string.
3288 */
3289 int len = rsastr_len(&hostkey);
3290 char fingerprint[100];
3d88e64d 3291 char *keystr = snewn(len, char);
32874aea 3292 rsastr_fmt(keystr, &hostkey);
3293 rsa_fingerprint(fingerprint, sizeof(fingerprint), &hostkey);
3d9449a1 3294
3295 ssh_set_frozen(ssh, 1);
3296 s->dlgret = verify_ssh_host_key(ssh->frontend,
3297 ssh->savedhost, ssh->savedport,
3298 "rsa", keystr, fingerprint,
3299 ssh_dialog_callback, ssh);
32874aea 3300 sfree(keystr);
3d9449a1 3301 if (s->dlgret < 0) {
3302 do {
3303 crReturn(0);
3304 if (pktin) {
3305 bombout(("Unexpected data from server while waiting"
3306 " for user host key response"));
3307 crStop(0);
3308 }
3309 } while (pktin || inlen > 0);
3310 s->dlgret = ssh->user_response;
3311 }
3312 ssh_set_frozen(ssh, 0);
3313
3314 if (s->dlgret == 0) {
9e296bfa 3315 ssh_disconnect(ssh, "User aborted at host key verification",
3316 NULL, 0, TRUE);
2b3f6c19 3317 crStop(0);
3d9449a1 3318 }
32874aea 3319 }
3320
3321 for (i = 0; i < 32; i++) {
51470298 3322 s->rsabuf[i] = ssh->session_key[i];
374330e2 3323 if (i < 16)
51470298 3324 s->rsabuf[i] ^= s->session_id[i];
374330e2 3325 }
3326
3327 if (hostkey.bytes > servkey.bytes) {
0016d70b 3328 ret = rsaencrypt(s->rsabuf, 32, &servkey);
3329 if (ret)
3330 ret = rsaencrypt(s->rsabuf, servkey.bytes, &hostkey);
374330e2 3331 } else {
0016d70b 3332 ret = rsaencrypt(s->rsabuf, 32, &hostkey);
3333 if (ret)
3334 ret = rsaencrypt(s->rsabuf, hostkey.bytes, &servkey);
3335 }
3336 if (!ret) {
2e85c969 3337 bombout(("SSH-1 public key encryptions failed due to bad formatting"));
0016d70b 3338 crStop(0);
374330e2 3339 }
3340
c5e9c988 3341 logevent("Encrypted session key");
3342
ca20bfcf 3343 {
3344 int cipher_chosen = 0, warn = 0;
3345 char *cipher_string = NULL;
51470298 3346 int i;
ca20bfcf 3347 for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) {
86916870 3348 int next_cipher = ssh->cfg.ssh_cipherlist[i];
ca20bfcf 3349 if (next_cipher == CIPHER_WARN) {
3350 /* If/when we choose a cipher, warn about it */
3351 warn = 1;
3352 } else if (next_cipher == CIPHER_AES) {
3353 /* XXX Probably don't need to mention this. */
2e85c969 3354 logevent("AES not supported in SSH-1, skipping");
ca20bfcf 3355 } else {
3356 switch (next_cipher) {
51470298 3357 case CIPHER_3DES: s->cipher_type = SSH_CIPHER_3DES;
ca20bfcf 3358 cipher_string = "3DES"; break;
51470298 3359 case CIPHER_BLOWFISH: s->cipher_type = SSH_CIPHER_BLOWFISH;
ca20bfcf 3360 cipher_string = "Blowfish"; break;
51470298 3361 case CIPHER_DES: s->cipher_type = SSH_CIPHER_DES;
ca20bfcf 3362 cipher_string = "single-DES"; break;
3363 }
51470298 3364 if (s->supported_ciphers_mask & (1 << s->cipher_type))
ca20bfcf 3365 cipher_chosen = 1;
3366 }
3367 }
3368 if (!cipher_chosen) {
51470298 3369 if ((s->supported_ciphers_mask & (1 << SSH_CIPHER_3DES)) == 0)
2e85c969 3370 bombout(("Server violates SSH-1 protocol by not "
ca20bfcf 3371 "supporting 3DES encryption"));
3372 else
3373 /* shouldn't happen */
6b5cf8b4 3374 bombout(("No supported ciphers found"));
7ffdbc1a 3375 crStop(0);
a99a05c0 3376 }
ca20bfcf 3377
3378 /* Warn about chosen cipher if necessary. */
bb348ab1 3379 if (warn) {
3d9449a1 3380 ssh_set_frozen(ssh, 1);
3381 s->dlgret = askalg(ssh->frontend, "cipher", cipher_string,
3382 ssh_dialog_callback, ssh);
3383 if (s->dlgret < 0) {
3384 do {
3385 crReturn(0);
3386 if (pktin) {
3387 bombout(("Unexpected data from server while waiting"
3388 " for user response"));
3389 crStop(0);
3390 }
3391 } while (pktin || inlen > 0);
3392 s->dlgret = ssh->user_response;
3393 }
3394 ssh_set_frozen(ssh, 0);
3395 if (s->dlgret == 0) {
9e296bfa 3396 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
3397 0, TRUE);
96ccde8b 3398 crStop(0);
3d9449a1 3399 }
bb348ab1 3400 }
bea1ef5f 3401 }
ca20bfcf 3402
51470298 3403 switch (s->cipher_type) {
32874aea 3404 case SSH_CIPHER_3DES:
3405 logevent("Using 3DES encryption");
3406 break;
3407 case SSH_CIPHER_DES:
3408 logevent("Using single-DES encryption");
3409 break;
3410 case SSH_CIPHER_BLOWFISH:
3411 logevent("Using Blowfish encryption");
3412 break;
c5e9c988 3413 }
bea1ef5f 3414
51470298 3415 send_packet(ssh, SSH1_CMSG_SESSION_KEY,
3416 PKT_CHAR, s->cipher_type,
32874aea 3417 PKT_DATA, cookie, 8,
51470298 3418 PKT_CHAR, (s->len * 8) >> 8, PKT_CHAR, (s->len * 8) & 0xFF,
3419 PKT_DATA, s->rsabuf, s->len,
3420 PKT_INT, ssh->v1_local_protoflags, PKT_END);
fb09bf1c 3421
c5e9c988 3422 logevent("Trying to enable encryption...");
374330e2 3423
51470298 3424 sfree(s->rsabuf);
374330e2 3425
51470298 3426 ssh->cipher = (s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
3427 s->cipher_type == SSH_CIPHER_DES ? &ssh_des :
3428 &ssh_3des);
371e569c 3429 ssh->v1_cipher_ctx = ssh->cipher->make_context();
3430 ssh->cipher->sesskey(ssh->v1_cipher_ctx, ssh->session_key);
57356d63 3431 logeventf(ssh, "Initialised %s encryption", ssh->cipher->text_name);
374330e2 3432
0183b242 3433 ssh->crcda_ctx = crcda_make_context();
3434 logevent("Installing CRC compensation attack detector");
3435
679539d7 3436 if (servkey.modulus) {
3437 sfree(servkey.modulus);
3438 servkey.modulus = NULL;
3439 }
3440 if (servkey.exponent) {
3441 sfree(servkey.exponent);
3442 servkey.exponent = NULL;
3443 }
3444 if (hostkey.modulus) {
3445 sfree(hostkey.modulus);
3446 hostkey.modulus = NULL;
3447 }
3448 if (hostkey.exponent) {
3449 sfree(hostkey.exponent);
3450 hostkey.exponent = NULL;
3451 }
ff3187f6 3452 crWaitUntil(pktin);
374330e2 3453
ff3187f6 3454 if (pktin->type != SSH1_SMSG_SUCCESS) {
6b5cf8b4 3455 bombout(("Encryption not successfully enabled"));
7ffdbc1a 3456 crStop(0);
8d5de777 3457 }
374330e2 3458
c5e9c988 3459 logevent("Successfully started encryption");
3460
edd0cb8a 3461 fflush(stdout); /* FIXME eh? */
374330e2 3462 {
471c20b0 3463 if (!get_remote_username(&ssh->cfg, s->username,
3464 sizeof(s->username))) {
edd0cb8a 3465 int ret; /* need not be kept over crReturn */
3466 s->cur_prompt = new_prompts(ssh->frontend);
3467 s->cur_prompt->to_server = TRUE;
3468 s->cur_prompt->name = dupstr("SSH login name");
3469 add_prompt(s->cur_prompt, dupstr("login as: "), TRUE,
3470 lenof(s->username));
3471 ret = get_userpass_input(s->cur_prompt, NULL, 0);
3472 while (ret < 0) {
51470298 3473 ssh->send_ok = 1;
edd0cb8a 3474 crWaitUntil(!pktin);
3475 ret = get_userpass_input(s->cur_prompt, in, inlen);
3476 ssh->send_ok = 0;
3477 }
3478 if (!ret) {
3479 /*
3480 * Failed to get a username. Terminate.
3481 */
3482 free_prompts(s->cur_prompt);
3483 ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
3484 crStop(0);
32874aea 3485 }
edd0cb8a 3486 memcpy(s->username, s->cur_prompt->prompts[0]->result,
3487 lenof(s->username));
3488 free_prompts(s->cur_prompt);
374330e2 3489 }
fb09bf1c 3490
51470298 3491 send_packet(ssh, SSH1_CMSG_USER, PKT_STR, s->username, PKT_END);
c5e9c988 3492 {
edd0cb8a 3493 char *userlog = dupprintf("Sent username \"%s\"", s->username);
c5e9c988 3494 logevent(userlog);
32874aea 3495 if (flags & FLAG_INTERACTIVE &&
3496 (!((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)))) {
51470298 3497 c_write_str(ssh, userlog);
edd0cb8a 3498 c_write_str(ssh, "\r\n");
3c8e959b 3499 }
edd0cb8a 3500 sfree(userlog);
c5e9c988 3501 }
374330e2 3502 }
3503
ff3187f6 3504 crWaitUntil(pktin);
374330e2 3505
d5b2c841 3506 if ((s->supported_auths_mask & (1 << SSH1_AUTH_RSA)) == 0) {
0df73905 3507 /* We must not attempt PK auth. Pretend we've already tried it. */
51470298 3508 s->tried_publickey = s->tried_agent = 1;
0df73905 3509 } else {
51470298 3510 s->tried_publickey = s->tried_agent = 0;
0df73905 3511 }
51470298 3512 s->tis_auth_refused = s->ccard_auth_refused = 0;
edd0cb8a 3513 /*
3514 * Load the public half of any configured keyfile for later use.
3515 */
9a30e26b 3516 if (!filename_is_null(ssh->cfg.keyfile)) {
edd0cb8a 3517 int keytype;
3518 logeventf(ssh, "Reading private key file \"%.150s\"",
3519 filename_to_str(&ssh->cfg.keyfile));
3520 keytype = key_type(&ssh->cfg.keyfile);
3521 if (keytype == SSH_KEYTYPE_SSH1) {
3522 const char *error;
3523 if (rsakey_pubblob(&ssh->cfg.keyfile,
3524 &s->publickey_blob, &s->publickey_bloblen,
3525 &s->publickey_comment, &error)) {
3526 s->publickey_encrypted = rsakey_encrypted(&ssh->cfg.keyfile,
3527 NULL);
3528 } else {
3529 char *msgbuf;
3530 logeventf(ssh, "Unable to load private key (%s)", error);
3531 msgbuf = dupprintf("Unable to load private key file "
3532 "\"%.150s\" (%s)\r\n",
3533 filename_to_str(&ssh->cfg.keyfile),
3534 error);
3535 c_write_str(ssh, msgbuf);
3536 sfree(msgbuf);
3537 s->publickey_blob = NULL;
3538 }
3539 } else {
3540 char *msgbuf;
3541 logeventf(ssh, "Unable to use this key file (%s)",
3542 key_type_to_str(keytype));
3543 msgbuf = dupprintf("Unable to use key file \"%.150s\""
3544 " (%s)\r\n",
3545 filename_to_str(&ssh->cfg.keyfile),
3546 key_type_to_str(keytype));
3547 c_write_str(ssh, msgbuf);
3548 sfree(msgbuf);
51470298 3549 s->publickey_blob = NULL;
edd0cb8a 3550 }
396778f1 3551 } else
51470298 3552 s->publickey_blob = NULL;
7cca0d81 3553
ff3187f6 3554 while (pktin->type == SSH1_SMSG_FAILURE) {
51470298 3555 s->pwpkt_type = SSH1_CMSG_AUTH_PASSWORD;
614a20a0 3556
973612f5 3557 if (ssh->cfg.tryagent && agent_exists() && !s->tried_agent) {
32874aea 3558 /*
3559 * Attempt RSA authentication using Pageant.
3560 */
32874aea 3561 void *r;
3562
51470298 3563 s->authed = FALSE;
3564 s->tried_agent = 1;
32874aea 3565 logevent("Pageant is running. Requesting keys.");
3566
3567 /* Request the keys held by the agent. */
51470298 3568 PUT_32BIT(s->request, 1);
3569 s->request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;
839f10db 3570 if (!agent_query(s->request, 5, &r, &s->responselen,
3571 ssh_agent_callback, ssh)) {
3572 do {
3573 crReturn(0);
ff3187f6 3574 if (pktin) {
839f10db 3575 bombout(("Unexpected data from server while waiting"
3576 " for agent response"));
3577 crStop(0);
3578 }
ff3187f6 3579 } while (pktin || inlen > 0);
839f10db 3580 r = ssh->agent_response;
3581 s->responselen = ssh->agent_response_len;
3582 }
51470298 3583 s->response = (unsigned char *) r;
3584 if (s->response && s->responselen >= 5 &&
3585 s->response[4] == SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
3586 s->p = s->response + 5;
3587 s->nkeys = GET_32BIT(s->p);
3588 s->p += 4;
2e85c969 3589 logeventf(ssh, "Pageant has %d SSH-1 keys", s->nkeys);
51470298 3590 for (s->keyi = 0; s->keyi < s->nkeys; s->keyi++) {
94cd7c3a 3591 unsigned char *pkblob = s->p;
51470298 3592 s->p += 4;
0016d70b 3593 {
3594 int n, ok = FALSE;
3595 do { /* do while (0) to make breaking easy */
3596 n = ssh1_read_bignum
3597 (s->p, s->responselen-(s->p-s->response),
3598 &s->key.exponent);
3599 if (n < 0)
3600 break;
3601 s->p += n;
3602 n = ssh1_read_bignum
3603 (s->p, s->responselen-(s->p-s->response),
3604 &s->key.modulus);
3605 if (n < 0)
3606 break;
3607 s->p += n;
3608 if (s->responselen - (s->p-s->response) < 4)
3609 break;
3610 s->commentlen = GET_32BIT(s->p);
3611 s->p += 4;
3612 if (s->responselen - (s->p-s->response) <
3613 s->commentlen)
3614 break;
3615 s->commentp = (char *)s->p;
3616 s->p += s->commentlen;
3617 ok = TRUE;
3618 } while (0);
3619 if (!ok) {
3620 logevent("Pageant key list packet was truncated");
3621 break;
3622 }
3623 }
94cd7c3a 3624 if (s->publickey_blob) {
3625 if (!memcmp(pkblob, s->publickey_blob,
3626 s->publickey_bloblen)) {
3627 logeventf(ssh, "Pageant key #%d matches "
3628 "configured key file", s->keyi);
3629 s->tried_publickey = 1;
3630 } else
3631 /* Skip non-configured key */
3632 continue;
3633 }
3634 logeventf(ssh, "Trying Pageant key #%d", s->keyi);
51470298 3635 send_packet(ssh, SSH1_CMSG_AUTH_RSA,
3636 PKT_BIGNUM, s->key.modulus, PKT_END);
ff3187f6 3637 crWaitUntil(pktin);
3638 if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
32874aea 3639 logevent("Key refused");
3640 continue;
3641 }
3642 logevent("Received RSA challenge");
ff3187f6 3643 if ((s->challenge = ssh1_pkt_getmp(pktin)) == NULL) {
0016d70b 3644 bombout(("Server's RSA challenge was badly formatted"));
3645 crStop(0);
3646 }
3647
32874aea 3648 {
3649 char *agentreq, *q, *ret;
2d466ffd 3650 void *vret;
32874aea 3651 int len, retlen;
3652 len = 1 + 4; /* message type, bit count */
51470298 3653 len += ssh1_bignum_length(s->key.exponent);
3654 len += ssh1_bignum_length(s->key.modulus);
3655 len += ssh1_bignum_length(s->challenge);
32874aea 3656 len += 16; /* session id */
3657 len += 4; /* response format */
3d88e64d 3658 agentreq = snewn(4 + len, char);
32874aea 3659 PUT_32BIT(agentreq, len);
3660 q = agentreq + 4;
3661 *q++ = SSH1_AGENTC_RSA_CHALLENGE;
51470298 3662 PUT_32BIT(q, bignum_bitcount(s->key.modulus));
32874aea 3663 q += 4;
51470298 3664 q += ssh1_write_bignum(q, s->key.exponent);
3665 q += ssh1_write_bignum(q, s->key.modulus);
3666 q += ssh1_write_bignum(q, s->challenge);
3667 memcpy(q, s->session_id, 16);
32874aea 3668 q += 16;
3669 PUT_32BIT(q, 1); /* response format */
839f10db 3670 if (!agent_query(agentreq, len + 4, &vret, &retlen,
3671 ssh_agent_callback, ssh)) {
3672 sfree(agentreq);
3673 do {
3674 crReturn(0);
ff3187f6 3675 if (pktin) {
839f10db 3676 bombout(("Unexpected data from server"
3677 " while waiting for agent"
3678 " response"));
3679 crStop(0);
3680 }
ff3187f6 3681 } while (pktin || inlen > 0);
839f10db 3682 vret = ssh->agent_response;
3683 retlen = ssh->agent_response_len;
3684 } else
3685 sfree(agentreq);
2d466ffd 3686 ret = vret;
32874aea 3687 if (ret) {
3688 if (ret[4] == SSH1_AGENT_RSA_RESPONSE) {
3689 logevent("Sending Pageant's response");
51470298 3690 send_packet(ssh, SSH1_CMSG_AUTH_RSA_RESPONSE,
32874aea 3691 PKT_DATA, ret + 5, 16,
3692 PKT_END);
3693 sfree(ret);
ff3187f6 3694 crWaitUntil(pktin);
3695 if (pktin->type == SSH1_SMSG_SUCCESS) {
32874aea 3696 logevent
3697 ("Pageant's response accepted");
3698 if (flags & FLAG_VERBOSE) {
51470298 3699 c_write_str(ssh, "Authenticated using"
3700 " RSA key \"");
3701 c_write(ssh, s->commentp,
3702 s->commentlen);
3703 c_write_str(ssh, "\" from agent\r\n");
32874aea 3704 }
51470298 3705 s->authed = TRUE;
32874aea 3706 } else
3707 logevent
3708 ("Pageant's response not accepted");
3709 } else {
3710 logevent
3711 ("Pageant failed to answer challenge");
3712 sfree(ret);
3713 }
3714 } else {
3715 logevent("No reply received from Pageant");
3716 }
3717 }
51470298 3718 freebn(s->key.exponent);
3719 freebn(s->key.modulus);
3720 freebn(s->challenge);
3721 if (s->authed)
32874aea 3722 break;
3723 }
29b1d0b3 3724 sfree(s->response);
94cd7c3a 3725 if (s->publickey_blob && !s->tried_publickey)
3726 logevent("Configured key file not in Pageant");
32874aea 3727 }
51470298 3728 if (s->authed)
32874aea 3729 break;
3730 }
edd0cb8a 3731 if (s->publickey_blob && !s->tried_publickey) {
3732 /*
3733 * Try public key authentication with the specified
3734 * key file.
3735 */
3736 int got_passphrase; /* need not be kept over crReturn */
3737 if (flags & FLAG_VERBOSE)
3738 c_write_str(ssh, "Trying public key authentication.\r\n");
3739 logeventf(ssh, "Trying public key \"%s\"",
3740 filename_to_str(&ssh->cfg.keyfile));
3741 s->tried_publickey = 1;
3742 got_passphrase = FALSE;
3743 while (!got_passphrase) {
3744 /*
3745 * Get a passphrase, if necessary.
3746 */
3747 char *passphrase = NULL; /* only written after crReturn */
3748 const char *error;
3749 if (!s->publickey_encrypted) {
3750 if (flags & FLAG_VERBOSE)
3751 c_write_str(ssh, "No passphrase required.\r\n");
3752 passphrase = NULL;
3753 } else {
3754 int ret; /* need not be kept over crReturn */
3755 s->cur_prompt = new_prompts(ssh->frontend);
3756 s->cur_prompt->to_server = FALSE;
3757 s->cur_prompt->name = dupstr("SSH key passphrase");
3758 add_prompt(s->cur_prompt,
3759 dupprintf("Passphrase for key \"%.100s\": ",
3760 s->publickey_comment),
3761 FALSE, SSH_MAX_PASSWORD_LEN);
3762 ret = get_userpass_input(s->cur_prompt, NULL, 0);
3763 while (ret < 0) {
3764 ssh->send_ok = 1;
3765 crWaitUntil(!pktin);
3766 ret = get_userpass_input(s->cur_prompt, in, inlen);
3767 ssh->send_ok = 0;
3768 }
3769 if (!ret) {
3770 /* Failed to get a passphrase. Terminate. */
3771 free_prompts(s->cur_prompt);
3772 ssh_disconnect(ssh, NULL, "Unable to authenticate",
3773 0, TRUE);
3774 crStop(0);
3775 }
3776 passphrase = dupstr(s->cur_prompt->prompts[0]->result);
3777 free_prompts(s->cur_prompt);
3778 }
3779 /*
3780 * Try decrypting key with passphrase.
3781 */
3782 ret = loadrsakey(&ssh->cfg.keyfile, &s->key, passphrase,
3783 &error);
3784 if (passphrase) {
3785 memset(passphrase, 0, strlen(passphrase));
3786 sfree(passphrase);
3787 }
3788 if (ret == 1) {
3789 /* Correct passphrase. */
3790 got_passphrase = TRUE;
3791 } else if (ret == 0) {
3792 c_write_str(ssh, "Couldn't load private key from ");
3793 c_write_str(ssh, filename_to_str(&ssh->cfg.keyfile));
3794 c_write_str(ssh, " (");
3795 c_write_str(ssh, error);
3796 c_write_str(ssh, ").\r\n");
3797 got_passphrase = FALSE;
3798 break; /* go and try something else */
3799 } else if (ret == -1) {
3800 c_write_str(ssh, "Wrong passphrase.\r\n"); /* FIXME */
edd0cb8a 3801 got_passphrase = FALSE;
3802 /* and try again */
43536490 3803 } else {
3804 assert(0 && "unexpected return from loadrsakey()");
edc23a8a 3805 got_passphrase = FALSE; /* placate optimisers */
edd0cb8a 3806 }
3807 }
3808
3809 if (got_passphrase) {
3810
3811 /*
3812 * Send a public key attempt.
3813 */
3814 send_packet(ssh, SSH1_CMSG_AUTH_RSA,
3815 PKT_BIGNUM, s->key.modulus, PKT_END);
3816
3817 crWaitUntil(pktin);
3818 if (pktin->type == SSH1_SMSG_FAILURE) {
3819 c_write_str(ssh, "Server refused our public key.\r\n");
7b575324 3820 continue; /* go and try something else */
edd0cb8a 3821 }
3822 if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
3823 bombout(("Bizarre response to offer of public key"));
3824 crStop(0);
3825 }
3826
3827 {
3828 int i;
3829 unsigned char buffer[32];
3830 Bignum challenge, response;
3831
3832 if ((challenge = ssh1_pkt_getmp(pktin)) == NULL) {
3833 bombout(("Server's RSA challenge was badly formatted"));
3834 crStop(0);
3835 }
3836 response = rsadecrypt(challenge, &s->key);
3837 freebn(s->key.private_exponent);/* burn the evidence */
3838
3839 for (i = 0; i < 32; i++) {
3840 buffer[i] = bignum_byte(response, 31 - i);
3841 }
3842
3843 MD5Init(&md5c);
3844 MD5Update(&md5c, buffer, 32);
3845 MD5Update(&md5c, s->session_id, 16);
3846 MD5Final(buffer, &md5c);
3847
3848 send_packet(ssh, SSH1_CMSG_AUTH_RSA_RESPONSE,
3849 PKT_DATA, buffer, 16, PKT_END);
3850
3851 freebn(challenge);
3852 freebn(response);
3853 }
3854
3855 crWaitUntil(pktin);
3856 if (pktin->type == SSH1_SMSG_FAILURE) {
3857 if (flags & FLAG_VERBOSE)
3858 c_write_str(ssh, "Failed to authenticate with"
3859 " our public key.\r\n");
7b575324 3860 continue; /* go and try something else */
edd0cb8a 3861 } else if (pktin->type != SSH1_SMSG_SUCCESS) {
3862 bombout(("Bizarre response to RSA authentication response"));
3863 crStop(0);
3864 }
3865
3866 break; /* we're through! */
3867 }
3868
3869 }
3870
3871 /*
3872 * Otherwise, try various forms of password-like authentication.
3873 */
3874 s->cur_prompt = new_prompts(ssh->frontend);
32874aea 3875
86916870 3876 if (ssh->cfg.try_tis_auth &&
51470298 3877 (s->supported_auths_mask & (1 << SSH1_AUTH_TIS)) &&
3878 !s->tis_auth_refused) {
3879 s->pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
32874aea 3880 logevent("Requested TIS authentication");
51470298 3881 send_packet(ssh, SSH1_CMSG_AUTH_TIS, PKT_END);
ff3187f6 3882 crWaitUntil(pktin);
3883 if (pktin->type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
32874aea 3884 logevent("TIS authentication declined");
3885 if (flags & FLAG_INTERACTIVE)
51470298 3886 c_write_str(ssh, "TIS authentication refused.\r\n");
3887 s->tis_auth_refused = 1;
614a20a0 3888 continue;
32874aea 3889 } else {
0016d70b 3890 char *challenge;
3891 int challengelen;
edd0cb8a 3892 char *instr_suf, *prompt;
0016d70b 3893
ff3187f6 3894 ssh_pkt_getstring(pktin, &challenge, &challengelen);
0016d70b 3895 if (!challenge) {
3896 bombout(("TIS challenge packet was badly formed"));
3897 crStop(0);
3898 }
32874aea 3899 logevent("Received TIS challenge");
edd0cb8a 3900 s->cur_prompt->to_server = TRUE;
3901 s->cur_prompt->name = dupstr("SSH TIS authentication");
614a20a0 3902 /* Prompt heuristic comes from OpenSSH */
edd0cb8a 3903 if (memchr(challenge, '\n', challengelen)) {
3904 instr_suf = dupstr("");
3905 prompt = dupprintf("%.*s", challengelen, challenge);
3906 } else {
3907 instr_suf = dupprintf("%.*s", challengelen, challenge);
3908 prompt = dupstr("Response: ");
3909 }
3910 s->cur_prompt->instruction =
3911 dupprintf("Using TIS authentication.%s%s",
3912 (*instr_suf) ? "\n" : "",
3913 instr_suf);
3914 s->cur_prompt->instr_reqd = TRUE;
3915 add_prompt(s->cur_prompt, prompt, FALSE, SSH_MAX_PASSWORD_LEN);
3916 sfree(instr_suf);
32874aea 3917 }
3918 }
86916870 3919 if (ssh->cfg.try_tis_auth &&
51470298 3920 (s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
3921 !s->ccard_auth_refused) {
3922 s->pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
32874aea 3923 logevent("Requested CryptoCard authentication");
51470298 3924 send_packet(ssh, SSH1_CMSG_AUTH_CCARD, PKT_END);
ff3187f6 3925 crWaitUntil(pktin);
3926 if (pktin->type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
32874aea 3927 logevent("CryptoCard authentication declined");
51470298 3928 c_write_str(ssh, "CryptoCard authentication refused.\r\n");
3929 s->ccard_auth_refused = 1;
614a20a0 3930 continue;
32874aea 3931 } else {
0016d70b 3932 char *challenge;
3933 int challengelen;
edd0cb8a 3934 char *instr_suf, *prompt;
0016d70b 3935
ff3187f6 3936 ssh_pkt_getstring(pktin, &challenge, &challengelen);
0016d70b 3937 if (!challenge) {
3938 bombout(("CryptoCard challenge packet was badly formed"));
3939 crStop(0);
3940 }
32874aea 3941 logevent("Received CryptoCard challenge");
edd0cb8a 3942 s->cur_prompt->to_server = TRUE;
3943 s->cur_prompt->name = dupstr("SSH CryptoCard authentication");
3944 s->cur_prompt->name_reqd = FALSE;
3945 /* Prompt heuristic comes from OpenSSH */
3946 if (memchr(challenge, '\n', challengelen)) {
3947 instr_suf = dupstr("");
3948 prompt = dupprintf("%.*s", challengelen, challenge);
3949 } else {
3950 instr_suf = dupprintf("%.*s", challengelen, challenge);
3951 prompt = dupstr("Response: ");
3952 }
3953 s->cur_prompt->instruction =
3954 dupprintf("Using CryptoCard authentication.%s%s",
3955 (*instr_suf) ? "\n" : "",
3956 instr_suf);
3957 s->cur_prompt->instr_reqd = TRUE;
3958 add_prompt(s->cur_prompt, prompt, FALSE, SSH_MAX_PASSWORD_LEN);
3959 sfree(instr_suf);
32874aea 3960 }
3961 }
51470298 3962 if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
8f9e3231 3963 if ((s->supported_auths_mask & (1 << SSH1_AUTH_PASSWORD)) == 0) {
3964 bombout(("No supported authentication methods available"));
3965 crStop(0);
3966 }
edd0cb8a 3967 s->cur_prompt->to_server = TRUE;
3968 s->cur_prompt->name = dupstr("SSH password");
3969 add_prompt(s->cur_prompt, dupprintf("%.90s@%.90s's password: ",
3970 s->username, ssh->savedhost),
3971 FALSE, SSH_MAX_PASSWORD_LEN);
32874aea 3972 }
a52f067e 3973
614a20a0 3974 /*
3975 * Show password prompt, having first obtained it via a TIS
3976 * or CryptoCard exchange if we're doing TIS or CryptoCard
3977 * authentication.
3978 */
edd0cb8a 3979 {
3980 int ret; /* need not be kept over crReturn */
3981 ret = get_userpass_input(s->cur_prompt, NULL, 0);
3982 while (ret < 0) {
3983 ssh->send_ok = 1;
3984 crWaitUntil(!pktin);
3985 ret = get_userpass_input(s->cur_prompt, in, inlen);
3986 ssh->send_ok = 0;
3987 }
3988 if (!ret) {
32874aea 3989 /*
edd0cb8a 3990 * Failed to get a password (for example
32874aea 3991 * because one was supplied on the command line
3992 * which has already failed to work). Terminate.
3993 */
edd0cb8a 3994 free_prompts(s->cur_prompt);
3995 ssh_disconnect(ssh, NULL, "Unable to authenticate", 0, TRUE);
3996 crStop(0);
32874aea 3997 }
32874aea 3998 }
3999
edd0cb8a 4000 if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
32874aea 4001 /*
edd0cb8a 4002 * Defence against traffic analysis: we send a
4003 * whole bunch of packets containing strings of
4004 * different lengths. One of these strings is the
4005 * password, in a SSH1_CMSG_AUTH_PASSWORD packet.
4006 * The others are all random data in
4007 * SSH1_MSG_IGNORE packets. This way a passive
4008 * listener can't tell which is the password, and
4009 * hence can't deduce the password length.
4010 *
4011 * Anybody with a password length greater than 16
4012 * bytes is going to have enough entropy in their
4013 * password that a listener won't find it _that_
4014 * much help to know how long it is. So what we'll
4015 * do is:
4016 *
4017 * - if password length < 16, we send 15 packets
4018 * containing string lengths 1 through 15
4019 *
4020 * - otherwise, we let N be the nearest multiple
4021 * of 8 below the password length, and send 8
4022 * packets containing string lengths N through
4023 * N+7. This won't obscure the order of
4024 * magnitude of the password length, but it will
4025 * introduce a bit of extra uncertainty.
4026 *
bf982899 4027 * A few servers can't deal with SSH1_MSG_IGNORE, at
4028 * least in this context. For these servers, we need
4029 * an alternative defence. We make use of the fact
4030 * that the password is interpreted as a C string:
4031 * so we can append a NUL, then some random data.
edd0cb8a 4032 *
bf982899 4033 * A few servers can deal with neither SSH1_MSG_IGNORE
4034 * here _nor_ a padded password string.
4035 * For these servers we are left with no defences
edd0cb8a 4036 * against password length sniffing.
32874aea 4037 */
bf982899 4038 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE) &&
4039 !(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
32874aea 4040 /*
edd0cb8a 4041 * The server can deal with SSH1_MSG_IGNORE, so
4042 * we can use the primary defence.
32874aea 4043 */
edd0cb8a 4044 int bottom, top, pwlen, i;
4045 char *randomstr;
32874aea 4046
edd0cb8a 4047 pwlen = strlen(s->cur_prompt->prompts[0]->result);
4048 if (pwlen < 16) {
4049 bottom = 0; /* zero length passwords are OK! :-) */
4050 top = 15;
4051 } else {
4052 bottom = pwlen & ~7;
4053 top = bottom + 7;
4054 }
32874aea 4055
edd0cb8a 4056 assert(pwlen >= bottom && pwlen <= top);
32874aea 4057
edd0cb8a 4058 randomstr = snewn(top + 1, char);
32874aea 4059
edd0cb8a 4060 for (i = bottom; i <= top; i++) {
4061 if (i == pwlen) {
4062 defer_packet(ssh, s->pwpkt_type,
4063 PKTT_PASSWORD, PKT_STR,
4064 s->cur_prompt->prompts[0]->result,
4065 PKTT_OTHER, PKT_END);
4066 } else {
4067 for (j = 0; j < i; j++) {
4068 do {
4069 randomstr[j] = random_byte();
4070 } while (randomstr[j] == '\0');
32874aea 4071 }
edd0cb8a 4072 randomstr[i] = '\0';
4073 defer_packet(ssh, SSH1_MSG_IGNORE,
4074 PKT_STR, randomstr, PKT_END);
32874aea 4075 }
edd0cb8a 4076 }
4077 logevent("Sending password with camouflage packets");
4078 ssh_pkt_defersend(ssh);
4079 sfree(randomstr);
4080 }
4081 else if (!(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
4082 /*
4083 * The server can't deal with SSH1_MSG_IGNORE
4084 * but can deal with padded passwords, so we
4085 * can use the secondary defence.
4086 */
4087 char string[64];
4088 char *ss;
4089 int len;
4090
4091 len = strlen(s->cur_prompt->prompts[0]->result);
4092 if (len < sizeof(string)) {
4093 ss = string;
4094 strcpy(string, s->cur_prompt->prompts[0]->result);
4095 len++; /* cover the zero byte */
4096 while (len < sizeof(string)) {
4097 string[len++] = (char) random_byte();
bd358db1 4098 }
bd358db1 4099 } else {
edd0cb8a 4100 ss = s->cur_prompt->prompts[0]->result;
32874aea 4101 }
edd0cb8a 4102 logevent("Sending length-padded password");
9a10ecf4 4103 send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
edd0cb8a 4104 PKT_INT, len, PKT_DATA, ss, len,
4105 PKTT_OTHER, PKT_END);
4106 } else {
4107 /*
bf982899 4108 * The server is believed unable to cope with
4109 * any of our password camouflage methods.
edd0cb8a 4110 */
4111 int len;
4112 len = strlen(s->cur_prompt->prompts[0]->result);
4113 logevent("Sending unpadded password");
4114 send_packet(ssh, s->pwpkt_type,
4115 PKTT_PASSWORD, PKT_INT, len,
4116 PKT_DATA, s->cur_prompt->prompts[0]->result, len,
4117 PKTT_OTHER, PKT_END);
32874aea 4118 }
edd0cb8a 4119 } else {
4120 send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
4121 PKT_STR, s->cur_prompt->prompts[0]->result,
4122 PKTT_OTHER, PKT_END);
32874aea 4123 }
c5e9c988 4124 logevent("Sent password");
edd0cb8a 4125 free_prompts(s->cur_prompt);
ff3187f6 4126 crWaitUntil(pktin);
4127 if (pktin->type == SSH1_SMSG_FAILURE) {
32874aea 4128 if (flags & FLAG_VERBOSE)
51470298 4129 c_write_str(ssh, "Access denied\r\n");
c5e9c988 4130 logevent("Authentication refused");
ff3187f6 4131 } else if (pktin->type != SSH1_SMSG_SUCCESS) {
4132 bombout(("Strange packet received, type %d", pktin->type));
7ffdbc1a 4133 crStop(0);
374330e2 4134 }
4135 }
4136
edd0cb8a 4137 /* Clear up */
4138 if (s->publickey_blob) {
4139 sfree(s->publickey_blob);
4140 sfree(s->publickey_comment);
4141 }
4142
c5e9c988 4143 logevent("Authentication successful");
4144
fb09bf1c 4145 crFinish(1);
4146}
4147
32874aea 4148void sshfwd_close(struct ssh_channel *c)
4149{
51470298 4150 Ssh ssh = c->ssh;
4151
1ef619ae 4152 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 4153 return;
36f94d1f 4154
80e48603 4155 if (c && !c->closes) {
4ed34d25 4156 /*
64d6ff88 4157 * If halfopen is true, we have sent
4ed34d25 4158 * CHANNEL_OPEN for this channel, but it hasn't even been
4159 * acknowledged by the server. So we must set a close flag
4160 * on it now, and then when the server acks the channel
4161 * open, we can close it then.
4162 */
64d6ff88 4163 if (!c->halfopen) {
51470298 4164 if (ssh->version == 1) {
4165 send_packet(ssh, SSH1_MSG_CHANNEL_CLOSE, PKT_INT, c->remoteid,
4ed34d25 4166 PKT_END);
4167 } else {
ff3187f6 4168 struct Packet *pktout;
4169 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
4170 ssh2_pkt_adduint32(pktout, c->remoteid);
4171 ssh2_pkt_send(ssh, pktout);
4ed34d25 4172 }
32874aea 4173 }
0357890f 4174 c->closes = 1; /* sent MSG_CLOSE */
32874aea 4175 if (c->type == CHAN_X11) {
4176 c->u.x11.s = NULL;
d74d141c 4177 logevent("Forwarded X11 connection terminated");
4ed34d25 4178 } else if (c->type == CHAN_SOCKDATA ||
4179 c->type == CHAN_SOCKDATA_DORMANT) {
d74d141c 4180 c->u.pfd.s = NULL;
4181 logevent("Forwarded port closed");
32874aea 4182 }
4183 }
4184}
4185
5471d09a 4186int sshfwd_write(struct ssh_channel *c, char *buf, int len)
32874aea 4187{
51470298 4188 Ssh ssh = c->ssh;
4189
1ef619ae 4190 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 4191 return 0;
36f94d1f 4192
51470298 4193 if (ssh->version == 1) {
4194 send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
32874aea 4195 PKT_INT, c->remoteid,
a2724fba 4196 PKT_INT, len, PKTT_DATA, PKT_DATA, buf, len,
9a10ecf4 4197 PKTT_OTHER, PKT_END);
5471d09a 4198 /*
2e85c969 4199 * In SSH-1 we can return 0 here - implying that forwarded
5471d09a 4200 * connections are never individually throttled - because
4201 * the only circumstance that can cause throttling will be
4202 * the whole SSH connection backing up, in which case
4203 * _everything_ will be throttled as a whole.
4204 */
4205 return 0;
783415f8 4206 } else {
32874aea 4207 ssh2_add_channel_data(c, buf, len);
5471d09a 4208 return ssh2_try_send(c);
4209 }
4210}
4211
4212void sshfwd_unthrottle(struct ssh_channel *c, int bufsize)
4213{
51470298 4214 Ssh ssh = c->ssh;
ff68564b 4215 int buflimit;
51470298 4216
1ef619ae 4217 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 4218 return;
36f94d1f 4219
51470298 4220 if (ssh->version == 1) {
ff68564b 4221 buflimit = SSH1_BUFFER_LIMIT;
5471d09a 4222 } else {
ff68564b 4223 buflimit = c->v.v2.locmaxwin;
4224 ssh2_set_window(c, bufsize < buflimit ? buflimit - bufsize : 0);
4225 }
4226 if (c->throttling_conn && bufsize <= buflimit) {
4227 c->throttling_conn = 0;
4228 ssh_throttle_conn(ssh, -1);
783415f8 4229 }
9c964e85 4230}
4231
06fadff5 4232static void ssh_queueing_handler(Ssh ssh, struct Packet *pktin)
4233{
4234 struct queued_handler *qh = ssh->qhead;
4235
4236 assert(qh != NULL);
4237
4238 assert(pktin->type == qh->msg1 || pktin->type == qh->msg2);
4239
4240 if (qh->msg1 > 0) {
4241 assert(ssh->packet_dispatch[qh->msg1] == ssh_queueing_handler);
4242 ssh->packet_dispatch[qh->msg1] = NULL;
4243 }
4244 if (qh->msg2 > 0) {
4245 assert(ssh->packet_dispatch[qh->msg2] == ssh_queueing_handler);
4246 ssh->packet_dispatch[qh->msg2] = NULL;
4247 }
4248
4249 if (qh->next) {
4250 ssh->qhead = qh->next;
4251
4252 if (ssh->qhead->msg1 > 0) {
4253 assert(ssh->packet_dispatch[ssh->qhead->msg1] == NULL);
4254 ssh->packet_dispatch[ssh->qhead->msg1] = ssh_queueing_handler;
4255 }
4256 if (ssh->qhead->msg2 > 0) {
4257 assert(ssh->packet_dispatch[ssh->qhead->msg2] == NULL);
4258 ssh->packet_dispatch[ssh->qhead->msg2] = ssh_queueing_handler;
4259 }
4260 } else {
4261 ssh->qhead = ssh->qtail = NULL;
4262 ssh->packet_dispatch[pktin->type] = NULL;
4263 }
4264
4265 qh->handler(ssh, pktin, qh->ctx);
4266
4267 sfree(qh);
4268}
4269
4270static void ssh_queue_handler(Ssh ssh, int msg1, int msg2,
4271 chandler_fn_t handler, void *ctx)
4272{
4273 struct queued_handler *qh;
4274
4275 qh = snew(struct queued_handler);
4276 qh->msg1 = msg1;
4277 qh->msg2 = msg2;
4278 qh->handler = handler;
4279 qh->ctx = ctx;
4280 qh->next = NULL;
4281
4282 if (ssh->qtail == NULL) {
4283 ssh->qhead = qh;
4284
4285 if (qh->msg1 > 0) {
4286 assert(ssh->packet_dispatch[qh->msg1] == NULL);
4287 ssh->packet_dispatch[qh->msg1] = ssh_queueing_handler;
4288 }
4289 if (qh->msg2 > 0) {
4290 assert(ssh->packet_dispatch[qh->msg2] == NULL);
4291 ssh->packet_dispatch[qh->msg2] = ssh_queueing_handler;
4292 }
4293 } else {
4294 ssh->qtail->next = qh;
4295 }
4296 ssh->qtail = qh;
4297}
4298
4299static void ssh_rportfwd_succfail(Ssh ssh, struct Packet *pktin, void *ctx)
4300{
4301 struct ssh_rportfwd *rpf, *pf = (struct ssh_rportfwd *)ctx;
4302
4303 if (pktin->type == (ssh->version == 1 ? SSH1_SMSG_SUCCESS :
4304 SSH2_MSG_REQUEST_SUCCESS)) {
4305 logeventf(ssh, "Remote port forwarding from %s enabled",
4306 pf->sportdesc);
4307 } else {
4308 logeventf(ssh, "Remote port forwarding from %s refused",
4309 pf->sportdesc);
4310
4311 rpf = del234(ssh->rportfwds, pf);
4312 assert(rpf == pf);
fda2feb1 4313 free_rportfwd(pf);
06fadff5 4314 }
4315}
4316
4317static void ssh_setup_portfwd(Ssh ssh, const Config *cfg)
4318{
84328ddb 4319 const char *portfwd_strptr = cfg->portfwd;
4320 struct ssh_portfwd *epf;
4321 int i;
06fadff5 4322
fda2feb1 4323 if (!ssh->portfwds) {
4324 ssh->portfwds = newtree234(ssh_portcmp);
4325 } else {
4326 /*
4327 * Go through the existing port forwardings and tag them
84328ddb 4328 * with status==DESTROY. Any that we want to keep will be
4329 * re-enabled (status==KEEP) as we go through the
4330 * configuration and find out which bits are the same as
4331 * they were before.
fda2feb1 4332 */
4333 struct ssh_portfwd *epf;
4334 int i;
4335 for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
84328ddb 4336 epf->status = DESTROY;
fda2feb1 4337 }
4338
06fadff5 4339 while (*portfwd_strptr) {
84328ddb 4340 char address_family, type;
4341 int sport,dport,sserv,dserv;
4342 char sports[256], dports[256], saddr[256], host[256];
4343 int n;
4344
05581745 4345 address_family = 'A';
4346 type = 'L';
84328ddb 4347 if (*portfwd_strptr == 'A' ||
4348 *portfwd_strptr == '4' ||
4349 *portfwd_strptr == '6')
4350 address_family = *portfwd_strptr++;
4351 if (*portfwd_strptr == 'L' ||
4352 *portfwd_strptr == 'R' ||
4353 *portfwd_strptr == 'D')
4354 type = *portfwd_strptr++;
05581745 4355
06fadff5 4356 saddr[0] = '\0';
05581745 4357
06fadff5 4358 n = 0;
4359 while (*portfwd_strptr && *portfwd_strptr != '\t') {
4360 if (*portfwd_strptr == ':') {
4361 /*
4362 * We've seen a colon in the middle of the
4363 * source port number. This means that
4364 * everything we've seen until now is the
4365 * source _address_, so we'll move it into
4366 * saddr and start sports from the beginning
4367 * again.
4368 */
4369 portfwd_strptr++;
4370 sports[n] = '\0';
4371 if (ssh->version == 1 && type == 'R') {
2e85c969 4372 logeventf(ssh, "SSH-1 cannot handle remote source address "
06fadff5 4373 "spec \"%s\"; ignoring", sports);
4374 } else
4375 strcpy(saddr, sports);
4376 n = 0;
4377 }
019164b0 4378 if (n < lenof(sports)-1) sports[n++] = *portfwd_strptr++;
06fadff5 4379 }
4380 sports[n] = 0;
4381 if (type != 'D') {
4382 if (*portfwd_strptr == '\t')
4383 portfwd_strptr++;
4384 n = 0;
4385 while (*portfwd_strptr && *portfwd_strptr != ':') {
019164b0 4386 if (n < lenof(host)-1) host[n++] = *portfwd_strptr++;
06fadff5 4387 }
4388 host[n] = 0;
4389 if (*portfwd_strptr == ':')
4390 portfwd_strptr++;
4391 n = 0;
4392 while (*portfwd_strptr) {
019164b0 4393 if (n < lenof(dports)-1) dports[n++] = *portfwd_strptr++;
06fadff5 4394 }
4395 dports[n] = 0;
4396 portfwd_strptr++;
4397 dport = atoi(dports);
4398 dserv = 0;
4399 if (dport == 0) {
4400 dserv = 1;
4401 dport = net_service_lookup(dports);
4402 if (!dport) {
4403 logeventf(ssh, "Service lookup failed for destination"
4404 " port \"%s\"", dports);
4405 }
4406 }
4407 } else {
4408 while (*portfwd_strptr) portfwd_strptr++;
a9e72926 4409 host[0] = 0;
4410 dports[0] = 0;
06fadff5 4411 dport = dserv = -1;
4412 portfwd_strptr++; /* eat the NUL and move to next one */
4413 }
4414 sport = atoi(sports);
4415 sserv = 0;
4416 if (sport == 0) {
4417 sserv = 1;
4418 sport = net_service_lookup(sports);
4419 if (!sport) {
4420 logeventf(ssh, "Service lookup failed for source"
4421 " port \"%s\"", sports);
4422 }
4423 }
4424 if (sport && dport) {
4425 /* Set up a description of the source port. */
fda2feb1 4426 struct ssh_portfwd *pfrec, *epfrec;
fda2feb1 4427
4428 pfrec = snew(struct ssh_portfwd);
4429 pfrec->type = type;
4430 pfrec->saddr = *saddr ? dupstr(saddr) : NULL;
3fe92132 4431 pfrec->sserv = sserv ? dupstr(sports) : NULL;
fda2feb1 4432 pfrec->sport = sport;
84328ddb 4433 pfrec->daddr = *host ? dupstr(host) : NULL;
3fe92132 4434 pfrec->dserv = dserv ? dupstr(dports) : NULL;
fda2feb1 4435 pfrec->dport = dport;
4436 pfrec->local = NULL;
4437 pfrec->remote = NULL;
05581745 4438 pfrec->addressfamily = (address_family == '4' ? ADDRTYPE_IPV4 :
4439 address_family == '6' ? ADDRTYPE_IPV6 :
4440 ADDRTYPE_UNSPEC);
fda2feb1 4441
4442 epfrec = add234(ssh->portfwds, pfrec);
4443 if (epfrec != pfrec) {
c00c1931 4444 if (epfrec->status == DESTROY) {
4445 /*
4446 * We already have a port forwarding up and running
4447 * with precisely these parameters. Hence, no need
4448 * to do anything; simply re-tag the existing one
4449 * as KEEP.
4450 */
4451 epfrec->status = KEEP;
4452 }
fda2feb1 4453 /*
c00c1931 4454 * Anything else indicates that there was a duplicate
4455 * in our input, which we'll silently ignore.
fda2feb1 4456 */
fda2feb1 4457 free_portfwd(pfrec);
84328ddb 4458 } else {
4459 pfrec->status = CREATE;
4460 }
4461 }
4462 }
4463
4464 /*
4465 * Now go through and destroy any port forwardings which were
4466 * not re-enabled.
4467 */
4468 for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
4469 if (epf->status == DESTROY) {
4470 char *message;
4471
4472 message = dupprintf("%s port forwarding from %s%s%d",
4473 epf->type == 'L' ? "local" :
4474 epf->type == 'R' ? "remote" : "dynamic",
4475 epf->saddr ? epf->saddr : "",
4476 epf->saddr ? ":" : "",
4477 epf->sport);
4478
4479 if (epf->type != 'D') {
4480 char *msg2 = dupprintf("%s to %s:%d", message,
4481 epf->daddr, epf->dport);
4482 sfree(message);
4483 message = msg2;
4484 }
4485
4486 logeventf(ssh, "Cancelling %s", message);
4487 sfree(message);
4488
4489 if (epf->remote) {
4490 struct ssh_rportfwd *rpf = epf->remote;
4491 struct Packet *pktout;
4492
4493 /*
4494 * Cancel the port forwarding at the server
4495 * end.
4496 */
4497 if (ssh->version == 1) {
4498 /*
4499 * We cannot cancel listening ports on the
2e85c969 4500 * server side in SSH-1! There's no message
84328ddb 4501 * to support it. Instead, we simply remove
4502 * the rportfwd record from the local end
4503 * so that any connections the server tries
4504 * to make on it are rejected.
4505 */
4506 } else {
4507 pktout = ssh2_pkt_init(SSH2_MSG_GLOBAL_REQUEST);
4508 ssh2_pkt_addstring(pktout, "cancel-tcpip-forward");
4509 ssh2_pkt_addbool(pktout, 0);/* _don't_ want reply */
4510 if (epf->saddr) {
4511 ssh2_pkt_addstring(pktout, epf->saddr);
4512 } else if (ssh->cfg.rport_acceptall) {
5188540b 4513 /* XXX: ssh->cfg.rport_acceptall may not represent
4514 * what was used to open the original connection,
4515 * since it's reconfigurable. */
84328ddb 4516 ssh2_pkt_addstring(pktout, "0.0.0.0");
4517 } else {
4518 ssh2_pkt_addstring(pktout, "127.0.0.1");
4519 }
4520 ssh2_pkt_adduint32(pktout, epf->sport);
4521 ssh2_pkt_send(ssh, pktout);
4522 }
4523
4524 del234(ssh->rportfwds, rpf);
4525 free_rportfwd(rpf);
4526 } else if (epf->local) {
4527 pfd_terminate(epf->local);
4528 }
4529
4530 delpos234(ssh->portfwds, i);
4531 free_portfwd(epf);
4532 i--; /* so we don't skip one in the list */
4533 }
4534
4535 /*
4536 * And finally, set up any new port forwardings (status==CREATE).
4537 */
4538 for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
4539 if (epf->status == CREATE) {
4540 char *sportdesc, *dportdesc;
3fe92132 4541 sportdesc = dupprintf("%s%s%s%s%d%s",
84328ddb 4542 epf->saddr ? epf->saddr : "",
4543 epf->saddr ? ":" : "",
3fe92132 4544 epf->sserv ? epf->sserv : "",
4545 epf->sserv ? "(" : "",
4546 epf->sport,
4547 epf->sserv ? ")" : "");
84328ddb 4548 if (epf->type == 'D') {
4549 dportdesc = NULL;
4550 } else {
3fe92132 4551 dportdesc = dupprintf("%s:%s%s%d%s",
4552 epf->daddr,
4553 epf->dserv ? epf->dserv : "",
4554 epf->dserv ? "(" : "",
4555 epf->dport,
4556 epf->dserv ? ")" : "");
84328ddb 4557 }
05581745 4558
84328ddb 4559 if (epf->type == 'L') {
4560 const char *err = pfd_addforward(epf->daddr, epf->dport,
4561 epf->saddr, epf->sport,
5188540b 4562 ssh, cfg,
84328ddb 4563 &epf->local,
4564 epf->addressfamily);
4565
4566 logeventf(ssh, "Local %sport %s forwarding to %s%s%s",
4567 epf->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " :
4568 epf->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "",
4569 sportdesc, dportdesc,
4570 err ? " failed: " : "", err ? err : "");
4571 } else if (epf->type == 'D') {
06fadff5 4572 const char *err = pfd_addforward(NULL, -1,
84328ddb 4573 epf->saddr, epf->sport,
5188540b 4574 ssh, cfg,
84328ddb 4575 &epf->local,
4576 epf->addressfamily);
4577
4578 logeventf(ssh, "Local %sport %s SOCKS dynamic forwarding%s%s",
4579 epf->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " :
4580 epf->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "",
4581 sportdesc,
4582 err ? " failed: " : "", err ? err : "");
06fadff5 4583 } else {
4584 struct ssh_rportfwd *pf;
4585
4586 /*
4587 * Ensure the remote port forwardings tree exists.
4588 */
4589 if (!ssh->rportfwds) {
4590 if (ssh->version == 1)
4591 ssh->rportfwds = newtree234(ssh_rportcmp_ssh1);
4592 else
4593 ssh->rportfwds = newtree234(ssh_rportcmp_ssh2);
4594 }
4595
4596 pf = snew(struct ssh_rportfwd);
84328ddb 4597 strncpy(pf->dhost, epf->daddr, lenof(pf->dhost)-1);
4598 pf->dhost[lenof(pf->dhost)-1] = '\0';
4599 pf->dport = epf->dport;
4600 pf->sport = epf->sport;
06fadff5 4601 if (add234(ssh->rportfwds, pf) != pf) {
4602 logeventf(ssh, "Duplicate remote port forwarding to %s:%d",
84328ddb 4603 epf->daddr, epf->dport);
06fadff5 4604 sfree(pf);
4605 } else {
4606 logeventf(ssh, "Requesting remote port %s"
84328ddb 4607 " forward to %s", sportdesc, dportdesc);
06fadff5 4608
4609 pf->sportdesc = sportdesc;
4610 sportdesc = NULL;
84328ddb 4611 epf->remote = pf;
4612 pf->pfrec = epf;
06fadff5 4613
4614 if (ssh->version == 1) {
4615 send_packet(ssh, SSH1_CMSG_PORT_FORWARD_REQUEST,
84328ddb 4616 PKT_INT, epf->sport,
4617 PKT_STR, epf->daddr,
4618 PKT_INT, epf->dport,
06fadff5 4619 PKT_END);
4620 ssh_queue_handler(ssh, SSH1_SMSG_SUCCESS,
4621 SSH1_SMSG_FAILURE,
4622 ssh_rportfwd_succfail, pf);
4623 } else {
4624 struct Packet *pktout;
4625 pktout = ssh2_pkt_init(SSH2_MSG_GLOBAL_REQUEST);
4626 ssh2_pkt_addstring(pktout, "tcpip-forward");
4627 ssh2_pkt_addbool(pktout, 1);/* want reply */
84328ddb 4628 if (epf->saddr) {
4629 ssh2_pkt_addstring(pktout, epf->saddr);
5188540b 4630 } else if (cfg->rport_acceptall) {
06fadff5 4631 ssh2_pkt_addstring(pktout, "0.0.0.0");
4632 } else {
4633 ssh2_pkt_addstring(pktout, "127.0.0.1");
4634 }
84328ddb 4635 ssh2_pkt_adduint32(pktout, epf->sport);
06fadff5 4636 ssh2_pkt_send(ssh, pktout);
4637
4638 ssh_queue_handler(ssh, SSH2_MSG_REQUEST_SUCCESS,
4639 SSH2_MSG_REQUEST_FAILURE,
4640 ssh_rportfwd_succfail, pf);
4641 }
4642 }
4643 }
4644 sfree(sportdesc);
84328ddb 4645 sfree(dportdesc);
06fadff5 4646 }
06fadff5 4647}
4648
51df0ab5 4649static void ssh1_smsg_stdout_stderr_data(Ssh ssh, struct Packet *pktin)
4650{
4651 char *string;
4652 int stringlen, bufsize;
4653
4654 ssh_pkt_getstring(pktin, &string, &stringlen);
4655 if (string == NULL) {
4656 bombout(("Incoming terminal data packet was badly formed"));
4657 return;
4658 }
4659
4660 bufsize = from_backend(ssh->frontend, pktin->type == SSH1_SMSG_STDERR_DATA,
4661 string, stringlen);
4662 if (!ssh->v1_stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) {
4663 ssh->v1_stdout_throttling = 1;
ff68564b 4664 ssh_throttle_conn(ssh, +1);
51df0ab5 4665 }
4666}
4667
4668static void ssh1_smsg_x11_open(Ssh ssh, struct Packet *pktin)
4669{
4670 /* Remote side is trying to open a channel to talk to our
4671 * X-Server. Give them back a local channel number. */
4672 struct ssh_channel *c;
4673 int remoteid = ssh_pkt_getuint32(pktin);
4674
4675 logevent("Received X11 connect request");
4676 /* Refuse if X11 forwarding is disabled. */
4677 if (!ssh->X11_fwd_enabled) {
4678 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4679 PKT_INT, remoteid, PKT_END);
4680 logevent("Rejected X11 connect request");
4681 } else {
4682 c = snew(struct ssh_channel);
4683 c->ssh = ssh;
4684
8def70c3 4685 if (x11_init(&c->u.x11.s, ssh->x11disp, c,
4686 NULL, -1, &ssh->cfg) != NULL) {
51df0ab5 4687 logevent("Opening X11 forward connection failed");
4688 sfree(c);
4689 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4690 PKT_INT, remoteid, PKT_END);
4691 } else {
4692 logevent
4693 ("Opening X11 forward connection succeeded");
4694 c->remoteid = remoteid;
64d6ff88 4695 c->halfopen = FALSE;
51df0ab5 4696 c->localid = alloc_channel_id(ssh);
4697 c->closes = 0;
ff68564b 4698 c->throttling_conn = 0;
51df0ab5 4699 c->type = CHAN_X11; /* identify channel type */
4700 add234(ssh->channels, c);
4701 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4702 PKT_INT, c->remoteid, PKT_INT,
4703 c->localid, PKT_END);
4704 logevent("Opened X11 forward channel");
4705 }
4706 }
4707}
4708
4709static void ssh1_smsg_agent_open(Ssh ssh, struct Packet *pktin)
4710{
4711 /* Remote side is trying to open a channel to talk to our
4712 * agent. Give them back a local channel number. */
4713 struct ssh_channel *c;
4714 int remoteid = ssh_pkt_getuint32(pktin);
4715
4716 /* Refuse if agent forwarding is disabled. */
4717 if (!ssh->agentfwd_enabled) {
4718 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4719 PKT_INT, remoteid, PKT_END);
4720 } else {
4721 c = snew(struct ssh_channel);
4722 c->ssh = ssh;
4723 c->remoteid = remoteid;
64d6ff88 4724 c->halfopen = FALSE;
51df0ab5 4725 c->localid = alloc_channel_id(ssh);
4726 c->closes = 0;
ff68564b 4727 c->throttling_conn = 0;
51df0ab5 4728 c->type = CHAN_AGENT; /* identify channel type */
4729 c->u.a.lensofar = 0;
4730 add234(ssh->channels, c);
4731 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4732 PKT_INT, c->remoteid, PKT_INT, c->localid,
4733 PKT_END);
4734 }
4735}
4736
4737static void ssh1_msg_port_open(Ssh ssh, struct Packet *pktin)
4738{
4739 /* Remote side is trying to open a channel to talk to a
4740 * forwarded port. Give them back a local channel number. */
4741 struct ssh_channel *c;
05581745 4742 struct ssh_rportfwd pf, *pfp;
51df0ab5 4743 int remoteid;
4744 int hostsize, port;
fb983202 4745 char *host;
51df0ab5 4746 const char *e;
4747 c = snew(struct ssh_channel);
4748 c->ssh = ssh;
4749
4750 remoteid = ssh_pkt_getuint32(pktin);
4751 ssh_pkt_getstring(pktin, &host, &hostsize);
4752 port = ssh_pkt_getuint32(pktin);
4753
4754 if (hostsize >= lenof(pf.dhost))
4755 hostsize = lenof(pf.dhost)-1;
4756 memcpy(pf.dhost, host, hostsize);
4757 pf.dhost[hostsize] = '\0';
4758 pf.dport = port;
05581745 4759 pfp = find234(ssh->rportfwds, &pf, NULL);
51df0ab5 4760
05581745 4761 if (pfp == NULL) {
fb983202 4762 logeventf(ssh, "Rejected remote port open request for %s:%d",
4763 pf.dhost, port);
51df0ab5 4764 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4765 PKT_INT, remoteid, PKT_END);
4766 } else {
fb983202 4767 logeventf(ssh, "Received remote port open request for %s:%d",
4768 pf.dhost, port);
51df0ab5 4769 e = pfd_newconnect(&c->u.pfd.s, pf.dhost, port,
05581745 4770 c, &ssh->cfg, pfp->pfrec->addressfamily);
51df0ab5 4771 if (e != NULL) {
fb983202 4772 logeventf(ssh, "Port open failed: %s", e);
51df0ab5 4773 sfree(c);
4774 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4775 PKT_INT, remoteid, PKT_END);
4776 } else {
4777 c->remoteid = remoteid;
64d6ff88 4778 c->halfopen = FALSE;
51df0ab5 4779 c->localid = alloc_channel_id(ssh);
4780 c->closes = 0;
ff68564b 4781 c->throttling_conn = 0;
51df0ab5 4782 c->type = CHAN_SOCKDATA; /* identify channel type */
4783 add234(ssh->channels, c);
4784 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4785 PKT_INT, c->remoteid, PKT_INT,
4786 c->localid, PKT_END);
4787 logevent("Forwarded port opened successfully");
4788 }
4789 }
4790}
4791
4792static void ssh1_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
4793{
4794 unsigned int remoteid = ssh_pkt_getuint32(pktin);
4795 unsigned int localid = ssh_pkt_getuint32(pktin);
4796 struct ssh_channel *c;
4797
4798 c = find234(ssh->channels, &remoteid, ssh_channelfind);
4799 if (c && c->type == CHAN_SOCKDATA_DORMANT) {
4800 c->remoteid = localid;
64d6ff88 4801 c->halfopen = FALSE;
51df0ab5 4802 c->type = CHAN_SOCKDATA;
ff68564b 4803 c->throttling_conn = 0;
51df0ab5 4804 pfd_confirm(c->u.pfd.s);
4805 }
4806
4807 if (c && c->closes) {
4808 /*
4809 * We have a pending close on this channel,
4810 * which we decided on before the server acked
4811 * the channel open. So now we know the
4812 * remoteid, we can close it again.
4813 */
4814 send_packet(ssh, SSH1_MSG_CHANNEL_CLOSE,
4815 PKT_INT, c->remoteid, PKT_END);
4816 }
4817}
4818
4819static void ssh1_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
4820{
4821 unsigned int remoteid = ssh_pkt_getuint32(pktin);
4822 struct ssh_channel *c;
4823
4824 c = find234(ssh->channels, &remoteid, ssh_channelfind);
4825 if (c && c->type == CHAN_SOCKDATA_DORMANT) {
4826 logevent("Forwarded connection refused by server");
4827 pfd_close(c->u.pfd.s);
4828 del234(ssh->channels, c);
4829 sfree(c);
4830 }
4831}
4832
4833static void ssh1_msg_channel_close(Ssh ssh, struct Packet *pktin)
4834{
4835 /* Remote side closes a channel. */
4836 unsigned i = ssh_pkt_getuint32(pktin);
4837 struct ssh_channel *c;
4838 c = find234(ssh->channels, &i, ssh_channelfind);
64d6ff88 4839 if (c && !c->halfopen) {
51df0ab5 4840 int closetype;
4841 closetype =
4842 (pktin->type == SSH1_MSG_CHANNEL_CLOSE ? 1 : 2);
4843
4844 if ((c->closes == 0) && (c->type == CHAN_X11)) {
4845 logevent("Forwarded X11 connection terminated");
4846 assert(c->u.x11.s != NULL);
4847 x11_close(c->u.x11.s);
4848 c->u.x11.s = NULL;
4849 }
4850 if ((c->closes == 0) && (c->type == CHAN_SOCKDATA)) {
4851 logevent("Forwarded port closed");
4852 assert(c->u.pfd.s != NULL);
4853 pfd_close(c->u.pfd.s);
4854 c->u.pfd.s = NULL;
4855 }
4856
4857 c->closes |= (closetype << 2); /* seen this message */
4858 if (!(c->closes & closetype)) {
4859 send_packet(ssh, pktin->type, PKT_INT, c->remoteid,
4860 PKT_END);
4861 c->closes |= closetype; /* sent it too */
4862 }
4863
4864 if (c->closes == 15) {
4865 del234(ssh->channels, c);
4866 sfree(c);
4867 }
4868 } else {
4869 bombout(("Received CHANNEL_CLOSE%s for %s channel %d\n",
4870 pktin->type == SSH1_MSG_CHANNEL_CLOSE ? "" :
4871 "_CONFIRMATION", c ? "half-open" : "nonexistent",
4872 i));
4873 }
4874}
4875
4876static void ssh1_msg_channel_data(Ssh ssh, struct Packet *pktin)
4877{
4878 /* Data sent down one of our channels. */
4879 int i = ssh_pkt_getuint32(pktin);
4880 char *p;
6d44acc9 4881 int len;
51df0ab5 4882 struct ssh_channel *c;
4883
4884 ssh_pkt_getstring(pktin, &p, &len);
4885
4886 c = find234(ssh->channels, &i, ssh_channelfind);
4887 if (c) {
4888 int bufsize = 0;
4889 switch (c->type) {
4890 case CHAN_X11:
4891 bufsize = x11_send(c->u.x11.s, p, len);
4892 break;
4893 case CHAN_SOCKDATA:
4894 bufsize = pfd_send(c->u.pfd.s, p, len);
4895 break;
4896 case CHAN_AGENT:
4897 /* Data for an agent message. Buffer it. */
4898 while (len > 0) {
4899 if (c->u.a.lensofar < 4) {
62ddb51e 4900 unsigned int l = min(4 - c->u.a.lensofar, (unsigned)len);
51df0ab5 4901 memcpy(c->u.a.msglen + c->u.a.lensofar, p,
4902 l);
4903 p += l;
4904 len -= l;
4905 c->u.a.lensofar += l;
4906 }
4907 if (c->u.a.lensofar == 4) {
4908 c->u.a.totallen =
4909 4 + GET_32BIT(c->u.a.msglen);
4910 c->u.a.message = snewn(c->u.a.totallen,
4911 unsigned char);
4912 memcpy(c->u.a.message, c->u.a.msglen, 4);
4913 }
4914 if (c->u.a.lensofar >= 4 && len > 0) {
aa63ab7e 4915 unsigned int l =
51df0ab5 4916 min(c->u.a.totallen - c->u.a.lensofar,
62ddb51e 4917 (unsigned)len);
51df0ab5 4918 memcpy(c->u.a.message + c->u.a.lensofar, p,
4919 l);
4920 p += l;
4921 len -= l;
4922 c->u.a.lensofar += l;
4923 }
4924 if (c->u.a.lensofar == c->u.a.totallen) {
4925 void *reply;
4926 int replylen;
4927 if (agent_query(c->u.a.message,
4928 c->u.a.totallen,
4929 &reply, &replylen,
4930 ssh_agentf_callback, c))
4931 ssh_agentf_callback(c, reply, replylen);
4932 sfree(c->u.a.message);
4933 c->u.a.lensofar = 0;
4934 }
4935 }
4936 bufsize = 0; /* agent channels never back up */
4937 break;
4938 }
ff68564b 4939 if (!c->throttling_conn && bufsize > SSH1_BUFFER_LIMIT) {
4940 c->throttling_conn = 1;
4941 ssh_throttle_conn(ssh, +1);
51df0ab5 4942 }
4943 }
4944}
4945
4946static void ssh1_smsg_exit_status(Ssh ssh, struct Packet *pktin)
4947{
51df0ab5 4948 ssh->exitcode = ssh_pkt_getuint32(pktin);
fb983202 4949 logeventf(ssh, "Server sent command exit status %d", ssh->exitcode);
51df0ab5 4950 send_packet(ssh, SSH1_CMSG_EXIT_CONFIRMATION, PKT_END);
4951 /*
4952 * In case `helpful' firewalls or proxies tack
4953 * extra human-readable text on the end of the
4954 * session which we might mistake for another
4955 * encrypted packet, we close the session once
4956 * we've sent EXIT_CONFIRMATION.
4957 */
9e296bfa 4958 ssh_disconnect(ssh, NULL, NULL, 0, TRUE);
51df0ab5 4959}
4960
c6ccd5c2 4961/* Helper function to deal with sending tty modes for REQUEST_PTY */
4962static void ssh1_send_ttymode(void *data, char *mode, char *val)
4963{
4964 struct Packet *pktout = (struct Packet *)data;
4965 int i = 0;
4966 unsigned int arg = 0;
4967 while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
4968 if (i == lenof(ssh_ttymodes)) return;
4969 switch (ssh_ttymodes[i].type) {
4970 case TTY_OP_CHAR:
4971 arg = ssh_tty_parse_specchar(val);
4972 break;
4973 case TTY_OP_BOOL:
4974 arg = ssh_tty_parse_boolean(val);
4975 break;
4976 }
4977 ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
4978 ssh2_pkt_addbyte(pktout, arg);
4979}
4980
4981
b09eaa88 4982static void do_ssh1_connection(Ssh ssh, unsigned char *in, int inlen,
4983 struct Packet *pktin)
32874aea 4984{
b09eaa88 4985 crBegin(ssh->do_ssh1_connection_crstate);
fb09bf1c 4986
51df0ab5 4987 ssh->packet_dispatch[SSH1_SMSG_STDOUT_DATA] =
4988 ssh->packet_dispatch[SSH1_SMSG_STDERR_DATA] =
4989 ssh1_smsg_stdout_stderr_data;
4990
4991 ssh->packet_dispatch[SSH1_MSG_CHANNEL_OPEN_CONFIRMATION] =
4992 ssh1_msg_channel_open_confirmation;
4993 ssh->packet_dispatch[SSH1_MSG_CHANNEL_OPEN_FAILURE] =
4994 ssh1_msg_channel_open_failure;
4995 ssh->packet_dispatch[SSH1_MSG_CHANNEL_CLOSE] =
4996 ssh->packet_dispatch[SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION] =
4997 ssh1_msg_channel_close;
4998 ssh->packet_dispatch[SSH1_MSG_CHANNEL_DATA] = ssh1_msg_channel_data;
4999 ssh->packet_dispatch[SSH1_SMSG_EXIT_STATUS] = ssh1_smsg_exit_status;
5000
86916870 5001 if (ssh->cfg.agentfwd && agent_exists()) {
32874aea 5002 logevent("Requesting agent forwarding");
51470298 5003 send_packet(ssh, SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END);
32874aea 5004 do {
5005 crReturnV;
ff3187f6 5006 } while (!pktin);
5007 if (pktin->type != SSH1_SMSG_SUCCESS
5008 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 5009 bombout(("Protocol confusion"));
7ffdbc1a 5010 crStopV;
ff3187f6 5011 } else if (pktin->type == SSH1_SMSG_FAILURE) {
32874aea 5012 logevent("Agent forwarding refused");
5013 } else {
5014 logevent("Agent forwarding enabled");
51470298 5015 ssh->agentfwd_enabled = TRUE;
51df0ab5 5016 ssh->packet_dispatch[SSH1_SMSG_AGENT_OPEN] = ssh1_smsg_agent_open;
db7d555c 5017 }
dacbd0e8 5018 }
5019
d070d2ad 5020 if (ssh->cfg.x11_forward &&
5021 (ssh->x11disp = x11_setup_display(ssh->cfg.x11_display,
5022 ssh->cfg.x11_auth, &ssh->cfg))) {
32874aea 5023 logevent("Requesting X11 forwarding");
f68353be 5024 /*
5025 * Note that while we blank the X authentication data here, we don't
5026 * take any special action to blank the start of an X11 channel,
5027 * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
5028 * without having session blanking enabled is likely to leak your
5029 * cookie into the log.
5030 */
51470298 5031 if (ssh->v1_local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER) {
5032 send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
8def70c3 5033 PKT_STR, ssh->x11disp->remoteauthprotoname,
5034 PKTT_PASSWORD,
5035 PKT_STR, ssh->x11disp->remoteauthdatastring,
5036 PKTT_OTHER,
5037 PKT_INT, ssh->x11disp->screennum,
421d6835 5038 PKT_END);
32874aea 5039 } else {
51470298 5040 send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
8def70c3 5041 PKT_STR, ssh->x11disp->remoteauthprotoname,
5042 PKTT_PASSWORD,
5043 PKT_STR, ssh->x11disp->remoteauthdatastring,
5044 PKTT_OTHER,
5045 PKT_END);
32874aea 5046 }
5047 do {
5048 crReturnV;
ff3187f6 5049 } while (!pktin);
5050 if (pktin->type != SSH1_SMSG_SUCCESS
5051 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 5052 bombout(("Protocol confusion"));
7ffdbc1a 5053 crStopV;
ff3187f6 5054 } else if (pktin->type == SSH1_SMSG_FAILURE) {
32874aea 5055 logevent("X11 forwarding refused");
5056 } else {
5057 logevent("X11 forwarding enabled");
51470298 5058 ssh->X11_fwd_enabled = TRUE;
51df0ab5 5059 ssh->packet_dispatch[SSH1_SMSG_X11_OPEN] = ssh1_smsg_x11_open;
9c964e85 5060 }
5061 }
5062
06fadff5 5063 ssh_setup_portfwd(ssh, &ssh->cfg);
5064 ssh->packet_dispatch[SSH1_MSG_PORT_OPEN] = ssh1_msg_port_open;
d74d141c 5065
86916870 5066 if (!ssh->cfg.nopty) {
c6ccd5c2 5067 struct Packet *pkt;
a5dd8467 5068 /* Unpick the terminal-speed string. */
5069 /* XXX perhaps we should allow no speeds to be sent. */
db219738 5070 ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
5071 sscanf(ssh->cfg.termspeed, "%d,%d", &ssh->ospeed, &ssh->ispeed);
a5dd8467 5072 /* Send the pty request. */
c6ccd5c2 5073 pkt = ssh1_pkt_init(SSH1_CMSG_REQUEST_PTY);
5074 ssh_pkt_addstring(pkt, ssh->cfg.termtype);
5075 ssh_pkt_adduint32(pkt, ssh->term_height);
5076 ssh_pkt_adduint32(pkt, ssh->term_width);
5077 ssh_pkt_adduint32(pkt, 0); /* width in pixels */
5078 ssh_pkt_adduint32(pkt, 0); /* height in pixels */
5079 parse_ttymodes(ssh, ssh->cfg.ttymodes,
5080 ssh1_send_ttymode, (void *)pkt);
5081 ssh_pkt_addbyte(pkt, SSH1_TTY_OP_ISPEED);
5082 ssh_pkt_adduint32(pkt, ssh->ispeed);
5083 ssh_pkt_addbyte(pkt, SSH1_TTY_OP_OSPEED);
5084 ssh_pkt_adduint32(pkt, ssh->ospeed);
5085 ssh_pkt_addbyte(pkt, SSH_TTY_OP_END);
5086 s_wrpkt(ssh, pkt);
51470298 5087 ssh->state = SSH_STATE_INTERMED;
32874aea 5088 do {
5089 crReturnV;
ff3187f6 5090 } while (!pktin);
5091 if (pktin->type != SSH1_SMSG_SUCCESS
5092 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 5093 bombout(("Protocol confusion"));
7ffdbc1a 5094 crStopV;
ff3187f6 5095 } else if (pktin->type == SSH1_SMSG_FAILURE) {
51470298 5096 c_write_str(ssh, "Server refused to allocate pty\r\n");
5097 ssh->editing = ssh->echoing = 1;
32874aea 5098 }
a5dd8467 5099 logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
db219738 5100 ssh->ospeed, ssh->ispeed);
0965bee0 5101 } else {
51470298 5102 ssh->editing = ssh->echoing = 1;
374330e2 5103 }
5104
86916870 5105 if (ssh->cfg.compression) {
51470298 5106 send_packet(ssh, SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);
32874aea 5107 do {
5108 crReturnV;
ff3187f6 5109 } while (!pktin);
5110 if (pktin->type != SSH1_SMSG_SUCCESS
5111 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 5112 bombout(("Protocol confusion"));
7ffdbc1a 5113 crStopV;
ff3187f6 5114 } else if (pktin->type == SSH1_SMSG_FAILURE) {
51470298 5115 c_write_str(ssh, "Server refused to compress\r\n");
32874aea 5116 }
4ba9b64b 5117 logevent("Started compression");
51470298 5118 ssh->v1_compressing = TRUE;
5366aed8 5119 ssh->cs_comp_ctx = zlib_compress_init();
5120 logevent("Initialised zlib (RFC1950) compression");
5121 ssh->sc_comp_ctx = zlib_decompress_init();
5122 logevent("Initialised zlib (RFC1950) decompression");
4ba9b64b 5123 }
5124
fd5e5847 5125 /*
5126 * Start the shell or command.
5127 *
2e85c969 5128 * Special case: if the first-choice command is an SSH-2
fd5e5847 5129 * subsystem (hence not usable here) and the second choice
5130 * exists, we fall straight back to that.
5131 */
5132 {
86916870 5133 char *cmd = ssh->cfg.remote_cmd_ptr;
04c52f10 5134
5135 if (!cmd) cmd = ssh->cfg.remote_cmd;
fd5e5847 5136
86916870 5137 if (ssh->cfg.ssh_subsys && ssh->cfg.remote_cmd_ptr2) {
5138 cmd = ssh->cfg.remote_cmd_ptr2;
51470298 5139 ssh->fallback_cmd = TRUE;
fd5e5847 5140 }
5141 if (*cmd)
51470298 5142 send_packet(ssh, SSH1_CMSG_EXEC_CMD, PKT_STR, cmd, PKT_END);
fd5e5847 5143 else
51470298 5144 send_packet(ssh, SSH1_CMSG_EXEC_SHELL, PKT_END);
fd5e5847 5145 logevent("Started session");
5146 }
374330e2 5147
51470298 5148 ssh->state = SSH_STATE_SESSION;
5149 if (ssh->size_needed)
5150 ssh_size(ssh, ssh->term_width, ssh->term_height);
5151 if (ssh->eof_needed)
5152 ssh_special(ssh, TS_EOF);
374330e2 5153
b9d7bcad 5154 if (ssh->ldisc)
5155 ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
51470298 5156 ssh->send_ok = 1;
5157 ssh->channels = newtree234(ssh_channelcmp);
374330e2 5158 while (1) {
d74d141c 5159
51df0ab5 5160 /*
5161 * By this point, most incoming packets are already being
5162 * handled by the dispatch table, and we need only pay
5163 * attention to the unusual ones.
5164 */
0357890f 5165
51df0ab5 5166 crReturnV;
5167 if (pktin) {
5168 if (pktin->type == SSH1_SMSG_SUCCESS) {
972a41c8 5169 /* may be from EXEC_SHELL on some servers */
ff3187f6 5170 } else if (pktin->type == SSH1_SMSG_FAILURE) {
972a41c8 5171 /* may be from EXEC_SHELL on some servers
374330e2 5172 * if no pty is available or in other odd cases. Ignore */
374330e2 5173 } else {
ff3187f6 5174 bombout(("Strange packet received: type %d", pktin->type));
7ffdbc1a 5175 crStopV;
374330e2 5176 }
5177 } else {
8df7a775 5178 while (inlen > 0) {
5179 int len = min(inlen, 512);
a2724fba 5180 send_packet(ssh, SSH1_CMSG_STDIN_DATA,
5181 PKT_INT, len, PKTT_DATA, PKT_DATA, in, len,
9a10ecf4 5182 PKTT_OTHER, PKT_END);
8df7a775 5183 in += len;
5184 inlen -= len;
5185 }
374330e2 5186 }
5187 }
5188
5189 crFinishV;
5190}
5191
5192/*
2e85c969 5193 * Handle the top-level SSH-2 protocol.
b09eaa88 5194 */
5195static void ssh1_msg_debug(Ssh ssh, struct Packet *pktin)
5196{
fb983202 5197 char *msg;
b09eaa88 5198 int msglen;
5199
5200 ssh_pkt_getstring(pktin, &msg, &msglen);
fb983202 5201 logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
b09eaa88 5202}
5203
5204static void ssh1_msg_disconnect(Ssh ssh, struct Packet *pktin)
5205{
5206 /* log reason code in disconnect message */
5207 char *msg;
5208 int msglen;
5209
5210 ssh_pkt_getstring(pktin, &msg, &msglen);
5211 bombout(("Server sent disconnect message:\n\"%.*s\"", msglen, msg));
5212}
5213
409bfa77 5214static void ssh_msg_ignore(Ssh ssh, struct Packet *pktin)
b09eaa88 5215{
5216 /* Do nothing, because we're ignoring it! Duhh. */
5217}
5218
5219static void ssh1_protocol_setup(Ssh ssh)
5220{
5221 int i;
5222
5223 /*
5224 * Most messages are handled by the coroutines.
5225 */
5226 for (i = 0; i < 256; i++)
5227 ssh->packet_dispatch[i] = NULL;
5228
5229 /*
5230 * These special message types we install handlers for.
5231 */
5232 ssh->packet_dispatch[SSH1_MSG_DISCONNECT] = ssh1_msg_disconnect;
5233 ssh->packet_dispatch[SSH1_MSG_IGNORE] = ssh_msg_ignore;
5234 ssh->packet_dispatch[SSH1_MSG_DEBUG] = ssh1_msg_debug;
5235}
5236
1c1a7262 5237static void ssh1_protocol(Ssh ssh, void *vin, int inlen,
b09eaa88 5238 struct Packet *pktin)
5239{
1c1a7262 5240 unsigned char *in=(unsigned char*)vin;
b09eaa88 5241 if (ssh->state == SSH_STATE_CLOSED)
5242 return;
5243
5244 if (pktin && ssh->packet_dispatch[pktin->type]) {
5245 ssh->packet_dispatch[pktin->type](ssh, pktin);
5246 return;
5247 }
5248
5249 if (!ssh->protocol_initial_phase_done) {
5250 if (do_ssh1_login(ssh, in, inlen, pktin))
5251 ssh->protocol_initial_phase_done = TRUE;
5252 else
5253 return;
5254 }
5255
5256 do_ssh1_connection(ssh, in, inlen, pktin);
5257}
5258
5259/*
e5574168 5260 * Utility routine for decoding comma-separated strings in KEXINIT.
5261 */
32874aea 5262static int in_commasep_string(char *needle, char *haystack, int haylen)
5263{
57356d63 5264 int needlen;
5265 if (!needle || !haystack) /* protect against null pointers */
5266 return 0;
5267 needlen = strlen(needle);
e5574168 5268 while (1) {
32874aea 5269 /*
5270 * Is it at the start of the string?
5271 */
5272 if (haylen >= needlen && /* haystack is long enough */
5273 !memcmp(needle, haystack, needlen) && /* initial match */
5274 (haylen == needlen || haystack[needlen] == ',')
5275 /* either , or EOS follows */
5276 )
5277 return 1;
5278 /*
5279 * If not, search for the next comma and resume after that.
5280 * If no comma found, terminate.
5281 */
5282 while (haylen > 0 && *haystack != ',')
5283 haylen--, haystack++;
5284 if (haylen == 0)
5285 return 0;
5286 haylen--, haystack++; /* skip over comma itself */
e5574168 5287 }
5288}
5289
5290/*
b59743d5 5291 * Similar routine for checking whether we have the first string in a list.
5292 */
5293static int first_in_commasep_string(char *needle, char *haystack, int haylen)
5294{
5295 int needlen;
5296 if (!needle || !haystack) /* protect against null pointers */
5297 return 0;
5298 needlen = strlen(needle);
5299 /*
5300 * Is it at the start of the string?
5301 */
5302 if (haylen >= needlen && /* haystack is long enough */
5303 !memcmp(needle, haystack, needlen) && /* initial match */
5304 (haylen == needlen || haystack[needlen] == ',')
5305 /* either , or EOS follows */
5306 )
5307 return 1;
5308 return 0;
5309}
5310
5311
5312/*
2e85c969 5313 * SSH-2 key creation method.
754c0df9 5314 * (Currently assumes 2 lots of any hash are sufficient to generate
5315 * keys/IVs for any cipher/MAC. SSH2_MKKEY_ITERS documents this assumption.)
d39f364a 5316 */
754c0df9 5317#define SSH2_MKKEY_ITERS (2)
b672f405 5318static void ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, char chr,
d8baa528 5319 unsigned char *keyspace)
32874aea 5320{
b672f405 5321 const struct ssh_hash *h = ssh->kex->hash;
5322 void *s;
5323 /* First hlen bytes. */
5324 s = h->init();
51470298 5325 if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
b672f405 5326 hash_mpint(h, s, K);
5327 h->bytes(s, H, h->hlen);
5328 h->bytes(s, &chr, 1);
5329 h->bytes(s, ssh->v2_session_id, ssh->v2_session_id_len);
5330 h->final(s, keyspace);
5331 /* Next hlen bytes. */
5332 s = h->init();
51470298 5333 if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
b672f405 5334 hash_mpint(h, s, K);
5335 h->bytes(s, H, h->hlen);
5336 h->bytes(s, keyspace, h->hlen);
5337 h->final(s, keyspace + h->hlen);
d39f364a 5338}
5339
5340/*
2e85c969 5341 * Handle the SSH-2 transport layer.
e5574168 5342 */
1c1a7262 5343static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
ff3187f6 5344 struct Packet *pktin)
e5574168 5345{
1c1a7262 5346 unsigned char *in = (unsigned char *)vin;
51470298 5347 struct do_ssh2_transport_state {
4763c1c2 5348 int nbits, pbits, warn_kex, warn_cscipher, warn_sccipher;
51470298 5349 Bignum p, g, e, f, K;
3dc9a6a7 5350 void *our_kexinit;
5351 int our_kexinitlen;
51470298 5352 int kex_init_value, kex_reply_value;
5353 const struct ssh_mac **maclist;
5354 int nmacs;
5355 const struct ssh2_cipher *cscipher_tobe;
5356 const struct ssh2_cipher *sccipher_tobe;
5357 const struct ssh_mac *csmac_tobe;
5358 const struct ssh_mac *scmac_tobe;
5359 const struct ssh_compress *cscomp_tobe;
5360 const struct ssh_compress *sccomp_tobe;
fae1a71b 5361 char *hostkeydata, *sigdata, *rsakeydata, *keystr, *fingerprint;
5362 int hostkeylen, siglen, rsakeylen;
51470298 5363 void *hkey; /* actual host key */
fae1a71b 5364 void *rsakey; /* for RSA kex */
754c0df9 5365 unsigned char exchange_hash[SSH2_KEX_MAX_HASH_LEN];
83e7d008 5366 int n_preferred_kex;
34557659 5367 const struct ssh_kexes *preferred_kex[KEX_MAX];
51470298 5368 int n_preferred_ciphers;
5369 const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX];
5370 const struct ssh_compress *preferred_comp;
e13bba36 5371 int got_session_id, activated_authconn;
ff3187f6 5372 struct Packet *pktout;
3d9449a1 5373 int dlgret;
5374 int guessok;
4763c1c2 5375 int ignorepkt;
51470298 5376 };
5377 crState(do_ssh2_transport_state);
5378
5379 crBegin(ssh->do_ssh2_transport_crstate);
5380
5381 s->cscipher_tobe = s->sccipher_tobe = NULL;
5382 s->csmac_tobe = s->scmac_tobe = NULL;
5383 s->cscomp_tobe = s->sccomp_tobe = NULL;
5384
e13bba36 5385 s->got_session_id = s->activated_authconn = FALSE;
e5574168 5386
e13bba36 5387 /*
5388 * Be prepared to work around the buggy MAC problem.
5389 */
5390 if (ssh->remote_bugs & BUG_SSH2_HMAC)
5391 s->maclist = buggymacs, s->nmacs = lenof(buggymacs);
5392 else
5393 s->maclist = macs, s->nmacs = lenof(macs);
5394
5395 begin_key_exchange:
acab36bc 5396 ssh->pkt_kctx = SSH2_PKTCTX_NOKEX;
51470298 5397 {
e13bba36 5398 int i, j, commalist_started;
5399
51470298 5400 /*
83e7d008 5401 * Set up the preferred key exchange. (NULL => warn below here)
5402 */
5403 s->n_preferred_kex = 0;
5404 for (i = 0; i < KEX_MAX; i++) {
5405 switch (ssh->cfg.ssh_kexlist[i]) {
5406 case KEX_DHGEX:
5407 s->preferred_kex[s->n_preferred_kex++] =
5408 &ssh_diffiehellman_gex;
5409 break;
5410 case KEX_DHGROUP14:
5411 s->preferred_kex[s->n_preferred_kex++] =
5412 &ssh_diffiehellman_group14;
5413 break;
5414 case KEX_DHGROUP1:
5415 s->preferred_kex[s->n_preferred_kex++] =
5416 &ssh_diffiehellman_group1;
5417 break;
fae1a71b 5418 case KEX_RSA:
5419 s->preferred_kex[s->n_preferred_kex++] =
5420 &ssh_rsa_kex;
5421 break;
754c0df9 5422 case KEX_WARN:
83e7d008 5423 /* Flag for later. Don't bother if it's the last in
5424 * the list. */
5425 if (i < KEX_MAX - 1) {
5426 s->preferred_kex[s->n_preferred_kex++] = NULL;
5427 }
5428 break;
5429 }
5430 }
83e7d008 5431
83e7d008 5432 /*
51470298 5433 * Set up the preferred ciphers. (NULL => warn below here)
5434 */
5435 s->n_preferred_ciphers = 0;
5436 for (i = 0; i < CIPHER_MAX; i++) {
86916870 5437 switch (ssh->cfg.ssh_cipherlist[i]) {
51470298 5438 case CIPHER_BLOWFISH:
5439 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_blowfish;
5440 break;
5441 case CIPHER_DES:
86916870 5442 if (ssh->cfg.ssh2_des_cbc) {
51470298 5443 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_des;
5444 }
5445 break;
5446 case CIPHER_3DES:
5447 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_3des;
5448 break;
5449 case CIPHER_AES:
5450 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_aes;
5451 break;
a2add208 5452 case CIPHER_ARCFOUR:
5453 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_arcfour;
5454 break;
51470298 5455 case CIPHER_WARN:
5456 /* Flag for later. Don't bother if it's the last in
5457 * the list. */
5458 if (i < CIPHER_MAX - 1) {
5459 s->preferred_ciphers[s->n_preferred_ciphers++] = NULL;
5460 }
5461 break;
ca20bfcf 5462 }
ca20bfcf 5463 }
7591b9ff 5464
e13bba36 5465 /*
5466 * Set up preferred compression.
5467 */
5468 if (ssh->cfg.compression)
5469 s->preferred_comp = &ssh_zlib;
5470 else
5471 s->preferred_comp = &ssh_comp_none;
51470298 5472
5473 /*
590f6a5f 5474 * Enable queueing of outgoing auth- or connection-layer
5475 * packets while we are in the middle of a key exchange.
5476 */
5477 ssh->queueing = TRUE;
5478
5479 /*
9442dd57 5480 * Flag that KEX is in progress.
5481 */
5482 ssh->kex_in_progress = TRUE;
5483
5484 /*
51470298 5485 * Construct and send our key exchange packet.
5486 */
ff3187f6 5487 s->pktout = ssh2_pkt_init(SSH2_MSG_KEXINIT);
51470298 5488 for (i = 0; i < 16; i++)
ff3187f6 5489 ssh2_pkt_addbyte(s->pktout, (unsigned char) random_byte());
51470298 5490 /* List key exchange algorithms. */
ff3187f6 5491 ssh2_pkt_addstring_start(s->pktout);
83e7d008 5492 commalist_started = 0;
5493 for (i = 0; i < s->n_preferred_kex; i++) {
34557659 5494 const struct ssh_kexes *k = s->preferred_kex[i];
83e7d008 5495 if (!k) continue; /* warning flag */
34557659 5496 for (j = 0; j < k->nkexes; j++) {
5497 if (commalist_started)
5498 ssh2_pkt_addstring_str(s->pktout, ",");
5499 ssh2_pkt_addstring_str(s->pktout, k->list[j]->name);
5500 commalist_started = 1;
5501 }
32874aea 5502 }
51470298 5503 /* List server host key algorithms. */
ff3187f6 5504 ssh2_pkt_addstring_start(s->pktout);
51470298 5505 for (i = 0; i < lenof(hostkey_algs); i++) {
ff3187f6 5506 ssh2_pkt_addstring_str(s->pktout, hostkey_algs[i]->name);
51470298 5507 if (i < lenof(hostkey_algs) - 1)
ff3187f6 5508 ssh2_pkt_addstring_str(s->pktout, ",");
32874aea 5509 }
51470298 5510 /* List client->server encryption algorithms. */
ff3187f6 5511 ssh2_pkt_addstring_start(s->pktout);
83e7d008 5512 commalist_started = 0;
51470298 5513 for (i = 0; i < s->n_preferred_ciphers; i++) {
5514 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5515 if (!c) continue; /* warning flag */
5516 for (j = 0; j < c->nciphers; j++) {
83e7d008 5517 if (commalist_started)
ff3187f6 5518 ssh2_pkt_addstring_str(s->pktout, ",");
5519 ssh2_pkt_addstring_str(s->pktout, c->list[j]->name);
83e7d008 5520 commalist_started = 1;
51470298 5521 }
5522 }
5523 /* List server->client encryption algorithms. */
ff3187f6 5524 ssh2_pkt_addstring_start(s->pktout);
83e7d008 5525 commalist_started = 0;
51470298 5526 for (i = 0; i < s->n_preferred_ciphers; i++) {
5527 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5528 if (!c) continue; /* warning flag */
5529 for (j = 0; j < c->nciphers; j++) {
83e7d008 5530 if (commalist_started)
ff3187f6 5531 ssh2_pkt_addstring_str(s->pktout, ",");
5532 ssh2_pkt_addstring_str(s->pktout, c->list[j]->name);
83e7d008 5533 commalist_started = 1;
51470298 5534 }
5535 }
5536 /* List client->server MAC algorithms. */
ff3187f6 5537 ssh2_pkt_addstring_start(s->pktout);
51470298 5538 for (i = 0; i < s->nmacs; i++) {
ff3187f6 5539 ssh2_pkt_addstring_str(s->pktout, s->maclist[i]->name);
51470298 5540 if (i < s->nmacs - 1)
ff3187f6 5541 ssh2_pkt_addstring_str(s->pktout, ",");
51470298 5542 }
5543 /* List server->client MAC algorithms. */
ff3187f6 5544 ssh2_pkt_addstring_start(s->pktout);
51470298 5545 for (i = 0; i < s->nmacs; i++) {
ff3187f6 5546 ssh2_pkt_addstring_str(s->pktout, s->maclist[i]->name);
51470298 5547 if (i < s->nmacs - 1)
ff3187f6 5548 ssh2_pkt_addstring_str(s->pktout, ",");
51470298 5549 }
5550 /* List client->server compression algorithms. */
ff3187f6 5551 ssh2_pkt_addstring_start(s->pktout);
f6e0abe2 5552 assert(lenof(compressions) > 1);
ff3187f6 5553 ssh2_pkt_addstring_str(s->pktout, s->preferred_comp->name);
f6e0abe2 5554 for (i = 0; i < lenof(compressions); i++) {
5555 const struct ssh_compress *c = compressions[i];
5556 if (c != s->preferred_comp) {
ff3187f6 5557 ssh2_pkt_addstring_str(s->pktout, ",");
5558 ssh2_pkt_addstring_str(s->pktout, c->name);
f6e0abe2 5559 }
51470298 5560 }
5561 /* List server->client compression algorithms. */
ff3187f6 5562 ssh2_pkt_addstring_start(s->pktout);
f6e0abe2 5563 assert(lenof(compressions) > 1);
ff3187f6 5564 ssh2_pkt_addstring_str(s->pktout, s->preferred_comp->name);
f6e0abe2 5565 for (i = 0; i < lenof(compressions); i++) {
5566 const struct ssh_compress *c = compressions[i];
5567 if (c != s->preferred_comp) {
ff3187f6 5568 ssh2_pkt_addstring_str(s->pktout, ",");
5569 ssh2_pkt_addstring_str(s->pktout, c->name);
f6e0abe2 5570 }
51470298 5571 }
5572 /* List client->server languages. Empty list. */
ff3187f6 5573 ssh2_pkt_addstring_start(s->pktout);
51470298 5574 /* List server->client languages. Empty list. */
ff3187f6 5575 ssh2_pkt_addstring_start(s->pktout);
51470298 5576 /* First KEX packet does _not_ follow, because we're not that brave. */
ff3187f6 5577 ssh2_pkt_addbool(s->pktout, FALSE);
51470298 5578 /* Reserved. */
ff3187f6 5579 ssh2_pkt_adduint32(s->pktout, 0);
e5574168 5580 }
0db56f73 5581
3dc9a6a7 5582 s->our_kexinitlen = s->pktout->length - 5;
5583 s->our_kexinit = snewn(s->our_kexinitlen, unsigned char);
5584 memcpy(s->our_kexinit, s->pktout->data + 5, s->our_kexinitlen);
0db56f73 5585
590f6a5f 5586 ssh2_pkt_send_noqueue(ssh, s->pktout);
e5574168 5587
ff3187f6 5588 if (!pktin)
5589 crWaitUntil(pktin);
e5574168 5590
5591 /*
5592 * Now examine the other side's KEXINIT to see what we're up
5593 * to.
5594 */
51470298 5595 {
4763c1c2 5596 char *str, *preferred;
3d9449a1 5597 int i, j, len;
51470298 5598
ff3187f6 5599 if (pktin->type != SSH2_MSG_KEXINIT) {
6b5cf8b4 5600 bombout(("expected key exchange packet from server"));
7ffdbc1a 5601 crStop(0);
32874aea 5602 }
51470298 5603 ssh->kex = NULL;
5604 ssh->hostkey = NULL;
5605 s->cscipher_tobe = NULL;
5606 s->sccipher_tobe = NULL;
5607 s->csmac_tobe = NULL;
5608 s->scmac_tobe = NULL;
5609 s->cscomp_tobe = NULL;
5610 s->sccomp_tobe = NULL;
4763c1c2 5611 s->warn_kex = s->warn_cscipher = s->warn_sccipher = FALSE;
5612
ff3187f6 5613 pktin->savedpos += 16; /* skip garbage cookie */
5614 ssh_pkt_getstring(pktin, &str, &len); /* key exchange algorithms */
4763c1c2 5615
5616 preferred = NULL;
83e7d008 5617 for (i = 0; i < s->n_preferred_kex; i++) {
34557659 5618 const struct ssh_kexes *k = s->preferred_kex[i];
83e7d008 5619 if (!k) {
4763c1c2 5620 s->warn_kex = TRUE;
5621 } else {
34557659 5622 for (j = 0; j < k->nkexes; j++) {
5623 if (!preferred) preferred = k->list[j]->name;
5624 if (in_commasep_string(k->list[j]->name, str, len)) {
5625 ssh->kex = k->list[j];
5626 break;
5627 }
5628 }
83e7d008 5629 }
4763c1c2 5630 if (ssh->kex)
51470298 5631 break;
32874aea 5632 }
83e7d008 5633 if (!ssh->kex) {
5634 bombout(("Couldn't agree a key exchange algorithm (available: %s)",
5635 str ? str : "(null)"));
5636 crStop(0);
5637 }
b59743d5 5638 /*
5639 * Note that the server's guess is considered wrong if it doesn't match
5640 * the first algorithm in our list, even if it's still the algorithm
5641 * we end up using.
5642 */
4763c1c2 5643 s->guessok = first_in_commasep_string(preferred, str, len);
ff3187f6 5644 ssh_pkt_getstring(pktin, &str, &len); /* host key algorithms */
51470298 5645 for (i = 0; i < lenof(hostkey_algs); i++) {
5646 if (in_commasep_string(hostkey_algs[i]->name, str, len)) {
5647 ssh->hostkey = hostkey_algs[i];
5648 break;
5649 }
5650 }
3d9449a1 5651 s->guessok = s->guessok &&
b59743d5 5652 first_in_commasep_string(hostkey_algs[0]->name, str, len);
ff3187f6 5653 ssh_pkt_getstring(pktin, &str, &len); /* client->server cipher */
51470298 5654 for (i = 0; i < s->n_preferred_ciphers; i++) {
5655 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5656 if (!c) {
4763c1c2 5657 s->warn_cscipher = TRUE;
51470298 5658 } else {
5659 for (j = 0; j < c->nciphers; j++) {
5660 if (in_commasep_string(c->list[j]->name, str, len)) {
5661 s->cscipher_tobe = c->list[j];
5662 break;
5663 }
ca20bfcf 5664 }
32874aea 5665 }
4763c1c2 5666 if (s->cscipher_tobe)
51470298 5667 break;
32874aea 5668 }
51470298 5669 if (!s->cscipher_tobe) {
6b5cf8b4 5670 bombout(("Couldn't agree a client-to-server cipher (available: %s)",
57356d63 5671 str ? str : "(null)"));
7ffdbc1a 5672 crStop(0);
ca20bfcf 5673 }
0ef8f407 5674
ff3187f6 5675 ssh_pkt_getstring(pktin, &str, &len); /* server->client cipher */
51470298 5676 for (i = 0; i < s->n_preferred_ciphers; i++) {
5677 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5678 if (!c) {
4763c1c2 5679 s->warn_sccipher = TRUE;
51470298 5680 } else {
5681 for (j = 0; j < c->nciphers; j++) {
5682 if (in_commasep_string(c->list[j]->name, str, len)) {
5683 s->sccipher_tobe = c->list[j];
5684 break;
5685 }
ca20bfcf 5686 }
32874aea 5687 }
4763c1c2 5688 if (s->sccipher_tobe)
51470298 5689 break;
32874aea 5690 }
51470298 5691 if (!s->sccipher_tobe) {
6b5cf8b4 5692 bombout(("Couldn't agree a server-to-client cipher (available: %s)",
57356d63 5693 str ? str : "(null)"));
7ffdbc1a 5694 crStop(0);
ca20bfcf 5695 }
0ef8f407 5696
ff3187f6 5697 ssh_pkt_getstring(pktin, &str, &len); /* client->server mac */
51470298 5698 for (i = 0; i < s->nmacs; i++) {
5699 if (in_commasep_string(s->maclist[i]->name, str, len)) {
5700 s->csmac_tobe = s->maclist[i];
5701 break;
5702 }
32874aea 5703 }
ff3187f6 5704 ssh_pkt_getstring(pktin, &str, &len); /* server->client mac */
51470298 5705 for (i = 0; i < s->nmacs; i++) {
5706 if (in_commasep_string(s->maclist[i]->name, str, len)) {
5707 s->scmac_tobe = s->maclist[i];
5708 break;
5709 }
32874aea 5710 }
ff3187f6 5711 ssh_pkt_getstring(pktin, &str, &len); /* client->server compression */
51470298 5712 for (i = 0; i < lenof(compressions) + 1; i++) {
5713 const struct ssh_compress *c =
5714 i == 0 ? s->preferred_comp : compressions[i - 1];
5715 if (in_commasep_string(c->name, str, len)) {
5716 s->cscomp_tobe = c;
5717 break;
5718 }
32874aea 5719 }
ff3187f6 5720 ssh_pkt_getstring(pktin, &str, &len); /* server->client compression */
51470298 5721 for (i = 0; i < lenof(compressions) + 1; i++) {
5722 const struct ssh_compress *c =
5723 i == 0 ? s->preferred_comp : compressions[i - 1];
5724 if (in_commasep_string(c->name, str, len)) {
5725 s->sccomp_tobe = c;
5726 break;
5727 }
32874aea 5728 }
b59743d5 5729 ssh_pkt_getstring(pktin, &str, &len); /* client->server language */
5730 ssh_pkt_getstring(pktin, &str, &len); /* server->client language */
4763c1c2 5731 s->ignorepkt = ssh2_pkt_getbool(pktin) && !s->guessok;
5732
5733 if (s->warn_kex) {
5734 ssh_set_frozen(ssh, 1);
5735 s->dlgret = askalg(ssh->frontend, "key-exchange algorithm",
5736 ssh->kex->name,
5737 ssh_dialog_callback, ssh);
5738 if (s->dlgret < 0) {
5739 do {
5740 crReturn(0);
5741 if (pktin) {
5742 bombout(("Unexpected data from server while"
5743 " waiting for user response"));
5744 crStop(0);
5745 }
5746 } while (pktin || inlen > 0);
5747 s->dlgret = ssh->user_response;
5748 }
5749 ssh_set_frozen(ssh, 0);
5750 if (s->dlgret == 0) {
9e296bfa 5751 ssh_disconnect(ssh, "User aborted at kex warning", NULL,
5752 0, TRUE);
a5a6f839 5753 crStop(0);
4763c1c2 5754 }
5755 }
5756
5757 if (s->warn_cscipher) {
5758 ssh_set_frozen(ssh, 1);
5759 s->dlgret = askalg(ssh->frontend,
5760 "client-to-server cipher",
5761 s->cscipher_tobe->name,
5762 ssh_dialog_callback, ssh);
5763 if (s->dlgret < 0) {
5764 do {
5765 crReturn(0);
5766 if (pktin) {
5767 bombout(("Unexpected data from server while"
5768 " waiting for user response"));
5769 crStop(0);
5770 }
5771 } while (pktin || inlen > 0);
5772 s->dlgret = ssh->user_response;
5773 }
5774 ssh_set_frozen(ssh, 0);
5775 if (s->dlgret == 0) {
9e296bfa 5776 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
5777 0, TRUE);
a5a6f839 5778 crStop(0);
4763c1c2 5779 }
5780 }
5781
5782 if (s->warn_sccipher) {
5783 ssh_set_frozen(ssh, 1);
5784 s->dlgret = askalg(ssh->frontend,
5785 "server-to-client cipher",
5786 s->sccipher_tobe->name,
5787 ssh_dialog_callback, ssh);
5788 if (s->dlgret < 0) {
5789 do {
5790 crReturn(0);
5791 if (pktin) {
5792 bombout(("Unexpected data from server while"
5793 " waiting for user response"));
5794 crStop(0);
5795 }
5796 } while (pktin || inlen > 0);
5797 s->dlgret = ssh->user_response;
5798 }
5799 ssh_set_frozen(ssh, 0);
5800 if (s->dlgret == 0) {
9e296bfa 5801 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
5802 0, TRUE);
a5a6f839 5803 crStop(0);
4763c1c2 5804 }
5805 }
5806
b672f405 5807 ssh->exhash = ssh->kex->hash->init();
5808 hash_string(ssh->kex->hash, ssh->exhash, ssh->v_c, strlen(ssh->v_c));
5809 hash_string(ssh->kex->hash, ssh->exhash, ssh->v_s, strlen(ssh->v_s));
5810 hash_string(ssh->kex->hash, ssh->exhash,
5811 s->our_kexinit, s->our_kexinitlen);
3dc9a6a7 5812 sfree(s->our_kexinit);
5813 if (pktin->length > 5)
b672f405 5814 hash_string(ssh->kex->hash, ssh->exhash,
5815 pktin->data + 5, pktin->length - 5);
3dc9a6a7 5816
4763c1c2 5817 if (s->ignorepkt) /* first_kex_packet_follows */
b59743d5 5818 crWaitUntil(pktin); /* Ignore packet */
e5574168 5819 }
e5574168 5820
fae1a71b 5821 if (ssh->kex->main_type == KEXTYPE_DH) {
30774ba3 5822 /*
5823 * Work out the number of bits of key we will need from the
5824 * key exchange. We start with the maximum key length of
5825 * either cipher...
5826 */
5827 {
5828 int csbits, scbits;
5829
5830 csbits = s->cscipher_tobe->keylen;
5831 scbits = s->sccipher_tobe->keylen;
5832 s->nbits = (csbits > scbits ? csbits : scbits);
5833 }
5834 /* The keys only have hlen-bit entropy, since they're based on
5835 * a hash. So cap the key size at hlen bits. */
5836 if (s->nbits > ssh->kex->hash->hlen * 8)
5837 s->nbits = ssh->kex->hash->hlen * 8;
5838
5839 /*
5840 * If we're doing Diffie-Hellman group exchange, start by
5841 * requesting a group.
5842 */
5843 if (!ssh->kex->pdata) {
5844 logevent("Doing Diffie-Hellman group exchange");
acab36bc 5845 ssh->pkt_kctx = SSH2_PKTCTX_DHGEX;
30774ba3 5846 /*
5847 * Work out how big a DH group we will need to allow that
5848 * much data.
5849 */
5850 s->pbits = 512 << ((s->nbits - 1) / 64);
5851 s->pktout = ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
5852 ssh2_pkt_adduint32(s->pktout, s->pbits);
5853 ssh2_pkt_send_noqueue(ssh, s->pktout);
5854
5855 crWaitUntil(pktin);
5856 if (pktin->type != SSH2_MSG_KEX_DH_GEX_GROUP) {
5857 bombout(("expected key exchange group packet from server"));
5858 crStop(0);
5859 }
5860 s->p = ssh2_pkt_getmp(pktin);
5861 s->g = ssh2_pkt_getmp(pktin);
5862 if (!s->p || !s->g) {
5863 bombout(("unable to read mp-ints from incoming group packet"));
5864 crStop(0);
5865 }
5866 ssh->kex_ctx = dh_setup_gex(s->p, s->g);
5867 s->kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
5868 s->kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
5869 } else {
acab36bc 5870 ssh->pkt_kctx = SSH2_PKTCTX_DHGROUP;
30774ba3 5871 ssh->kex_ctx = dh_setup_group(ssh->kex);
5872 s->kex_init_value = SSH2_MSG_KEXDH_INIT;
5873 s->kex_reply_value = SSH2_MSG_KEXDH_REPLY;
5874 logeventf(ssh, "Using Diffie-Hellman with standard group \"%s\"",
5875 ssh->kex->groupname);
5876 }
e5574168 5877
30774ba3 5878 logeventf(ssh, "Doing Diffie-Hellman key exchange with hash %s",
5879 ssh->kex->hash->text_name);
5880 /*
5881 * Now generate and send e for Diffie-Hellman.
5882 */
5883 set_busy_status(ssh->frontend, BUSY_CPU); /* this can take a while */
5884 s->e = dh_create_e(ssh->kex_ctx, s->nbits * 2);
5885 s->pktout = ssh2_pkt_init(s->kex_init_value);
5886 ssh2_pkt_addmp(s->pktout, s->e);
5887 ssh2_pkt_send_noqueue(ssh, s->pktout);
5888
5889 set_busy_status(ssh->frontend, BUSY_WAITING); /* wait for server */
5890 crWaitUntil(pktin);
5891 if (pktin->type != s->kex_reply_value) {
5892 bombout(("expected key exchange reply packet from server"));
5893 crStop(0);
5894 }
5895 set_busy_status(ssh->frontend, BUSY_CPU); /* cogitate */
5896 ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
5897 s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
5898 s->f = ssh2_pkt_getmp(pktin);
5899 if (!s->f) {
5900 bombout(("unable to parse key exchange reply packet"));
5901 crStop(0);
5902 }
5903 ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
e5574168 5904
30774ba3 5905 s->K = dh_find_K(ssh->kex_ctx, s->f);
e5574168 5906
30774ba3 5907 /* We assume everything from now on will be quick, and it might
5908 * involve user interaction. */
5909 set_busy_status(ssh->frontend, BUSY_NOT);
755e0524 5910
30774ba3 5911 hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen);
5912 if (!ssh->kex->pdata) {
5913 hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits);
5914 hash_mpint(ssh->kex->hash, ssh->exhash, s->p);
5915 hash_mpint(ssh->kex->hash, ssh->exhash, s->g);
5916 }
5917 hash_mpint(ssh->kex->hash, ssh->exhash, s->e);
5918 hash_mpint(ssh->kex->hash, ssh->exhash, s->f);
5919
5920 dh_cleanup(ssh->kex_ctx);
5921 freebn(s->f);
5922 if (!ssh->kex->pdata) {
5923 freebn(s->g);
5924 freebn(s->p);
5925 }
fae1a71b 5926 } else {
5927 logeventf(ssh, "Doing RSA key exchange with hash %s",
5928 ssh->kex->hash->text_name);
acab36bc 5929 ssh->pkt_kctx = SSH2_PKTCTX_RSAKEX;
fae1a71b 5930 /*
5931 * RSA key exchange. First expect a KEXRSA_PUBKEY packet
5932 * from the server.
5933 */
5934 crWaitUntil(pktin);
5935 if (pktin->type != SSH2_MSG_KEXRSA_PUBKEY) {
5936 bombout(("expected RSA public key packet from server"));
5937 crStop(0);
5938 }
5939
5940 ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
5941 hash_string(ssh->kex->hash, ssh->exhash,
5942 s->hostkeydata, s->hostkeylen);
5943 s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
5944
5945 {
5946 char *keydata;
5947 ssh_pkt_getstring(pktin, &keydata, &s->rsakeylen);
5948 s->rsakeydata = snewn(s->rsakeylen, char);
5949 memcpy(s->rsakeydata, keydata, s->rsakeylen);
5950 }
5951
5952 s->rsakey = ssh_rsakex_newkey(s->rsakeydata, s->rsakeylen);
5953 if (!s->rsakey) {
5954 sfree(s->rsakeydata);
5955 bombout(("unable to parse RSA public key from server"));
5956 crStop(0);
5957 }
5958
5959 hash_string(ssh->kex->hash, ssh->exhash, s->rsakeydata, s->rsakeylen);
5960
5961 /*
5962 * Next, set up a shared secret K, of precisely KLEN -
5963 * 2*HLEN - 49 bits, where KLEN is the bit length of the
5964 * RSA key modulus and HLEN is the bit length of the hash
5965 * we're using.
5966 */
5967 {
5968 int klen = ssh_rsakex_klen(s->rsakey);
5969 int nbits = klen - (2*ssh->kex->hash->hlen*8 + 49);
5970 int i, byte = 0;
5971 unsigned char *kstr1, *kstr2, *outstr;
5972 int kstr1len, kstr2len, outstrlen;
5973
5974 s->K = bn_power_2(nbits - 1);
5975
5976 for (i = 0; i < nbits; i++) {
5977 if ((i & 7) == 0) {
5978 byte = random_byte();
5979 }
5980 bignum_set_bit(s->K, i, (byte >> (i & 7)) & 1);
5981 }
5982
5983 /*
5984 * Encode this as an mpint.
5985 */
5986 kstr1 = ssh2_mpint_fmt(s->K, &kstr1len);
5987 kstr2 = snewn(kstr2len = 4 + kstr1len, unsigned char);
5988 PUT_32BIT(kstr2, kstr1len);
5989 memcpy(kstr2 + 4, kstr1, kstr1len);
5990
5991 /*
5992 * Encrypt it with the given RSA key.
5993 */
5994 outstrlen = (klen + 7) / 8;
5995 outstr = snewn(outstrlen, unsigned char);
5996 ssh_rsakex_encrypt(ssh->kex->hash, kstr2, kstr2len,
5997 outstr, outstrlen, s->rsakey);
5998
5999 /*
6000 * And send it off in a return packet.
6001 */
6002 s->pktout = ssh2_pkt_init(SSH2_MSG_KEXRSA_SECRET);
6003 ssh2_pkt_addstring_start(s->pktout);
7108a872 6004 ssh2_pkt_addstring_data(s->pktout, (char *)outstr, outstrlen);
fae1a71b 6005 ssh2_pkt_send_noqueue(ssh, s->pktout);
6006
6007 hash_string(ssh->kex->hash, ssh->exhash, outstr, outstrlen);
6008
6009 sfree(kstr2);
6010 sfree(kstr1);
6011 sfree(outstr);
6012 }
6013
6014 ssh_rsakex_freekey(s->rsakey);
6015
6016 crWaitUntil(pktin);
6017 if (pktin->type != SSH2_MSG_KEXRSA_DONE) {
6018 sfree(s->rsakeydata);
6019 bombout(("expected signature packet from server"));
6020 crStop(0);
6021 }
6022
6023 ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
6024
6025 sfree(s->rsakeydata);
6026 }
6027
b672f405 6028 hash_mpint(ssh->kex->hash, ssh->exhash, s->K);
6029 assert(ssh->kex->hash->hlen <= sizeof(s->exchange_hash));
6030 ssh->kex->hash->final(ssh->exhash, s->exchange_hash);
e5574168 6031
fabd1805 6032 ssh->kex_ctx = NULL;
3709bfe9 6033
7cca0d81 6034#if 0
765c4200 6035 debug(("Exchange hash is:\n"));
b672f405 6036 dmemdump(s->exchange_hash, ssh->kex->hash->hlen);
7cca0d81 6037#endif
6038
51470298 6039 if (!s->hkey ||
6040 !ssh->hostkey->verifysig(s->hkey, s->sigdata, s->siglen,
b672f405 6041 (char *)s->exchange_hash,
6042 ssh->kex->hash->hlen)) {
6b5cf8b4 6043 bombout(("Server's host key did not match the signature supplied"));
7ffdbc1a 6044 crStop(0);
8d5de777 6045 }
e5574168 6046
6047 /*
7cca0d81 6048 * Authenticate remote host: verify host key. (We've already
6049 * checked the signature of the exchange hash.)
e5574168 6050 */
51470298 6051 s->keystr = ssh->hostkey->fmtkey(s->hkey);
6052 s->fingerprint = ssh->hostkey->fingerprint(s->hkey);
3d9449a1 6053 ssh_set_frozen(ssh, 1);
6054 s->dlgret = verify_ssh_host_key(ssh->frontend,
6055 ssh->savedhost, ssh->savedport,
6056 ssh->hostkey->keytype, s->keystr,
6057 s->fingerprint,
6058 ssh_dialog_callback, ssh);
6059 if (s->dlgret < 0) {
6060 do {
6061 crReturn(0);
6062 if (pktin) {
6063 bombout(("Unexpected data from server while waiting"
6064 " for user host key response"));
6065 crStop(0);
6066 }
6067 } while (pktin || inlen > 0);
6068 s->dlgret = ssh->user_response;
6069 }
6070 ssh_set_frozen(ssh, 0);
6071 if (s->dlgret == 0) {
9e296bfa 6072 ssh_disconnect(ssh, "User aborted at host key verification", NULL,
6073 0, TRUE);
3d9449a1 6074 crStop(0);
6075 }
e13bba36 6076 if (!s->got_session_id) { /* don't bother logging this in rekeys */
5e0d7cb8 6077 logevent("Host key fingerprint is:");
51470298 6078 logevent(s->fingerprint);
5e0d7cb8 6079 }
51470298 6080 sfree(s->fingerprint);
6081 sfree(s->keystr);
6082 ssh->hostkey->freekey(s->hkey);
d39f364a 6083
6084 /*
9442dd57 6085 * The exchange hash from the very first key exchange is also
6086 * the session id, used in session key construction and
6087 * authentication.
6088 */
e13bba36 6089 if (!s->got_session_id) {
b672f405 6090 assert(sizeof(s->exchange_hash) <= sizeof(ssh->v2_session_id));
9442dd57 6091 memcpy(ssh->v2_session_id, s->exchange_hash,
6092 sizeof(s->exchange_hash));
b672f405 6093 ssh->v2_session_id_len = ssh->kex->hash->hlen;
6052bb76 6094 assert(ssh->v2_session_id_len <= sizeof(ssh->v2_session_id));
e13bba36 6095 s->got_session_id = TRUE;
6096 }
9442dd57 6097
6098 /*
7cca0d81 6099 * Send SSH2_MSG_NEWKEYS.
d39f364a 6100 */
ff3187f6 6101 s->pktout = ssh2_pkt_init(SSH2_MSG_NEWKEYS);
590f6a5f 6102 ssh2_pkt_send_noqueue(ssh, s->pktout);
9442dd57 6103 ssh->outgoing_data_size = 0; /* start counting from here */
6104
6105 /*
6106 * We've sent client NEWKEYS, so create and initialise
c64fe7d4 6107 * client-to-server session keys.
9442dd57 6108 */
6109 if (ssh->cs_cipher_ctx)
6110 ssh->cscipher->free_context(ssh->cs_cipher_ctx);
6111 ssh->cscipher = s->cscipher_tobe;
6112 ssh->cs_cipher_ctx = ssh->cscipher->make_context();
6113
6114 if (ssh->cs_mac_ctx)
6115 ssh->csmac->free_context(ssh->cs_mac_ctx);
6116 ssh->csmac = s->csmac_tobe;
6117 ssh->cs_mac_ctx = ssh->csmac->make_context();
6118
6119 if (ssh->cs_comp_ctx)
6120 ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
6121 ssh->cscomp = s->cscomp_tobe;
6122 ssh->cs_comp_ctx = ssh->cscomp->compress_init();
6123
6124 /*
6125 * Set IVs on client-to-server keys. Here we use the exchange
6126 * hash from the _first_ key exchange.
6127 */
6128 {
754c0df9 6129 unsigned char keyspace[SSH2_KEX_MAX_HASH_LEN * SSH2_MKKEY_ITERS];
6130 assert(sizeof(keyspace) >= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
b672f405 6131 ssh2_mkkey(ssh,s->K,s->exchange_hash,'C',keyspace);
754c0df9 6132 assert((ssh->cscipher->keylen+7) / 8 <=
6133 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
9442dd57 6134 ssh->cscipher->setkey(ssh->cs_cipher_ctx, keyspace);
b672f405 6135 ssh2_mkkey(ssh,s->K,s->exchange_hash,'A',keyspace);
754c0df9 6136 assert(ssh->cscipher->blksize <=
6137 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
9442dd57 6138 ssh->cscipher->setiv(ssh->cs_cipher_ctx, keyspace);
b672f405 6139 ssh2_mkkey(ssh,s->K,s->exchange_hash,'E',keyspace);
754c0df9 6140 assert(ssh->csmac->len <=
6141 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
9442dd57 6142 ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace);
754c0df9 6143 memset(keyspace, 0, sizeof(keyspace));
9442dd57 6144 }
6145
6146 logeventf(ssh, "Initialised %.200s client->server encryption",
6147 ssh->cscipher->text_name);
6148 logeventf(ssh, "Initialised %.200s client->server MAC algorithm",
6149 ssh->csmac->text_name);
6150 if (ssh->cscomp->text_name)
6151 logeventf(ssh, "Initialised %s compression",
6152 ssh->cscomp->text_name);
590f6a5f 6153
6154 /*
6155 * Now our end of the key exchange is complete, we can send all
6156 * our queued higher-layer packets.
6157 */
6158 ssh->queueing = FALSE;
6159 ssh2_pkt_queuesend(ssh);
d39f364a 6160
6161 /*
8406eaf9 6162 * Expect SSH2_MSG_NEWKEYS from server.
6163 */
ff3187f6 6164 crWaitUntil(pktin);
6165 if (pktin->type != SSH2_MSG_NEWKEYS) {
6b5cf8b4 6166 bombout(("expected new-keys packet from server"));
7ffdbc1a 6167 crStop(0);
8406eaf9 6168 }
9442dd57 6169 ssh->incoming_data_size = 0; /* start counting from here */
8406eaf9 6170
6171 /*
9442dd57 6172 * We've seen server NEWKEYS, so create and initialise
6173 * server-to-client session keys.
d39f364a 6174 */
371e569c 6175 if (ssh->sc_cipher_ctx)
6176 ssh->sccipher->free_context(ssh->sc_cipher_ctx);
51470298 6177 ssh->sccipher = s->sccipher_tobe;
371e569c 6178 ssh->sc_cipher_ctx = ssh->sccipher->make_context();
e0e1a00d 6179
e0e1a00d 6180 if (ssh->sc_mac_ctx)
6181 ssh->scmac->free_context(ssh->sc_mac_ctx);
51470298 6182 ssh->scmac = s->scmac_tobe;
e0e1a00d 6183 ssh->sc_mac_ctx = ssh->scmac->make_context();
6184
5366aed8 6185 if (ssh->sc_comp_ctx)
6186 ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
51470298 6187 ssh->sccomp = s->sccomp_tobe;
5366aed8 6188 ssh->sc_comp_ctx = ssh->sccomp->decompress_init();
6189
d39f364a 6190 /*
9442dd57 6191 * Set IVs on server-to-client keys. Here we use the exchange
6192 * hash from the _first_ key exchange.
d39f364a 6193 */
51470298 6194 {
754c0df9 6195 unsigned char keyspace[SSH2_KEX_MAX_HASH_LEN * SSH2_MKKEY_ITERS];
6196 assert(sizeof(keyspace) >= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
b672f405 6197 ssh2_mkkey(ssh,s->K,s->exchange_hash,'D',keyspace);
754c0df9 6198 assert((ssh->sccipher->keylen+7) / 8 <=
6199 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
371e569c 6200 ssh->sccipher->setkey(ssh->sc_cipher_ctx, keyspace);
b672f405 6201 ssh2_mkkey(ssh,s->K,s->exchange_hash,'B',keyspace);
754c0df9 6202 assert(ssh->sccipher->blksize <=
6203 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
371e569c 6204 ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace);
b672f405 6205 ssh2_mkkey(ssh,s->K,s->exchange_hash,'F',keyspace);
754c0df9 6206 assert(ssh->scmac->len <=
6207 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
e0e1a00d 6208 ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace);
754c0df9 6209 memset(keyspace, 0, sizeof(keyspace));
51470298 6210 }
57356d63 6211 logeventf(ssh, "Initialised %.200s server->client encryption",
6212 ssh->sccipher->text_name);
6c135243 6213 logeventf(ssh, "Initialised %.200s server->client MAC algorithm",
6214 ssh->scmac->text_name);
57356d63 6215 if (ssh->sccomp->text_name)
6216 logeventf(ssh, "Initialised %s decompression",
6217 ssh->sccomp->text_name);
9442dd57 6218
6219 /*
fae1a71b 6220 * Free shared secret.
9442dd57 6221 */
679539d7 6222 freebn(s->K);
d39f364a 6223
033b4cef 6224 /*
e13bba36 6225 * Key exchange is over. Loop straight back round if we have a
6226 * deferred rekey reason.
6227 */
6228 if (ssh->deferred_rekey_reason) {
6229 logevent(ssh->deferred_rekey_reason);
6230 pktin = NULL;
6231 ssh->deferred_rekey_reason = NULL;
6232 goto begin_key_exchange;
6233 }
6234
6235 /*
6236 * Otherwise, schedule a timer for our next rekey.
9442dd57 6237 */
6238 ssh->kex_in_progress = FALSE;
e6c1536e 6239 ssh->last_rekey = GETTICKCOUNT();
d57f70af 6240 if (ssh->cfg.ssh_rekey_time != 0)
6241 ssh->next_rekey = schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
6242 ssh2_timer, ssh);
e13bba36 6243
9442dd57 6244 /*
0db56f73 6245 * If this is the first key exchange phase, we must pass the
6246 * SSH2_MSG_NEWKEYS packet to the next layer, not because it
6247 * wants to see it but because it will need time to initialise
6248 * itself before it sees an actual packet. In subsequent key
6249 * exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
6250 * it would only confuse the layer above.
6251 */
e13bba36 6252 if (s->activated_authconn) {
0e3607ed 6253 crReturn(0);
0db56f73 6254 }
e13bba36 6255 s->activated_authconn = TRUE;
0db56f73 6256
6257 /*
7cca0d81 6258 * Now we're encrypting. Begin returning 1 to the protocol main
6259 * function so that other things can run on top of the
6260 * transport. If we ever see a KEXINIT, we must go back to the
6261 * start.
9442dd57 6262 *
6263 * We _also_ go back to the start if we see pktin==NULL and
6264 * inlen==-1, because this is a special signal meaning
6265 * `initiate client-driven rekey', and `in' contains a message
6266 * giving the reason for the rekey.
033b4cef 6267 */
9442dd57 6268 while (!((pktin && pktin->type == SSH2_MSG_KEXINIT) ||
6269 (!pktin && inlen == -1))) {
f382c87d 6270 wait_for_rekey:
32874aea 6271 crReturn(1);
e96adf72 6272 }
9442dd57 6273 if (pktin) {
6274 logevent("Server initiated key re-exchange");
6275 } else {
f382c87d 6276 /*
6277 * Special case: if the server bug is set that doesn't
6278 * allow rekeying, we give a different log message and
6279 * continue waiting. (If such a server _initiates_ a rekey,
6280 * we process it anyway!)
6281 */
6282 if ((ssh->remote_bugs & BUG_SSH2_REKEY)) {
6283 logeventf(ssh, "Server bug prevents key re-exchange (%s)",
6284 (char *)in);
6285 /* Reset the counters, so that at least this message doesn't
6286 * hit the event log _too_ often. */
6287 ssh->outgoing_data_size = 0;
6288 ssh->incoming_data_size = 0;
6289 if (ssh->cfg.ssh_rekey_time != 0) {
6290 ssh->next_rekey =
6291 schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
6292 ssh2_timer, ssh);
6293 }
6294 goto wait_for_rekey; /* this is utterly horrid */
6295 } else {
6296 logeventf(ssh, "Initiating key re-exchange (%s)", (char *)in);
f382c87d 6297 }
9442dd57 6298 }
7cca0d81 6299 goto begin_key_exchange;
e5574168 6300
6301 crFinish(1);
6302}
6303
7cca0d81 6304/*
2e85c969 6305 * Add data to an SSH-2 channel output buffer.
783415f8 6306 */
32874aea 6307static void ssh2_add_channel_data(struct ssh_channel *c, char *buf,
6308 int len)
6309{
5471d09a 6310 bufchain_add(&c->v.v2.outbuffer, buf, len);
783415f8 6311}
6312
6313/*
2e85c969 6314 * Attempt to send data on an SSH-2 channel.
783415f8 6315 */
5471d09a 6316static int ssh2_try_send(struct ssh_channel *c)
32874aea 6317{
51470298 6318 Ssh ssh = c->ssh;
ff3187f6 6319 struct Packet *pktout;
51470298 6320
5471d09a 6321 while (c->v.v2.remwindow > 0 && bufchain_size(&c->v.v2.outbuffer) > 0) {
6322 int len;
6323 void *data;
6324 bufchain_prefix(&c->v.v2.outbuffer, &data, &len);
6325 if ((unsigned)len > c->v.v2.remwindow)
6326 len = c->v.v2.remwindow;
6327 if ((unsigned)len > c->v.v2.remmaxpkt)
6328 len = c->v.v2.remmaxpkt;
ff3187f6 6329 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
6330 ssh2_pkt_adduint32(pktout, c->remoteid);
ff3187f6 6331 ssh2_pkt_addstring_start(pktout);
a2724fba 6332 dont_log_data(ssh, pktout, PKTLOG_OMIT);
ff3187f6 6333 ssh2_pkt_addstring_data(pktout, data, len);
6334 end_log_omission(ssh, pktout);
6335 ssh2_pkt_send(ssh, pktout);
5471d09a 6336 bufchain_consume(&c->v.v2.outbuffer, len);
6337 c->v.v2.remwindow -= len;
6338 }
6339
6340 /*
6341 * After having sent as much data as we can, return the amount
6342 * still buffered.
6343 */
6344 return bufchain_size(&c->v.v2.outbuffer);
6345}
6346
1bfc7e93 6347static void ssh2_try_send_and_unthrottle(struct ssh_channel *c)
6348{
6349 int bufsize;
6350 if (c->closes)
6351 return; /* don't send on closing channels */
6352 bufsize = ssh2_try_send(c);
6353 if (bufsize == 0) {
6354 switch (c->type) {
6355 case CHAN_MAINSESSION:
6356 /* stdin need not receive an unthrottle
6357 * notification since it will be polled */
6358 break;
6359 case CHAN_X11:
6360 x11_unthrottle(c->u.x11.s);
6361 break;
6362 case CHAN_AGENT:
6363 /* agent sockets are request/response and need no
6364 * buffer management */
6365 break;
6366 case CHAN_SOCKDATA:
6367 pfd_unthrottle(c->u.pfd.s);
6368 break;
6369 }
6370 }
6371}
6372
5471d09a 6373/*
94bdfe40 6374 * Set up most of a new ssh_channel for SSH-2.
6375 */
6376static void ssh2_channel_init(struct ssh_channel *c)
6377{
6378 Ssh ssh = c->ssh;
6379 c->localid = alloc_channel_id(ssh);
6380 c->closes = 0;
6381 c->throttling_conn = FALSE;
6382 c->v.v2.locwindow = c->v.v2.locmaxwin = c->v.v2.remlocwin =
6383 ssh->cfg.ssh_simple ? OUR_V2_BIGWIN : OUR_V2_WINSIZE;
6384 c->v.v2.winadj_head = c->v.v2.winadj_tail = NULL;
6385 c->v.v2.throttle_state = UNTHROTTLED;
6386 bufchain_init(&c->v.v2.outbuffer);
6387}
6388
6389/*
2e85c969 6390 * Potentially enlarge the window on an SSH-2 channel.
5471d09a 6391 */
9fca3f8c 6392static void ssh2_set_window(struct ssh_channel *c, int newwin)
5471d09a 6393{
51470298 6394 Ssh ssh = c->ssh;
6395
6b69f42e 6396 /*
6397 * Never send WINDOW_ADJUST for a channel that the remote side
6398 * already thinks it's closed; there's no point, since it won't
6399 * be sending any more data anyway.
6400 */
6401 if (c->closes != 0)
6402 return;
6403
d252310a 6404 /*
c9739dba 6405 * If the remote end has a habit of ignoring maxpkt, limit the
6406 * window so that it has no choice (assuming it doesn't ignore the
6407 * window as well).
6408 */
6409 if ((ssh->remote_bugs & BUG_SSH2_MAXPKT) && newwin > OUR_V2_MAXPKT)
6410 newwin = OUR_V2_MAXPKT;
6411
6412
6413 /*
d252310a 6414 * Only send a WINDOW_ADJUST if there's significantly more window
6415 * available than the other end thinks there is. This saves us
6416 * sending a WINDOW_ADJUST for every character in a shell session.
6417 *
6418 * "Significant" is arbitrarily defined as half the window size.
6419 */
3361b80a 6420 if (newwin / 2 >= c->v.v2.locwindow) {
ff3187f6 6421 struct Packet *pktout;
0e443c99 6422 struct winadj *wa;
ff3187f6 6423
0e443c99 6424 /*
6425 * In order to keep track of how much window the client
6426 * actually has available, we'd like it to acknowledge each
6427 * WINDOW_ADJUST. We can't do that directly, so we accompany
6428 * it with a CHANNEL_REQUEST that has to be acknowledged.
6429 *
6430 * This is only necessary if we're opening the window wide.
6431 * If we're not, then throughput is being constrained by
6432 * something other than the maximum window size anyway.
6433 *
6434 * We also only send this if the main channel has finished its
6435 * initial CHANNEL_REQUESTs and installed the default
6436 * CHANNEL_FAILURE handler, so as not to risk giving it
6437 * unexpected CHANNEL_FAILUREs.
6438 */
6439 if (newwin == c->v.v2.locmaxwin &&
6440 ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE]) {
6441 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
6442 ssh2_pkt_adduint32(pktout, c->remoteid);
6443 ssh2_pkt_addstring(pktout, "winadj@putty.projects.tartarus.org");
6444 ssh2_pkt_addbool(pktout, TRUE);
6445 ssh2_pkt_send(ssh, pktout);
6446
6447 /*
6448 * CHANNEL_FAILURE doesn't come with any indication of
6449 * what message caused it, so we have to keep track of the
6450 * outstanding CHANNEL_REQUESTs ourselves.
6451 */
6452 wa = snew(struct winadj);
6453 wa->size = newwin - c->v.v2.locwindow;
6454 wa->next = NULL;
6455 if (!c->v.v2.winadj_head)
6456 c->v.v2.winadj_head = wa;
6457 else
6458 c->v.v2.winadj_tail->next = wa;
6459 c->v.v2.winadj_tail = wa;
6460 if (c->v.v2.throttle_state != UNTHROTTLED)
6461 c->v.v2.throttle_state = UNTHROTTLING;
6462 } else {
6463 /* Pretend the WINDOW_ADJUST was acked immediately. */
6464 c->v.v2.remlocwin = newwin;
6465 c->v.v2.throttle_state = THROTTLED;
6466 }
ff3187f6 6467 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
6468 ssh2_pkt_adduint32(pktout, c->remoteid);
6469 ssh2_pkt_adduint32(pktout, newwin - c->v.v2.locwindow);
6470 ssh2_pkt_send(ssh, pktout);
5471d09a 6471 c->v.v2.locwindow = newwin;
783415f8 6472 }
6473}
6474
e223b7c7 6475/*
6476 * Find the channel associated with a message. If there's no channel,
6477 * or it's not properly open, make a noise about it and return NULL.
6478 */
6479static struct ssh_channel *ssh2_channel_msg(Ssh ssh, struct Packet *pktin)
6480{
6481 unsigned localid = ssh_pkt_getuint32(pktin);
6482 struct ssh_channel *c;
6483
6484 c = find234(ssh->channels, &localid, ssh_channelfind);
6485 if (!c ||
6486 (c->halfopen && pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION &&
6487 pktin->type != SSH2_MSG_CHANNEL_OPEN_FAILURE)) {
6488 char *buf = dupprintf("Received %s for %s channel %u",
6489 ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx,
6490 pktin->type),
6491 c ? "half-open" : "nonexistent", localid);
6492 ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6493 sfree(buf);
6494 return NULL;
6495 }
6496 return c;
6497}
6498
837d6ba6 6499static void ssh2_msg_channel_success(Ssh ssh, struct Packet *pktin)
6500{
6501 /*
6502 * This should never get called. All channel requests are either
6503 * sent with want_reply false or are sent before this handler gets
6504 * installed.
6505 */
6506 struct ssh_channel *c;
6507 struct winadj *wa;
6508
6509 c = ssh2_channel_msg(ssh, pktin);
6510 if (!c)
6511 return;
6512 wa = c->v.v2.winadj_head;
6513 if (wa)
6514 ssh_disconnect(ssh, NULL, "Received SSH_MSG_CHANNEL_SUCCESS for "
6515 "\"winadj@putty.projects.tartarus.org\"",
6516 SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6517 else
6518 ssh_disconnect(ssh, NULL,
6519 "Received unsolicited SSH_MSG_CHANNEL_SUCCESS",
6520 SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6521}
6522
0e443c99 6523static void ssh2_msg_channel_failure(Ssh ssh, struct Packet *pktin)
6524{
6525 /*
6526 * The only time this should get called is for "winadj@putty"
6527 * messages sent above. All other channel requests are either
6528 * sent with want_reply false or are sent before this handler gets
6529 * installed.
6530 */
0e443c99 6531 struct ssh_channel *c;
6532 struct winadj *wa;
6533
e223b7c7 6534 c = ssh2_channel_msg(ssh, pktin);
0e443c99 6535 if (!c)
e223b7c7 6536 return;
0e443c99 6537 wa = c->v.v2.winadj_head;
837d6ba6 6538 if (!wa) {
6539 ssh_disconnect(ssh, NULL,
6540 "Received unsolicited SSH_MSG_CHANNEL_FAILURE",
6541 SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6542 return;
0e443c99 6543 }
837d6ba6 6544 c->v.v2.winadj_head = wa->next;
6545 c->v.v2.remlocwin += wa->size;
6546 sfree(wa);
6547 /*
6548 * winadj messages are only sent when the window is fully open, so
6549 * if we get an ack of one, we know any pending unthrottle is
6550 * complete.
6551 */
6552 if (c->v.v2.throttle_state == UNTHROTTLING)
6553 c->v.v2.throttle_state = UNTHROTTLED;
0e443c99 6554}
6555
51df0ab5 6556static void ssh2_msg_channel_window_adjust(Ssh ssh, struct Packet *pktin)
b09eaa88 6557{
b09eaa88 6558 struct ssh_channel *c;
e223b7c7 6559 c = ssh2_channel_msg(ssh, pktin);
6560 if (!c)
6561 return;
6562 if (!c->closes) {
b09eaa88 6563 c->v.v2.remwindow += ssh_pkt_getuint32(pktin);
1bfc7e93 6564 ssh2_try_send_and_unthrottle(c);
6565 }
b09eaa88 6566}
6567
51df0ab5 6568static void ssh2_msg_channel_data(Ssh ssh, struct Packet *pktin)
6569{
6570 char *data;
6d44acc9 6571 int length;
51df0ab5 6572 struct ssh_channel *c;
e223b7c7 6573 c = ssh2_channel_msg(ssh, pktin);
51df0ab5 6574 if (!c)
e223b7c7 6575 return;
51df0ab5 6576 if (pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
6577 ssh_pkt_getuint32(pktin) != SSH2_EXTENDED_DATA_STDERR)
6578 return; /* extended but not stderr */
6579 ssh_pkt_getstring(pktin, &data, &length);
6580 if (data) {
6581 int bufsize = 0;
6582 c->v.v2.locwindow -= length;
0e443c99 6583 c->v.v2.remlocwin -= length;
51df0ab5 6584 switch (c->type) {
6585 case CHAN_MAINSESSION:
6586 bufsize =
6587 from_backend(ssh->frontend, pktin->type ==
6588 SSH2_MSG_CHANNEL_EXTENDED_DATA,
6589 data, length);
6590 break;
6591 case CHAN_X11:
6592 bufsize = x11_send(c->u.x11.s, data, length);
6593 break;
6594 case CHAN_SOCKDATA:
6595 bufsize = pfd_send(c->u.pfd.s, data, length);
6596 break;
6597 case CHAN_AGENT:
6598 while (length > 0) {
6599 if (c->u.a.lensofar < 4) {
62ddb51e 6600 unsigned int l = min(4 - c->u.a.lensofar,
6601 (unsigned)length);
51df0ab5 6602 memcpy(c->u.a.msglen + c->u.a.lensofar,
6603 data, l);
6604 data += l;
6605 length -= l;
6606 c->u.a.lensofar += l;
6607 }
6608 if (c->u.a.lensofar == 4) {
6609 c->u.a.totallen =
6610 4 + GET_32BIT(c->u.a.msglen);
6611 c->u.a.message = snewn(c->u.a.totallen,
6612 unsigned char);
6613 memcpy(c->u.a.message, c->u.a.msglen, 4);
6614 }
6615 if (c->u.a.lensofar >= 4 && length > 0) {
aa63ab7e 6616 unsigned int l =
51df0ab5 6617 min(c->u.a.totallen - c->u.a.lensofar,
62ddb51e 6618 (unsigned)length);
51df0ab5 6619 memcpy(c->u.a.message + c->u.a.lensofar,
6620 data, l);
6621 data += l;
6622 length -= l;
6623 c->u.a.lensofar += l;
6624 }
6625 if (c->u.a.lensofar == c->u.a.totallen) {
6626 void *reply;
6627 int replylen;
6628 if (agent_query(c->u.a.message,
6629 c->u.a.totallen,
6630 &reply, &replylen,
6631 ssh_agentf_callback, c))
6632 ssh_agentf_callback(c, reply, replylen);
6633 sfree(c->u.a.message);
6634 c->u.a.lensofar = 0;
6635 }
6636 }
6637 bufsize = 0;
6638 break;
6639 }
6640 /*
0e443c99 6641 * If it looks like the remote end hit the end of its window,
6642 * and we didn't want it to do that, think about using a
6643 * larger window.
6644 */
6645 if (c->v.v2.remlocwin <= 0 && c->v.v2.throttle_state == UNTHROTTLED &&
6646 c->v.v2.locmaxwin < 0x40000000)
6647 c->v.v2.locmaxwin += OUR_V2_WINSIZE;
6648 /*
51df0ab5 6649 * If we are not buffering too much data,
6650 * enlarge the window again at the remote side.
467e064d 6651 * If we are buffering too much, we may still
6652 * need to adjust the window if the server's
6653 * sent excess data.
51df0ab5 6654 */
9b53e9b8 6655 ssh2_set_window(c, bufsize < c->v.v2.locmaxwin ?
6656 c->v.v2.locmaxwin - bufsize : 0);
ff68564b 6657 /*
6658 * If we're either buffering way too much data, or if we're
6659 * buffering anything at all and we're in "simple" mode,
6660 * throttle the whole channel.
6661 */
6662 if ((bufsize > c->v.v2.locmaxwin ||
6663 (ssh->cfg.ssh_simple && bufsize > 0)) &&
6664 !c->throttling_conn) {
6665 c->throttling_conn = 1;
6666 ssh_throttle_conn(ssh, +1);
6667 }
51df0ab5 6668 }
6669}
6670
6671static void ssh2_msg_channel_eof(Ssh ssh, struct Packet *pktin)
6672{
51df0ab5 6673 struct ssh_channel *c;
6674
e223b7c7 6675 c = ssh2_channel_msg(ssh, pktin);
51df0ab5 6676 if (!c)
e223b7c7 6677 return;
51df0ab5 6678
6679 if (c->type == CHAN_X11) {
6680 /*
6681 * Remote EOF on an X11 channel means we should
6682 * wrap up and close the channel ourselves.
6683 */
6684 x11_close(c->u.x11.s);
5959132d 6685 c->u.x11.s = NULL;
51df0ab5 6686 sshfwd_close(c);
6687 } else if (c->type == CHAN_AGENT) {
6688 sshfwd_close(c);
6689 } else if (c->type == CHAN_SOCKDATA) {
6690 pfd_close(c->u.pfd.s);
5959132d 6691 c->u.pfd.s = NULL;
51df0ab5 6692 sshfwd_close(c);
6693 }
6694}
6695
6696static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
6697{
51df0ab5 6698 struct ssh_channel *c;
6699 struct Packet *pktout;
6700
e223b7c7 6701 c = ssh2_channel_msg(ssh, pktin);
6702 if (!c)
51df0ab5 6703 return;
51df0ab5 6704 /* Do pre-close processing on the channel. */
6705 switch (c->type) {
6706 case CHAN_MAINSESSION:
6707 ssh->mainchan = NULL;
6708 update_specials_menu(ssh->frontend);
6709 break;
6710 case CHAN_X11:
6711 if (c->u.x11.s != NULL)
6712 x11_close(c->u.x11.s);
6713 sshfwd_close(c);
6714 break;
6715 case CHAN_AGENT:
6716 sshfwd_close(c);
6717 break;
6718 case CHAN_SOCKDATA:
6719 if (c->u.pfd.s != NULL)
6720 pfd_close(c->u.pfd.s);
6721 sshfwd_close(c);
6722 break;
6723 }
6724 if (c->closes == 0) {
6725 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6726 ssh2_pkt_adduint32(pktout, c->remoteid);
6727 ssh2_pkt_send(ssh, pktout);
6728 }
6729 del234(ssh->channels, c);
6730 bufchain_clear(&c->v.v2.outbuffer);
6731 sfree(c);
6732
6733 /*
6734 * See if that was the last channel left open.
6735 * (This is only our termination condition if we're
6736 * not running in -N mode.)
6737 */
6738 if (!ssh->cfg.ssh_no_shell && count234(ssh->channels) == 0) {
51df0ab5 6739 /*
6740 * We used to send SSH_MSG_DISCONNECT here,
6741 * because I'd believed that _every_ conforming
2e85c969 6742 * SSH-2 connection had to end with a disconnect
51df0ab5 6743 * being sent by at least one side; apparently
6744 * I was wrong and it's perfectly OK to
6745 * unceremoniously slam the connection shut
6746 * when you're done, and indeed OpenSSH feels
6747 * this is more polite than sending a
6748 * DISCONNECT. So now we don't.
6749 */
9e296bfa 6750 ssh_disconnect(ssh, "All channels closed", NULL, 0, TRUE);
51df0ab5 6751 }
6752}
6753
6754static void ssh2_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
6755{
51df0ab5 6756 struct ssh_channel *c;
6757 struct Packet *pktout;
6758
e223b7c7 6759 c = ssh2_channel_msg(ssh, pktin);
51df0ab5 6760 if (!c)
e223b7c7 6761 return;
51df0ab5 6762 if (c->type != CHAN_SOCKDATA_DORMANT)
6763 return; /* dunno why they're confirming this */
6764 c->remoteid = ssh_pkt_getuint32(pktin);
64d6ff88 6765 c->halfopen = FALSE;
51df0ab5 6766 c->type = CHAN_SOCKDATA;
6767 c->v.v2.remwindow = ssh_pkt_getuint32(pktin);
6768 c->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
6769 if (c->u.pfd.s)
6770 pfd_confirm(c->u.pfd.s);
6771 if (c->closes) {
6772 /*
6773 * We have a pending close on this channel,
6774 * which we decided on before the server acked
6775 * the channel open. So now we know the
6776 * remoteid, we can close it again.
6777 */
6778 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6779 ssh2_pkt_adduint32(pktout, c->remoteid);
6780 ssh2_pkt_send(ssh, pktout);
6781 }
6782}
6783
6784static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
6785{
6786 static const char *const reasons[] = {
6787 "<unknown reason code>",
6788 "Administratively prohibited",
6789 "Connect failed",
6790 "Unknown channel type",
6791 "Resource shortage",
6792 };
51df0ab5 6793 unsigned reason_code;
6794 char *reason_string;
6795 int reason_length;
51df0ab5 6796 struct ssh_channel *c;
e223b7c7 6797 c = ssh2_channel_msg(ssh, pktin);
51df0ab5 6798 if (!c)
e223b7c7 6799 return;
51df0ab5 6800 if (c->type != CHAN_SOCKDATA_DORMANT)
6801 return; /* dunno why they're failing this */
6802
6803 reason_code = ssh_pkt_getuint32(pktin);
6804 if (reason_code >= lenof(reasons))
6805 reason_code = 0; /* ensure reasons[reason_code] in range */
6806 ssh_pkt_getstring(pktin, &reason_string, &reason_length);
fb983202 6807 logeventf(ssh, "Forwarded connection refused by server: %s [%.*s]",
6808 reasons[reason_code], reason_length, reason_string);
51df0ab5 6809
6810 pfd_close(c->u.pfd.s);
6811
6812 del234(ssh->channels, c);
6813 sfree(c);
6814}
6815
6816static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin)
6817{
51df0ab5 6818 char *type;
6819 int typelen, want_reply;
6820 int reply = SSH2_MSG_CHANNEL_FAILURE; /* default */
6821 struct ssh_channel *c;
6822 struct Packet *pktout;
6823
e223b7c7 6824 c = ssh2_channel_msg(ssh, pktin);
6825 if (!c)
6826 return;
51df0ab5 6827 ssh_pkt_getstring(pktin, &type, &typelen);
6828 want_reply = ssh2_pkt_getbool(pktin);
6829
6830 /*
51df0ab5 6831 * Having got the channel number, we now look at
6832 * the request type string to see if it's something
6833 * we recognise.
6834 */
6835 if (c == ssh->mainchan) {
6836 /*
6837 * We recognise "exit-status" and "exit-signal" on
6838 * the primary channel.
6839 */
6840 if (typelen == 11 &&
6841 !memcmp(type, "exit-status", 11)) {
6842
6843 ssh->exitcode = ssh_pkt_getuint32(pktin);
6844 logeventf(ssh, "Server sent command exit status %d",
6845 ssh->exitcode);
6846 reply = SSH2_MSG_CHANNEL_SUCCESS;
6847
6848 } else if (typelen == 11 &&
6849 !memcmp(type, "exit-signal", 11)) {
6850
6851 int is_plausible = TRUE, is_int = FALSE;
6852 char *fmt_sig = "", *fmt_msg = "";
6853 char *msg;
6854 int msglen = 0, core = FALSE;
6855 /* ICK: older versions of OpenSSH (e.g. 3.4p1)
6856 * provide an `int' for the signal, despite its
bccbeb71 6857 * having been a `string' in the drafts of RFC 4254 since at
51df0ab5 6858 * least 2001. (Fixed in session.c 1.147.) Try to
6859 * infer which we can safely parse it as. */
6860 {
6861 unsigned char *p = pktin->body +
6862 pktin->savedpos;
6863 long len = pktin->length - pktin->savedpos;
6864 unsigned long num = GET_32BIT(p); /* what is it? */
6865 /* If it's 0, it hardly matters; assume string */
6866 if (num == 0) {
6867 is_int = FALSE;
6868 } else {
6869 int maybe_int = FALSE, maybe_str = FALSE;
6870#define CHECK_HYPOTHESIS(offset, result) \
6871 do { \
6872 long q = offset; \
6873 if (q >= 0 && q+4 <= len) { \
6874 q = q + 4 + GET_32BIT(p+q); \
6875 if (q >= 0 && q+4 <= len && \
c849ff23 6876 ((q = q + 4 + GET_32BIT(p+q))!= 0) && q == len) \
51df0ab5 6877 result = TRUE; \
6878 } \
6879 } while(0)
6880 CHECK_HYPOTHESIS(4+1, maybe_int);
6881 CHECK_HYPOTHESIS(4+num+1, maybe_str);
6882#undef CHECK_HYPOTHESIS
6883 if (maybe_int && !maybe_str)
6884 is_int = TRUE;
6885 else if (!maybe_int && maybe_str)
6886 is_int = FALSE;
6887 else
6888 /* Crikey. Either or neither. Panic. */
6889 is_plausible = FALSE;
6890 }
6891 }
d051d1b4 6892 ssh->exitcode = 128; /* means `unknown signal' */
51df0ab5 6893 if (is_plausible) {
6894 if (is_int) {
6895 /* Old non-standard OpenSSH. */
6896 int signum = ssh_pkt_getuint32(pktin);
6897 fmt_sig = dupprintf(" %d", signum);
d051d1b4 6898 ssh->exitcode = 128 + signum;
51df0ab5 6899 } else {
bccbeb71 6900 /* As per RFC 4254. */
51df0ab5 6901 char *sig;
6902 int siglen;
6903 ssh_pkt_getstring(pktin, &sig, &siglen);
6904 /* Signal name isn't supposed to be blank, but
6905 * let's cope gracefully if it is. */
6906 if (siglen) {
6907 fmt_sig = dupprintf(" \"%.*s\"",
6908 siglen, sig);
6909 }
d051d1b4 6910
6911 /*
6912 * Really hideous method of translating the
6913 * signal description back into a locally
6914 * meaningful number.
6915 */
6916
6917 if (0)
6918 ;
b707973a 6919#define TRANSLATE_SIGNAL(s) \
6920 else if (siglen == lenof(#s)-1 && !memcmp(sig, #s, siglen)) \
6921 ssh->exitcode = 128 + SIG ## s
d051d1b4 6922#ifdef SIGABRT
b707973a 6923 TRANSLATE_SIGNAL(ABRT);
d051d1b4 6924#endif
6925#ifdef SIGALRM
b707973a 6926 TRANSLATE_SIGNAL(ALRM);
d051d1b4 6927#endif
6928#ifdef SIGFPE
b707973a 6929 TRANSLATE_SIGNAL(FPE);
d051d1b4 6930#endif
6931#ifdef SIGHUP
b707973a 6932 TRANSLATE_SIGNAL(HUP);
d051d1b4 6933#endif
6934#ifdef SIGILL
b707973a 6935 TRANSLATE_SIGNAL(ILL);
d051d1b4 6936#endif
6937#ifdef SIGINT
b707973a 6938 TRANSLATE_SIGNAL(INT);
d051d1b4 6939#endif
6940#ifdef SIGKILL
b707973a 6941 TRANSLATE_SIGNAL(KILL);
d051d1b4 6942#endif
6943#ifdef SIGPIPE
b707973a 6944 TRANSLATE_SIGNAL(PIPE);
d051d1b4 6945#endif
6946#ifdef SIGQUIT
b707973a 6947 TRANSLATE_SIGNAL(QUIT);
d051d1b4 6948#endif
6949#ifdef SIGSEGV
b707973a 6950 TRANSLATE_SIGNAL(SEGV);
d051d1b4 6951#endif
6952#ifdef SIGTERM
b707973a 6953 TRANSLATE_SIGNAL(TERM);
d051d1b4 6954#endif
6955#ifdef SIGUSR1
b707973a 6956 TRANSLATE_SIGNAL(USR1);
d051d1b4 6957#endif
6958#ifdef SIGUSR2
b707973a 6959 TRANSLATE_SIGNAL(USR2);
d051d1b4 6960#endif
b707973a 6961#undef TRANSLATE_SIGNAL
d051d1b4 6962 else
6963 ssh->exitcode = 128;
51df0ab5 6964 }
6965 core = ssh2_pkt_getbool(pktin);
6966 ssh_pkt_getstring(pktin, &msg, &msglen);
6967 if (msglen) {
6968 fmt_msg = dupprintf(" (\"%.*s\")", msglen, msg);
6969 }
6970 /* ignore lang tag */
6971 } /* else don't attempt to parse */
6972 logeventf(ssh, "Server exited on signal%s%s%s",
6973 fmt_sig, core ? " (core dumped)" : "",
6974 fmt_msg);
6975 if (*fmt_sig) sfree(fmt_sig);
6976 if (*fmt_msg) sfree(fmt_msg);
6977 reply = SSH2_MSG_CHANNEL_SUCCESS;
6978
6979 }
6980 } else {
6981 /*
6982 * This is a channel request we don't know
6983 * about, so we now either ignore the request
6984 * or respond with CHANNEL_FAILURE, depending
6985 * on want_reply.
6986 */
6987 reply = SSH2_MSG_CHANNEL_FAILURE;
6988 }
6989 if (want_reply) {
6990 pktout = ssh2_pkt_init(reply);
6991 ssh2_pkt_adduint32(pktout, c->remoteid);
6992 ssh2_pkt_send(ssh, pktout);
6993 }
6994}
6995
6996static void ssh2_msg_global_request(Ssh ssh, struct Packet *pktin)
6997{
6998 char *type;
6999 int typelen, want_reply;
7000 struct Packet *pktout;
7001
7002 ssh_pkt_getstring(pktin, &type, &typelen);
7003 want_reply = ssh2_pkt_getbool(pktin);
7004
7005 /*
7006 * We currently don't support any global requests
7007 * at all, so we either ignore the request or
7008 * respond with REQUEST_FAILURE, depending on
7009 * want_reply.
7010 */
7011 if (want_reply) {
7012 pktout = ssh2_pkt_init(SSH2_MSG_REQUEST_FAILURE);
7013 ssh2_pkt_send(ssh, pktout);
7014 }
7015}
7016
7017static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin)
7018{
7019 char *type;
7020 int typelen;
7021 char *peeraddr;
7022 int peeraddrlen;
7023 int peerport;
7024 char *error = NULL;
7025 struct ssh_channel *c;
7026 unsigned remid, winsize, pktsize;
7027 struct Packet *pktout;
7028
7029 ssh_pkt_getstring(pktin, &type, &typelen);
7030 c = snew(struct ssh_channel);
7031 c->ssh = ssh;
7032
7033 remid = ssh_pkt_getuint32(pktin);
7034 winsize = ssh_pkt_getuint32(pktin);
7035 pktsize = ssh_pkt_getuint32(pktin);
7036
7037 if (typelen == 3 && !memcmp(type, "x11", 3)) {
7038 char *addrstr;
5907ebda 7039 const char *x11err;
51df0ab5 7040
7041 ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
7042 addrstr = snewn(peeraddrlen+1, char);
7043 memcpy(addrstr, peeraddr, peeraddrlen);
7044 addrstr[peeraddrlen] = '\0';
7045 peerport = ssh_pkt_getuint32(pktin);
7046
7047 logeventf(ssh, "Received X11 connect request from %s:%d",
7048 addrstr, peerport);
7049
7050 if (!ssh->X11_fwd_enabled)
7051 error = "X11 forwarding is not enabled";
5907ebda 7052 else if ((x11err = x11_init(&c->u.x11.s, ssh->x11disp, c,
7053 addrstr, peerport, &ssh->cfg)) != NULL) {
7054 logeventf(ssh, "Local X11 connection failed: %s", x11err);
51df0ab5 7055 error = "Unable to open an X11 connection";
7056 } else {
7057 logevent("Opening X11 forward connection succeeded");
7058 c->type = CHAN_X11;
7059 }
7060
7061 sfree(addrstr);
7062 } else if (typelen == 15 &&
7063 !memcmp(type, "forwarded-tcpip", 15)) {
7064 struct ssh_rportfwd pf, *realpf;
7065 char *dummy;
7066 int dummylen;
7067 ssh_pkt_getstring(pktin, &dummy, &dummylen);/* skip address */
7068 pf.sport = ssh_pkt_getuint32(pktin);
7069 ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
7070 peerport = ssh_pkt_getuint32(pktin);
7071 realpf = find234(ssh->rportfwds, &pf, NULL);
7072 logeventf(ssh, "Received remote port %d open request "
7073 "from %s:%d", pf.sport, peeraddr, peerport);
7074 if (realpf == NULL) {
7075 error = "Remote port is not recognised";
7076 } else {
7077 const char *e = pfd_newconnect(&c->u.pfd.s,
7078 realpf->dhost,
7079 realpf->dport, c,
05581745 7080 &ssh->cfg,
7081 realpf->pfrec->addressfamily);
51df0ab5 7082 logeventf(ssh, "Attempting to forward remote port to "
7083 "%s:%d", realpf->dhost, realpf->dport);
7084 if (e != NULL) {
7085 logeventf(ssh, "Port open failed: %s", e);
7086 error = "Port open failed";
7087 } else {
7088 logevent("Forwarded port opened successfully");
7089 c->type = CHAN_SOCKDATA;
7090 }
7091 }
7092 } else if (typelen == 22 &&
c49cf994 7093 !memcmp(type, "auth-agent@openssh.com", 22)) {
51df0ab5 7094 if (!ssh->agentfwd_enabled)
7095 error = "Agent forwarding is not enabled";
7096 else {
7097 c->type = CHAN_AGENT; /* identify channel type */
7098 c->u.a.lensofar = 0;
7099 }
7100 } else {
7101 error = "Unsupported channel type requested";
7102 }
7103
7104 c->remoteid = remid;
64d6ff88 7105 c->halfopen = FALSE;
51df0ab5 7106 if (error) {
7107 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_FAILURE);
7108 ssh2_pkt_adduint32(pktout, c->remoteid);
7109 ssh2_pkt_adduint32(pktout, SSH2_OPEN_CONNECT_FAILED);
7110 ssh2_pkt_addstring(pktout, error);
7111 ssh2_pkt_addstring(pktout, "en"); /* language tag */
7112 ssh2_pkt_send(ssh, pktout);
7113 logeventf(ssh, "Rejected channel open: %s", error);
7114 sfree(c);
7115 } else {
94bdfe40 7116 ssh2_channel_init(c);
51df0ab5 7117 c->v.v2.remwindow = winsize;
7118 c->v.v2.remmaxpkt = pktsize;
51df0ab5 7119 add234(ssh->channels, c);
7120 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
7121 ssh2_pkt_adduint32(pktout, c->remoteid);
7122 ssh2_pkt_adduint32(pktout, c->localid);
7123 ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);
954d5c5a 7124 ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
51df0ab5 7125 ssh2_pkt_send(ssh, pktout);
7126 }
7127}
7128
6bbce591 7129/*
7130 * Buffer banner messages for later display at some convenient point.
7131 */
7132static void ssh2_msg_userauth_banner(Ssh ssh, struct Packet *pktin)
7133{
7134 /* Arbitrary limit to prevent unbounded inflation of buffer */
7135 if (bufchain_size(&ssh->banner) <= 131072) {
7136 char *banner = NULL;
7137 int size = 0;
7138 ssh_pkt_getstring(pktin, &banner, &size);
7139 if (banner)
7140 bufchain_add(&ssh->banner, banner, size);
7141 }
7142}
7143
c6ccd5c2 7144/* Helper function to deal with sending tty modes for "pty-req" */
7145static void ssh2_send_ttymode(void *data, char *mode, char *val)
7146{
7147 struct Packet *pktout = (struct Packet *)data;
7148 int i = 0;
7149 unsigned int arg = 0;
7150 while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
7151 if (i == lenof(ssh_ttymodes)) return;
7152 switch (ssh_ttymodes[i].type) {
7153 case TTY_OP_CHAR:
7154 arg = ssh_tty_parse_specchar(val);
7155 break;
7156 case TTY_OP_BOOL:
7157 arg = ssh_tty_parse_boolean(val);
7158 break;
7159 }
7160 ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
7161 ssh2_pkt_adduint32(pktout, arg);
7162}
7163
783415f8 7164/*
2e85c969 7165 * Handle the SSH-2 userauth and connection layers.
7cca0d81 7166 */
ff3187f6 7167static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
7168 struct Packet *pktin)
7cca0d81 7169{
51470298 7170 struct do_ssh2_authconn_state {
7171 enum {
51470298 7172 AUTH_TYPE_NONE,
7173 AUTH_TYPE_PUBLICKEY,
7174 AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
7175 AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
7176 AUTH_TYPE_PASSWORD,
42af6a67 7177 AUTH_TYPE_GSSAPI,
51470298 7178 AUTH_TYPE_KEYBOARD_INTERACTIVE,
7179 AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
7180 } type;
a1a1fae4 7181 int done_service_req;
51470298 7182 int gotit, need_pw, can_pubkey, can_passwd, can_keyb_inter;
94cd7c3a 7183 int tried_pubkey_config, done_agent;
bf84a03a 7184#ifndef NO_GSSAPI
42af6a67 7185 int can_gssapi;
7186 int tried_gssapi;
bf84a03a 7187#endif
edd0cb8a 7188 int kbd_inter_refused;
51470298 7189 int we_are_in;
edd0cb8a 7190 prompts_t *cur_prompt;
7191 int num_prompts;
51470298 7192 char username[100];
e955d348 7193 char *password;
51470298 7194 int got_username;
51470298 7195 void *publickey_blob;
7196 int publickey_bloblen;
edd0cb8a 7197 int publickey_encrypted;
7198 char *publickey_algorithm;
7199 char *publickey_comment;
94cd7c3a 7200 unsigned char agent_request[5], *agent_response, *agentp;
7201 int agent_responselen;
7202 unsigned char *pkblob_in_agent;
51470298 7203 int keyi, nkeys;
51470298 7204 char *pkblob, *alg, *commentp;
7205 int pklen, alglen, commentlen;
7206 int siglen, retlen, len;
7207 char *q, *agentreq, *ret;
7208 int try_send;
73feed4f 7209 int num_env, env_left, env_ok;
ff3187f6 7210 struct Packet *pktout;
bf84a03a 7211#ifndef NO_GSSAPI
42af6a67 7212 Ssh_gss_ctx gss_ctx;
7213 Ssh_gss_buf gss_buf;
7214 Ssh_gss_buf gss_rcvtok, gss_sndtok;
7215 Ssh_gss_name gss_srv_name;
7216 Ssh_gss_stat gss_stat;
bf84a03a 7217#endif
51470298 7218 };
7219 crState(do_ssh2_authconn_state);
7220
7221 crBegin(ssh->do_ssh2_authconn_crstate);
e5574168 7222
a1a1fae4 7223 s->done_service_req = FALSE;
7224 s->we_are_in = FALSE;
bf84a03a 7225#ifndef NO_GSSAPI
42af6a67 7226 s->tried_gssapi = FALSE;
bf84a03a 7227#endif
42af6a67 7228
a1a1fae4 7229 if (!ssh->cfg.ssh_no_userauth) {
7230 /*
7231 * Request userauth protocol, and await a response to it.
7232 */
7233 s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
7234 ssh2_pkt_addstring(s->pktout, "ssh-userauth");
7235 ssh2_pkt_send(ssh, s->pktout);
7236 crWaitUntilV(pktin);
7237 if (pktin->type == SSH2_MSG_SERVICE_ACCEPT)
7238 s->done_service_req = TRUE;
7239 }
7240 if (!s->done_service_req) {
7241 /*
7242 * Request connection protocol directly, without authentication.
7243 */
7244 s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
7245 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7246 ssh2_pkt_send(ssh, s->pktout);
7247 crWaitUntilV(pktin);
7248 if (pktin->type == SSH2_MSG_SERVICE_ACCEPT) {
7249 s->we_are_in = TRUE; /* no auth required */
7250 } else {
7251 bombout(("Server refused service request"));
7252 crStopV;
7253 }
8d5de777 7254 }
7cca0d81 7255
94cd7c3a 7256 /* Arrange to be able to deal with any BANNERs that come in.
7257 * (We do this now as packets may come in during the next bit.) */
7258 bufchain_init(&ssh->banner);
7259 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] =
7260 ssh2_msg_userauth_banner;
7261
7cca0d81 7262 /*
edd0cb8a 7263 * Misc one-time setup for authentication.
7264 */
7265 s->publickey_blob = NULL;
7266 if (!s->we_are_in) {
7267
7268 /*
7269 * Load the public half of any configured public key file
7270 * for later use.
7271 */
7272 if (!filename_is_null(ssh->cfg.keyfile)) {
7273 int keytype;
7274 logeventf(ssh, "Reading private key file \"%.150s\"",
7275 filename_to_str(&ssh->cfg.keyfile));
7276 keytype = key_type(&ssh->cfg.keyfile);
7277 if (keytype == SSH_KEYTYPE_SSH2) {
7278 const char *error;
7279 s->publickey_blob =
7280 ssh2_userkey_loadpub(&ssh->cfg.keyfile,
7281 &s->publickey_algorithm,
7282 &s->publickey_bloblen,
7283 &s->publickey_comment, &error);
7284 if (s->publickey_blob) {
7285 s->publickey_encrypted =
7286 ssh2_userkey_encrypted(&ssh->cfg.keyfile, NULL);
7287 } else {
7288 char *msgbuf;
7289 logeventf(ssh, "Unable to load private key (%s)",
7290 error);
7291 msgbuf = dupprintf("Unable to load private key file "
7292 "\"%.150s\" (%s)\r\n",
7293 filename_to_str(&ssh->cfg.keyfile),
7294 error);
7295 c_write_str(ssh, msgbuf);
7296 sfree(msgbuf);
7297 }
7298 } else {
7299 char *msgbuf;
7300 logeventf(ssh, "Unable to use this key file (%s)",
7301 key_type_to_str(keytype));
7302 msgbuf = dupprintf("Unable to use key file \"%.150s\""
7303 " (%s)\r\n",
7304 filename_to_str(&ssh->cfg.keyfile),
7305 key_type_to_str(keytype));
7306 c_write_str(ssh, msgbuf);
7307 sfree(msgbuf);
7308 s->publickey_blob = NULL;
7309 }
7310 }
7311
94cd7c3a 7312 /*
7313 * Find out about any keys Pageant has (but if there's a
7314 * public key configured, filter out all others).
7315 */
7316 s->nkeys = 0;
7317 s->agent_response = NULL;
7318 s->pkblob_in_agent = NULL;
116f229d 7319 if (ssh->cfg.tryagent && agent_exists()) {
94cd7c3a 7320
7321 void *r;
7322
7323 logevent("Pageant is running. Requesting keys.");
7324
7325 /* Request the keys held by the agent. */
7326 PUT_32BIT(s->agent_request, 1);
7327 s->agent_request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
7328 if (!agent_query(s->agent_request, 5, &r, &s->agent_responselen,
7329 ssh_agent_callback, ssh)) {
7330 do {
7331 crReturnV;
7332 if (pktin) {
7333 bombout(("Unexpected data from server while"
7334 " waiting for agent response"));
7335 crStopV;
7336 }
7337 } while (pktin || inlen > 0);
7338 r = ssh->agent_response;
7339 s->agent_responselen = ssh->agent_response_len;
7340 }
7341 s->agent_response = (unsigned char *) r;
7342 if (s->agent_response && s->agent_responselen >= 5 &&
7343 s->agent_response[4] == SSH2_AGENT_IDENTITIES_ANSWER) {
7344 int keyi;
7345 unsigned char *p;
7346 p = s->agent_response + 5;
7347 s->nkeys = GET_32BIT(p);
7348 p += 4;
7349 logeventf(ssh, "Pageant has %d SSH-2 keys", s->nkeys);
7350 if (s->publickey_blob) {
7351 /* See if configured key is in agent. */
7352 for (keyi = 0; keyi < s->nkeys; keyi++) {
7353 s->pklen = GET_32BIT(p);
7354 if (s->pklen == s->publickey_bloblen &&
7355 !memcmp(p+4, s->publickey_blob,
7356 s->publickey_bloblen)) {
7357 logeventf(ssh, "Pageant key #%d matches "
7358 "configured key file", keyi);
7359 s->keyi = keyi;
7360 s->pkblob_in_agent = p;
7361 break;
7362 }
7363 p += 4 + s->pklen;
7364 p += GET_32BIT(p) + 4; /* comment */
7365 }
7366 if (!s->pkblob_in_agent) {
7367 logevent("Configured key file not in Pageant");
7368 s->nkeys = 0;
7369 }
7370 }
7371 }
7372 }
7373
edd0cb8a 7374 }
7375
7376 /*
1408a877 7377 * We repeat this whole loop, including the username prompt,
7378 * until we manage a successful authentication. If the user
51470298 7379 * types the wrong _password_, they can be sent back to the
7380 * beginning to try another username, if this is configured on.
7381 * (If they specify a username in the config, they are never
7382 * asked, even if they do give a wrong password.)
1408a877 7383 *
7384 * I think this best serves the needs of
7385 *
7386 * - the people who have no configuration, no keys, and just
7387 * want to try repeated (username,password) pairs until they
7388 * type both correctly
7389 *
7390 * - people who have keys and configuration but occasionally
7391 * need to fall back to passwords
7392 *
7393 * - people with a key held in Pageant, who might not have
7394 * logged in to a particular machine before; so they want to
7395 * type a username, and then _either_ their key will be
7396 * accepted, _or_ they will type a password. If they mistype
7397 * the username they will want to be able to get back and
7398 * retype it!
7cca0d81 7399 */
51470298 7400 s->username[0] = '\0';
7401 s->got_username = FALSE;
a1a1fae4 7402 while (!s->we_are_in) {
1408a877 7403 /*
7404 * Get a username.
7405 */
86916870 7406 if (s->got_username && !ssh->cfg.change_username) {
5bb641e1 7407 /*
7408 * We got a username last time round this loop, and
7409 * with change_username turned off we don't try to get
7410 * it again.
7411 */
471c20b0 7412 } else if (!get_remote_username(&ssh->cfg, s->username,
7413 sizeof(s->username))) {
edd0cb8a 7414 int ret; /* need not be kept over crReturn */
7415 s->cur_prompt = new_prompts(ssh->frontend);
7416 s->cur_prompt->to_server = TRUE;
7417 s->cur_prompt->name = dupstr("SSH login name");
7418 add_prompt(s->cur_prompt, dupstr("login as: "), TRUE,
7419 lenof(s->username));
7420 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7421 while (ret < 0) {
51470298 7422 ssh->send_ok = 1;
edd0cb8a 7423 crWaitUntilV(!pktin);
7424 ret = get_userpass_input(s->cur_prompt, in, inlen);
7425 ssh->send_ok = 0;
32874aea 7426 }
edd0cb8a 7427 if (!ret) {
7428 /*
7429 * get_userpass_input() failed to get a username.
7430 * Terminate.
7431 */
7432 free_prompts(s->cur_prompt);
7433 ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
7434 crStopV;
7435 }
7436 memcpy(s->username, s->cur_prompt->prompts[0]->result,
7437 lenof(s->username));
7438 free_prompts(s->cur_prompt);
7cca0d81 7439 } else {
57356d63 7440 char *stuff;
65a22376 7441 if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
57356d63 7442 stuff = dupprintf("Using username \"%s\".\r\n", s->username);
51470298 7443 c_write_str(ssh, stuff);
57356d63 7444 sfree(stuff);
7cca0d81 7445 }
7446 }
51470298 7447 s->got_username = TRUE;
7cca0d81 7448
65a22376 7449 /*
1408a877 7450 * Send an authentication request using method "none": (a)
7451 * just in case it succeeds, and (b) so that we know what
7452 * authentication methods we can usefully try next.
65a22376 7453 */
acab36bc 7454 ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
51470298 7455
ff3187f6 7456 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7457 ssh2_pkt_addstring(s->pktout, s->username);
7458 ssh2_pkt_addstring(s->pktout, "ssh-connection");/* service requested */
7459 ssh2_pkt_addstring(s->pktout, "none"); /* method */
7460 ssh2_pkt_send(ssh, s->pktout);
51470298 7461 s->type = AUTH_TYPE_NONE;
7462 s->gotit = FALSE;
7463 s->we_are_in = FALSE;
7464
7465 s->tried_pubkey_config = FALSE;
6ac3a551 7466 s->kbd_inter_refused = FALSE;
65a22376 7467
94cd7c3a 7468 /* Reset agent request state. */
7469 s->done_agent = FALSE;
7470 if (s->agent_response) {
7471 if (s->pkblob_in_agent) {
7472 s->agentp = s->pkblob_in_agent;
7473 } else {
7474 s->agentp = s->agent_response + 5 + 4;
7475 s->keyi = 0;
7476 }
7477 }
7478
1408a877 7479 while (1) {
7480 /*
7481 * Wait for the result of the last authentication request.
7482 */
51470298 7483 if (!s->gotit)
ff3187f6 7484 crWaitUntilV(pktin);
6bbce591 7485 /*
7486 * Now is a convenient point to spew any banner material
7487 * that we've accumulated. (This should ensure that when
7488 * we exit the auth loop, we haven't any left to deal
7489 * with.)
7490 */
7491 {
7492 int size = bufchain_size(&ssh->banner);
32874aea 7493 /*
7494 * Don't show the banner if we're operating in
7495 * non-verbose non-interactive mode. (It's probably
7496 * a script, which means nobody will read the
7497 * banner _anyway_, and moreover the printing of
7498 * the banner will screw up processing on the
7499 * output of (say) plink.)
7500 */
6bbce591 7501 if (size && (flags & (FLAG_VERBOSE | FLAG_INTERACTIVE))) {
7502 char *banner = snewn(size, char);
7503 bufchain_fetch(&ssh->banner, banner, size);
7504 c_write_untrusted(ssh, banner, size);
7505 sfree(banner);
32874aea 7506 }
6bbce591 7507 bufchain_clear(&ssh->banner);
1408a877 7508 }
ff3187f6 7509 if (pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
1408a877 7510 logevent("Access granted");
51470298 7511 s->we_are_in = TRUE;
1408a877 7512 break;
7513 }
65a22376 7514
42af6a67 7515 if (pktin->type != SSH2_MSG_USERAUTH_FAILURE && s->type != AUTH_TYPE_GSSAPI) {
e955d348 7516 bombout(("Strange packet received during authentication: "
7517 "type %d", pktin->type));
7ffdbc1a 7518 crStopV;
65a22376 7519 }
7520
51470298 7521 s->gotit = FALSE;
65a22376 7522
1408a877 7523 /*
7524 * OK, we're now sitting on a USERAUTH_FAILURE message, so
7525 * we can look at the string in it and know what we can
7526 * helpfully try next.
7527 */
ff3187f6 7528 if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
1408a877 7529 char *methods;
7530 int methlen;
ff3187f6 7531 ssh_pkt_getstring(pktin, &methods, &methlen);
ff3187f6 7532 if (!ssh2_pkt_getbool(pktin)) {
1408a877 7533 /*
7534 * We have received an unequivocal Access
7535 * Denied. This can translate to a variety of
7536 * messages:
7537 *
7538 * - if we'd just tried "none" authentication,
7539 * it's not worth printing anything at all
7540 *
7541 * - if we'd just tried a public key _offer_,
7542 * the message should be "Server refused our
7543 * key" (or no message at all if the key
7544 * came from Pageant)
7545 *
7546 * - if we'd just tried anything else, the
7547 * message really should be "Access denied".
7548 *
7549 * Additionally, if we'd just tried password
7550 * authentication, we should break out of this
7551 * whole loop so as to go back to the username
91f57d1f 7552 * prompt (iff we're configured to allow
7553 * username change attempts).
1408a877 7554 */
51470298 7555 if (s->type == AUTH_TYPE_NONE) {
1408a877 7556 /* do nothing */
51470298 7557 } else if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
7558 s->type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
7559 if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
7560 c_write_str(ssh, "Server refused our key\r\n");
1408a877 7561 logevent("Server refused public key");
51470298 7562 } else if (s->type==AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET) {
4bdf7c46 7563 /* server declined keyboard-interactive; ignore */
1408a877 7564 } else {
51470298 7565 c_write_str(ssh, "Access denied\r\n");
1408a877 7566 logevent("Access denied");
91f57d1f 7567 if (s->type == AUTH_TYPE_PASSWORD &&
7568 ssh->cfg.change_username) {
6c9dce7c 7569 /* XXX perhaps we should allow
7570 * keyboard-interactive to do this too? */
51470298 7571 s->we_are_in = FALSE;
1408a877 7572 break;
7573 }
7574 }
7575 } else {
51470298 7576 c_write_str(ssh, "Further authentication required\r\n");
1408a877 7577 logevent("Further authentication required");
7578 }
65a22376 7579
51470298 7580 s->can_pubkey =
32874aea 7581 in_commasep_string("publickey", methods, methlen);
51470298 7582 s->can_passwd =
32874aea 7583 in_commasep_string("password", methods, methlen);
86916870 7584 s->can_keyb_inter = ssh->cfg.try_ki_auth &&
761187b6 7585 in_commasep_string("keyboard-interactive", methods, methlen);
42af6a67 7586#ifndef NO_GSSAPI
7587 s->can_gssapi = ssh->cfg.try_gssapi_auth &&
7588 in_commasep_string("gssapi-with-mic", methods, methlen) &&
7589 ssh_gss_init();
7590#endif
1408a877 7591 }
65a22376 7592
acab36bc 7593 ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
65a22376 7594
94cd7c3a 7595 if (s->can_pubkey && !s->done_agent && s->nkeys) {
0405e71f 7596
1983e559 7597 /*
94cd7c3a 7598 * Attempt public-key authentication using a key from Pageant.
1983e559 7599 */
1983e559 7600
acab36bc 7601 ssh->pkt_actx = SSH2_PKTCTX_PUBLICKEY;
00db133f 7602
94cd7c3a 7603 logeventf(ssh, "Trying Pageant key #%d", s->keyi);
7604
7605 /* Unpack key from agent response */
7606 s->pklen = GET_32BIT(s->agentp);
7607 s->agentp += 4;
7608 s->pkblob = (char *)s->agentp;
7609 s->agentp += s->pklen;
7610 s->alglen = GET_32BIT(s->pkblob);
7611 s->alg = s->pkblob + 4;
7612 s->commentlen = GET_32BIT(s->agentp);
7613 s->agentp += 4;
7614 s->commentp = (char *)s->agentp;
7615 s->agentp += s->commentlen;
7616 /* s->agentp now points at next key, if any */
7617
7618 /* See if server will accept it */
7619 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7620 ssh2_pkt_addstring(s->pktout, s->username);
7621 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7622 /* service requested */
7623 ssh2_pkt_addstring(s->pktout, "publickey");
7624 /* method */
7625 ssh2_pkt_addbool(s->pktout, FALSE); /* no signature included */
7626 ssh2_pkt_addstring_start(s->pktout);
7627 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
7628 ssh2_pkt_addstring_start(s->pktout);
7629 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
7630 ssh2_pkt_send(ssh, s->pktout);
7631 s->type = AUTH_TYPE_PUBLICKEY_OFFER_QUIET;
1983e559 7632
94cd7c3a 7633 crWaitUntilV(pktin);
7634 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
1983e559 7635
94cd7c3a 7636 /* Offer of key refused. */
7637 s->gotit = TRUE;
1983e559 7638
94cd7c3a 7639 } else {
7640
7641 void *vret;
1983e559 7642
94cd7c3a 7643 if (flags & FLAG_VERBOSE) {
7644 c_write_str(ssh, "Authenticating with "
7645 "public key \"");
7646 c_write(ssh, s->commentp, s->commentlen);
7647 c_write_str(ssh, "\" from agent\r\n");
7648 }
1983e559 7649
94cd7c3a 7650 /*
7651 * Server is willing to accept the key.
7652 * Construct a SIGN_REQUEST.
7653 */
7654 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7655 ssh2_pkt_addstring(s->pktout, s->username);
7656 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7657 /* service requested */
7658 ssh2_pkt_addstring(s->pktout, "publickey");
7659 /* method */
7660 ssh2_pkt_addbool(s->pktout, TRUE); /* signature included */
7661 ssh2_pkt_addstring_start(s->pktout);
7662 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
7663 ssh2_pkt_addstring_start(s->pktout);
7664 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
7665
7666 /* Ask agent for signature. */
7667 s->siglen = s->pktout->length - 5 + 4 +
7668 ssh->v2_session_id_len;
7669 if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7670 s->siglen -= 4;
7671 s->len = 1; /* message type */
7672 s->len += 4 + s->pklen; /* key blob */
7673 s->len += 4 + s->siglen; /* data to sign */
7674 s->len += 4; /* flags */
7675 s->agentreq = snewn(4 + s->len, char);
7676 PUT_32BIT(s->agentreq, s->len);
7677 s->q = s->agentreq + 4;
7678 *s->q++ = SSH2_AGENTC_SIGN_REQUEST;
7679 PUT_32BIT(s->q, s->pklen);
7680 s->q += 4;
7681 memcpy(s->q, s->pkblob, s->pklen);
7682 s->q += s->pklen;
7683 PUT_32BIT(s->q, s->siglen);
7684 s->q += 4;
7685 /* Now the data to be signed... */
7686 if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7687 PUT_32BIT(s->q, ssh->v2_session_id_len);
51470298 7688 s->q += 4;
94cd7c3a 7689 }
7690 memcpy(s->q, ssh->v2_session_id,
7691 ssh->v2_session_id_len);
7692 s->q += ssh->v2_session_id_len;
7693 memcpy(s->q, s->pktout->data + 5,
7694 s->pktout->length - 5);
7695 s->q += s->pktout->length - 5;
7696 /* And finally the (zero) flags word. */
7697 PUT_32BIT(s->q, 0);
7698 if (!agent_query(s->agentreq, s->len + 4,
7699 &vret, &s->retlen,
7700 ssh_agent_callback, ssh)) {
7701 do {
7702 crReturnV;
7703 if (pktin) {
7704 bombout(("Unexpected data from server"
7705 " while waiting for agent"
7706 " response"));
7707 crStopV;
1983e559 7708 }
94cd7c3a 7709 } while (pktin || inlen > 0);
7710 vret = ssh->agent_response;
7711 s->retlen = ssh->agent_response_len;
7712 }
7713 s->ret = vret;
7714 sfree(s->agentreq);
7715 if (s->ret) {
7716 if (s->ret[4] == SSH2_AGENT_SIGN_RESPONSE) {
7717 logevent("Sending Pageant's response");
7718 ssh2_add_sigblob(ssh, s->pktout,
7719 s->pkblob, s->pklen,
7720 s->ret + 9,
7721 GET_32BIT(s->ret + 5));
7722 ssh2_pkt_send(ssh, s->pktout);
7723 s->type = AUTH_TYPE_PUBLICKEY;
7724 } else {
7725 /* FIXME: less drastic response */
7726 bombout(("Pageant failed to answer challenge"));
7727 crStopV;
1983e559 7728 }
7729 }
1983e559 7730 }
94cd7c3a 7731
7732 /* Do we have any keys left to try? */
7733 if (s->pkblob_in_agent) {
7734 s->done_agent = TRUE;
7735 s->tried_pubkey_config = TRUE;
7736 } else {
7737 s->keyi++;
7738 if (s->keyi >= s->nkeys)
7739 s->done_agent = TRUE;
7740 }
1983e559 7741
edd0cb8a 7742 } else if (s->can_pubkey && s->publickey_blob &&
7743 !s->tried_pubkey_config) {
65a22376 7744
edd0cb8a 7745 struct ssh2_userkey *key; /* not live over crReturn */
7746 char *passphrase; /* not live over crReturn */
65a22376 7747
acab36bc 7748 ssh->pkt_actx = SSH2_PKTCTX_PUBLICKEY;
00db133f 7749
edd0cb8a 7750 s->tried_pubkey_config = TRUE;
7751
65a22376 7752 /*
1408a877 7753 * Try the public key supplied in the configuration.
7754 *
7755 * First, offer the public blob to see if the server is
7756 * willing to accept it.
65a22376 7757 */
ff3187f6 7758 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7759 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7760 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7761 /* service requested */
7762 ssh2_pkt_addstring(s->pktout, "publickey"); /* method */
7763 ssh2_pkt_addbool(s->pktout, FALSE);
7764 /* no signature included */
7765 ssh2_pkt_addstring(s->pktout, s->publickey_algorithm);
7766 ssh2_pkt_addstring_start(s->pktout);
7767 ssh2_pkt_addstring_data(s->pktout,
7768 (char *)s->publickey_blob,
7769 s->publickey_bloblen);
ff3187f6 7770 ssh2_pkt_send(ssh, s->pktout);
edd0cb8a 7771 logevent("Offered public key");
ff3187f6 7772
7773 crWaitUntilV(pktin);
edd0cb8a 7774 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
7775 /* Key refused. Give up. */
7776 s->gotit = TRUE; /* reconsider message next loop */
7777 s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
7778 continue; /* process this new message */
45068b27 7779 }
edd0cb8a 7780 logevent("Offer of public key accepted");
af659722 7781
45068b27 7782 /*
edd0cb8a 7783 * Actually attempt a serious authentication using
7784 * the key.
45068b27 7785 */
edd0cb8a 7786 if (flags & FLAG_VERBOSE) {
7787 c_write_str(ssh, "Authenticating with public key \"");
7788 c_write_str(ssh, s->publickey_comment);
7789 c_write_str(ssh, "\"\r\n");
7790 }
7791 key = NULL;
7792 while (!key) {
7793 const char *error; /* not live over crReturn */
7794 if (s->publickey_encrypted) {
7795 /*
7796 * Get a passphrase from the user.
7797 */
7798 int ret; /* need not be kept over crReturn */
7799 s->cur_prompt = new_prompts(ssh->frontend);
7800 s->cur_prompt->to_server = FALSE;
7801 s->cur_prompt->name = dupstr("SSH key passphrase");
7802 add_prompt(s->cur_prompt,
7803 dupprintf("Passphrase for key \"%.100s\": ",
7804 s->publickey_comment),
7805 FALSE, SSH_MAX_PASSWORD_LEN);
7806 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7807 while (ret < 0) {
7808 ssh->send_ok = 1;
7809 crWaitUntilV(!pktin);
7810 ret = get_userpass_input(s->cur_prompt,
7811 in, inlen);
7812 ssh->send_ok = 0;
7813 }
7814 if (!ret) {
7815 /* Failed to get a passphrase. Terminate. */
7816 free_prompts(s->cur_prompt);
7817 ssh_disconnect(ssh, NULL,
7818 "Unable to authenticate",
7819 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7820 TRUE);
7821 crStopV;
85fdbe25 7822 }
edd0cb8a 7823 passphrase =
7824 dupstr(s->cur_prompt->prompts[0]->result);
7825 free_prompts(s->cur_prompt);
45068b27 7826 } else {
edd0cb8a 7827 passphrase = NULL; /* no passphrase needed */
45068b27 7828 }
1408a877 7829
edd0cb8a 7830 /*
7831 * Try decrypting the key.
7832 */
7833 key = ssh2_load_userkey(&ssh->cfg.keyfile, passphrase,
7834 &error);
7835 if (passphrase) {
7836 /* burn the evidence */
7837 memset(passphrase, 0, strlen(passphrase));
7838 sfree(passphrase);
7839 }
7840 if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
7841 if (passphrase &&
7842 (key == SSH2_WRONG_PASSPHRASE)) {
7843 c_write_str(ssh, "Wrong passphrase\r\n");
7844 key = NULL;
7845 /* and loop again */
7846 } else {
7847 c_write_str(ssh, "Unable to load private key (");
7848 c_write_str(ssh, error);
7849 c_write_str(ssh, ")\r\n");
7850 key = NULL;
7851 break; /* try something else */
7852 }
1408a877 7853 }
65a22376 7854 }
65a22376 7855
edd0cb8a 7856 if (key) {
1dd353b5 7857 unsigned char *pkblob, *sigblob, *sigdata;
7858 int pkblob_len, sigblob_len, sigdata_len;
edd0cb8a 7859 int p;
65a22376 7860
1408a877 7861 /*
7862 * We have loaded the private key and the server
7863 * has announced that it's willing to accept it.
7864 * Hallelujah. Generate a signature and send it.
7865 */
ff3187f6 7866 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7867 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7868 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7869 /* service requested */
7870 ssh2_pkt_addstring(s->pktout, "publickey");
7871 /* method */
ff3187f6 7872 ssh2_pkt_addbool(s->pktout, TRUE);
edd0cb8a 7873 /* signature follows */
ff3187f6 7874 ssh2_pkt_addstring(s->pktout, key->alg->name);
edd0cb8a 7875 pkblob = key->alg->public_blob(key->data,
7876 &pkblob_len);
ff3187f6 7877 ssh2_pkt_addstring_start(s->pktout);
edd0cb8a 7878 ssh2_pkt_addstring_data(s->pktout, (char *)pkblob,
7879 pkblob_len);
1408a877 7880
7881 /*
7882 * The data to be signed is:
7883 *
7884 * string session-id
7885 *
7886 * followed by everything so far placed in the
7887 * outgoing packet.
7888 */
b672f405 7889 sigdata_len = s->pktout->length - 5 + 4 +
7890 ssh->v2_session_id_len;
edd0cb8a 7891 if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7892 sigdata_len -= 4;
92d60585 7893 sigdata = snewn(sigdata_len, unsigned char);
edd0cb8a 7894 p = 0;
7895 if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7896 PUT_32BIT(sigdata+p, ssh->v2_session_id_len);
7897 p += 4;
7898 }
b672f405 7899 memcpy(sigdata+p, ssh->v2_session_id,
7900 ssh->v2_session_id_len);
7901 p += ssh->v2_session_id_len;
ff3187f6 7902 memcpy(sigdata+p, s->pktout->data + 5,
7903 s->pktout->length - 5);
edd0cb8a 7904 p += s->pktout->length - 5;
7905 assert(p == sigdata_len);
d8baa528 7906 sigblob = key->alg->sign(key->data, (char *)sigdata,
1dd353b5 7907 sigdata_len, &sigblob_len);
ff3187f6 7908 ssh2_add_sigblob(ssh, s->pktout, pkblob, pkblob_len,
1dd353b5 7909 sigblob, sigblob_len);
7910 sfree(pkblob);
7911 sfree(sigblob);
1408a877 7912 sfree(sigdata);
7913
ff3187f6 7914 ssh2_pkt_send(ssh, s->pktout);
51470298 7915 s->type = AUTH_TYPE_PUBLICKEY;
75374b2f 7916 key->alg->freekey(key->data);
1408a877 7917 }
edd0cb8a 7918
42af6a67 7919#ifndef NO_GSSAPI
7920 } else if (s->can_gssapi && !s->tried_gssapi) {
7921
7922 /* GSSAPI Authentication */
7923
86557057 7924 int micoffset, len;
7925 char *data;
42af6a67 7926 Ssh_gss_buf mic;
7927 s->type = AUTH_TYPE_GSSAPI;
7928 s->tried_gssapi = TRUE;
7929 s->gotit = TRUE;
7930 ssh->pkt_actx = SSH2_PKTCTX_GSSAPI;
7931
7932 /* Sending USERAUTH_REQUEST with "gssapi-with-mic" method */
7933 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7934 ssh2_pkt_addstring(s->pktout, s->username);
7935 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7936 ssh2_pkt_addstring(s->pktout, "gssapi-with-mic");
7937
7938 /* add mechanism info */
7939 ssh_gss_indicate_mech(&s->gss_buf);
7940
7941 /* number of GSSAPI mechanisms */
7942 ssh2_pkt_adduint32(s->pktout,1);
7943
7944 /* length of OID + 2 */
86557057 7945 ssh2_pkt_adduint32(s->pktout, s->gss_buf.length + 2);
42af6a67 7946 ssh2_pkt_addbyte(s->pktout, SSH2_GSS_OIDTYPE);
7947
7948 /* length of OID */
86557057 7949 ssh2_pkt_addbyte(s->pktout, (unsigned char) s->gss_buf.length);
42af6a67 7950
86557057 7951 ssh_pkt_adddata(s->pktout, s->gss_buf.value,
7952 s->gss_buf.length);
42af6a67 7953 ssh2_pkt_send(ssh, s->pktout);
7954 crWaitUntilV(pktin);
7955 if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_RESPONSE) {
7956 logevent("GSSAPI authentication request refused");
7957 continue;
7958 }
7959
7960 /* check returned packet ... */
7961
86557057 7962 ssh_pkt_getstring(pktin, &data, &len);
7963 s->gss_rcvtok.value = data;
7964 s->gss_rcvtok.length = len;
7965 if (s->gss_rcvtok.length != s->gss_buf.length + 2 ||
7966 ((char *)s->gss_rcvtok.value)[0] != SSH2_GSS_OIDTYPE ||
7967 ((char *)s->gss_rcvtok.value)[1] != s->gss_buf.length ||
7968 memcmp((char *)s->gss_rcvtok.value + 2,
7969 s->gss_buf.value,s->gss_buf.length) ) {
42af6a67 7970 logevent("GSSAPI authentication - wrong response from server");
7971 continue;
7972 }
7973
7974 /* now start running */
7975 s->gss_stat = ssh_gss_import_name(ssh->fullhostname,
7976 &s->gss_srv_name);
7977 if (s->gss_stat != SSH_GSS_OK) {
7978 if (s->gss_stat == SSH_GSS_BAD_HOST_NAME)
7979 logevent("GSSAPI import name failed - Bad service name");
7980 else
7981 logevent("GSSAPI import name failed");
7982 continue;
7983 }
7984
7985 /* fetch TGT into GSS engine */
7986 s->gss_stat = ssh_gss_acquire_cred(&s->gss_ctx);
7987
7988 if (s->gss_stat != SSH_GSS_OK) {
7989 logevent("GSSAPI authentication failed to get credentials");
7990 ssh_gss_release_name(&s->gss_srv_name);
7991 continue;
7992 }
7993
7994 /* initial tokens are empty */
86557057 7995 SSH_GSS_CLEAR_BUF(&s->gss_rcvtok);
99a3b3c9 7996 SSH_GSS_CLEAR_BUF(&s->gss_sndtok);
42af6a67 7997
7998 /* now enter the loop */
7999 do {
8000 s->gss_stat = ssh_gss_init_sec_context(&s->gss_ctx,
8001 s->gss_srv_name,
8002 ssh->cfg.gssapifwd,
8003 &s->gss_rcvtok,
8004 &s->gss_sndtok);
8005
8006 if (s->gss_stat!=SSH_GSS_S_COMPLETE &&
8007 s->gss_stat!=SSH_GSS_S_CONTINUE_NEEDED) {
8008 logevent("GSSAPI authentication initialisation failed");
8009
8010 if (ssh_gss_display_status(s->gss_ctx,&s->gss_buf) == SSH_GSS_OK) {
86557057 8011 logevent(s->gss_buf.value);
8012 sfree(s->gss_buf.value);
42af6a67 8013 }
8014
8015 break;
8016 }
8017 logevent("GSSAPI authentication initialised");
8018
8019 /* Client and server now exchange tokens until GSSAPI
8020 * no longer says CONTINUE_NEEDED */
8021
86557057 8022 if (s->gss_sndtok.length != 0) {
42af6a67 8023 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
8024 ssh_pkt_addstring_start(s->pktout);
86557057 8025 ssh_pkt_addstring_data(s->pktout,s->gss_sndtok.value,s->gss_sndtok.length);
42af6a67 8026 ssh2_pkt_send(ssh, s->pktout);
8027 ssh_gss_free_tok(&s->gss_sndtok);
8028 }
8029
8030 if (s->gss_stat == SSH_GSS_S_CONTINUE_NEEDED) {
8031 crWaitUntilV(pktin);
8032 if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_TOKEN) {
8033 logevent("GSSAPI authentication - bad server response");
8034 s->gss_stat = SSH_GSS_FAILURE;
8035 break;
8036 }
86557057 8037 ssh_pkt_getstring(pktin, &data, &len);
8038 s->gss_rcvtok.value = data;
8039 s->gss_rcvtok.length = len;
42af6a67 8040 }
8041 } while (s-> gss_stat == SSH_GSS_S_CONTINUE_NEEDED);
8042
8043 if (s->gss_stat != SSH_GSS_OK) {
8044 ssh_gss_release_name(&s->gss_srv_name);
8045 ssh_gss_release_cred(&s->gss_ctx);
8046 continue;
8047 }
8048 logevent("GSSAPI authentication loop finished OK");
8049
8050 /* Now send the MIC */
8051
8052 s->pktout = ssh2_pkt_init(0);
8053 micoffset = s->pktout->length;
8054 ssh_pkt_addstring_start(s->pktout);
8055 ssh_pkt_addstring_data(s->pktout, (char *)ssh->v2_session_id, ssh->v2_session_id_len);
8056 ssh_pkt_addbyte(s->pktout, SSH2_MSG_USERAUTH_REQUEST);
8057 ssh_pkt_addstring(s->pktout, s->username);
8058 ssh_pkt_addstring(s->pktout, "ssh-connection");
8059 ssh_pkt_addstring(s->pktout, "gssapi-with-mic");
8060
86557057 8061 s->gss_buf.value = (char *)s->pktout->data + micoffset;
8062 s->gss_buf.length = s->pktout->length - micoffset;
42af6a67 8063
8064 ssh_gss_get_mic(s->gss_ctx, &s->gss_buf, &mic);
8065 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_GSSAPI_MIC);
8066 ssh_pkt_addstring_start(s->pktout);
86557057 8067 ssh_pkt_addstring_data(s->pktout, mic.value, mic.length);
42af6a67 8068 ssh2_pkt_send(ssh, s->pktout);
8069 ssh_gss_free_mic(&mic);
8070
8071 s->gotit = FALSE;
8072
8073 ssh_gss_release_name(&s->gss_srv_name);
8074 ssh_gss_release_cred(&s->gss_ctx);
8075 continue;
8076#endif
edd0cb8a 8077 } else if (s->can_keyb_inter && !s->kbd_inter_refused) {
8078
8079 /*
8080 * Keyboard-interactive authentication.
8081 */
edd0cb8a 8082
edd0cb8a 8083 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
8084
acab36bc 8085 ssh->pkt_actx = SSH2_PKTCTX_KBDINTER;
edd0cb8a 8086
8087 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
8088 ssh2_pkt_addstring(s->pktout, s->username);
8089 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8090 /* service requested */
8091 ssh2_pkt_addstring(s->pktout, "keyboard-interactive");
8092 /* method */
8093 ssh2_pkt_addstring(s->pktout, ""); /* lang */
8094 ssh2_pkt_addstring(s->pktout, ""); /* submethods */
8095 ssh2_pkt_send(ssh, s->pktout);
8096
8097 crWaitUntilV(pktin);
8098 if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
8099 /* Server is not willing to do keyboard-interactive
b8e3173d 8100 * at all (or, bizarrely but legally, accepts the
8101 * user without actually issuing any prompts).
8102 * Give up on it entirely. */
edd0cb8a 8103 s->gotit = TRUE;
8104 if (pktin->type == SSH2_MSG_USERAUTH_FAILURE)
8105 logevent("Keyboard-interactive authentication refused");
8106 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
8107 s->kbd_inter_refused = TRUE; /* don't try it again */
8108 continue;
8109 }
8110
8111 /*
b8e3173d 8112 * Loop while the server continues to send INFO_REQUESTs.
edd0cb8a 8113 */
b8e3173d 8114 while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
edd0cb8a 8115
b8e3173d 8116 char *name, *inst, *lang;
8117 int name_len, inst_len, lang_len;
8118 int i;
8119
8120 /*
8121 * We've got a fresh USERAUTH_INFO_REQUEST.
8122 * Get the preamble and start building a prompt.
8123 */
8124 ssh_pkt_getstring(pktin, &name, &name_len);
8125 ssh_pkt_getstring(pktin, &inst, &inst_len);
8126 ssh_pkt_getstring(pktin, &lang, &lang_len);
8127 s->cur_prompt = new_prompts(ssh->frontend);
8128 s->cur_prompt->to_server = TRUE;
edd0cb8a 8129
b8e3173d 8130 /*
9ea10e78 8131 * Get any prompt(s) from the packet.
b8e3173d 8132 */
8133 s->num_prompts = ssh_pkt_getuint32(pktin);
8134 for (i = 0; i < s->num_prompts; i++) {
8135 char *prompt;
8136 int prompt_len;
8137 int echo;
8138 static char noprompt[] =
8139 "<server failed to send prompt>: ";
8140
8141 ssh_pkt_getstring(pktin, &prompt, &prompt_len);
8142 echo = ssh2_pkt_getbool(pktin);
8143 if (!prompt_len) {
8144 prompt = noprompt;
8145 prompt_len = lenof(noprompt)-1;
8146 }
8147 add_prompt(s->cur_prompt,
8148 dupprintf("%.*s", prompt_len, prompt),
8149 echo, SSH_MAX_PASSWORD_LEN);
edd0cb8a 8150 }
b8e3173d 8151
9874c9d7 8152 if (name_len) {
8153 /* FIXME: better prefix to distinguish from
8154 * local prompts? */
8155 s->cur_prompt->name =
8156 dupprintf("SSH server: %.*s", name_len, name);
8157 s->cur_prompt->name_reqd = TRUE;
8158 } else {
8159 s->cur_prompt->name =
8160 dupstr("SSH server authentication");
8161 s->cur_prompt->name_reqd = FALSE;
8162 }
8163 /* We add a prefix to try to make it clear that a prompt
8164 * has come from the server.
8165 * FIXME: ugly to print "Using..." in prompt _every_
8166 * time round. Can this be done more subtly? */
8167 /* Special case: for reasons best known to themselves,
8168 * some servers send k-i requests with no prompts and
8169 * nothing to display. Keep quiet in this case. */
8170 if (s->num_prompts || name_len || inst_len) {
8171 s->cur_prompt->instruction =
8172 dupprintf("Using keyboard-interactive authentication.%s%.*s",
8173 inst_len ? "\n" : "", inst_len, inst);
8174 s->cur_prompt->instr_reqd = TRUE;
8175 } else {
8176 s->cur_prompt->instr_reqd = FALSE;
8177 }
8178
b8e3173d 8179 /*
9ea10e78 8180 * Display any instructions, and get the user's
8181 * response(s).
b8e3173d 8182 */
9ea10e78 8183 {
b8e3173d 8184 int ret; /* not live over crReturn */
8185 ret = get_userpass_input(s->cur_prompt, NULL, 0);
8186 while (ret < 0) {
8187 ssh->send_ok = 1;
8188 crWaitUntilV(!pktin);
8189 ret = get_userpass_input(s->cur_prompt, in, inlen);
8190 ssh->send_ok = 0;
8191 }
8192 if (!ret) {
8193 /*
8194 * Failed to get responses. Terminate.
8195 */
8196 free_prompts(s->cur_prompt);
8197 ssh_disconnect(ssh, NULL, "Unable to authenticate",
8198 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
8199 TRUE);
8200 crStopV;
8201 }
edd0cb8a 8202 }
b8e3173d 8203
8204 /*
9ea10e78 8205 * Send the response(s) to the server.
b8e3173d 8206 */
8207 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_INFO_RESPONSE);
b8e3173d 8208 ssh2_pkt_adduint32(s->pktout, s->num_prompts);
8209 for (i=0; i < s->num_prompts; i++) {
8210 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
8211 ssh2_pkt_addstring(s->pktout,
8212 s->cur_prompt->prompts[i]->result);
8213 end_log_omission(ssh, s->pktout);
8214 }
18524056 8215 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
b8e3173d 8216
8217 /*
8218 * Get the next packet in case it's another
8219 * INFO_REQUEST.
8220 */
8221 crWaitUntilV(pktin);
8222
edd0cb8a 8223 }
8224
8225 /*
b8e3173d 8226 * We should have SUCCESS or FAILURE now.
edd0cb8a 8227 */
b8e3173d 8228 s->gotit = TRUE;
edd0cb8a 8229
8230 } else if (s->can_passwd) {
8231
8232 /*
8233 * Plain old password authentication.
8234 */
8235 int ret; /* not live over crReturn */
e955d348 8236 int changereq_first_time; /* not live over crReturn */
edd0cb8a 8237
acab36bc 8238 ssh->pkt_actx = SSH2_PKTCTX_PASSWORD;
edd0cb8a 8239
8240 s->cur_prompt = new_prompts(ssh->frontend);
8241 s->cur_prompt->to_server = TRUE;
8242 s->cur_prompt->name = dupstr("SSH password");
8243 add_prompt(s->cur_prompt, dupprintf("%.90s@%.90s's password: ",
8244 s->username,
8245 ssh->savedhost),
8246 FALSE, SSH_MAX_PASSWORD_LEN);
8247
8248 ret = get_userpass_input(s->cur_prompt, NULL, 0);
8249 while (ret < 0) {
8250 ssh->send_ok = 1;
8251 crWaitUntilV(!pktin);
8252 ret = get_userpass_input(s->cur_prompt, in, inlen);
8253 ssh->send_ok = 0;
8254 }
8255 if (!ret) {
8256 /*
8257 * Failed to get responses. Terminate.
8258 */
8259 free_prompts(s->cur_prompt);
8260 ssh_disconnect(ssh, NULL, "Unable to authenticate",
8261 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
8262 TRUE);
8263 crStopV;
8264 }
e955d348 8265 /*
8266 * Squirrel away the password. (We may need it later if
8267 * asked to change it.)
8268 */
8269 s->password = dupstr(s->cur_prompt->prompts[0]->result);
8270 free_prompts(s->cur_prompt);
edd0cb8a 8271
8272 /*
8273 * Send the password packet.
8274 *
95d2d262 8275 * We pad out the password packet to 256 bytes to make
8276 * it harder for an attacker to find the length of the
8277 * user's password.
1408a877 8278 *
95d2d262 8279 * Anyone using a password longer than 256 bytes
8280 * probably doesn't have much to worry about from
1408a877 8281 * people who find out how long their password is!
65a22376 8282 */
ff3187f6 8283 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
8284 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 8285 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8286 /* service requested */
ff3187f6 8287 ssh2_pkt_addstring(s->pktout, "password");
8288 ssh2_pkt_addbool(s->pktout, FALSE);
8289 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
e955d348 8290 ssh2_pkt_addstring(s->pktout, s->password);
ff3187f6 8291 end_log_omission(ssh, s->pktout);
18524056 8292 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
0d43337a 8293 logevent("Sent password");
28f4d4f0 8294 s->type = AUTH_TYPE_PASSWORD;
edd0cb8a 8295
e955d348 8296 /*
8297 * Wait for next packet, in case it's a password change
8298 * request.
8299 */
8300 crWaitUntilV(pktin);
8301 changereq_first_time = TRUE;
8302
8303 while (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
8304
8305 /*
8306 * We're being asked for a new password
8307 * (perhaps not for the first time).
8308 * Loop until the server accepts it.
8309 */
8310
8311 int got_new = FALSE; /* not live over crReturn */
8312 char *prompt; /* not live over crReturn */
8313 int prompt_len; /* not live over crReturn */
8314
8315 {
8316 char *msg;
8317 if (changereq_first_time)
8318 msg = "Server requested password change";
8319 else
8320 msg = "Server rejected new password";
8321 logevent(msg);
8322 c_write_str(ssh, msg);
8323 c_write_str(ssh, "\r\n");
8324 }
8325
8326 ssh_pkt_getstring(pktin, &prompt, &prompt_len);
8327
8328 s->cur_prompt = new_prompts(ssh->frontend);
8329 s->cur_prompt->to_server = TRUE;
8330 s->cur_prompt->name = dupstr("New SSH password");
8331 s->cur_prompt->instruction =
8332 dupprintf("%.*s", prompt_len, prompt);
8333 s->cur_prompt->instr_reqd = TRUE;
d9add7bc 8334 /*
8335 * There's no explicit requirement in the protocol
8336 * for the "old" passwords in the original and
8337 * password-change messages to be the same, and
8338 * apparently some Cisco kit supports password change
8339 * by the user entering a blank password originally
8340 * and the real password subsequently, so,
8341 * reluctantly, we prompt for the old password again.
8342 *
8343 * (On the other hand, some servers don't even bother
8344 * to check this field.)
8345 */
8346 add_prompt(s->cur_prompt,
8347 dupstr("Current password (blank for previously entered password): "),
8348 FALSE, SSH_MAX_PASSWORD_LEN);
e955d348 8349 add_prompt(s->cur_prompt, dupstr("Enter new password: "),
8350 FALSE, SSH_MAX_PASSWORD_LEN);
8351 add_prompt(s->cur_prompt, dupstr("Confirm new password: "),
8352 FALSE, SSH_MAX_PASSWORD_LEN);
8353
8354 /*
8355 * Loop until the user manages to enter the same
8356 * password twice.
8357 */
8358 while (!got_new) {
8359
8360 ret = get_userpass_input(s->cur_prompt, NULL, 0);
8361 while (ret < 0) {
8362 ssh->send_ok = 1;
8363 crWaitUntilV(!pktin);
8364 ret = get_userpass_input(s->cur_prompt, in, inlen);
8365 ssh->send_ok = 0;
8366 }
8367 if (!ret) {
8368 /*
8369 * Failed to get responses. Terminate.
8370 */
8371 /* burn the evidence */
8372 free_prompts(s->cur_prompt);
8373 memset(s->password, 0, strlen(s->password));
8374 sfree(s->password);
8375 ssh_disconnect(ssh, NULL, "Unable to authenticate",
8376 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
8377 TRUE);
8378 crStopV;
8379 }
8380
8381 /*
d9add7bc 8382 * If the user specified a new original password
8383 * (IYSWIM), overwrite any previously specified
8384 * one.
8385 * (A side effect is that the user doesn't have to
8386 * re-enter it if they louse up the new password.)
8387 */
8388 if (s->cur_prompt->prompts[0]->result[0]) {
8389 memset(s->password, 0, strlen(s->password));
8390 /* burn the evidence */
8391 sfree(s->password);
8392 s->password =
8393 dupstr(s->cur_prompt->prompts[0]->result);
8394 }
8395
8396 /*
8397 * Check the two new passwords match.
e955d348 8398 */
d9add7bc 8399 got_new = (strcmp(s->cur_prompt->prompts[1]->result,
8400 s->cur_prompt->prompts[2]->result)
e955d348 8401 == 0);
8402 if (!got_new)
8403 /* They don't. Silly user. */
8404 c_write_str(ssh, "Passwords do not match\r\n");
8405
8406 }
8407
8408 /*
8409 * Send the new password (along with the old one).
8410 * (see above for padding rationale)
8411 */
8412 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
e955d348 8413 ssh2_pkt_addstring(s->pktout, s->username);
8414 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8415 /* service requested */
8416 ssh2_pkt_addstring(s->pktout, "password");
8417 ssh2_pkt_addbool(s->pktout, TRUE);
8418 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
8419 ssh2_pkt_addstring(s->pktout, s->password);
8420 ssh2_pkt_addstring(s->pktout,
d9add7bc 8421 s->cur_prompt->prompts[1]->result);
e955d348 8422 free_prompts(s->cur_prompt);
8423 end_log_omission(ssh, s->pktout);
18524056 8424 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
e955d348 8425 logevent("Sent new password");
8426
8427 /*
8428 * Now see what the server has to say about it.
8429 * (If it's CHANGEREQ again, it's not happy with the
8430 * new password.)
8431 */
8432 crWaitUntilV(pktin);
8433 changereq_first_time = FALSE;
8434
8435 }
8436
8437 /*
8438 * We need to reexamine the current pktin at the top
8439 * of the loop. Either:
8440 * - we weren't asked to change password at all, in
8441 * which case it's a SUCCESS or FAILURE with the
8442 * usual meaning
8443 * - we sent a new password, and the server was
8444 * either OK with it (SUCCESS or FAILURE w/partial
8445 * success) or unhappy with the _old_ password
8446 * (FAILURE w/o partial success)
8447 * In any of these cases, we go back to the top of
8448 * the loop and start again.
8449 */
8450 s->gotit = TRUE;
8451
8452 /*
8453 * We don't need the old password any more, in any
8454 * case. Burn the evidence.
8455 */
8456 memset(s->password, 0, strlen(s->password));
8457 sfree(s->password);
8458
1408a877 8459 } else {
edd0cb8a 8460
9e296bfa 8461 ssh_disconnect(ssh, NULL,
8462 "No supported authentication methods available",
8463 SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
8464 FALSE);
7ffdbc1a 8465 crStopV;
edd0cb8a 8466
65a22376 8467 }
edd0cb8a 8468
65a22376 8469 }
a1a1fae4 8470 }
6bbce591 8471 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
7cca0d81 8472
edd0cb8a 8473 /* Clear up various bits and pieces from authentication. */
8474 if (s->publickey_blob) {
8475 sfree(s->publickey_blob);
8476 sfree(s->publickey_comment);
8477 }
94cd7c3a 8478 if (s->agent_response)
8479 sfree(s->agent_response);
edd0cb8a 8480
7cca0d81 8481 /*
a1a1fae4 8482 * Now the connection protocol has started, one way or another.
7cca0d81 8483 */
8484
0ed48730 8485 ssh->channels = newtree234(ssh_channelcmp);
8486
7cca0d81 8487 /*
b09eaa88 8488 * Set up handlers for some connection protocol messages, so we
8489 * don't have to handle them repeatedly in this coroutine.
8490 */
8491 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] =
8492 ssh2_msg_channel_window_adjust;
51df0ab5 8493 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] =
8494 ssh2_msg_global_request;
b09eaa88 8495
8496 /*
0ed48730 8497 * Create the main session channel.
7cca0d81 8498 */
feb02b4e 8499 if (ssh->cfg.ssh_no_shell) {
8500 ssh->mainchan = NULL;
8501 } else if (*ssh->cfg.ssh_nc_host) {
8502 /*
8503 * Just start a direct-tcpip channel and use it as the main
8504 * channel.
8505 */
8506 ssh->mainchan = snew(struct ssh_channel);
8507 ssh->mainchan->ssh = ssh;
94bdfe40 8508 ssh2_channel_init(ssh->mainchan);
23828b7e 8509 logeventf(ssh,
8510 "Opening direct-tcpip channel to %s:%d in place of session",
8511 ssh->cfg.ssh_nc_host, ssh->cfg.ssh_nc_port);
feb02b4e 8512 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
8513 ssh2_pkt_addstring(s->pktout, "direct-tcpip");
8514 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
feb02b4e 8515 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
8516 ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT); /* our max pkt size */
8517 ssh2_pkt_addstring(s->pktout, ssh->cfg.ssh_nc_host);
8518 ssh2_pkt_adduint32(s->pktout, ssh->cfg.ssh_nc_port);
8519 /*
23828b7e 8520 * There's nothing meaningful to put in the originator
8521 * fields, but some servers insist on syntactically correct
8522 * information.
feb02b4e 8523 */
8524 ssh2_pkt_addstring(s->pktout, "0.0.0.0");
8525 ssh2_pkt_adduint32(s->pktout, 0);
8526 ssh2_pkt_send(ssh, s->pktout);
8527
8528 crWaitUntilV(pktin);
8529 if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
8530 bombout(("Server refused to open a direct-tcpip channel"));
8531 crStopV;
8532 /* FIXME: error data comes back in FAILURE packet */
8533 }
8534 if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
8535 bombout(("Server's channel confirmation cited wrong channel"));
8536 crStopV;
8537 }
8538 ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
8539 ssh->mainchan->halfopen = FALSE;
8540 ssh->mainchan->type = CHAN_MAINSESSION;
feb02b4e 8541 ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
8542 ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
feb02b4e 8543 add234(ssh->channels, ssh->mainchan);
8544 update_specials_menu(ssh->frontend);
23828b7e 8545 logevent("Opened direct-tcpip channel");
feb02b4e 8546 ssh->ncmode = TRUE;
8547 } else {
0ed48730 8548 ssh->mainchan = snew(struct ssh_channel);
8549 ssh->mainchan->ssh = ssh;
94bdfe40 8550 ssh2_channel_init(ssh->mainchan);
ff3187f6 8551 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
8552 ssh2_pkt_addstring(s->pktout, "session");
8553 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
ff3187f6 8554 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
954d5c5a 8555 ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT); /* our max pkt size */
ff3187f6 8556 ssh2_pkt_send(ssh, s->pktout);
8557 crWaitUntilV(pktin);
8558 if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
0ed48730 8559 bombout(("Server refused to open a session"));
8560 crStopV;
8561 /* FIXME: error data comes back in FAILURE packet */
8562 }
ff3187f6 8563 if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
0ed48730 8564 bombout(("Server's channel confirmation cited wrong channel"));
8565 crStopV;
8566 }
ff3187f6 8567 ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
64d6ff88 8568 ssh->mainchan->halfopen = FALSE;
0ed48730 8569 ssh->mainchan->type = CHAN_MAINSESSION;
ff3187f6 8570 ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
8571 ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
0ed48730 8572 add234(ssh->channels, ssh->mainchan);
62638676 8573 update_specials_menu(ssh->frontend);
0ed48730 8574 logevent("Opened channel for session");
feb02b4e 8575 ssh->ncmode = FALSE;
8576 }
7cca0d81 8577
8578 /*
51df0ab5 8579 * Now we have a channel, make dispatch table entries for
8580 * general channel-based messages.
8581 */
8582 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] =
8583 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] =
8584 ssh2_msg_channel_data;
8585 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_channel_eof;
8586 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_channel_close;
8587 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] =
8588 ssh2_msg_channel_open_confirmation;
8589 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] =
8590 ssh2_msg_channel_open_failure;
8591 ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] =
8592 ssh2_msg_channel_request;
8593 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] =
8594 ssh2_msg_channel_open;
8595
b589b816 8596 if (ssh->mainchan && ssh->cfg.ssh_simple) {
3361b80a 8597 /*
8598 * This message indicates to the server that we promise
8599 * not to try to run any other channel in parallel with
8600 * this one, so it's safe for it to advertise a very large
8601 * window and leave the flow control to TCP.
8602 */
8603 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8604 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
8605 ssh2_pkt_addstring(s->pktout, "simple@putty.projects.tartarus.org");
8606 ssh2_pkt_addbool(s->pktout, 0); /* no reply */
8607 ssh2_pkt_send(ssh, s->pktout);
8608 }
8609
51df0ab5 8610 /*
783415f8 8611 * Potentially enable X11 forwarding.
8612 */
d070d2ad 8613 if (ssh->mainchan && !ssh->ncmode && ssh->cfg.x11_forward &&
8614 (ssh->x11disp = x11_setup_display(ssh->cfg.x11_display,
8615 ssh->cfg.x11_auth, &ssh->cfg))) {
32874aea 8616 logevent("Requesting X11 forwarding");
ff3187f6 8617 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8618 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
8619 ssh2_pkt_addstring(s->pktout, "x11-req");
8620 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8621 ssh2_pkt_addbool(s->pktout, 0); /* many connections */
8def70c3 8622 ssh2_pkt_addstring(s->pktout, ssh->x11disp->remoteauthprotoname);
f68353be 8623 /*
8624 * Note that while we blank the X authentication data here, we don't
8625 * take any special action to blank the start of an X11 channel,
8626 * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
8627 * without having session blanking enabled is likely to leak your
8628 * cookie into the log.
8629 */
178c3872 8630 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
8def70c3 8631 ssh2_pkt_addstring(s->pktout, ssh->x11disp->remoteauthdatastring);
178c3872 8632 end_log_omission(ssh, s->pktout);
8def70c3 8633 ssh2_pkt_adduint32(s->pktout, ssh->x11disp->screennum);
ff3187f6 8634 ssh2_pkt_send(ssh, s->pktout);
32874aea 8635
b09eaa88 8636 crWaitUntilV(pktin);
32874aea 8637
ff3187f6 8638 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8639 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8640 bombout(("Unexpected response to X11 forwarding request:"
ff3187f6 8641 " packet type %d", pktin->type));
7ffdbc1a 8642 crStopV;
32874aea 8643 }
8644 logevent("X11 forwarding refused");
8645 } else {
8646 logevent("X11 forwarding enabled");
51470298 8647 ssh->X11_fwd_enabled = TRUE;
32874aea 8648 }
783415f8 8649 }
8650
8651 /*
bc240b21 8652 * Enable port forwardings.
8653 */
06fadff5 8654 ssh_setup_portfwd(ssh, &ssh->cfg);
bc240b21 8655
8656 /*
36c2a3e9 8657 * Potentially enable agent forwarding.
8658 */
feb02b4e 8659 if (ssh->mainchan && !ssh->ncmode && ssh->cfg.agentfwd && agent_exists()) {
32874aea 8660 logevent("Requesting OpenSSH-style agent forwarding");
ff3187f6 8661 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8662 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
8663 ssh2_pkt_addstring(s->pktout, "auth-agent-req@openssh.com");
8664 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8665 ssh2_pkt_send(ssh, s->pktout);
32874aea 8666
b09eaa88 8667 crWaitUntilV(pktin);
32874aea 8668
ff3187f6 8669 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8670 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8671 bombout(("Unexpected response to agent forwarding request:"
ff3187f6 8672 " packet type %d", pktin->type));
7ffdbc1a 8673 crStopV;
32874aea 8674 }
8675 logevent("Agent forwarding refused");
8676 } else {
8677 logevent("Agent forwarding enabled");
51470298 8678 ssh->agentfwd_enabled = TRUE;
32874aea 8679 }
36c2a3e9 8680 }
8681
8682 /*
7cca0d81 8683 * Now allocate a pty for the session.
8684 */
feb02b4e 8685 if (ssh->mainchan && !ssh->ncmode && !ssh->cfg.nopty) {
a5dd8467 8686 /* Unpick the terminal-speed string. */
8687 /* XXX perhaps we should allow no speeds to be sent. */
db219738 8688 ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
8689 sscanf(ssh->cfg.termspeed, "%d,%d", &ssh->ospeed, &ssh->ispeed);
a5dd8467 8690 /* Build the pty request. */
ff3187f6 8691 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8692 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); /* recipient channel */
8693 ssh2_pkt_addstring(s->pktout, "pty-req");
8694 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8695 ssh2_pkt_addstring(s->pktout, ssh->cfg.termtype);
8696 ssh2_pkt_adduint32(s->pktout, ssh->term_width);
8697 ssh2_pkt_adduint32(s->pktout, ssh->term_height);
8698 ssh2_pkt_adduint32(s->pktout, 0); /* pixel width */
8699 ssh2_pkt_adduint32(s->pktout, 0); /* pixel height */
8700 ssh2_pkt_addstring_start(s->pktout);
c6ccd5c2 8701 parse_ttymodes(ssh, ssh->cfg.ttymodes,
8702 ssh2_send_ttymode, (void *)s->pktout);
8703 ssh2_pkt_addbyte(s->pktout, SSH2_TTY_OP_ISPEED);
ff3187f6 8704 ssh2_pkt_adduint32(s->pktout, ssh->ispeed);
c6ccd5c2 8705 ssh2_pkt_addbyte(s->pktout, SSH2_TTY_OP_OSPEED);
ff3187f6 8706 ssh2_pkt_adduint32(s->pktout, ssh->ospeed);
8707 ssh2_pkt_addstring_data(s->pktout, "\0", 1); /* TTY_OP_END */
8708 ssh2_pkt_send(ssh, s->pktout);
51470298 8709 ssh->state = SSH_STATE_INTERMED;
32874aea 8710
b09eaa88 8711 crWaitUntilV(pktin);
32874aea 8712
ff3187f6 8713 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8714 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8715 bombout(("Unexpected response to pty request:"
ff3187f6 8716 " packet type %d", pktin->type));
7ffdbc1a 8717 crStopV;
32874aea 8718 }
51470298 8719 c_write_str(ssh, "Server refused to allocate pty\r\n");
8720 ssh->editing = ssh->echoing = 1;
32874aea 8721 } else {
a5dd8467 8722 logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
db219738 8723 ssh->ospeed, ssh->ispeed);
32874aea 8724 }
0965bee0 8725 } else {
51470298 8726 ssh->editing = ssh->echoing = 1;
7cca0d81 8727 }
8728
8729 /*
73feed4f 8730 * Send environment variables.
8731 *
8732 * Simplest thing here is to send all the requests at once, and
8733 * then wait for a whole bunch of successes or failures.
8734 */
feb02b4e 8735 if (ssh->mainchan && !ssh->ncmode && *ssh->cfg.environmt) {
73feed4f 8736 char *e = ssh->cfg.environmt;
8737 char *var, *varend, *val;
8738
8739 s->num_env = 0;
8740
8741 while (*e) {
8742 var = e;
8743 while (*e && *e != '\t') e++;
8744 varend = e;
8745 if (*e == '\t') e++;
8746 val = e;
8747 while (*e) e++;
8748 e++;
8749
ff3187f6 8750 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8751 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
8752 ssh2_pkt_addstring(s->pktout, "env");
8753 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8754 ssh2_pkt_addstring_start(s->pktout);
8755 ssh2_pkt_addstring_data(s->pktout, var, varend-var);
8756 ssh2_pkt_addstring(s->pktout, val);
8757 ssh2_pkt_send(ssh, s->pktout);
73feed4f 8758
8759 s->num_env++;
8760 }
8761
8762 logeventf(ssh, "Sent %d environment variables", s->num_env);
8763
8764 s->env_ok = 0;
8765 s->env_left = s->num_env;
8766
8767 while (s->env_left > 0) {
b09eaa88 8768 crWaitUntilV(pktin);
73feed4f 8769
ff3187f6 8770 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8771 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
73feed4f 8772 bombout(("Unexpected response to environment request:"
ff3187f6 8773 " packet type %d", pktin->type));
73feed4f 8774 crStopV;
8775 }
8776 } else {
8777 s->env_ok++;
8778 }
8779
8780 s->env_left--;
8781 }
8782
8783 if (s->env_ok == s->num_env) {
8784 logevent("All environment variables successfully set");
8785 } else if (s->env_ok == 0) {
8786 logevent("All environment variables refused");
8787 c_write_str(ssh, "Server refused to set environment variables\r\n");
8788 } else {
8789 logeventf(ssh, "%d environment variables refused",
8790 s->num_env - s->env_ok);
8791 c_write_str(ssh, "Server refused to set all environment variables\r\n");
8792 }
8793 }
8794
8795 /*
fd5e5847 8796 * Start a shell or a remote command. We may have to attempt
8797 * this twice if the config data has provided a second choice
8798 * of command.
7cca0d81 8799 */
feb02b4e 8800 if (ssh->mainchan && !ssh->ncmode) while (1) {
fd5e5847 8801 int subsys;
8802 char *cmd;
8803
51470298 8804 if (ssh->fallback_cmd) {
86916870 8805 subsys = ssh->cfg.ssh_subsys2;
8806 cmd = ssh->cfg.remote_cmd_ptr2;
fd5e5847 8807 } else {
86916870 8808 subsys = ssh->cfg.ssh_subsys;
8809 cmd = ssh->cfg.remote_cmd_ptr;
04c52f10 8810 if (!cmd) cmd = ssh->cfg.remote_cmd;
fd5e5847 8811 }
8812
ff3187f6 8813 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8814 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); /* recipient channel */
fd5e5847 8815 if (subsys) {
ff3187f6 8816 ssh2_pkt_addstring(s->pktout, "subsystem");
8817 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8818 ssh2_pkt_addstring(s->pktout, cmd);
fd5e5847 8819 } else if (*cmd) {
ff3187f6 8820 ssh2_pkt_addstring(s->pktout, "exec");
8821 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8822 ssh2_pkt_addstring(s->pktout, cmd);
fd5e5847 8823 } else {
ff3187f6 8824 ssh2_pkt_addstring(s->pktout, "shell");
8825 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
32874aea 8826 }
ff3187f6 8827 ssh2_pkt_send(ssh, s->pktout);
b09eaa88 8828
8829 crWaitUntilV(pktin);
8830
ff3187f6 8831 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8832 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8833 bombout(("Unexpected response to shell/command request:"
ff3187f6 8834 " packet type %d", pktin->type));
7ffdbc1a 8835 crStopV;
fd5e5847 8836 }
8837 /*
8838 * We failed to start the command. If this is the
8839 * fallback command, we really are finished; if it's
8840 * not, and if the fallback command exists, try falling
8841 * back to it before complaining.
8842 */
86916870 8843 if (!ssh->fallback_cmd && ssh->cfg.remote_cmd_ptr2 != NULL) {
fd5e5847 8844 logevent("Primary command failed; attempting fallback");
51470298 8845 ssh->fallback_cmd = TRUE;
fd5e5847 8846 continue;
8847 }
6b5cf8b4 8848 bombout(("Server refused to start a shell/command"));
7ffdbc1a 8849 crStopV;
fd5e5847 8850 } else {
8851 logevent("Started a shell/command");
32874aea 8852 }
fd5e5847 8853 break;
7cca0d81 8854 }
8855
51470298 8856 ssh->state = SSH_STATE_SESSION;
8857 if (ssh->size_needed)
8858 ssh_size(ssh, ssh->term_width, ssh->term_height);
8859 if (ssh->eof_needed)
8860 ssh_special(ssh, TS_EOF);
6e48c3fe 8861
7cca0d81 8862 /*
0e443c99 8863 * All the initial channel requests are done, so install the default
8864 * failure handler.
8865 */
837d6ba6 8866 ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = ssh2_msg_channel_success;
0e443c99 8867 ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = ssh2_msg_channel_failure;
8868
8869 /*
7cca0d81 8870 * Transfer data!
8871 */
b9d7bcad 8872 if (ssh->ldisc)
8873 ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
0ed48730 8874 if (ssh->mainchan)
8875 ssh->send_ok = 1;
7cca0d81 8876 while (1) {
e5574168 8877 crReturnV;
51470298 8878 s->try_send = FALSE;
ff3187f6 8879 if (pktin) {
2b7540a7 8880
51df0ab5 8881 /*
8882 * _All_ the connection-layer packets we expect to
8883 * receive are now handled by the dispatch table.
8884 * Anything that reaches here must be bogus.
8885 */
32874aea 8886
51df0ab5 8887 bombout(("Strange packet received: type %d", pktin->type));
8888 crStopV;
0ed48730 8889 } else if (ssh->mainchan) {
32874aea 8890 /*
8891 * We have spare data. Add it to the channel buffer.
8892 */
d8baa528 8893 ssh2_add_channel_data(ssh->mainchan, (char *)in, inlen);
51470298 8894 s->try_send = TRUE;
32874aea 8895 }
51470298 8896 if (s->try_send) {
32874aea 8897 int i;
8898 struct ssh_channel *c;
8899 /*
8900 * Try to send data on all channels if we can.
8901 */
1bfc7e93 8902 for (i = 0; NULL != (c = index234(ssh->channels, i)); i++)
8903 ssh2_try_send_and_unthrottle(c);
7cca0d81 8904 }
e5574168 8905 }
8906
8907 crFinishV;
8908}
8909
8910/*
2e85c969 8911 * Handlers for SSH-2 messages that might arrive at any moment.
b09eaa88 8912 */
409bfa77 8913static void ssh2_msg_disconnect(Ssh ssh, struct Packet *pktin)
b09eaa88 8914{
8915 /* log reason code in disconnect message */
8916 char *buf, *msg;
60860bc3 8917 int reason, msglen;
b09eaa88 8918
8919 reason = ssh_pkt_getuint32(pktin);
8920 ssh_pkt_getstring(pktin, &msg, &msglen);
8921
8922 if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {
8923 buf = dupprintf("Received disconnect message (%s)",
8924 ssh2_disconnect_reasons[reason]);
8925 } else {
8926 buf = dupprintf("Received disconnect message (unknown"
8927 " type %d)", reason);
8928 }
8929 logevent(buf);
8930 sfree(buf);
60860bc3 8931 buf = dupprintf("Disconnection message text: %.*s",
8932 msglen, msg);
b09eaa88 8933 logevent(buf);
60860bc3 8934 bombout(("Server sent disconnect message\ntype %d (%s):\n\"%.*s\"",
b09eaa88 8935 reason,
8936 (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?
8937 ssh2_disconnect_reasons[reason] : "unknown",
60860bc3 8938 msglen, msg));
b09eaa88 8939 sfree(buf);
8940}
8941
409bfa77 8942static void ssh2_msg_debug(Ssh ssh, struct Packet *pktin)
b09eaa88 8943{
8944 /* log the debug message */
fb983202 8945 char *msg;
b09eaa88 8946 int msglen;
8947 int always_display;
8948
8949 /* XXX maybe we should actually take notice of this */
8950 always_display = ssh2_pkt_getbool(pktin);
8951 ssh_pkt_getstring(pktin, &msg, &msglen);
8952
fb983202 8953 logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
b09eaa88 8954}
8955
409bfa77 8956static void ssh2_msg_something_unimplemented(Ssh ssh, struct Packet *pktin)
b09eaa88 8957{
8958 struct Packet *pktout;
8959 pktout = ssh2_pkt_init(SSH2_MSG_UNIMPLEMENTED);
8960 ssh2_pkt_adduint32(pktout, pktin->sequence);
8961 /*
8962 * UNIMPLEMENTED messages MUST appear in the same order as the
8963 * messages they respond to. Hence, never queue them.
8964 */
8965 ssh2_pkt_send_noqueue(ssh, pktout);
8966}
8967
8968/*
2e85c969 8969 * Handle the top-level SSH-2 protocol.
7cca0d81 8970 */
b09eaa88 8971static void ssh2_protocol_setup(Ssh ssh)
8972{
8973 int i;
8974
8975 /*
8976 * Most messages cause SSH2_MSG_UNIMPLEMENTED.
8977 */
8978 for (i = 0; i < 256; i++)
8979 ssh->packet_dispatch[i] = ssh2_msg_something_unimplemented;
8980
8981 /*
8982 * Any message we actually understand, we set to NULL so that
8983 * the coroutines will get it.
8984 */
8985 ssh->packet_dispatch[SSH2_MSG_UNIMPLEMENTED] = NULL;
8986 ssh->packet_dispatch[SSH2_MSG_SERVICE_REQUEST] = NULL;
8987 ssh->packet_dispatch[SSH2_MSG_SERVICE_ACCEPT] = NULL;
8988 ssh->packet_dispatch[SSH2_MSG_KEXINIT] = NULL;
8989 ssh->packet_dispatch[SSH2_MSG_NEWKEYS] = NULL;
8990 ssh->packet_dispatch[SSH2_MSG_KEXDH_INIT] = NULL;
8991 ssh->packet_dispatch[SSH2_MSG_KEXDH_REPLY] = NULL;
8992 /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REQUEST] = NULL; duplicate case value */
8993 /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_GROUP] = NULL; duplicate case value */
8994 ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_INIT] = NULL;
8995 ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REPLY] = NULL;
8996 ssh->packet_dispatch[SSH2_MSG_USERAUTH_REQUEST] = NULL;
8997 ssh->packet_dispatch[SSH2_MSG_USERAUTH_FAILURE] = NULL;
8998 ssh->packet_dispatch[SSH2_MSG_USERAUTH_SUCCESS] = NULL;
8999 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
9000 ssh->packet_dispatch[SSH2_MSG_USERAUTH_PK_OK] = NULL;
9001 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ] = NULL; duplicate case value */
9002 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_REQUEST] = NULL; duplicate case value */
9003 ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_RESPONSE] = NULL;
9004 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] = NULL;
9005 ssh->packet_dispatch[SSH2_MSG_REQUEST_SUCCESS] = NULL;
9006 ssh->packet_dispatch[SSH2_MSG_REQUEST_FAILURE] = NULL;
9007 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = NULL;
9008 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] = NULL;
9009 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] = NULL;
9010 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] = NULL;
9011 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] = NULL;
9012 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] = NULL;
9013 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = NULL;
9014 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = NULL;
9015 ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] = NULL;
9016 ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = NULL;
9017 ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = NULL;
9018
9019 /*
9020 * These special message types we install handlers for.
9021 */
9022 ssh->packet_dispatch[SSH2_MSG_DISCONNECT] = ssh2_msg_disconnect;
2e85c969 9023 ssh->packet_dispatch[SSH2_MSG_IGNORE] = ssh_msg_ignore; /* shared with SSH-1 */
b09eaa88 9024 ssh->packet_dispatch[SSH2_MSG_DEBUG] = ssh2_msg_debug;
9025}
9026
9442dd57 9027static void ssh2_timer(void *ctx, long now)
9028{
9029 Ssh ssh = (Ssh)ctx;
9030
ecbb0000 9031 if (ssh->state == SSH_STATE_CLOSED)
9032 return;
9033
e6c1536e 9034 if (!ssh->kex_in_progress && ssh->cfg.ssh_rekey_time != 0 &&
9442dd57 9035 now - ssh->next_rekey >= 0) {
f382c87d 9036 do_ssh2_transport(ssh, "timeout", -1, NULL);
9442dd57 9037 }
9038}
9039
1c1a7262 9040static void ssh2_protocol(Ssh ssh, void *vin, int inlen,
ff3187f6 9041 struct Packet *pktin)
7cca0d81 9042{
1c1a7262 9043 unsigned char *in = (unsigned char *)vin;
b09eaa88 9044 if (ssh->state == SSH_STATE_CLOSED)
9045 return;
9046
9442dd57 9047 if (pktin) {
9048 ssh->incoming_data_size += pktin->encrypted_len;
9049 if (!ssh->kex_in_progress &&
d57f70af 9050 ssh->max_data_size != 0 &&
9051 ssh->incoming_data_size > ssh->max_data_size)
f382c87d 9052 do_ssh2_transport(ssh, "too much data received", -1, NULL);
9442dd57 9053 }
9054
b09eaa88 9055 if (pktin && ssh->packet_dispatch[pktin->type]) {
9056 ssh->packet_dispatch[pktin->type](ssh, pktin);
32874aea 9057 return;
b09eaa88 9058 }
9059
9060 if (!ssh->protocol_initial_phase_done ||
9061 (pktin && pktin->type >= 20 && pktin->type < 50)) {
9062 if (do_ssh2_transport(ssh, in, inlen, pktin) &&
9063 !ssh->protocol_initial_phase_done) {
9064 ssh->protocol_initial_phase_done = TRUE;
9065 /*
9066 * Allow authconn to initialise itself.
9067 */
9068 do_ssh2_authconn(ssh, NULL, 0, NULL);
9069 }
9070 } else {
9071 do_ssh2_authconn(ssh, in, inlen, pktin);
9072 }
7cca0d81 9073}
9074
9075/*
8df7a775 9076 * Called to set up the connection.
374330e2 9077 *
9078 * Returns an error message, or NULL on success.
374330e2 9079 */
cbe2d68f 9080static const char *ssh_init(void *frontend_handle, void **backend_handle,
9081 Config *cfg,
79bf227b 9082 char *host, int port, char **realhost, int nodelay,
9083 int keepalive)
32874aea 9084{
cbe2d68f 9085 const char *p;
51470298 9086 Ssh ssh;
9087
3d88e64d 9088 ssh = snew(struct ssh_tag);
86916870 9089 ssh->cfg = *cfg; /* STRUCTURE COPY */
125105d1 9090 ssh->version = 0; /* when not ready yet */
51470298 9091 ssh->s = NULL;
9092 ssh->cipher = NULL;
371e569c 9093 ssh->v1_cipher_ctx = NULL;
0183b242 9094 ssh->crcda_ctx = NULL;
51470298 9095 ssh->cscipher = NULL;
371e569c 9096 ssh->cs_cipher_ctx = NULL;
51470298 9097 ssh->sccipher = NULL;
371e569c 9098 ssh->sc_cipher_ctx = NULL;
51470298 9099 ssh->csmac = NULL;
a8327734 9100 ssh->cs_mac_ctx = NULL;
51470298 9101 ssh->scmac = NULL;
e0e1a00d 9102 ssh->sc_mac_ctx = NULL;
51470298 9103 ssh->cscomp = NULL;
5366aed8 9104 ssh->cs_comp_ctx = NULL;
51470298 9105 ssh->sccomp = NULL;
5366aed8 9106 ssh->sc_comp_ctx = NULL;
51470298 9107 ssh->kex = NULL;
389aa499 9108 ssh->kex_ctx = NULL;
51470298 9109 ssh->hostkey = NULL;
9110 ssh->exitcode = -1;
ac934965 9111 ssh->close_expected = FALSE;
9e296bfa 9112 ssh->clean_exit = FALSE;
51470298 9113 ssh->state = SSH_STATE_PREPACKET;
9114 ssh->size_needed = FALSE;
9115 ssh->eof_needed = FALSE;
b9d7bcad 9116 ssh->ldisc = NULL;
a8327734 9117 ssh->logctx = NULL;
51470298 9118 ssh->deferred_send_data = NULL;
9119 ssh->deferred_len = 0;
9120 ssh->deferred_size = 0;
9121 ssh->fallback_cmd = 0;
acab36bc 9122 ssh->pkt_kctx = SSH2_PKTCTX_NOKEX;
9123 ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
8def70c3 9124 ssh->x11disp = NULL;
be738459 9125 ssh->v1_compressing = FALSE;
51470298 9126 ssh->v2_outgoing_sequence = 0;
9127 ssh->ssh1_rdpkt_crstate = 0;
9128 ssh->ssh2_rdpkt_crstate = 0;
9129 ssh->do_ssh_init_crstate = 0;
9130 ssh->ssh_gotdata_crstate = 0;
b09eaa88 9131 ssh->do_ssh1_connection_crstate = 0;
51470298 9132 ssh->do_ssh1_login_crstate = 0;
9133 ssh->do_ssh2_transport_crstate = 0;
9134 ssh->do_ssh2_authconn_crstate = 0;
9135 ssh->do_ssh_init_state = NULL;
9136 ssh->do_ssh1_login_state = NULL;
9137 ssh->do_ssh2_transport_state = NULL;
9138 ssh->do_ssh2_authconn_state = NULL;
4320baf7 9139 ssh->v_c = NULL;
9140 ssh->v_s = NULL;
6571dbfd 9141 ssh->mainchan = NULL;
968d2d92 9142 ssh->throttled_all = 0;
9143 ssh->v1_stdout_throttling = 0;
590f6a5f 9144 ssh->queue = NULL;
9145 ssh->queuelen = ssh->queuesize = 0;
9146 ssh->queueing = FALSE;
06fadff5 9147 ssh->qhead = ssh->qtail = NULL;
e13bba36 9148 ssh->deferred_rekey_reason = NULL;
3d9449a1 9149 bufchain_init(&ssh->queued_incoming_data);
9150 ssh->frozen = FALSE;
51470298 9151
9152 *backend_handle = ssh;
32874aea 9153
8f203108 9154#ifdef MSCRYPTOAPI
32874aea 9155 if (crypto_startup() == 0)
8f203108 9156 return "Microsoft high encryption pack not installed!";
9157#endif
374330e2 9158
51470298 9159 ssh->frontend = frontend_handle;
86916870 9160 ssh->term_width = ssh->cfg.width;
9161 ssh->term_height = ssh->cfg.height;
887035a5 9162
fabd1805 9163 ssh->channels = NULL;
9164 ssh->rportfwds = NULL;
f47a5ffb 9165 ssh->portfwds = NULL;
fabd1805 9166
51470298 9167 ssh->send_ok = 0;
9168 ssh->editing = 0;
9169 ssh->echoing = 0;
ff68564b 9170 ssh->conn_throttle_count = 0;
51470298 9171 ssh->overall_bufsize = 0;
9172 ssh->fallback_cmd = 0;
8df7a775 9173
3648d4c5 9174 ssh->protocol = NULL;
9175
b09eaa88 9176 ssh->protocol_initial_phase_done = FALSE;
9177
39934deb 9178 ssh->pinger = NULL;
9179
9442dd57 9180 ssh->incoming_data_size = ssh->outgoing_data_size =
9181 ssh->deferred_data_size = 0L;
d57f70af 9182 ssh->max_data_size = parse_blocksize(ssh->cfg.ssh_rekey_data);
9442dd57 9183 ssh->kex_in_progress = FALSE;
9184
79bf227b 9185 p = connect_to_host(ssh, host, port, realhost, nodelay, keepalive);
fb09bf1c 9186 if (p != NULL)
9187 return p;
374330e2 9188
5d17ccfc 9189 random_ref();
9190
374330e2 9191 return NULL;
9192}
9193
fabd1805 9194static void ssh_free(void *handle)
9195{
9196 Ssh ssh = (Ssh) handle;
9197 struct ssh_channel *c;
9198 struct ssh_rportfwd *pf;
9199
9200 if (ssh->v1_cipher_ctx)
9201 ssh->cipher->free_context(ssh->v1_cipher_ctx);
9202 if (ssh->cs_cipher_ctx)
9203 ssh->cscipher->free_context(ssh->cs_cipher_ctx);
9204 if (ssh->sc_cipher_ctx)
9205 ssh->sccipher->free_context(ssh->sc_cipher_ctx);
9206 if (ssh->cs_mac_ctx)
9207 ssh->csmac->free_context(ssh->cs_mac_ctx);
9208 if (ssh->sc_mac_ctx)
9209 ssh->scmac->free_context(ssh->sc_mac_ctx);
29b1d0b3 9210 if (ssh->cs_comp_ctx) {
9211 if (ssh->cscomp)
9212 ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
9213 else
9214 zlib_compress_cleanup(ssh->cs_comp_ctx);
9215 }
9216 if (ssh->sc_comp_ctx) {
9217 if (ssh->sccomp)
9218 ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
9219 else
9220 zlib_decompress_cleanup(ssh->sc_comp_ctx);
9221 }
fabd1805 9222 if (ssh->kex_ctx)
9223 dh_cleanup(ssh->kex_ctx);
9224 sfree(ssh->savedhost);
9225
590f6a5f 9226 while (ssh->queuelen-- > 0)
9227 ssh_free_packet(ssh->queue[ssh->queuelen]);
9228 sfree(ssh->queue);
9229
06fadff5 9230 while (ssh->qhead) {
9231 struct queued_handler *qh = ssh->qhead;
9232 ssh->qhead = qh->next;
9233 sfree(ssh->qhead);
9234 }
9235 ssh->qhead = ssh->qtail = NULL;
9236
fabd1805 9237 if (ssh->channels) {
9238 while ((c = delpos234(ssh->channels, 0)) != NULL) {
9239 switch (c->type) {
9240 case CHAN_X11:
9241 if (c->u.x11.s != NULL)
9242 x11_close(c->u.x11.s);
9243 break;
9244 case CHAN_SOCKDATA:
9245 if (c->u.pfd.s != NULL)
9246 pfd_close(c->u.pfd.s);
9247 break;
9248 }
9249 sfree(c);
9250 }
9251 freetree234(ssh->channels);
cdb52705 9252 ssh->channels = NULL;
fabd1805 9253 }
9254
9255 if (ssh->rportfwds) {
9256 while ((pf = delpos234(ssh->rportfwds, 0)) != NULL)
9257 sfree(pf);
9258 freetree234(ssh->rportfwds);
cdb52705 9259 ssh->rportfwds = NULL;
fabd1805 9260 }
9261 sfree(ssh->deferred_send_data);
8def70c3 9262 if (ssh->x11disp)
9263 x11_free_display(ssh->x11disp);
fabd1805 9264 sfree(ssh->do_ssh_init_state);
9265 sfree(ssh->do_ssh1_login_state);
9266 sfree(ssh->do_ssh2_transport_state);
9267 sfree(ssh->do_ssh2_authconn_state);
4320baf7 9268 sfree(ssh->v_c);
9269 sfree(ssh->v_s);
42af6a67 9270 sfree(ssh->fullhostname);
679539d7 9271 if (ssh->crcda_ctx) {
9272 crcda_free_context(ssh->crcda_ctx);
9273 ssh->crcda_ctx = NULL;
9274 }
fabd1805 9275 if (ssh->s)
ac934965 9276 ssh_do_close(ssh, TRUE);
9442dd57 9277 expire_timer_context(ssh);
39934deb 9278 if (ssh->pinger)
9279 pinger_free(ssh->pinger);
3d9449a1 9280 bufchain_clear(&ssh->queued_incoming_data);
ee50e8b6 9281 sfree(ssh);
5d17ccfc 9282
9283 random_unref();
fabd1805 9284}
9285
374330e2 9286/*
86916870 9287 * Reconfigure the SSH backend.
86916870 9288 */
9289static void ssh_reconfig(void *handle, Config *cfg)
9290{
9291 Ssh ssh = (Ssh) handle;
e13bba36 9292 char *rekeying = NULL, rekey_mandatory = FALSE;
e6c1536e 9293 unsigned long old_max_data_size;
9294
39934deb 9295 pinger_reconfig(ssh->pinger, &ssh->cfg, cfg);
3b6606c7 9296 if (ssh->portfwds)
9297 ssh_setup_portfwd(ssh, cfg);
e6c1536e 9298
9299 if (ssh->cfg.ssh_rekey_time != cfg->ssh_rekey_time &&
9300 cfg->ssh_rekey_time != 0) {
9301 long new_next = ssh->last_rekey + cfg->ssh_rekey_time*60*TICKSPERSEC;
9302 long now = GETTICKCOUNT();
9303
9304 if (new_next - now < 0) {
f382c87d 9305 rekeying = "timeout shortened";
e6c1536e 9306 } else {
9307 ssh->next_rekey = schedule_timer(new_next - now, ssh2_timer, ssh);
9308 }
9309 }
9310
9311 old_max_data_size = ssh->max_data_size;
9312 ssh->max_data_size = parse_blocksize(cfg->ssh_rekey_data);
9313 if (old_max_data_size != ssh->max_data_size &&
9314 ssh->max_data_size != 0) {
9315 if (ssh->outgoing_data_size > ssh->max_data_size ||
9316 ssh->incoming_data_size > ssh->max_data_size)
f382c87d 9317 rekeying = "data limit lowered";
e6c1536e 9318 }
9319
e13bba36 9320 if (ssh->cfg.compression != cfg->compression) {
f382c87d 9321 rekeying = "compression setting changed";
e13bba36 9322 rekey_mandatory = TRUE;
9323 }
9324
9325 if (ssh->cfg.ssh2_des_cbc != cfg->ssh2_des_cbc ||
9326 memcmp(ssh->cfg.ssh_cipherlist, cfg->ssh_cipherlist,
9327 sizeof(ssh->cfg.ssh_cipherlist))) {
f382c87d 9328 rekeying = "cipher settings changed";
e13bba36 9329 rekey_mandatory = TRUE;
e6c1536e 9330 }
9331
86916870 9332 ssh->cfg = *cfg; /* STRUCTURE COPY */
e13bba36 9333
9334 if (rekeying) {
9335 if (!ssh->kex_in_progress) {
9336 do_ssh2_transport(ssh, rekeying, -1, NULL);
9337 } else if (rekey_mandatory) {
9338 ssh->deferred_rekey_reason = rekeying;
9339 }
9340 }
86916870 9341}
9342
9343/*
86dc445a 9344 * Called to send data down the SSH connection.
374330e2 9345 */
51470298 9346static int ssh_send(void *handle, char *buf, int len)
32874aea 9347{
51470298 9348 Ssh ssh = (Ssh) handle;
9349
9350 if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
5471d09a 9351 return 0;
374330e2 9352
d8baa528 9353 ssh->protocol(ssh, (unsigned char *)buf, len, 0);
5471d09a 9354
51470298 9355 return ssh_sendbuffer(ssh);
5471d09a 9356}
9357
9358/*
9359 * Called to query the current amount of buffered stdin data.
9360 */
51470298 9361static int ssh_sendbuffer(void *handle)
5471d09a 9362{
51470298 9363 Ssh ssh = (Ssh) handle;
5471d09a 9364 int override_value;
9365
51470298 9366 if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
5471d09a 9367 return 0;
9368
9369 /*
9370 * If the SSH socket itself has backed up, add the total backup
9371 * size on that to any individual buffer on the stdin channel.
9372 */
9373 override_value = 0;
51470298 9374 if (ssh->throttled_all)
9375 override_value = ssh->overall_bufsize;
5471d09a 9376
51470298 9377 if (ssh->version == 1) {
5471d09a 9378 return override_value;
51470298 9379 } else if (ssh->version == 2) {
9380 if (!ssh->mainchan || ssh->mainchan->closes > 0)
5471d09a 9381 return override_value;
9382 else
51470298 9383 return (override_value +
9384 bufchain_size(&ssh->mainchan->v.v2.outbuffer));
5471d09a 9385 }
9386
9387 return 0;
374330e2 9388}
9389
9390/*
6e48c3fe 9391 * Called to set the size of the window from SSH's POV.
374330e2 9392 */
51470298 9393static void ssh_size(void *handle, int width, int height)
32874aea 9394{
51470298 9395 Ssh ssh = (Ssh) handle;
ff3187f6 9396 struct Packet *pktout;
51470298 9397
9398 ssh->term_width = width;
9399 ssh->term_height = height;
f278d6f8 9400
51470298 9401 switch (ssh->state) {
374330e2 9402 case SSH_STATE_BEFORE_SIZE:
3687d221 9403 case SSH_STATE_PREPACKET:
21248260 9404 case SSH_STATE_CLOSED:
374330e2 9405 break; /* do nothing */
9406 case SSH_STATE_INTERMED:
51470298 9407 ssh->size_needed = TRUE; /* buffer for later */
374330e2 9408 break;
9409 case SSH_STATE_SESSION:
86916870 9410 if (!ssh->cfg.nopty) {
51470298 9411 if (ssh->version == 1) {
9412 send_packet(ssh, SSH1_CMSG_WINDOW_SIZE,
9413 PKT_INT, ssh->term_height,
9414 PKT_INT, ssh->term_width,
32874aea 9415 PKT_INT, 0, PKT_INT, 0, PKT_END);
0ed48730 9416 } else if (ssh->mainchan) {
ff3187f6 9417 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
9418 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
9419 ssh2_pkt_addstring(pktout, "window-change");
9420 ssh2_pkt_addbool(pktout, 0);
9421 ssh2_pkt_adduint32(pktout, ssh->term_width);
9422 ssh2_pkt_adduint32(pktout, ssh->term_height);
9423 ssh2_pkt_adduint32(pktout, 0);
9424 ssh2_pkt_adduint32(pktout, 0);
9425 ssh2_pkt_send(ssh, pktout);
32874aea 9426 }
9427 }
9428 break;
374330e2 9429 }
9430}
9431
9432/*
125105d1 9433 * Return a list of the special codes that make sense in this
9434 * protocol.
9435 */
9436static const struct telnet_special *ssh_get_specials(void *handle)
9437{
786ba75e 9438 static const struct telnet_special ssh1_ignore_special[] = {
9439 {"IGNORE message", TS_NOP}
9440 };
cf6ddb95 9441 static const struct telnet_special ssh2_ignore_special[] = {
62638676 9442 {"IGNORE message", TS_NOP},
cf6ddb95 9443 };
9444 static const struct telnet_special ssh2_rekey_special[] = {
9442dd57 9445 {"Repeat key exchange", TS_REKEY},
62638676 9446 };
9447 static const struct telnet_special ssh2_session_specials[] = {
6f2d0cde 9448 {NULL, TS_SEP},
9449 {"Break", TS_BRK},
bccbeb71 9450 /* These are the signal names defined by RFC 4254.
6f2d0cde 9451 * They include all the ISO C signals, but are a subset of the POSIX
9452 * required signals. */
9453 {"SIGINT (Interrupt)", TS_SIGINT},
9454 {"SIGTERM (Terminate)", TS_SIGTERM},
9455 {"SIGKILL (Kill)", TS_SIGKILL},
9456 {"SIGQUIT (Quit)", TS_SIGQUIT},
9457 {"SIGHUP (Hangup)", TS_SIGHUP},
9458 {"More signals", TS_SUBMENU},
9459 {"SIGABRT", TS_SIGABRT}, {"SIGALRM", TS_SIGALRM},
9460 {"SIGFPE", TS_SIGFPE}, {"SIGILL", TS_SIGILL},
9461 {"SIGPIPE", TS_SIGPIPE}, {"SIGSEGV", TS_SIGSEGV},
9462 {"SIGUSR1", TS_SIGUSR1}, {"SIGUSR2", TS_SIGUSR2},
9463 {NULL, TS_EXITMENU}
62638676 9464 };
9465 static const struct telnet_special specials_end[] = {
6f2d0cde 9466 {NULL, TS_EXITMENU}
62638676 9467 };
786ba75e 9468 /* XXX review this length for any changes: */
cf6ddb95 9469 static struct telnet_special ssh_specials[lenof(ssh2_ignore_special) +
9470 lenof(ssh2_rekey_special) +
62638676 9471 lenof(ssh2_session_specials) +
9472 lenof(specials_end)];
125105d1 9473 Ssh ssh = (Ssh) handle;
62638676 9474 int i = 0;
9475#define ADD_SPECIALS(name) \
9476 do { \
9477 assert((i + lenof(name)) <= lenof(ssh_specials)); \
9478 memcpy(&ssh_specials[i], name, sizeof name); \
9479 i += lenof(name); \
9480 } while(0)
125105d1 9481
9482 if (ssh->version == 1) {
62638676 9483 /* Don't bother offering IGNORE if we've decided the remote
9484 * won't cope with it, since we wouldn't bother sending it if
9485 * asked anyway. */
9486 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
786ba75e 9487 ADD_SPECIALS(ssh1_ignore_special);
125105d1 9488 } else if (ssh->version == 2) {
cf6ddb95 9489 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE))
9490 ADD_SPECIALS(ssh2_ignore_special);
9491 if (!(ssh->remote_bugs & BUG_SSH2_REKEY))
9492 ADD_SPECIALS(ssh2_rekey_special);
62638676 9493 if (ssh->mainchan)
9494 ADD_SPECIALS(ssh2_session_specials);
9495 } /* else we're not ready yet */
9496
9497 if (i) {
9498 ADD_SPECIALS(specials_end);
9499 return ssh_specials;
9500 } else {
125105d1 9501 return NULL;
62638676 9502 }
9503#undef ADD_SPECIALS
125105d1 9504}
9505
9506/*
86dc445a 9507 * Send special codes. TS_EOF is useful for `plink', so you
6abbf9e3 9508 * can send an EOF and collect resulting output (e.g. `plink
9509 * hostname sort').
374330e2 9510 */
51470298 9511static void ssh_special(void *handle, Telnet_Special code)
32874aea 9512{
51470298 9513 Ssh ssh = (Ssh) handle;
ff3187f6 9514 struct Packet *pktout;
51470298 9515
6abbf9e3 9516 if (code == TS_EOF) {
51470298 9517 if (ssh->state != SSH_STATE_SESSION) {
32874aea 9518 /*
9519 * Buffer the EOF in case we are pre-SESSION, so we can
9520 * send it as soon as we reach SESSION.
9521 */
9522 if (code == TS_EOF)
51470298 9523 ssh->eof_needed = TRUE;
32874aea 9524 return;
9525 }
51470298 9526 if (ssh->version == 1) {
9527 send_packet(ssh, SSH1_CMSG_EOF, PKT_END);
0ed48730 9528 } else if (ssh->mainchan) {
ff3187f6 9529 struct Packet *pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
9530 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
9531 ssh2_pkt_send(ssh, pktout);
00a0b113 9532 ssh->send_ok = 0; /* now stop trying to read from stdin */
32874aea 9533 }
9534 logevent("Sent EOF message");
125105d1 9535 } else if (code == TS_PING || code == TS_NOP) {
51470298 9536 if (ssh->state == SSH_STATE_CLOSED
9537 || ssh->state == SSH_STATE_PREPACKET) return;
9538 if (ssh->version == 1) {
9539 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
9540 send_packet(ssh, SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
32874aea 9541 } else {
cf6ddb95 9542 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE)) {
9543 pktout = ssh2_pkt_init(SSH2_MSG_IGNORE);
9544 ssh2_pkt_addstring_start(pktout);
9545 ssh2_pkt_send_noqueue(ssh, pktout);
9546 }
32874aea 9547 }
9442dd57 9548 } else if (code == TS_REKEY) {
9549 if (!ssh->kex_in_progress && ssh->version == 2) {
f382c87d 9550 do_ssh2_transport(ssh, "at user request", -1, NULL);
9442dd57 9551 }
125105d1 9552 } else if (code == TS_BRK) {
9553 if (ssh->state == SSH_STATE_CLOSED
9554 || ssh->state == SSH_STATE_PREPACKET) return;
9555 if (ssh->version == 1) {
2e85c969 9556 logevent("Unable to send BREAK signal in SSH-1");
0ed48730 9557 } else if (ssh->mainchan) {
ff3187f6 9558 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
9559 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
9560 ssh2_pkt_addstring(pktout, "break");
9561 ssh2_pkt_addbool(pktout, 0);
9562 ssh2_pkt_adduint32(pktout, 0); /* default break length */
9563 ssh2_pkt_send(ssh, pktout);
125105d1 9564 }
6abbf9e3 9565 } else {
6f2d0cde 9566 /* Is is a POSIX signal? */
9567 char *signame = NULL;
9568 if (code == TS_SIGABRT) signame = "ABRT";
9569 if (code == TS_SIGALRM) signame = "ALRM";
9570 if (code == TS_SIGFPE) signame = "FPE";
9571 if (code == TS_SIGHUP) signame = "HUP";
9572 if (code == TS_SIGILL) signame = "ILL";
9573 if (code == TS_SIGINT) signame = "INT";
9574 if (code == TS_SIGKILL) signame = "KILL";
9575 if (code == TS_SIGPIPE) signame = "PIPE";
9576 if (code == TS_SIGQUIT) signame = "QUIT";
9577 if (code == TS_SIGSEGV) signame = "SEGV";
9578 if (code == TS_SIGTERM) signame = "TERM";
9579 if (code == TS_SIGUSR1) signame = "USR1";
9580 if (code == TS_SIGUSR2) signame = "USR2";
9581 /* The SSH-2 protocol does in principle support arbitrary named
9582 * signals, including signame@domain, but we don't support those. */
9583 if (signame) {
9584 /* It's a signal. */
9585 if (ssh->version == 2 && ssh->mainchan) {
ff3187f6 9586 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
9587 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
9588 ssh2_pkt_addstring(pktout, "signal");
9589 ssh2_pkt_addbool(pktout, 0);
9590 ssh2_pkt_addstring(pktout, signame);
9591 ssh2_pkt_send(ssh, pktout);
6f2d0cde 9592 logeventf(ssh, "Sent signal SIG%s", signame);
9593 }
9594 } else {
9595 /* Never heard of it. Do nothing */
9596 }
6abbf9e3 9597 }
374330e2 9598}
9599
51470298 9600void *new_sock_channel(void *handle, Socket s)
d74d141c 9601{
51470298 9602 Ssh ssh = (Ssh) handle;
d74d141c 9603 struct ssh_channel *c;
3d88e64d 9604 c = snew(struct ssh_channel);
d74d141c 9605
70c0cbe1 9606 c->ssh = ssh;
9607 ssh2_channel_init(c);
9608 c->halfopen = TRUE;
9609 c->type = CHAN_SOCKDATA_DORMANT;/* identify channel type */
9610 c->u.pfd.s = s;
9611 add234(ssh->channels, c);
d74d141c 9612 return c;
9613}
9614
5471d09a 9615/*
9616 * This is called when stdout/stderr (the entity to which
9617 * from_backend sends data) manages to clear some backlog.
9618 */
ae9ae89f 9619static void ssh_unthrottle(void *handle, int bufsize)
5471d09a 9620{
51470298 9621 Ssh ssh = (Ssh) handle;
ff68564b 9622 int buflimit;
9623
51470298 9624 if (ssh->version == 1) {
9625 if (ssh->v1_stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
9626 ssh->v1_stdout_throttling = 0;
ff68564b 9627 ssh_throttle_conn(ssh, -1);
5471d09a 9628 }
9629 } else {
ff68564b 9630 if (ssh->mainchan) {
ab87bf1d 9631 ssh2_set_window(ssh->mainchan,
ff68564b 9632 bufsize < ssh->mainchan->v.v2.locmaxwin ?
9633 ssh->mainchan->v.v2.locmaxwin - bufsize : 0);
9634 if (ssh->cfg.ssh_simple)
9635 buflimit = 0;
9636 else
9637 buflimit = ssh->mainchan->v.v2.locmaxwin;
9638 if (ssh->mainchan->throttling_conn && bufsize <= buflimit) {
9639 ssh->mainchan->throttling_conn = 0;
9640 ssh_throttle_conn(ssh, -1);
9641 }
9642 }
5471d09a 9643 }
9644}
9645
6b78788a 9646void ssh_send_port_open(void *channel, char *hostname, int port, char *org)
d74d141c 9647{
9648 struct ssh_channel *c = (struct ssh_channel *)channel;
6b78788a 9649 Ssh ssh = c->ssh;
ff3187f6 9650 struct Packet *pktout;
d74d141c 9651
57356d63 9652 logeventf(ssh, "Opening forwarded connection to %s:%d", hostname, port);
d74d141c 9653
51470298 9654 if (ssh->version == 1) {
9655 send_packet(ssh, SSH1_MSG_PORT_OPEN,
bc240b21 9656 PKT_INT, c->localid,
9657 PKT_STR, hostname,
9658 PKT_INT, port,
31fb1866 9659 /* PKT_STR, <org:orgport>, */
bc240b21 9660 PKT_END);
9661 } else {
ff3187f6 9662 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
9663 ssh2_pkt_addstring(pktout, "direct-tcpip");
9664 ssh2_pkt_adduint32(pktout, c->localid);
ff3187f6 9665 ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);/* our window size */
954d5c5a 9666 ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
ff3187f6 9667 ssh2_pkt_addstring(pktout, hostname);
9668 ssh2_pkt_adduint32(pktout, port);
bc240b21 9669 /*
9670 * We make up values for the originator data; partly it's
9671 * too much hassle to keep track, and partly I'm not
9672 * convinced the server should be told details like that
9673 * about my local network configuration.
1f182589 9674 * The "originator IP address" is syntactically a numeric
9675 * IP address, and some servers (e.g., Tectia) get upset
9676 * if it doesn't match this syntax.
bc240b21 9677 */
1f182589 9678 ssh2_pkt_addstring(pktout, "0.0.0.0");
ff3187f6 9679 ssh2_pkt_adduint32(pktout, 0);
9680 ssh2_pkt_send(ssh, pktout);
bc240b21 9681 }
d74d141c 9682}
9683
6226c939 9684static int ssh_connected(void *handle)
32874aea 9685{
51470298 9686 Ssh ssh = (Ssh) handle;
6226c939 9687 return ssh->s != NULL;
32874aea 9688}
8ccc75b0 9689
51470298 9690static int ssh_sendok(void *handle)
32874aea 9691{
51470298 9692 Ssh ssh = (Ssh) handle;
9693 return ssh->send_ok;
32874aea 9694}
fb09bf1c 9695
51470298 9696static int ssh_ldisc(void *handle, int option)
32874aea 9697{
51470298 9698 Ssh ssh = (Ssh) handle;
32874aea 9699 if (option == LD_ECHO)
51470298 9700 return ssh->echoing;
32874aea 9701 if (option == LD_EDIT)
51470298 9702 return ssh->editing;
0965bee0 9703 return FALSE;
9704}
9705
b9d7bcad 9706static void ssh_provide_ldisc(void *handle, void *ldisc)
9707{
9708 Ssh ssh = (Ssh) handle;
9709 ssh->ldisc = ldisc;
9710}
9711
a8327734 9712static void ssh_provide_logctx(void *handle, void *logctx)
9713{
9714 Ssh ssh = (Ssh) handle;
9715 ssh->logctx = logctx;
9716}
9717
51470298 9718static int ssh_return_exitcode(void *handle)
9719{
9720 Ssh ssh = (Ssh) handle;
3bb2f322 9721 if (ssh->s != NULL)
9722 return -1;
9723 else
3c112d53 9724 return (ssh->exitcode >= 0 ? ssh->exitcode : INT_MAX);
51470298 9725}
9726
9727/*
f89c3294 9728 * cfg_info for SSH is the currently running version of the
9729 * protocol. (1 for 1; 2 for 2; 0 for not-decided-yet.)
9730 */
9731static int ssh_cfg_info(void *handle)
9732{
9733 Ssh ssh = (Ssh) handle;
9734 return ssh->version;
9735}
9736
9737/*
51470298 9738 * Gross hack: pscp will try to start SFTP but fall back to scp1 if
9739 * that fails. This variable is the means by which scp.c can reach
9740 * into the SSH code and find out which one it got.
9741 */
9742extern int ssh_fallback_cmd(void *handle)
d8d6c7e5 9743{
51470298 9744 Ssh ssh = (Ssh) handle;
9745 return ssh->fallback_cmd;
d8d6c7e5 9746}
9747
374330e2 9748Backend ssh_backend = {
9749 ssh_init,
fabd1805 9750 ssh_free,
86916870 9751 ssh_reconfig,
374330e2 9752 ssh_send,
5471d09a 9753 ssh_sendbuffer,
374330e2 9754 ssh_size,
4017be6d 9755 ssh_special,
125105d1 9756 ssh_get_specials,
6226c939 9757 ssh_connected,
d8d6c7e5 9758 ssh_return_exitcode,
97db3be4 9759 ssh_sendok,
0965bee0 9760 ssh_ldisc,
b9d7bcad 9761 ssh_provide_ldisc,
a8327734 9762 ssh_provide_logctx,
5471d09a 9763 ssh_unthrottle,
f89c3294 9764 ssh_cfg_info,
9e164d82 9765 "ssh",
9766 PROT_SSH,
97db3be4 9767 22
bc240b21 9768};