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