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