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