Update docs for change to UTF-8 by default, and emphasise UTF-8 more generally.
[sgt/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 RSAKey servkey, hostkey;
3275 struct MD5Context md5c;
51470298 3276 struct do_ssh1_login_state {
30919997 3277 int crLine;
51470298 3278 int len;
3279 unsigned char *rsabuf, *keystr1, *keystr2;
3280 unsigned long supported_ciphers_mask, supported_auths_mask;
3281 int tried_publickey, tried_agent;
3282 int tis_auth_refused, ccard_auth_refused;
3283 unsigned char session_id[16];
3284 int cipher_type;
51470298 3285 void *publickey_blob;
3286 int publickey_bloblen;
edd0cb8a 3287 char *publickey_comment;
3288 int publickey_encrypted;
3289 prompts_t *cur_prompt;
51470298 3290 char c;
3291 int pwpkt_type;
3292 unsigned char request[5], *response, *p;
3293 int responselen;
3294 int keyi, nkeys;
3295 int authed;
3296 struct RSAKey key;
3297 Bignum challenge;
3298 char *commentp;
3299 int commentlen;
3d9449a1 3300 int dlgret;
4a693cfc 3301 Filename *keyfile;
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
ff3187f6 3324 if (!ssh1_pkt_getrsakey(pktin, &servkey, &s->keystr1) ||
3325 !ssh1_pkt_getrsakey(pktin, &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, " ");
32874aea 3337 hostkey.comment = NULL;
3338 rsa_fingerprint(logmsg + strlen(logmsg),
3339 sizeof(logmsg) - strlen(logmsg), &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);
51470298 3354 MD5Update(&md5c, s->keystr2, hostkey.bytes);
3355 MD5Update(&md5c, s->keystr1, 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 */
3365 if (hostkey.bits > hostkey.bytes * 8 ||
3366 servkey.bits > servkey.bytes * 8) {
2e85c969 3367 bombout(("SSH-1 public keys were badly formatted"));
0016d70b 3368 crStop(0);
3369 }
3370
51470298 3371 s->len = (hostkey.bytes > servkey.bytes ? hostkey.bytes : servkey.bytes);
374330e2 3372
3d88e64d 3373 s->rsabuf = snewn(s->len, unsigned char);
374330e2 3374
89ee5268 3375 /*
3376 * Verify the host key.
3377 */
3378 {
32874aea 3379 /*
3380 * First format the key into a string.
3381 */
3382 int len = rsastr_len(&hostkey);
3383 char fingerprint[100];
3d88e64d 3384 char *keystr = snewn(len, char);
32874aea 3385 rsastr_fmt(keystr, &hostkey);
3386 rsa_fingerprint(fingerprint, sizeof(fingerprint), &hostkey);
3d9449a1 3387
3388 ssh_set_frozen(ssh, 1);
3389 s->dlgret = verify_ssh_host_key(ssh->frontend,
3390 ssh->savedhost, ssh->savedport,
3391 "rsa", keystr, fingerprint,
3392 ssh_dialog_callback, ssh);
32874aea 3393 sfree(keystr);
3d9449a1 3394 if (s->dlgret < 0) {
3395 do {
3396 crReturn(0);
3397 if (pktin) {
3398 bombout(("Unexpected data from server while waiting"
3399 " for user host key response"));
3400 crStop(0);
3401 }
3402 } while (pktin || inlen > 0);
3403 s->dlgret = ssh->user_response;
3404 }
3405 ssh_set_frozen(ssh, 0);
3406
3407 if (s->dlgret == 0) {
9e296bfa 3408 ssh_disconnect(ssh, "User aborted at host key verification",
3409 NULL, 0, TRUE);
2b3f6c19 3410 crStop(0);
3d9449a1 3411 }
32874aea 3412 }
3413
3414 for (i = 0; i < 32; i++) {
51470298 3415 s->rsabuf[i] = ssh->session_key[i];
374330e2 3416 if (i < 16)
51470298 3417 s->rsabuf[i] ^= s->session_id[i];
374330e2 3418 }
3419
3420 if (hostkey.bytes > servkey.bytes) {
0016d70b 3421 ret = rsaencrypt(s->rsabuf, 32, &servkey);
3422 if (ret)
3423 ret = rsaencrypt(s->rsabuf, servkey.bytes, &hostkey);
374330e2 3424 } else {
0016d70b 3425 ret = rsaencrypt(s->rsabuf, 32, &hostkey);
3426 if (ret)
3427 ret = rsaencrypt(s->rsabuf, hostkey.bytes, &servkey);
3428 }
3429 if (!ret) {
2e85c969 3430 bombout(("SSH-1 public key encryptions failed due to bad formatting"));
0016d70b 3431 crStop(0);
374330e2 3432 }
3433
c5e9c988 3434 logevent("Encrypted session key");
3435
ca20bfcf 3436 {
3437 int cipher_chosen = 0, warn = 0;
3438 char *cipher_string = NULL;
51470298 3439 int i;
ca20bfcf 3440 for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) {
4a693cfc 3441 int next_cipher = conf_get_int_int(ssh->conf,
3442 CONF_ssh_cipherlist, i);
ca20bfcf 3443 if (next_cipher == CIPHER_WARN) {
3444 /* If/when we choose a cipher, warn about it */
3445 warn = 1;
3446 } else if (next_cipher == CIPHER_AES) {
3447 /* XXX Probably don't need to mention this. */
2e85c969 3448 logevent("AES not supported in SSH-1, skipping");
ca20bfcf 3449 } else {
3450 switch (next_cipher) {
51470298 3451 case CIPHER_3DES: s->cipher_type = SSH_CIPHER_3DES;
ca20bfcf 3452 cipher_string = "3DES"; break;
51470298 3453 case CIPHER_BLOWFISH: s->cipher_type = SSH_CIPHER_BLOWFISH;
ca20bfcf 3454 cipher_string = "Blowfish"; break;
51470298 3455 case CIPHER_DES: s->cipher_type = SSH_CIPHER_DES;
ca20bfcf 3456 cipher_string = "single-DES"; break;
3457 }
51470298 3458 if (s->supported_ciphers_mask & (1 << s->cipher_type))
ca20bfcf 3459 cipher_chosen = 1;
3460 }
3461 }
3462 if (!cipher_chosen) {
51470298 3463 if ((s->supported_ciphers_mask & (1 << SSH_CIPHER_3DES)) == 0)
2e85c969 3464 bombout(("Server violates SSH-1 protocol by not "
ca20bfcf 3465 "supporting 3DES encryption"));
3466 else
3467 /* shouldn't happen */
6b5cf8b4 3468 bombout(("No supported ciphers found"));
7ffdbc1a 3469 crStop(0);
a99a05c0 3470 }
ca20bfcf 3471
3472 /* Warn about chosen cipher if necessary. */
bb348ab1 3473 if (warn) {
3d9449a1 3474 ssh_set_frozen(ssh, 1);
3475 s->dlgret = askalg(ssh->frontend, "cipher", cipher_string,
3476 ssh_dialog_callback, ssh);
3477 if (s->dlgret < 0) {
3478 do {
3479 crReturn(0);
3480 if (pktin) {
3481 bombout(("Unexpected data from server while waiting"
3482 " for user response"));
3483 crStop(0);
3484 }
3485 } while (pktin || inlen > 0);
3486 s->dlgret = ssh->user_response;
3487 }
3488 ssh_set_frozen(ssh, 0);
3489 if (s->dlgret == 0) {
9e296bfa 3490 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
3491 0, TRUE);
96ccde8b 3492 crStop(0);
3d9449a1 3493 }
bb348ab1 3494 }
bea1ef5f 3495 }
ca20bfcf 3496
51470298 3497 switch (s->cipher_type) {
32874aea 3498 case SSH_CIPHER_3DES:
3499 logevent("Using 3DES encryption");
3500 break;
3501 case SSH_CIPHER_DES:
3502 logevent("Using single-DES encryption");
3503 break;
3504 case SSH_CIPHER_BLOWFISH:
3505 logevent("Using Blowfish encryption");
3506 break;
c5e9c988 3507 }
bea1ef5f 3508
51470298 3509 send_packet(ssh, SSH1_CMSG_SESSION_KEY,
3510 PKT_CHAR, s->cipher_type,
32874aea 3511 PKT_DATA, cookie, 8,
51470298 3512 PKT_CHAR, (s->len * 8) >> 8, PKT_CHAR, (s->len * 8) & 0xFF,
3513 PKT_DATA, s->rsabuf, s->len,
3514 PKT_INT, ssh->v1_local_protoflags, PKT_END);
fb09bf1c 3515
c5e9c988 3516 logevent("Trying to enable encryption...");
374330e2 3517
51470298 3518 sfree(s->rsabuf);
374330e2 3519
51470298 3520 ssh->cipher = (s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
3521 s->cipher_type == SSH_CIPHER_DES ? &ssh_des :
3522 &ssh_3des);
371e569c 3523 ssh->v1_cipher_ctx = ssh->cipher->make_context();
3524 ssh->cipher->sesskey(ssh->v1_cipher_ctx, ssh->session_key);
57356d63 3525 logeventf(ssh, "Initialised %s encryption", ssh->cipher->text_name);
374330e2 3526
0183b242 3527 ssh->crcda_ctx = crcda_make_context();
3528 logevent("Installing CRC compensation attack detector");
3529
679539d7 3530 if (servkey.modulus) {
3531 sfree(servkey.modulus);
3532 servkey.modulus = NULL;
3533 }
3534 if (servkey.exponent) {
3535 sfree(servkey.exponent);
3536 servkey.exponent = NULL;
3537 }
3538 if (hostkey.modulus) {
3539 sfree(hostkey.modulus);
3540 hostkey.modulus = NULL;
3541 }
3542 if (hostkey.exponent) {
3543 sfree(hostkey.exponent);
3544 hostkey.exponent = NULL;
3545 }
ff3187f6 3546 crWaitUntil(pktin);
374330e2 3547
ff3187f6 3548 if (pktin->type != SSH1_SMSG_SUCCESS) {
6b5cf8b4 3549 bombout(("Encryption not successfully enabled"));
7ffdbc1a 3550 crStop(0);
8d5de777 3551 }
374330e2 3552
c5e9c988 3553 logevent("Successfully started encryption");
3554
edd0cb8a 3555 fflush(stdout); /* FIXME eh? */
374330e2 3556 {
4a693cfc 3557 if ((ssh->username = get_remote_username(ssh->conf)) == NULL) {
edd0cb8a 3558 int ret; /* need not be kept over crReturn */
3559 s->cur_prompt = new_prompts(ssh->frontend);
3560 s->cur_prompt->to_server = TRUE;
3561 s->cur_prompt->name = dupstr("SSH login name");
b61f81bc 3562 add_prompt(s->cur_prompt, dupstr("login as: "), TRUE);
edd0cb8a 3563 ret = get_userpass_input(s->cur_prompt, NULL, 0);
3564 while (ret < 0) {
51470298 3565 ssh->send_ok = 1;
edd0cb8a 3566 crWaitUntil(!pktin);
3567 ret = get_userpass_input(s->cur_prompt, in, inlen);
3568 ssh->send_ok = 0;
3569 }
3570 if (!ret) {
3571 /*
3572 * Failed to get a username. Terminate.
3573 */
3574 free_prompts(s->cur_prompt);
3575 ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
3576 crStop(0);
32874aea 3577 }
4a693cfc 3578 ssh->username = dupstr(s->cur_prompt->prompts[0]->result);
edd0cb8a 3579 free_prompts(s->cur_prompt);
374330e2 3580 }
fb09bf1c 3581
4a693cfc 3582 send_packet(ssh, SSH1_CMSG_USER, PKT_STR, ssh->username, PKT_END);
c5e9c988 3583 {
4a693cfc 3584 char *userlog = dupprintf("Sent username \"%s\"", ssh->username);
c5e9c988 3585 logevent(userlog);
32874aea 3586 if (flags & FLAG_INTERACTIVE &&
3587 (!((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)))) {
51470298 3588 c_write_str(ssh, userlog);
edd0cb8a 3589 c_write_str(ssh, "\r\n");
3c8e959b 3590 }
edd0cb8a 3591 sfree(userlog);
c5e9c988 3592 }
374330e2 3593 }
3594
ff3187f6 3595 crWaitUntil(pktin);
374330e2 3596
d5b2c841 3597 if ((s->supported_auths_mask & (1 << SSH1_AUTH_RSA)) == 0) {
0df73905 3598 /* We must not attempt PK auth. Pretend we've already tried it. */
51470298 3599 s->tried_publickey = s->tried_agent = 1;
0df73905 3600 } else {
51470298 3601 s->tried_publickey = s->tried_agent = 0;
0df73905 3602 }
51470298 3603 s->tis_auth_refused = s->ccard_auth_refused = 0;
edd0cb8a 3604 /*
3605 * Load the public half of any configured keyfile for later use.
3606 */
4a693cfc 3607 s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
962468d4 3608 if (!filename_is_null(s->keyfile)) {
edd0cb8a 3609 int keytype;
3610 logeventf(ssh, "Reading private key file \"%.150s\"",
4a693cfc 3611 filename_to_str(s->keyfile));
3612 keytype = key_type(s->keyfile);
edd0cb8a 3613 if (keytype == SSH_KEYTYPE_SSH1) {
3614 const char *error;
4a693cfc 3615 if (rsakey_pubblob(s->keyfile,
edd0cb8a 3616 &s->publickey_blob, &s->publickey_bloblen,
3617 &s->publickey_comment, &error)) {
4a693cfc 3618 s->publickey_encrypted = rsakey_encrypted(s->keyfile,
edd0cb8a 3619 NULL);
3620 } else {
3621 char *msgbuf;
3622 logeventf(ssh, "Unable to load private key (%s)", error);
3623 msgbuf = dupprintf("Unable to load private key file "
3624 "\"%.150s\" (%s)\r\n",
4a693cfc 3625 filename_to_str(s->keyfile),
edd0cb8a 3626 error);
3627 c_write_str(ssh, msgbuf);
3628 sfree(msgbuf);
3629 s->publickey_blob = NULL;
3630 }
3631 } else {
3632 char *msgbuf;
3633 logeventf(ssh, "Unable to use this key file (%s)",
3634 key_type_to_str(keytype));
3635 msgbuf = dupprintf("Unable to use key file \"%.150s\""
3636 " (%s)\r\n",
4a693cfc 3637 filename_to_str(s->keyfile),
edd0cb8a 3638 key_type_to_str(keytype));
3639 c_write_str(ssh, msgbuf);
3640 sfree(msgbuf);
51470298 3641 s->publickey_blob = NULL;
edd0cb8a 3642 }
396778f1 3643 } else
51470298 3644 s->publickey_blob = NULL;
7cca0d81 3645
ff3187f6 3646 while (pktin->type == SSH1_SMSG_FAILURE) {
51470298 3647 s->pwpkt_type = SSH1_CMSG_AUTH_PASSWORD;
614a20a0 3648
4a693cfc 3649 if (conf_get_int(ssh->conf, CONF_tryagent) && agent_exists() && !s->tried_agent) {
32874aea 3650 /*
3651 * Attempt RSA authentication using Pageant.
3652 */
32874aea 3653 void *r;
3654
51470298 3655 s->authed = FALSE;
3656 s->tried_agent = 1;
32874aea 3657 logevent("Pageant is running. Requesting keys.");
3658
3659 /* Request the keys held by the agent. */
51470298 3660 PUT_32BIT(s->request, 1);
3661 s->request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;
839f10db 3662 if (!agent_query(s->request, 5, &r, &s->responselen,
3663 ssh_agent_callback, ssh)) {
3664 do {
3665 crReturn(0);
ff3187f6 3666 if (pktin) {
839f10db 3667 bombout(("Unexpected data from server while waiting"
3668 " for agent response"));
3669 crStop(0);
3670 }
ff3187f6 3671 } while (pktin || inlen > 0);
839f10db 3672 r = ssh->agent_response;
3673 s->responselen = ssh->agent_response_len;
3674 }
51470298 3675 s->response = (unsigned char *) r;
3676 if (s->response && s->responselen >= 5 &&
3677 s->response[4] == SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
3678 s->p = s->response + 5;
3679 s->nkeys = GET_32BIT(s->p);
3680 s->p += 4;
2e85c969 3681 logeventf(ssh, "Pageant has %d SSH-1 keys", s->nkeys);
51470298 3682 for (s->keyi = 0; s->keyi < s->nkeys; s->keyi++) {
94cd7c3a 3683 unsigned char *pkblob = s->p;
51470298 3684 s->p += 4;
0016d70b 3685 {
3686 int n, ok = FALSE;
3687 do { /* do while (0) to make breaking easy */
3688 n = ssh1_read_bignum
3689 (s->p, s->responselen-(s->p-s->response),
3690 &s->key.exponent);
3691 if (n < 0)
3692 break;
3693 s->p += n;
3694 n = ssh1_read_bignum
3695 (s->p, s->responselen-(s->p-s->response),
3696 &s->key.modulus);
3697 if (n < 0)
3698 break;
3699 s->p += n;
3700 if (s->responselen - (s->p-s->response) < 4)
3701 break;
3702 s->commentlen = GET_32BIT(s->p);
3703 s->p += 4;
3704 if (s->responselen - (s->p-s->response) <
3705 s->commentlen)
3706 break;
3707 s->commentp = (char *)s->p;
3708 s->p += s->commentlen;
3709 ok = TRUE;
3710 } while (0);
3711 if (!ok) {
3712 logevent("Pageant key list packet was truncated");
3713 break;
3714 }
3715 }
94cd7c3a 3716 if (s->publickey_blob) {
3717 if (!memcmp(pkblob, s->publickey_blob,
3718 s->publickey_bloblen)) {
3719 logeventf(ssh, "Pageant key #%d matches "
3720 "configured key file", s->keyi);
3721 s->tried_publickey = 1;
3722 } else
3723 /* Skip non-configured key */
3724 continue;
3725 }
3726 logeventf(ssh, "Trying Pageant key #%d", s->keyi);
51470298 3727 send_packet(ssh, SSH1_CMSG_AUTH_RSA,
3728 PKT_BIGNUM, s->key.modulus, PKT_END);
ff3187f6 3729 crWaitUntil(pktin);
3730 if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
32874aea 3731 logevent("Key refused");
3732 continue;
3733 }
3734 logevent("Received RSA challenge");
ff3187f6 3735 if ((s->challenge = ssh1_pkt_getmp(pktin)) == NULL) {
0016d70b 3736 bombout(("Server's RSA challenge was badly formatted"));
3737 crStop(0);
3738 }
3739
32874aea 3740 {
3741 char *agentreq, *q, *ret;
2d466ffd 3742 void *vret;
32874aea 3743 int len, retlen;
3744 len = 1 + 4; /* message type, bit count */
51470298 3745 len += ssh1_bignum_length(s->key.exponent);
3746 len += ssh1_bignum_length(s->key.modulus);
3747 len += ssh1_bignum_length(s->challenge);
32874aea 3748 len += 16; /* session id */
3749 len += 4; /* response format */
3d88e64d 3750 agentreq = snewn(4 + len, char);
32874aea 3751 PUT_32BIT(agentreq, len);
3752 q = agentreq + 4;
3753 *q++ = SSH1_AGENTC_RSA_CHALLENGE;
51470298 3754 PUT_32BIT(q, bignum_bitcount(s->key.modulus));
32874aea 3755 q += 4;
51470298 3756 q += ssh1_write_bignum(q, s->key.exponent);
3757 q += ssh1_write_bignum(q, s->key.modulus);
3758 q += ssh1_write_bignum(q, s->challenge);
3759 memcpy(q, s->session_id, 16);
32874aea 3760 q += 16;
3761 PUT_32BIT(q, 1); /* response format */
839f10db 3762 if (!agent_query(agentreq, len + 4, &vret, &retlen,
3763 ssh_agent_callback, ssh)) {
3764 sfree(agentreq);
3765 do {
3766 crReturn(0);
ff3187f6 3767 if (pktin) {
839f10db 3768 bombout(("Unexpected data from server"
3769 " while waiting for agent"
3770 " response"));
3771 crStop(0);
3772 }
ff3187f6 3773 } while (pktin || inlen > 0);
839f10db 3774 vret = ssh->agent_response;
3775 retlen = ssh->agent_response_len;
3776 } else
3777 sfree(agentreq);
2d466ffd 3778 ret = vret;
32874aea 3779 if (ret) {
3780 if (ret[4] == SSH1_AGENT_RSA_RESPONSE) {
3781 logevent("Sending Pageant's response");
51470298 3782 send_packet(ssh, SSH1_CMSG_AUTH_RSA_RESPONSE,
32874aea 3783 PKT_DATA, ret + 5, 16,
3784 PKT_END);
3785 sfree(ret);
ff3187f6 3786 crWaitUntil(pktin);
3787 if (pktin->type == SSH1_SMSG_SUCCESS) {
32874aea 3788 logevent
3789 ("Pageant's response accepted");
3790 if (flags & FLAG_VERBOSE) {
51470298 3791 c_write_str(ssh, "Authenticated using"
3792 " RSA key \"");
3793 c_write(ssh, s->commentp,
3794 s->commentlen);
3795 c_write_str(ssh, "\" from agent\r\n");
32874aea 3796 }
51470298 3797 s->authed = TRUE;
32874aea 3798 } else
3799 logevent
3800 ("Pageant's response not accepted");
3801 } else {
3802 logevent
3803 ("Pageant failed to answer challenge");
3804 sfree(ret);
3805 }
3806 } else {
3807 logevent("No reply received from Pageant");
3808 }
3809 }
51470298 3810 freebn(s->key.exponent);
3811 freebn(s->key.modulus);
3812 freebn(s->challenge);
3813 if (s->authed)
32874aea 3814 break;
3815 }
29b1d0b3 3816 sfree(s->response);
94cd7c3a 3817 if (s->publickey_blob && !s->tried_publickey)
3818 logevent("Configured key file not in Pageant");
5ff99b8e 3819 } else {
3820 logevent("Failed to get reply from Pageant");
3821 }
51470298 3822 if (s->authed)
32874aea 3823 break;
3824 }
edd0cb8a 3825 if (s->publickey_blob && !s->tried_publickey) {
3826 /*
3827 * Try public key authentication with the specified
3828 * key file.
3829 */
3830 int got_passphrase; /* need not be kept over crReturn */
3831 if (flags & FLAG_VERBOSE)
3832 c_write_str(ssh, "Trying public key authentication.\r\n");
4a693cfc 3833 s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
edd0cb8a 3834 logeventf(ssh, "Trying public key \"%s\"",
4a693cfc 3835 filename_to_str(s->keyfile));
edd0cb8a 3836 s->tried_publickey = 1;
3837 got_passphrase = FALSE;
3838 while (!got_passphrase) {
3839 /*
3840 * Get a passphrase, if necessary.
3841 */
3842 char *passphrase = NULL; /* only written after crReturn */
3843 const char *error;
3844 if (!s->publickey_encrypted) {
3845 if (flags & FLAG_VERBOSE)
3846 c_write_str(ssh, "No passphrase required.\r\n");
3847 passphrase = NULL;
3848 } else {
3849 int ret; /* need not be kept over crReturn */
3850 s->cur_prompt = new_prompts(ssh->frontend);
3851 s->cur_prompt->to_server = FALSE;
3852 s->cur_prompt->name = dupstr("SSH key passphrase");
3853 add_prompt(s->cur_prompt,
3854 dupprintf("Passphrase for key \"%.100s\": ",
b61f81bc 3855 s->publickey_comment), FALSE);
edd0cb8a 3856 ret = get_userpass_input(s->cur_prompt, NULL, 0);
3857 while (ret < 0) {
3858 ssh->send_ok = 1;
3859 crWaitUntil(!pktin);
3860 ret = get_userpass_input(s->cur_prompt, in, inlen);
3861 ssh->send_ok = 0;
3862 }
3863 if (!ret) {
3864 /* Failed to get a passphrase. Terminate. */
3865 free_prompts(s->cur_prompt);
3866 ssh_disconnect(ssh, NULL, "Unable to authenticate",
3867 0, TRUE);
3868 crStop(0);
3869 }
3870 passphrase = dupstr(s->cur_prompt->prompts[0]->result);
3871 free_prompts(s->cur_prompt);
3872 }
3873 /*
3874 * Try decrypting key with passphrase.
3875 */
4a693cfc 3876 s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
3877 ret = loadrsakey(s->keyfile, &s->key, passphrase,
edd0cb8a 3878 &error);
3879 if (passphrase) {
dfb88efd 3880 smemclr(passphrase, strlen(passphrase));
edd0cb8a 3881 sfree(passphrase);
3882 }
3883 if (ret == 1) {
3884 /* Correct passphrase. */
3885 got_passphrase = TRUE;
3886 } else if (ret == 0) {
3887 c_write_str(ssh, "Couldn't load private key from ");
4a693cfc 3888 c_write_str(ssh, filename_to_str(s->keyfile));
edd0cb8a 3889 c_write_str(ssh, " (");
3890 c_write_str(ssh, error);
3891 c_write_str(ssh, ").\r\n");
3892 got_passphrase = FALSE;
3893 break; /* go and try something else */
3894 } else if (ret == -1) {
3895 c_write_str(ssh, "Wrong passphrase.\r\n"); /* FIXME */
edd0cb8a 3896 got_passphrase = FALSE;
3897 /* and try again */
43536490 3898 } else {
3899 assert(0 && "unexpected return from loadrsakey()");
edc23a8a 3900 got_passphrase = FALSE; /* placate optimisers */
edd0cb8a 3901 }
3902 }
3903
3904 if (got_passphrase) {
3905
3906 /*
3907 * Send a public key attempt.
3908 */
3909 send_packet(ssh, SSH1_CMSG_AUTH_RSA,
3910 PKT_BIGNUM, s->key.modulus, PKT_END);
3911
3912 crWaitUntil(pktin);
3913 if (pktin->type == SSH1_SMSG_FAILURE) {
3914 c_write_str(ssh, "Server refused our public key.\r\n");
7b575324 3915 continue; /* go and try something else */
edd0cb8a 3916 }
3917 if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
3918 bombout(("Bizarre response to offer of public key"));
3919 crStop(0);
3920 }
3921
3922 {
3923 int i;
3924 unsigned char buffer[32];
3925 Bignum challenge, response;
3926
3927 if ((challenge = ssh1_pkt_getmp(pktin)) == NULL) {
3928 bombout(("Server's RSA challenge was badly formatted"));
3929 crStop(0);
3930 }
3931 response = rsadecrypt(challenge, &s->key);
3932 freebn(s->key.private_exponent);/* burn the evidence */
3933
3934 for (i = 0; i < 32; i++) {
3935 buffer[i] = bignum_byte(response, 31 - i);
3936 }
3937
3938 MD5Init(&md5c);
3939 MD5Update(&md5c, buffer, 32);
3940 MD5Update(&md5c, s->session_id, 16);
3941 MD5Final(buffer, &md5c);
3942
3943 send_packet(ssh, SSH1_CMSG_AUTH_RSA_RESPONSE,
3944 PKT_DATA, buffer, 16, PKT_END);
3945
3946 freebn(challenge);
3947 freebn(response);
3948 }
3949
3950 crWaitUntil(pktin);
3951 if (pktin->type == SSH1_SMSG_FAILURE) {
3952 if (flags & FLAG_VERBOSE)
3953 c_write_str(ssh, "Failed to authenticate with"
3954 " our public key.\r\n");
7b575324 3955 continue; /* go and try something else */
edd0cb8a 3956 } else if (pktin->type != SSH1_SMSG_SUCCESS) {
3957 bombout(("Bizarre response to RSA authentication response"));
3958 crStop(0);
3959 }
3960
3961 break; /* we're through! */
3962 }
3963
3964 }
3965
3966 /*
3967 * Otherwise, try various forms of password-like authentication.
3968 */
3969 s->cur_prompt = new_prompts(ssh->frontend);
32874aea 3970
4a693cfc 3971 if (conf_get_int(ssh->conf, CONF_try_tis_auth) &&
51470298 3972 (s->supported_auths_mask & (1 << SSH1_AUTH_TIS)) &&
3973 !s->tis_auth_refused) {
3974 s->pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
32874aea 3975 logevent("Requested TIS authentication");
51470298 3976 send_packet(ssh, SSH1_CMSG_AUTH_TIS, PKT_END);
ff3187f6 3977 crWaitUntil(pktin);
3978 if (pktin->type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
32874aea 3979 logevent("TIS authentication declined");
3980 if (flags & FLAG_INTERACTIVE)
51470298 3981 c_write_str(ssh, "TIS authentication refused.\r\n");
3982 s->tis_auth_refused = 1;
614a20a0 3983 continue;
32874aea 3984 } else {
0016d70b 3985 char *challenge;
3986 int challengelen;
edd0cb8a 3987 char *instr_suf, *prompt;
0016d70b 3988
ff3187f6 3989 ssh_pkt_getstring(pktin, &challenge, &challengelen);
0016d70b 3990 if (!challenge) {
3991 bombout(("TIS challenge packet was badly formed"));
3992 crStop(0);
3993 }
32874aea 3994 logevent("Received TIS challenge");
edd0cb8a 3995 s->cur_prompt->to_server = TRUE;
3996 s->cur_prompt->name = dupstr("SSH TIS authentication");
614a20a0 3997 /* Prompt heuristic comes from OpenSSH */
edd0cb8a 3998 if (memchr(challenge, '\n', challengelen)) {
3999 instr_suf = dupstr("");
4000 prompt = dupprintf("%.*s", challengelen, challenge);
4001 } else {
4002 instr_suf = dupprintf("%.*s", challengelen, challenge);
4003 prompt = dupstr("Response: ");
4004 }
4005 s->cur_prompt->instruction =
4006 dupprintf("Using TIS authentication.%s%s",
4007 (*instr_suf) ? "\n" : "",
4008 instr_suf);
4009 s->cur_prompt->instr_reqd = TRUE;
b61f81bc 4010 add_prompt(s->cur_prompt, prompt, FALSE);
edd0cb8a 4011 sfree(instr_suf);
32874aea 4012 }
4013 }
4a693cfc 4014 if (conf_get_int(ssh->conf, CONF_try_tis_auth) &&
51470298 4015 (s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
4016 !s->ccard_auth_refused) {
4017 s->pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
32874aea 4018 logevent("Requested CryptoCard authentication");
51470298 4019 send_packet(ssh, SSH1_CMSG_AUTH_CCARD, PKT_END);
ff3187f6 4020 crWaitUntil(pktin);
4021 if (pktin->type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
32874aea 4022 logevent("CryptoCard authentication declined");
51470298 4023 c_write_str(ssh, "CryptoCard authentication refused.\r\n");
4024 s->ccard_auth_refused = 1;
614a20a0 4025 continue;
32874aea 4026 } else {
0016d70b 4027 char *challenge;
4028 int challengelen;
edd0cb8a 4029 char *instr_suf, *prompt;
0016d70b 4030
ff3187f6 4031 ssh_pkt_getstring(pktin, &challenge, &challengelen);
0016d70b 4032 if (!challenge) {
4033 bombout(("CryptoCard challenge packet was badly formed"));
4034 crStop(0);
4035 }
32874aea 4036 logevent("Received CryptoCard challenge");
edd0cb8a 4037 s->cur_prompt->to_server = TRUE;
4038 s->cur_prompt->name = dupstr("SSH CryptoCard authentication");
4039 s->cur_prompt->name_reqd = FALSE;
4040 /* Prompt heuristic comes from OpenSSH */
4041 if (memchr(challenge, '\n', challengelen)) {
4042 instr_suf = dupstr("");
4043 prompt = dupprintf("%.*s", challengelen, challenge);
4044 } else {
4045 instr_suf = dupprintf("%.*s", challengelen, challenge);
4046 prompt = dupstr("Response: ");
4047 }
4048 s->cur_prompt->instruction =
4049 dupprintf("Using CryptoCard authentication.%s%s",
4050 (*instr_suf) ? "\n" : "",
4051 instr_suf);
4052 s->cur_prompt->instr_reqd = TRUE;
b61f81bc 4053 add_prompt(s->cur_prompt, prompt, FALSE);
edd0cb8a 4054 sfree(instr_suf);
32874aea 4055 }
4056 }
51470298 4057 if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
8f9e3231 4058 if ((s->supported_auths_mask & (1 << SSH1_AUTH_PASSWORD)) == 0) {
4059 bombout(("No supported authentication methods available"));
4060 crStop(0);
4061 }
edd0cb8a 4062 s->cur_prompt->to_server = TRUE;
4063 s->cur_prompt->name = dupstr("SSH password");
4a693cfc 4064 add_prompt(s->cur_prompt, dupprintf("%s@%s's password: ",
4065 ssh->username, ssh->savedhost),
b61f81bc 4066 FALSE);
32874aea 4067 }
a52f067e 4068
614a20a0 4069 /*
4070 * Show password prompt, having first obtained it via a TIS
4071 * or CryptoCard exchange if we're doing TIS or CryptoCard
4072 * authentication.
4073 */
edd0cb8a 4074 {
4075 int ret; /* need not be kept over crReturn */
4076 ret = get_userpass_input(s->cur_prompt, NULL, 0);
4077 while (ret < 0) {
4078 ssh->send_ok = 1;
4079 crWaitUntil(!pktin);
4080 ret = get_userpass_input(s->cur_prompt, in, inlen);
4081 ssh->send_ok = 0;
4082 }
4083 if (!ret) {
32874aea 4084 /*
edd0cb8a 4085 * Failed to get a password (for example
32874aea 4086 * because one was supplied on the command line
4087 * which has already failed to work). Terminate.
4088 */
edd0cb8a 4089 free_prompts(s->cur_prompt);
4090 ssh_disconnect(ssh, NULL, "Unable to authenticate", 0, TRUE);
4091 crStop(0);
32874aea 4092 }
32874aea 4093 }
4094
edd0cb8a 4095 if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
32874aea 4096 /*
edd0cb8a 4097 * Defence against traffic analysis: we send a
4098 * whole bunch of packets containing strings of
4099 * different lengths. One of these strings is the
4100 * password, in a SSH1_CMSG_AUTH_PASSWORD packet.
4101 * The others are all random data in
4102 * SSH1_MSG_IGNORE packets. This way a passive
4103 * listener can't tell which is the password, and
4104 * hence can't deduce the password length.
4105 *
4106 * Anybody with a password length greater than 16
4107 * bytes is going to have enough entropy in their
4108 * password that a listener won't find it _that_
4109 * much help to know how long it is. So what we'll
4110 * do is:
4111 *
4112 * - if password length < 16, we send 15 packets
4113 * containing string lengths 1 through 15
4114 *
4115 * - otherwise, we let N be the nearest multiple
4116 * of 8 below the password length, and send 8
4117 * packets containing string lengths N through
4118 * N+7. This won't obscure the order of
4119 * magnitude of the password length, but it will
4120 * introduce a bit of extra uncertainty.
4121 *
bf982899 4122 * A few servers can't deal with SSH1_MSG_IGNORE, at
4123 * least in this context. For these servers, we need
4124 * an alternative defence. We make use of the fact
4125 * that the password is interpreted as a C string:
4126 * so we can append a NUL, then some random data.
edd0cb8a 4127 *
bf982899 4128 * A few servers can deal with neither SSH1_MSG_IGNORE
4129 * here _nor_ a padded password string.
4130 * For these servers we are left with no defences
edd0cb8a 4131 * against password length sniffing.
32874aea 4132 */
bf982899 4133 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE) &&
4134 !(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
32874aea 4135 /*
edd0cb8a 4136 * The server can deal with SSH1_MSG_IGNORE, so
4137 * we can use the primary defence.
32874aea 4138 */
edd0cb8a 4139 int bottom, top, pwlen, i;
4140 char *randomstr;
32874aea 4141
edd0cb8a 4142 pwlen = strlen(s->cur_prompt->prompts[0]->result);
4143 if (pwlen < 16) {
4144 bottom = 0; /* zero length passwords are OK! :-) */
4145 top = 15;
4146 } else {
4147 bottom = pwlen & ~7;
4148 top = bottom + 7;
4149 }
32874aea 4150
edd0cb8a 4151 assert(pwlen >= bottom && pwlen <= top);
32874aea 4152
edd0cb8a 4153 randomstr = snewn(top + 1, char);
32874aea 4154
edd0cb8a 4155 for (i = bottom; i <= top; i++) {
4156 if (i == pwlen) {
4157 defer_packet(ssh, s->pwpkt_type,
4158 PKTT_PASSWORD, PKT_STR,
4159 s->cur_prompt->prompts[0]->result,
4160 PKTT_OTHER, PKT_END);
4161 } else {
4162 for (j = 0; j < i; j++) {
4163 do {
4164 randomstr[j] = random_byte();
4165 } while (randomstr[j] == '\0');
32874aea 4166 }
edd0cb8a 4167 randomstr[i] = '\0';
4168 defer_packet(ssh, SSH1_MSG_IGNORE,
4169 PKT_STR, randomstr, PKT_END);
32874aea 4170 }
edd0cb8a 4171 }
4172 logevent("Sending password with camouflage packets");
4173 ssh_pkt_defersend(ssh);
4174 sfree(randomstr);
4175 }
4176 else if (!(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
4177 /*
4178 * The server can't deal with SSH1_MSG_IGNORE
4179 * but can deal with padded passwords, so we
4180 * can use the secondary defence.
4181 */
4182 char string[64];
4183 char *ss;
4184 int len;
4185
4186 len = strlen(s->cur_prompt->prompts[0]->result);
4187 if (len < sizeof(string)) {
4188 ss = string;
4189 strcpy(string, s->cur_prompt->prompts[0]->result);
4190 len++; /* cover the zero byte */
4191 while (len < sizeof(string)) {
4192 string[len++] = (char) random_byte();
bd358db1 4193 }
bd358db1 4194 } else {
edd0cb8a 4195 ss = s->cur_prompt->prompts[0]->result;
32874aea 4196 }
edd0cb8a 4197 logevent("Sending length-padded password");
9a10ecf4 4198 send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
edd0cb8a 4199 PKT_INT, len, PKT_DATA, ss, len,
4200 PKTT_OTHER, PKT_END);
4201 } else {
4202 /*
bf982899 4203 * The server is believed unable to cope with
4204 * any of our password camouflage methods.
edd0cb8a 4205 */
4206 int len;
4207 len = strlen(s->cur_prompt->prompts[0]->result);
4208 logevent("Sending unpadded password");
4209 send_packet(ssh, s->pwpkt_type,
4210 PKTT_PASSWORD, PKT_INT, len,
4211 PKT_DATA, s->cur_prompt->prompts[0]->result, len,
4212 PKTT_OTHER, PKT_END);
32874aea 4213 }
edd0cb8a 4214 } else {
4215 send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
4216 PKT_STR, s->cur_prompt->prompts[0]->result,
4217 PKTT_OTHER, PKT_END);
32874aea 4218 }
c5e9c988 4219 logevent("Sent password");
edd0cb8a 4220 free_prompts(s->cur_prompt);
ff3187f6 4221 crWaitUntil(pktin);
4222 if (pktin->type == SSH1_SMSG_FAILURE) {
32874aea 4223 if (flags & FLAG_VERBOSE)
51470298 4224 c_write_str(ssh, "Access denied\r\n");
c5e9c988 4225 logevent("Authentication refused");
ff3187f6 4226 } else if (pktin->type != SSH1_SMSG_SUCCESS) {
4227 bombout(("Strange packet received, type %d", pktin->type));
7ffdbc1a 4228 crStop(0);
374330e2 4229 }
4230 }
4231
edd0cb8a 4232 /* Clear up */
4233 if (s->publickey_blob) {
4234 sfree(s->publickey_blob);
4235 sfree(s->publickey_comment);
4236 }
4237
c5e9c988 4238 logevent("Authentication successful");
4239
fb09bf1c 4240 crFinish(1);
4241}
4242
bc06669b 4243static void ssh_channel_try_eof(struct ssh_channel *c)
4244{
4245 Ssh ssh = c->ssh;
4246 assert(c->pending_eof); /* precondition for calling us */
4247 if (c->halfopen)
4248 return; /* can't close: not even opened yet */
4249 if (ssh->version == 2 && bufchain_size(&c->v.v2.outbuffer) > 0)
4250 return; /* can't send EOF: pending outgoing data */
4251
3620f307 4252 c->pending_eof = FALSE; /* we're about to send it */
bc06669b 4253 if (ssh->version == 1) {
4254 send_packet(ssh, SSH1_MSG_CHANNEL_CLOSE, PKT_INT, c->remoteid,
4255 PKT_END);
4256 c->closes |= CLOSES_SENT_EOF;
4257 } else {
4258 struct Packet *pktout;
4259 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
4260 ssh2_pkt_adduint32(pktout, c->remoteid);
4261 ssh2_pkt_send(ssh, pktout);
4262 c->closes |= CLOSES_SENT_EOF;
3620f307 4263 ssh2_channel_check_close(c);
bc06669b 4264 }
bc06669b 4265}
4266
4267void sshfwd_write_eof(struct ssh_channel *c)
32874aea 4268{
51470298 4269 Ssh ssh = c->ssh;
4270
1ef619ae 4271 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 4272 return;
36f94d1f 4273
bc06669b 4274 if (c->closes & CLOSES_SENT_EOF)
4275 return;
78280721 4276
bc06669b 4277 c->pending_eof = TRUE;
4278 ssh_channel_try_eof(c);
32874aea 4279}
4280
c6b41791 4281void sshfwd_unclean_close(struct ssh_channel *c)
4282{
4283 Ssh ssh = c->ssh;
c6b41791 4284
4285 if (ssh->state == SSH_STATE_CLOSED)
4286 return;
4287
c6b41791 4288 switch (c->type) {
4289 case CHAN_X11:
4290 x11_close(c->u.x11.s);
04120005 4291 logevent("Forwarded X11 connection terminated due to local error");
c6b41791 4292 break;
4293 case CHAN_SOCKDATA:
4294 case CHAN_SOCKDATA_DORMANT:
4295 pfd_close(c->u.pfd.s);
04120005 4296 logevent("Forwarded port closed due to local error");
c6b41791 4297 break;
4298 }
4299 c->type = CHAN_ZOMBIE;
96210393 4300
c6b41791 4301 ssh2_channel_check_close(c);
4302}
4303
5471d09a 4304int sshfwd_write(struct ssh_channel *c, char *buf, int len)
32874aea 4305{
51470298 4306 Ssh ssh = c->ssh;
4307
1ef619ae 4308 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 4309 return 0;
36f94d1f 4310
51470298 4311 if (ssh->version == 1) {
4312 send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
32874aea 4313 PKT_INT, c->remoteid,
a2724fba 4314 PKT_INT, len, PKTT_DATA, PKT_DATA, buf, len,
9a10ecf4 4315 PKTT_OTHER, PKT_END);
5471d09a 4316 /*
2e85c969 4317 * In SSH-1 we can return 0 here - implying that forwarded
5471d09a 4318 * connections are never individually throttled - because
4319 * the only circumstance that can cause throttling will be
4320 * the whole SSH connection backing up, in which case
4321 * _everything_ will be throttled as a whole.
4322 */
4323 return 0;
783415f8 4324 } else {
32874aea 4325 ssh2_add_channel_data(c, buf, len);
5471d09a 4326 return ssh2_try_send(c);
4327 }
4328}
4329
4330void sshfwd_unthrottle(struct ssh_channel *c, int bufsize)
4331{
51470298 4332 Ssh ssh = c->ssh;
ff68564b 4333 int buflimit;
51470298 4334
1ef619ae 4335 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 4336 return;
36f94d1f 4337
51470298 4338 if (ssh->version == 1) {
ff68564b 4339 buflimit = SSH1_BUFFER_LIMIT;
5471d09a 4340 } else {
ff68564b 4341 buflimit = c->v.v2.locmaxwin;
4342 ssh2_set_window(c, bufsize < buflimit ? buflimit - bufsize : 0);
4343 }
4344 if (c->throttling_conn && bufsize <= buflimit) {
4345 c->throttling_conn = 0;
4346 ssh_throttle_conn(ssh, -1);
783415f8 4347 }
9c964e85 4348}
4349
06fadff5 4350static void ssh_queueing_handler(Ssh ssh, struct Packet *pktin)
4351{
4352 struct queued_handler *qh = ssh->qhead;
4353
4354 assert(qh != NULL);
4355
4356 assert(pktin->type == qh->msg1 || pktin->type == qh->msg2);
4357
4358 if (qh->msg1 > 0) {
4359 assert(ssh->packet_dispatch[qh->msg1] == ssh_queueing_handler);
bc074147 4360 ssh->packet_dispatch[qh->msg1] = ssh->q_saved_handler1;
06fadff5 4361 }
4362 if (qh->msg2 > 0) {
4363 assert(ssh->packet_dispatch[qh->msg2] == ssh_queueing_handler);
bc074147 4364 ssh->packet_dispatch[qh->msg2] = ssh->q_saved_handler2;
06fadff5 4365 }
4366
4367 if (qh->next) {
4368 ssh->qhead = qh->next;
4369
4370 if (ssh->qhead->msg1 > 0) {
bc074147 4371 ssh->q_saved_handler1 = ssh->packet_dispatch[ssh->qhead->msg1];
06fadff5 4372 ssh->packet_dispatch[ssh->qhead->msg1] = ssh_queueing_handler;
4373 }
4374 if (ssh->qhead->msg2 > 0) {
bc074147 4375 ssh->q_saved_handler2 = ssh->packet_dispatch[ssh->qhead->msg2];
06fadff5 4376 ssh->packet_dispatch[ssh->qhead->msg2] = ssh_queueing_handler;
4377 }
4378 } else {
4379 ssh->qhead = ssh->qtail = NULL;
06fadff5 4380 }
4381
4382 qh->handler(ssh, pktin, qh->ctx);
4383
4384 sfree(qh);
4385}
4386
4387static void ssh_queue_handler(Ssh ssh, int msg1, int msg2,
4388 chandler_fn_t handler, void *ctx)
4389{
4390 struct queued_handler *qh;
4391
4392 qh = snew(struct queued_handler);
4393 qh->msg1 = msg1;
4394 qh->msg2 = msg2;
4395 qh->handler = handler;
4396 qh->ctx = ctx;
4397 qh->next = NULL;
4398
4399 if (ssh->qtail == NULL) {
4400 ssh->qhead = qh;
4401
4402 if (qh->msg1 > 0) {
bc074147 4403 ssh->q_saved_handler1 = ssh->packet_dispatch[ssh->qhead->msg1];
06fadff5 4404 ssh->packet_dispatch[qh->msg1] = ssh_queueing_handler;
4405 }
4406 if (qh->msg2 > 0) {
bc074147 4407 ssh->q_saved_handler2 = ssh->packet_dispatch[ssh->qhead->msg2];
06fadff5 4408 ssh->packet_dispatch[qh->msg2] = ssh_queueing_handler;
4409 }
4410 } else {
4411 ssh->qtail->next = qh;
4412 }
4413 ssh->qtail = qh;
4414}
4415
4416static void ssh_rportfwd_succfail(Ssh ssh, struct Packet *pktin, void *ctx)
4417{
4418 struct ssh_rportfwd *rpf, *pf = (struct ssh_rportfwd *)ctx;
4419
4420 if (pktin->type == (ssh->version == 1 ? SSH1_SMSG_SUCCESS :
4421 SSH2_MSG_REQUEST_SUCCESS)) {
4422 logeventf(ssh, "Remote port forwarding from %s enabled",
4423 pf->sportdesc);
4424 } else {
4425 logeventf(ssh, "Remote port forwarding from %s refused",
4426 pf->sportdesc);
4427
4428 rpf = del234(ssh->rportfwds, pf);
4429 assert(rpf == pf);
8aea57fd 4430 pf->pfrec->remote = NULL;
fda2feb1 4431 free_rportfwd(pf);
06fadff5 4432 }
4433}
4434
4a693cfc 4435static void ssh_setup_portfwd(Ssh ssh, Conf *conf)
06fadff5 4436{
84328ddb 4437 struct ssh_portfwd *epf;
4438 int i;
4a693cfc 4439 char *key, *val;
06fadff5 4440
fda2feb1 4441 if (!ssh->portfwds) {
4442 ssh->portfwds = newtree234(ssh_portcmp);
4443 } else {
4444 /*
4445 * Go through the existing port forwardings and tag them
84328ddb 4446 * with status==DESTROY. Any that we want to keep will be
4447 * re-enabled (status==KEEP) as we go through the
4448 * configuration and find out which bits are the same as
4449 * they were before.
fda2feb1 4450 */
4451 struct ssh_portfwd *epf;
4452 int i;
4453 for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
84328ddb 4454 epf->status = DESTROY;
fda2feb1 4455 }
4456
4a693cfc 4457 for (val = conf_get_str_strs(conf, CONF_portfwd, NULL, &key);
4458 val != NULL;
4459 val = conf_get_str_strs(conf, CONF_portfwd, key, &key)) {
4460 char *kp, *kp2, *vp, *vp2;
84328ddb 4461 char address_family, type;
4462 int sport,dport,sserv,dserv;
4a693cfc 4463 char *sports, *dports, *saddr, *host;
4464
4465 kp = key;
84328ddb 4466
05581745 4467 address_family = 'A';
4468 type = 'L';
4a693cfc 4469 if (*kp == 'A' || *kp == '4' || *kp == '6')
4470 address_family = *kp++;
4471 if (*kp == 'L' || *kp == 'R')
4472 type = *kp++;
4473
4474 if ((kp2 = strchr(kp, ':')) != NULL) {
4475 /*
4476 * There's a colon in the middle of the source port
4477 * string, which means that the part before it is
4478 * actually a source address.
4479 */
4480 saddr = dupprintf("%.*s", (int)(kp2 - kp), kp);
4481 sports = kp2+1;
06fadff5 4482 } else {
4a693cfc 4483 saddr = NULL;
4484 sports = kp;
06fadff5 4485 }
4486 sport = atoi(sports);
4487 sserv = 0;
4488 if (sport == 0) {
4489 sserv = 1;
4490 sport = net_service_lookup(sports);
4491 if (!sport) {
4492 logeventf(ssh, "Service lookup failed for source"
4493 " port \"%s\"", sports);
4494 }
4495 }
4a693cfc 4496
4497 if (type == 'L' && !strcmp(val, "D")) {
4498 /* dynamic forwarding */
4499 host = NULL;
4500 dports = NULL;
4501 dport = -1;
4502 dserv = 0;
4503 type = 'D';
4504 } else {
4505 /* ordinary forwarding */
4506 vp = val;
4507 vp2 = vp + strcspn(vp, ":");
4508 host = dupprintf("%.*s", (int)(vp2 - vp), vp);
4509 if (vp2)
4510 vp2++;
4511 dports = vp2;
4512 dport = atoi(dports);
4513 dserv = 0;
4514 if (dport == 0) {
4515 dserv = 1;
4516 dport = net_service_lookup(dports);
4517 if (!dport) {
4518 logeventf(ssh, "Service lookup failed for destination"
4519 " port \"%s\"", dports);
4520 }
4521 }
4522 }
4523
06fadff5 4524 if (sport && dport) {
4525 /* Set up a description of the source port. */
fda2feb1 4526 struct ssh_portfwd *pfrec, *epfrec;
fda2feb1 4527
4528 pfrec = snew(struct ssh_portfwd);
4529 pfrec->type = type;
4a693cfc 4530 pfrec->saddr = saddr;
3fe92132 4531 pfrec->sserv = sserv ? dupstr(sports) : NULL;
fda2feb1 4532 pfrec->sport = sport;
4a693cfc 4533 pfrec->daddr = host;
3fe92132 4534 pfrec->dserv = dserv ? dupstr(dports) : NULL;
fda2feb1 4535 pfrec->dport = dport;
4536 pfrec->local = NULL;
4537 pfrec->remote = NULL;
05581745 4538 pfrec->addressfamily = (address_family == '4' ? ADDRTYPE_IPV4 :
4539 address_family == '6' ? ADDRTYPE_IPV6 :
4540 ADDRTYPE_UNSPEC);
fda2feb1 4541
4542 epfrec = add234(ssh->portfwds, pfrec);
4543 if (epfrec != pfrec) {
c00c1931 4544 if (epfrec->status == DESTROY) {
4545 /*
4546 * We already have a port forwarding up and running
4547 * with precisely these parameters. Hence, no need
4548 * to do anything; simply re-tag the existing one
4549 * as KEEP.
4550 */
4551 epfrec->status = KEEP;
4552 }
fda2feb1 4553 /*
c00c1931 4554 * Anything else indicates that there was a duplicate
4555 * in our input, which we'll silently ignore.
fda2feb1 4556 */
fda2feb1 4557 free_portfwd(pfrec);
84328ddb 4558 } else {
4559 pfrec->status = CREATE;
4560 }
4a693cfc 4561 } else {
4562 sfree(saddr);
4563 sfree(host);
84328ddb 4564 }
4565 }
4566
4567 /*
4568 * Now go through and destroy any port forwardings which were
4569 * not re-enabled.
4570 */
4571 for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
4572 if (epf->status == DESTROY) {
4573 char *message;
4574
4575 message = dupprintf("%s port forwarding from %s%s%d",
4576 epf->type == 'L' ? "local" :
4577 epf->type == 'R' ? "remote" : "dynamic",
4578 epf->saddr ? epf->saddr : "",
4579 epf->saddr ? ":" : "",
4580 epf->sport);
4581
4582 if (epf->type != 'D') {
4583 char *msg2 = dupprintf("%s to %s:%d", message,
4584 epf->daddr, epf->dport);
4585 sfree(message);
4586 message = msg2;
4587 }
4588
4589 logeventf(ssh, "Cancelling %s", message);
4590 sfree(message);
4591
8aea57fd 4592 /* epf->remote or epf->local may be NULL if setting up a
4593 * forwarding failed. */
84328ddb 4594 if (epf->remote) {
4595 struct ssh_rportfwd *rpf = epf->remote;
4596 struct Packet *pktout;
4597
4598 /*
4599 * Cancel the port forwarding at the server
4600 * end.
4601 */
4602 if (ssh->version == 1) {
4603 /*
4604 * We cannot cancel listening ports on the
2e85c969 4605 * server side in SSH-1! There's no message
84328ddb 4606 * to support it. Instead, we simply remove
4607 * the rportfwd record from the local end
4608 * so that any connections the server tries
4609 * to make on it are rejected.
4610 */
4611 } else {
4612 pktout = ssh2_pkt_init(SSH2_MSG_GLOBAL_REQUEST);
4613 ssh2_pkt_addstring(pktout, "cancel-tcpip-forward");
4614 ssh2_pkt_addbool(pktout, 0);/* _don't_ want reply */
4615 if (epf->saddr) {
4616 ssh2_pkt_addstring(pktout, epf->saddr);
4a693cfc 4617 } else if (conf_get_int(conf, CONF_rport_acceptall)) {
4618 /* XXX: rport_acceptall may not represent
5188540b 4619 * what was used to open the original connection,
4620 * since it's reconfigurable. */
b1b5c358 4621 ssh2_pkt_addstring(pktout, "");
84328ddb 4622 } else {
b1b5c358 4623 ssh2_pkt_addstring(pktout, "localhost");
84328ddb 4624 }
4625 ssh2_pkt_adduint32(pktout, epf->sport);
4626 ssh2_pkt_send(ssh, pktout);
4627 }
4628
4629 del234(ssh->rportfwds, rpf);
4630 free_rportfwd(rpf);
4631 } else if (epf->local) {
4632 pfd_terminate(epf->local);
4633 }
4634
4635 delpos234(ssh->portfwds, i);
4636 free_portfwd(epf);
4637 i--; /* so we don't skip one in the list */
4638 }
4639
4640 /*
4641 * And finally, set up any new port forwardings (status==CREATE).
4642 */
4643 for (i = 0; (epf = index234(ssh->portfwds, i)) != NULL; i++)
4644 if (epf->status == CREATE) {
4645 char *sportdesc, *dportdesc;
3fe92132 4646 sportdesc = dupprintf("%s%s%s%s%d%s",
84328ddb 4647 epf->saddr ? epf->saddr : "",
4648 epf->saddr ? ":" : "",
3fe92132 4649 epf->sserv ? epf->sserv : "",
4650 epf->sserv ? "(" : "",
4651 epf->sport,
4652 epf->sserv ? ")" : "");
84328ddb 4653 if (epf->type == 'D') {
4654 dportdesc = NULL;
4655 } else {
3fe92132 4656 dportdesc = dupprintf("%s:%s%s%d%s",
4657 epf->daddr,
4658 epf->dserv ? epf->dserv : "",
4659 epf->dserv ? "(" : "",
4660 epf->dport,
4661 epf->dserv ? ")" : "");
84328ddb 4662 }
05581745 4663
84328ddb 4664 if (epf->type == 'L') {
4665 const char *err = pfd_addforward(epf->daddr, epf->dport,
4666 epf->saddr, epf->sport,
4a693cfc 4667 ssh, conf,
84328ddb 4668 &epf->local,
4669 epf->addressfamily);
4670
4671 logeventf(ssh, "Local %sport %s forwarding to %s%s%s",
4672 epf->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " :
4673 epf->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "",
4674 sportdesc, dportdesc,
4675 err ? " failed: " : "", err ? err : "");
4676 } else if (epf->type == 'D') {
06fadff5 4677 const char *err = pfd_addforward(NULL, -1,
84328ddb 4678 epf->saddr, epf->sport,
4a693cfc 4679 ssh, conf,
84328ddb 4680 &epf->local,
4681 epf->addressfamily);
4682
4683 logeventf(ssh, "Local %sport %s SOCKS dynamic forwarding%s%s",
4684 epf->addressfamily == ADDRTYPE_IPV4 ? "IPv4 " :
4685 epf->addressfamily == ADDRTYPE_IPV6 ? "IPv6 " : "",
4686 sportdesc,
4687 err ? " failed: " : "", err ? err : "");
06fadff5 4688 } else {
4689 struct ssh_rportfwd *pf;
4690
4691 /*
4692 * Ensure the remote port forwardings tree exists.
4693 */
4694 if (!ssh->rportfwds) {
4695 if (ssh->version == 1)
4696 ssh->rportfwds = newtree234(ssh_rportcmp_ssh1);
4697 else
4698 ssh->rportfwds = newtree234(ssh_rportcmp_ssh2);
4699 }
4700
4701 pf = snew(struct ssh_rportfwd);
84328ddb 4702 strncpy(pf->dhost, epf->daddr, lenof(pf->dhost)-1);
4703 pf->dhost[lenof(pf->dhost)-1] = '\0';
4704 pf->dport = epf->dport;
4705 pf->sport = epf->sport;
06fadff5 4706 if (add234(ssh->rportfwds, pf) != pf) {
4707 logeventf(ssh, "Duplicate remote port forwarding to %s:%d",
84328ddb 4708 epf->daddr, epf->dport);
06fadff5 4709 sfree(pf);
4710 } else {
4711 logeventf(ssh, "Requesting remote port %s"
84328ddb 4712 " forward to %s", sportdesc, dportdesc);
06fadff5 4713
4714 pf->sportdesc = sportdesc;
4715 sportdesc = NULL;
84328ddb 4716 epf->remote = pf;
4717 pf->pfrec = epf;
06fadff5 4718
4719 if (ssh->version == 1) {
4720 send_packet(ssh, SSH1_CMSG_PORT_FORWARD_REQUEST,
84328ddb 4721 PKT_INT, epf->sport,
4722 PKT_STR, epf->daddr,
4723 PKT_INT, epf->dport,
06fadff5 4724 PKT_END);
4725 ssh_queue_handler(ssh, SSH1_SMSG_SUCCESS,
4726 SSH1_SMSG_FAILURE,
4727 ssh_rportfwd_succfail, pf);
4728 } else {
4729 struct Packet *pktout;
4730 pktout = ssh2_pkt_init(SSH2_MSG_GLOBAL_REQUEST);
4731 ssh2_pkt_addstring(pktout, "tcpip-forward");
4732 ssh2_pkt_addbool(pktout, 1);/* want reply */
84328ddb 4733 if (epf->saddr) {
4734 ssh2_pkt_addstring(pktout, epf->saddr);
4a693cfc 4735 } else if (conf_get_int(conf, CONF_rport_acceptall)) {
b1b5c358 4736 ssh2_pkt_addstring(pktout, "");
06fadff5 4737 } else {
b1b5c358 4738 ssh2_pkt_addstring(pktout, "localhost");
06fadff5 4739 }
84328ddb 4740 ssh2_pkt_adduint32(pktout, epf->sport);
06fadff5 4741 ssh2_pkt_send(ssh, pktout);
4742
4743 ssh_queue_handler(ssh, SSH2_MSG_REQUEST_SUCCESS,
4744 SSH2_MSG_REQUEST_FAILURE,
4745 ssh_rportfwd_succfail, pf);
4746 }
4747 }
4748 }
4749 sfree(sportdesc);
84328ddb 4750 sfree(dportdesc);
06fadff5 4751 }
06fadff5 4752}
4753
51df0ab5 4754static void ssh1_smsg_stdout_stderr_data(Ssh ssh, struct Packet *pktin)
4755{
4756 char *string;
4757 int stringlen, bufsize;
4758
4759 ssh_pkt_getstring(pktin, &string, &stringlen);
4760 if (string == NULL) {
4761 bombout(("Incoming terminal data packet was badly formed"));
4762 return;
4763 }
4764
4765 bufsize = from_backend(ssh->frontend, pktin->type == SSH1_SMSG_STDERR_DATA,
4766 string, stringlen);
4767 if (!ssh->v1_stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) {
4768 ssh->v1_stdout_throttling = 1;
ff68564b 4769 ssh_throttle_conn(ssh, +1);
51df0ab5 4770 }
4771}
4772
4773static void ssh1_smsg_x11_open(Ssh ssh, struct Packet *pktin)
4774{
4775 /* Remote side is trying to open a channel to talk to our
4776 * X-Server. Give them back a local channel number. */
4777 struct ssh_channel *c;
4778 int remoteid = ssh_pkt_getuint32(pktin);
4779
4780 logevent("Received X11 connect request");
4781 /* Refuse if X11 forwarding is disabled. */
4782 if (!ssh->X11_fwd_enabled) {
4783 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4784 PKT_INT, remoteid, PKT_END);
4785 logevent("Rejected X11 connect request");
4786 } else {
4787 c = snew(struct ssh_channel);
4788 c->ssh = ssh;
4789
8def70c3 4790 if (x11_init(&c->u.x11.s, ssh->x11disp, c,
4a693cfc 4791 NULL, -1, ssh->conf) != NULL) {
51df0ab5 4792 logevent("Opening X11 forward connection failed");
4793 sfree(c);
4794 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4795 PKT_INT, remoteid, PKT_END);
4796 } else {
4797 logevent
4798 ("Opening X11 forward connection succeeded");
4799 c->remoteid = remoteid;
64d6ff88 4800 c->halfopen = FALSE;
51df0ab5 4801 c->localid = alloc_channel_id(ssh);
4802 c->closes = 0;
bc06669b 4803 c->pending_eof = FALSE;
ff68564b 4804 c->throttling_conn = 0;
51df0ab5 4805 c->type = CHAN_X11; /* identify channel type */
4806 add234(ssh->channels, c);
4807 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4808 PKT_INT, c->remoteid, PKT_INT,
4809 c->localid, PKT_END);
4810 logevent("Opened X11 forward channel");
4811 }
4812 }
4813}
4814
4815static void ssh1_smsg_agent_open(Ssh ssh, struct Packet *pktin)
4816{
4817 /* Remote side is trying to open a channel to talk to our
4818 * agent. Give them back a local channel number. */
4819 struct ssh_channel *c;
4820 int remoteid = ssh_pkt_getuint32(pktin);
4821
4822 /* Refuse if agent forwarding is disabled. */
4823 if (!ssh->agentfwd_enabled) {
4824 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4825 PKT_INT, remoteid, PKT_END);
4826 } else {
4827 c = snew(struct ssh_channel);
4828 c->ssh = ssh;
4829 c->remoteid = remoteid;
64d6ff88 4830 c->halfopen = FALSE;
51df0ab5 4831 c->localid = alloc_channel_id(ssh);
4832 c->closes = 0;
bc06669b 4833 c->pending_eof = FALSE;
ff68564b 4834 c->throttling_conn = 0;
51df0ab5 4835 c->type = CHAN_AGENT; /* identify channel type */
4836 c->u.a.lensofar = 0;
bc06669b 4837 c->u.a.message = NULL;
be3f980d 4838 c->u.a.outstanding_requests = 0;
51df0ab5 4839 add234(ssh->channels, c);
4840 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4841 PKT_INT, c->remoteid, PKT_INT, c->localid,
4842 PKT_END);
4843 }
4844}
4845
4846static void ssh1_msg_port_open(Ssh ssh, struct Packet *pktin)
4847{
4848 /* Remote side is trying to open a channel to talk to a
4849 * forwarded port. Give them back a local channel number. */
4850 struct ssh_channel *c;
05581745 4851 struct ssh_rportfwd pf, *pfp;
51df0ab5 4852 int remoteid;
4853 int hostsize, port;
fb983202 4854 char *host;
51df0ab5 4855 const char *e;
4856 c = snew(struct ssh_channel);
4857 c->ssh = ssh;
4858
4859 remoteid = ssh_pkt_getuint32(pktin);
4860 ssh_pkt_getstring(pktin, &host, &hostsize);
4861 port = ssh_pkt_getuint32(pktin);
4862
4863 if (hostsize >= lenof(pf.dhost))
4864 hostsize = lenof(pf.dhost)-1;
4865 memcpy(pf.dhost, host, hostsize);
4866 pf.dhost[hostsize] = '\0';
4867 pf.dport = port;
05581745 4868 pfp = find234(ssh->rportfwds, &pf, NULL);
51df0ab5 4869
05581745 4870 if (pfp == NULL) {
fb983202 4871 logeventf(ssh, "Rejected remote port open request for %s:%d",
4872 pf.dhost, port);
51df0ab5 4873 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4874 PKT_INT, remoteid, PKT_END);
4875 } else {
fb983202 4876 logeventf(ssh, "Received remote port open request for %s:%d",
4877 pf.dhost, port);
51df0ab5 4878 e = pfd_newconnect(&c->u.pfd.s, pf.dhost, port,
4a693cfc 4879 c, ssh->conf, pfp->pfrec->addressfamily);
51df0ab5 4880 if (e != NULL) {
fb983202 4881 logeventf(ssh, "Port open failed: %s", e);
51df0ab5 4882 sfree(c);
4883 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_FAILURE,
4884 PKT_INT, remoteid, PKT_END);
4885 } else {
4886 c->remoteid = remoteid;
64d6ff88 4887 c->halfopen = FALSE;
51df0ab5 4888 c->localid = alloc_channel_id(ssh);
4889 c->closes = 0;
bc06669b 4890 c->pending_eof = FALSE;
ff68564b 4891 c->throttling_conn = 0;
51df0ab5 4892 c->type = CHAN_SOCKDATA; /* identify channel type */
4893 add234(ssh->channels, c);
4894 send_packet(ssh, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
4895 PKT_INT, c->remoteid, PKT_INT,
4896 c->localid, PKT_END);
4897 logevent("Forwarded port opened successfully");
4898 }
4899 }
4900}
4901
4902static void ssh1_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
4903{
4904 unsigned int remoteid = ssh_pkt_getuint32(pktin);
4905 unsigned int localid = ssh_pkt_getuint32(pktin);
4906 struct ssh_channel *c;
4907
4908 c = find234(ssh->channels, &remoteid, ssh_channelfind);
4909 if (c && c->type == CHAN_SOCKDATA_DORMANT) {
4910 c->remoteid = localid;
64d6ff88 4911 c->halfopen = FALSE;
51df0ab5 4912 c->type = CHAN_SOCKDATA;
ff68564b 4913 c->throttling_conn = 0;
51df0ab5 4914 pfd_confirm(c->u.pfd.s);
4915 }
4916
bc06669b 4917 if (c && c->pending_eof) {
51df0ab5 4918 /*
4919 * We have a pending close on this channel,
4920 * which we decided on before the server acked
4921 * the channel open. So now we know the
4922 * remoteid, we can close it again.
4923 */
bc06669b 4924 ssh_channel_try_eof(c);
51df0ab5 4925 }
4926}
4927
4928static void ssh1_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
4929{
4930 unsigned int remoteid = ssh_pkt_getuint32(pktin);
4931 struct ssh_channel *c;
4932
4933 c = find234(ssh->channels, &remoteid, ssh_channelfind);
4934 if (c && c->type == CHAN_SOCKDATA_DORMANT) {
4935 logevent("Forwarded connection refused by server");
4936 pfd_close(c->u.pfd.s);
4937 del234(ssh->channels, c);
4938 sfree(c);
4939 }
4940}
4941
4942static void ssh1_msg_channel_close(Ssh ssh, struct Packet *pktin)
4943{
4944 /* Remote side closes a channel. */
4945 unsigned i = ssh_pkt_getuint32(pktin);
4946 struct ssh_channel *c;
4947 c = find234(ssh->channels, &i, ssh_channelfind);
64d6ff88 4948 if (c && !c->halfopen) {
51df0ab5 4949
bc06669b 4950 if (pktin->type == SSH1_MSG_CHANNEL_CLOSE &&
4951 !(c->closes & CLOSES_RCVD_EOF)) {
4952 /*
4953 * Received CHANNEL_CLOSE, which we translate into
4954 * outgoing EOF.
4955 */
4956 int send_close = FALSE;
4957
4958 c->closes |= CLOSES_RCVD_EOF;
4959
4960 switch (c->type) {
4961 case CHAN_X11:
4962 if (c->u.x11.s)
4963 x11_send_eof(c->u.x11.s);
4964 else
4965 send_close = TRUE;
9fb91415 4966 break;
bc06669b 4967 case CHAN_SOCKDATA:
4968 if (c->u.pfd.s)
9fb91415 4969 pfd_send_eof(c->u.pfd.s);
bc06669b 4970 else
4971 send_close = TRUE;
9fb91415 4972 break;
bc06669b 4973 case CHAN_AGENT:
4974 send_close = TRUE;
9fb91415 4975 break;
bc06669b 4976 }
51df0ab5 4977
bc06669b 4978 if (send_close && !(c->closes & CLOSES_SENT_EOF)) {
4979 send_packet(ssh, SSH1_MSG_CHANNEL_CLOSE, PKT_INT, c->remoteid,
4980 PKT_END);
4981 c->closes |= CLOSES_SENT_EOF;
4982 }
4983 }
4984
4985 if (pktin->type == SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION &&
4986 !(c->closes & CLOSES_RCVD_CLOSE)) {
4987
4988 if (!(c->closes & CLOSES_SENT_EOF)) {
4989 bombout(("Received CHANNEL_CLOSE_CONFIRMATION for channel %d"
4990 " for which we never sent CHANNEL_CLOSE\n", i));
4991 }
4992
4993 c->closes |= CLOSES_RCVD_CLOSE;
4994 }
4995
4996 if (!((CLOSES_SENT_EOF | CLOSES_RCVD_EOF) & ~c->closes) &&
4997 !(c->closes & CLOSES_SENT_CLOSE)) {
4998 send_packet(ssh, SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION,
4999 PKT_INT, c->remoteid, PKT_END);
5000 c->closes |= CLOSES_SENT_CLOSE;
5001 }
5002
5003 if (!((CLOSES_SENT_CLOSE | CLOSES_RCVD_CLOSE) & ~c->closes))
5004 ssh_channel_destroy(c);
51df0ab5 5005 } else {
5006 bombout(("Received CHANNEL_CLOSE%s for %s channel %d\n",
5007 pktin->type == SSH1_MSG_CHANNEL_CLOSE ? "" :
5008 "_CONFIRMATION", c ? "half-open" : "nonexistent",
5009 i));
5010 }
5011}
5012
5013static void ssh1_msg_channel_data(Ssh ssh, struct Packet *pktin)
5014{
5015 /* Data sent down one of our channels. */
5016 int i = ssh_pkt_getuint32(pktin);
5017 char *p;
6d44acc9 5018 int len;
51df0ab5 5019 struct ssh_channel *c;
5020
5021 ssh_pkt_getstring(pktin, &p, &len);
5022
5023 c = find234(ssh->channels, &i, ssh_channelfind);
5024 if (c) {
5025 int bufsize = 0;
5026 switch (c->type) {
5027 case CHAN_X11:
5028 bufsize = x11_send(c->u.x11.s, p, len);
5029 break;
5030 case CHAN_SOCKDATA:
5031 bufsize = pfd_send(c->u.pfd.s, p, len);
5032 break;
5033 case CHAN_AGENT:
5034 /* Data for an agent message. Buffer it. */
5035 while (len > 0) {
5036 if (c->u.a.lensofar < 4) {
62ddb51e 5037 unsigned int l = min(4 - c->u.a.lensofar, (unsigned)len);
51df0ab5 5038 memcpy(c->u.a.msglen + c->u.a.lensofar, p,
5039 l);
5040 p += l;
5041 len -= l;
5042 c->u.a.lensofar += l;
5043 }
5044 if (c->u.a.lensofar == 4) {
5045 c->u.a.totallen =
5046 4 + GET_32BIT(c->u.a.msglen);
5047 c->u.a.message = snewn(c->u.a.totallen,
5048 unsigned char);
5049 memcpy(c->u.a.message, c->u.a.msglen, 4);
5050 }
5051 if (c->u.a.lensofar >= 4 && len > 0) {
aa63ab7e 5052 unsigned int l =
51df0ab5 5053 min(c->u.a.totallen - c->u.a.lensofar,
62ddb51e 5054 (unsigned)len);
51df0ab5 5055 memcpy(c->u.a.message + c->u.a.lensofar, p,
5056 l);
5057 p += l;
5058 len -= l;
5059 c->u.a.lensofar += l;
5060 }
5061 if (c->u.a.lensofar == c->u.a.totallen) {
5062 void *reply;
5063 int replylen;
be3f980d 5064 c->u.a.outstanding_requests++;
51df0ab5 5065 if (agent_query(c->u.a.message,
5066 c->u.a.totallen,
5067 &reply, &replylen,
5068 ssh_agentf_callback, c))
5069 ssh_agentf_callback(c, reply, replylen);
5070 sfree(c->u.a.message);
5071 c->u.a.lensofar = 0;
5072 }
5073 }
5074 bufsize = 0; /* agent channels never back up */
5075 break;
5076 }
ff68564b 5077 if (!c->throttling_conn && bufsize > SSH1_BUFFER_LIMIT) {
5078 c->throttling_conn = 1;
5079 ssh_throttle_conn(ssh, +1);
51df0ab5 5080 }
5081 }
5082}
5083
5084static void ssh1_smsg_exit_status(Ssh ssh, struct Packet *pktin)
5085{
51df0ab5 5086 ssh->exitcode = ssh_pkt_getuint32(pktin);
fb983202 5087 logeventf(ssh, "Server sent command exit status %d", ssh->exitcode);
51df0ab5 5088 send_packet(ssh, SSH1_CMSG_EXIT_CONFIRMATION, PKT_END);
5089 /*
5090 * In case `helpful' firewalls or proxies tack
5091 * extra human-readable text on the end of the
5092 * session which we might mistake for another
5093 * encrypted packet, we close the session once
5094 * we've sent EXIT_CONFIRMATION.
5095 */
9e296bfa 5096 ssh_disconnect(ssh, NULL, NULL, 0, TRUE);
51df0ab5 5097}
5098
c6ccd5c2 5099/* Helper function to deal with sending tty modes for REQUEST_PTY */
5100static void ssh1_send_ttymode(void *data, char *mode, char *val)
5101{
5102 struct Packet *pktout = (struct Packet *)data;
5103 int i = 0;
5104 unsigned int arg = 0;
5105 while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
5106 if (i == lenof(ssh_ttymodes)) return;
5107 switch (ssh_ttymodes[i].type) {
5108 case TTY_OP_CHAR:
5109 arg = ssh_tty_parse_specchar(val);
5110 break;
5111 case TTY_OP_BOOL:
5112 arg = ssh_tty_parse_boolean(val);
5113 break;
5114 }
5115 ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
5116 ssh2_pkt_addbyte(pktout, arg);
5117}
5118
5119
b09eaa88 5120static void do_ssh1_connection(Ssh ssh, unsigned char *in, int inlen,
5121 struct Packet *pktin)
32874aea 5122{
b09eaa88 5123 crBegin(ssh->do_ssh1_connection_crstate);
fb09bf1c 5124
51df0ab5 5125 ssh->packet_dispatch[SSH1_SMSG_STDOUT_DATA] =
5126 ssh->packet_dispatch[SSH1_SMSG_STDERR_DATA] =
5127 ssh1_smsg_stdout_stderr_data;
5128
5129 ssh->packet_dispatch[SSH1_MSG_CHANNEL_OPEN_CONFIRMATION] =
5130 ssh1_msg_channel_open_confirmation;
5131 ssh->packet_dispatch[SSH1_MSG_CHANNEL_OPEN_FAILURE] =
5132 ssh1_msg_channel_open_failure;
5133 ssh->packet_dispatch[SSH1_MSG_CHANNEL_CLOSE] =
5134 ssh->packet_dispatch[SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION] =
5135 ssh1_msg_channel_close;
5136 ssh->packet_dispatch[SSH1_MSG_CHANNEL_DATA] = ssh1_msg_channel_data;
5137 ssh->packet_dispatch[SSH1_SMSG_EXIT_STATUS] = ssh1_smsg_exit_status;
5138
4a693cfc 5139 if (conf_get_int(ssh->conf, CONF_agentfwd) && agent_exists()) {
32874aea 5140 logevent("Requesting agent forwarding");
51470298 5141 send_packet(ssh, SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END);
32874aea 5142 do {
5143 crReturnV;
ff3187f6 5144 } while (!pktin);
5145 if (pktin->type != SSH1_SMSG_SUCCESS
5146 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 5147 bombout(("Protocol confusion"));
7ffdbc1a 5148 crStopV;
ff3187f6 5149 } else if (pktin->type == SSH1_SMSG_FAILURE) {
32874aea 5150 logevent("Agent forwarding refused");
5151 } else {
5152 logevent("Agent forwarding enabled");
51470298 5153 ssh->agentfwd_enabled = TRUE;
51df0ab5 5154 ssh->packet_dispatch[SSH1_SMSG_AGENT_OPEN] = ssh1_smsg_agent_open;
db7d555c 5155 }
dacbd0e8 5156 }
5157
4a693cfc 5158 if (conf_get_int(ssh->conf, CONF_x11_forward) &&
5159 (ssh->x11disp = x11_setup_display(conf_get_str(ssh->conf, CONF_x11_display),
5160 conf_get_int(ssh->conf, CONF_x11_auth), ssh->conf))) {
32874aea 5161 logevent("Requesting X11 forwarding");
f68353be 5162 /*
5163 * Note that while we blank the X authentication data here, we don't
5164 * take any special action to blank the start of an X11 channel,
5165 * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
5166 * without having session blanking enabled is likely to leak your
5167 * cookie into the log.
5168 */
51470298 5169 if (ssh->v1_local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER) {
5170 send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
8def70c3 5171 PKT_STR, ssh->x11disp->remoteauthprotoname,
5172 PKTT_PASSWORD,
5173 PKT_STR, ssh->x11disp->remoteauthdatastring,
5174 PKTT_OTHER,
5175 PKT_INT, ssh->x11disp->screennum,
421d6835 5176 PKT_END);
32874aea 5177 } else {
51470298 5178 send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
8def70c3 5179 PKT_STR, ssh->x11disp->remoteauthprotoname,
5180 PKTT_PASSWORD,
5181 PKT_STR, ssh->x11disp->remoteauthdatastring,
5182 PKTT_OTHER,
5183 PKT_END);
32874aea 5184 }
5185 do {
5186 crReturnV;
ff3187f6 5187 } while (!pktin);
5188 if (pktin->type != SSH1_SMSG_SUCCESS
5189 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 5190 bombout(("Protocol confusion"));
7ffdbc1a 5191 crStopV;
ff3187f6 5192 } else if (pktin->type == SSH1_SMSG_FAILURE) {
32874aea 5193 logevent("X11 forwarding refused");
5194 } else {
5195 logevent("X11 forwarding enabled");
51470298 5196 ssh->X11_fwd_enabled = TRUE;
51df0ab5 5197 ssh->packet_dispatch[SSH1_SMSG_X11_OPEN] = ssh1_smsg_x11_open;
9c964e85 5198 }
5199 }
5200
4a693cfc 5201 ssh_setup_portfwd(ssh, ssh->conf);
06fadff5 5202 ssh->packet_dispatch[SSH1_MSG_PORT_OPEN] = ssh1_msg_port_open;
d74d141c 5203
4a693cfc 5204 if (!conf_get_int(ssh->conf, CONF_nopty)) {
c6ccd5c2 5205 struct Packet *pkt;
a5dd8467 5206 /* Unpick the terminal-speed string. */
5207 /* XXX perhaps we should allow no speeds to be sent. */
db219738 5208 ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
4a693cfc 5209 sscanf(conf_get_str(ssh->conf, CONF_termspeed), "%d,%d", &ssh->ospeed, &ssh->ispeed);
a5dd8467 5210 /* Send the pty request. */
c6ccd5c2 5211 pkt = ssh1_pkt_init(SSH1_CMSG_REQUEST_PTY);
4a693cfc 5212 ssh_pkt_addstring(pkt, conf_get_str(ssh->conf, CONF_termtype));
c6ccd5c2 5213 ssh_pkt_adduint32(pkt, ssh->term_height);
5214 ssh_pkt_adduint32(pkt, ssh->term_width);
5215 ssh_pkt_adduint32(pkt, 0); /* width in pixels */
5216 ssh_pkt_adduint32(pkt, 0); /* height in pixels */
4a693cfc 5217 parse_ttymodes(ssh, ssh1_send_ttymode, (void *)pkt);
c6ccd5c2 5218 ssh_pkt_addbyte(pkt, SSH1_TTY_OP_ISPEED);
5219 ssh_pkt_adduint32(pkt, ssh->ispeed);
5220 ssh_pkt_addbyte(pkt, SSH1_TTY_OP_OSPEED);
5221 ssh_pkt_adduint32(pkt, ssh->ospeed);
5222 ssh_pkt_addbyte(pkt, SSH_TTY_OP_END);
5223 s_wrpkt(ssh, pkt);
51470298 5224 ssh->state = SSH_STATE_INTERMED;
32874aea 5225 do {
5226 crReturnV;
ff3187f6 5227 } while (!pktin);
5228 if (pktin->type != SSH1_SMSG_SUCCESS
5229 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 5230 bombout(("Protocol confusion"));
7ffdbc1a 5231 crStopV;
ff3187f6 5232 } else if (pktin->type == SSH1_SMSG_FAILURE) {
51470298 5233 c_write_str(ssh, "Server refused to allocate pty\r\n");
5234 ssh->editing = ssh->echoing = 1;
4a202fc6 5235 } else {
5236 logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
5237 ssh->ospeed, ssh->ispeed);
5238 ssh->got_pty = TRUE;
5239 }
0965bee0 5240 } else {
51470298 5241 ssh->editing = ssh->echoing = 1;
374330e2 5242 }
5243
4a693cfc 5244 if (conf_get_int(ssh->conf, CONF_compression)) {
51470298 5245 send_packet(ssh, SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);
32874aea 5246 do {
5247 crReturnV;
ff3187f6 5248 } while (!pktin);
5249 if (pktin->type != SSH1_SMSG_SUCCESS
5250 && pktin->type != SSH1_SMSG_FAILURE) {
6b5cf8b4 5251 bombout(("Protocol confusion"));
7ffdbc1a 5252 crStopV;
ff3187f6 5253 } else if (pktin->type == SSH1_SMSG_FAILURE) {
51470298 5254 c_write_str(ssh, "Server refused to compress\r\n");
32874aea 5255 }
4ba9b64b 5256 logevent("Started compression");
51470298 5257 ssh->v1_compressing = TRUE;
5366aed8 5258 ssh->cs_comp_ctx = zlib_compress_init();
5259 logevent("Initialised zlib (RFC1950) compression");
5260 ssh->sc_comp_ctx = zlib_decompress_init();
5261 logevent("Initialised zlib (RFC1950) decompression");
4ba9b64b 5262 }
5263
fd5e5847 5264 /*
5265 * Start the shell or command.
5266 *
2e85c969 5267 * Special case: if the first-choice command is an SSH-2
fd5e5847 5268 * subsystem (hence not usable here) and the second choice
5269 * exists, we fall straight back to that.
5270 */
5271 {
4a693cfc 5272 char *cmd = conf_get_str(ssh->conf, CONF_remote_cmd);
fd5e5847 5273
4a693cfc 5274 if (conf_get_int(ssh->conf, CONF_ssh_subsys) &&
5275 conf_get_str(ssh->conf, CONF_remote_cmd2)) {
5276 cmd = conf_get_str(ssh->conf, CONF_remote_cmd2);
51470298 5277 ssh->fallback_cmd = TRUE;
fd5e5847 5278 }
5279 if (*cmd)
51470298 5280 send_packet(ssh, SSH1_CMSG_EXEC_CMD, PKT_STR, cmd, PKT_END);
fd5e5847 5281 else
51470298 5282 send_packet(ssh, SSH1_CMSG_EXEC_SHELL, PKT_END);
fd5e5847 5283 logevent("Started session");
5284 }
374330e2 5285
51470298 5286 ssh->state = SSH_STATE_SESSION;
5287 if (ssh->size_needed)
5288 ssh_size(ssh, ssh->term_width, ssh->term_height);
5289 if (ssh->eof_needed)
5290 ssh_special(ssh, TS_EOF);
374330e2 5291
b9d7bcad 5292 if (ssh->ldisc)
5293 ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
51470298 5294 ssh->send_ok = 1;
5295 ssh->channels = newtree234(ssh_channelcmp);
374330e2 5296 while (1) {
d74d141c 5297
51df0ab5 5298 /*
5299 * By this point, most incoming packets are already being
5300 * handled by the dispatch table, and we need only pay
5301 * attention to the unusual ones.
5302 */
0357890f 5303
51df0ab5 5304 crReturnV;
5305 if (pktin) {
5306 if (pktin->type == SSH1_SMSG_SUCCESS) {
972a41c8 5307 /* may be from EXEC_SHELL on some servers */
ff3187f6 5308 } else if (pktin->type == SSH1_SMSG_FAILURE) {
972a41c8 5309 /* may be from EXEC_SHELL on some servers
374330e2 5310 * if no pty is available or in other odd cases. Ignore */
374330e2 5311 } else {
ff3187f6 5312 bombout(("Strange packet received: type %d", pktin->type));
7ffdbc1a 5313 crStopV;
374330e2 5314 }
5315 } else {
8df7a775 5316 while (inlen > 0) {
5317 int len = min(inlen, 512);
a2724fba 5318 send_packet(ssh, SSH1_CMSG_STDIN_DATA,
5319 PKT_INT, len, PKTT_DATA, PKT_DATA, in, len,
9a10ecf4 5320 PKTT_OTHER, PKT_END);
8df7a775 5321 in += len;
5322 inlen -= len;
5323 }
374330e2 5324 }
5325 }
5326
5327 crFinishV;
5328}
5329
5330/*
2e85c969 5331 * Handle the top-level SSH-2 protocol.
b09eaa88 5332 */
5333static void ssh1_msg_debug(Ssh ssh, struct Packet *pktin)
5334{
fb983202 5335 char *msg;
b09eaa88 5336 int msglen;
5337
5338 ssh_pkt_getstring(pktin, &msg, &msglen);
fb983202 5339 logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
b09eaa88 5340}
5341
5342static void ssh1_msg_disconnect(Ssh ssh, struct Packet *pktin)
5343{
5344 /* log reason code in disconnect message */
5345 char *msg;
5346 int msglen;
5347
5348 ssh_pkt_getstring(pktin, &msg, &msglen);
5349 bombout(("Server sent disconnect message:\n\"%.*s\"", msglen, msg));
5350}
5351
409bfa77 5352static void ssh_msg_ignore(Ssh ssh, struct Packet *pktin)
b09eaa88 5353{
5354 /* Do nothing, because we're ignoring it! Duhh. */
5355}
5356
5357static void ssh1_protocol_setup(Ssh ssh)
5358{
5359 int i;
5360
5361 /*
5362 * Most messages are handled by the coroutines.
5363 */
5364 for (i = 0; i < 256; i++)
5365 ssh->packet_dispatch[i] = NULL;
5366
5367 /*
5368 * These special message types we install handlers for.
5369 */
5370 ssh->packet_dispatch[SSH1_MSG_DISCONNECT] = ssh1_msg_disconnect;
5371 ssh->packet_dispatch[SSH1_MSG_IGNORE] = ssh_msg_ignore;
5372 ssh->packet_dispatch[SSH1_MSG_DEBUG] = ssh1_msg_debug;
5373}
5374
1c1a7262 5375static void ssh1_protocol(Ssh ssh, void *vin, int inlen,
b09eaa88 5376 struct Packet *pktin)
5377{
1c1a7262 5378 unsigned char *in=(unsigned char*)vin;
b09eaa88 5379 if (ssh->state == SSH_STATE_CLOSED)
5380 return;
5381
5382 if (pktin && ssh->packet_dispatch[pktin->type]) {
5383 ssh->packet_dispatch[pktin->type](ssh, pktin);
5384 return;
5385 }
5386
5387 if (!ssh->protocol_initial_phase_done) {
5388 if (do_ssh1_login(ssh, in, inlen, pktin))
5389 ssh->protocol_initial_phase_done = TRUE;
5390 else
5391 return;
5392 }
5393
5394 do_ssh1_connection(ssh, in, inlen, pktin);
5395}
5396
5397/*
e5574168 5398 * Utility routine for decoding comma-separated strings in KEXINIT.
5399 */
32874aea 5400static int in_commasep_string(char *needle, char *haystack, int haylen)
5401{
57356d63 5402 int needlen;
5403 if (!needle || !haystack) /* protect against null pointers */
5404 return 0;
5405 needlen = strlen(needle);
e5574168 5406 while (1) {
32874aea 5407 /*
5408 * Is it at the start of the string?
5409 */
5410 if (haylen >= needlen && /* haystack is long enough */
5411 !memcmp(needle, haystack, needlen) && /* initial match */
5412 (haylen == needlen || haystack[needlen] == ',')
5413 /* either , or EOS follows */
5414 )
5415 return 1;
5416 /*
5417 * If not, search for the next comma and resume after that.
5418 * If no comma found, terminate.
5419 */
5420 while (haylen > 0 && *haystack != ',')
5421 haylen--, haystack++;
5422 if (haylen == 0)
5423 return 0;
5424 haylen--, haystack++; /* skip over comma itself */
e5574168 5425 }
5426}
5427
5428/*
b59743d5 5429 * Similar routine for checking whether we have the first string in a list.
5430 */
5431static int first_in_commasep_string(char *needle, char *haystack, int haylen)
5432{
5433 int needlen;
5434 if (!needle || !haystack) /* protect against null pointers */
5435 return 0;
5436 needlen = strlen(needle);
5437 /*
5438 * Is it at the start of the string?
5439 */
5440 if (haylen >= needlen && /* haystack is long enough */
5441 !memcmp(needle, haystack, needlen) && /* initial match */
5442 (haylen == needlen || haystack[needlen] == ',')
5443 /* either , or EOS follows */
5444 )
5445 return 1;
5446 return 0;
5447}
5448
5449
5450/*
2e85c969 5451 * SSH-2 key creation method.
754c0df9 5452 * (Currently assumes 2 lots of any hash are sufficient to generate
5453 * keys/IVs for any cipher/MAC. SSH2_MKKEY_ITERS documents this assumption.)
d39f364a 5454 */
754c0df9 5455#define SSH2_MKKEY_ITERS (2)
b672f405 5456static void ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, char chr,
d8baa528 5457 unsigned char *keyspace)
32874aea 5458{
b672f405 5459 const struct ssh_hash *h = ssh->kex->hash;
5460 void *s;
5461 /* First hlen bytes. */
5462 s = h->init();
51470298 5463 if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
b672f405 5464 hash_mpint(h, s, K);
5465 h->bytes(s, H, h->hlen);
5466 h->bytes(s, &chr, 1);
5467 h->bytes(s, ssh->v2_session_id, ssh->v2_session_id_len);
5468 h->final(s, keyspace);
5469 /* Next hlen bytes. */
5470 s = h->init();
51470298 5471 if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
b672f405 5472 hash_mpint(h, s, K);
5473 h->bytes(s, H, h->hlen);
5474 h->bytes(s, keyspace, h->hlen);
5475 h->final(s, keyspace + h->hlen);
d39f364a 5476}
5477
5478/*
2e85c969 5479 * Handle the SSH-2 transport layer.
e5574168 5480 */
0b106f61 5481static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
ff3187f6 5482 struct Packet *pktin)
e5574168 5483{
1c1a7262 5484 unsigned char *in = (unsigned char *)vin;
51470298 5485 struct do_ssh2_transport_state {
30919997 5486 int crLine;
4763c1c2 5487 int nbits, pbits, warn_kex, warn_cscipher, warn_sccipher;
51470298 5488 Bignum p, g, e, f, K;
3dc9a6a7 5489 void *our_kexinit;
5490 int our_kexinitlen;
51470298 5491 int kex_init_value, kex_reply_value;
5492 const struct ssh_mac **maclist;
5493 int nmacs;
5494 const struct ssh2_cipher *cscipher_tobe;
5495 const struct ssh2_cipher *sccipher_tobe;
5496 const struct ssh_mac *csmac_tobe;
5497 const struct ssh_mac *scmac_tobe;
5498 const struct ssh_compress *cscomp_tobe;
5499 const struct ssh_compress *sccomp_tobe;
fae1a71b 5500 char *hostkeydata, *sigdata, *rsakeydata, *keystr, *fingerprint;
5501 int hostkeylen, siglen, rsakeylen;
51470298 5502 void *hkey; /* actual host key */
fae1a71b 5503 void *rsakey; /* for RSA kex */
754c0df9 5504 unsigned char exchange_hash[SSH2_KEX_MAX_HASH_LEN];
83e7d008 5505 int n_preferred_kex;
34557659 5506 const struct ssh_kexes *preferred_kex[KEX_MAX];
51470298 5507 int n_preferred_ciphers;
5508 const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX];
5509 const struct ssh_compress *preferred_comp;
ab18ccff 5510 int userauth_succeeded; /* for delayed compression */
5511 int pending_compression;
e13bba36 5512 int got_session_id, activated_authconn;
ff3187f6 5513 struct Packet *pktout;
3d9449a1 5514 int dlgret;
5515 int guessok;
4763c1c2 5516 int ignorepkt;
51470298 5517 };
5518 crState(do_ssh2_transport_state);
5519
30919997 5520 crBeginState;
51470298 5521
5522 s->cscipher_tobe = s->sccipher_tobe = NULL;
5523 s->csmac_tobe = s->scmac_tobe = NULL;
5524 s->cscomp_tobe = s->sccomp_tobe = NULL;
5525
e13bba36 5526 s->got_session_id = s->activated_authconn = FALSE;
ab18ccff 5527 s->userauth_succeeded = FALSE;
5528 s->pending_compression = FALSE;
e5574168 5529
e13bba36 5530 /*
5531 * Be prepared to work around the buggy MAC problem.
5532 */
5533 if (ssh->remote_bugs & BUG_SSH2_HMAC)
5534 s->maclist = buggymacs, s->nmacs = lenof(buggymacs);
5535 else
5536 s->maclist = macs, s->nmacs = lenof(macs);
5537
5538 begin_key_exchange:
acab36bc 5539 ssh->pkt_kctx = SSH2_PKTCTX_NOKEX;
51470298 5540 {
cc18f256 5541 int i, j, k, commalist_started;
e13bba36 5542
51470298 5543 /*
83e7d008 5544 * Set up the preferred key exchange. (NULL => warn below here)
5545 */
5546 s->n_preferred_kex = 0;
5547 for (i = 0; i < KEX_MAX; i++) {
4a693cfc 5548 switch (conf_get_int_int(ssh->conf, CONF_ssh_kexlist, i)) {
83e7d008 5549 case KEX_DHGEX:
5550 s->preferred_kex[s->n_preferred_kex++] =
5551 &ssh_diffiehellman_gex;
5552 break;
5553 case KEX_DHGROUP14:
5554 s->preferred_kex[s->n_preferred_kex++] =
5555 &ssh_diffiehellman_group14;
5556 break;
5557 case KEX_DHGROUP1:
5558 s->preferred_kex[s->n_preferred_kex++] =
5559 &ssh_diffiehellman_group1;
5560 break;
fae1a71b 5561 case KEX_RSA:
5562 s->preferred_kex[s->n_preferred_kex++] =
5563 &ssh_rsa_kex;
5564 break;
754c0df9 5565 case KEX_WARN:
83e7d008 5566 /* Flag for later. Don't bother if it's the last in
5567 * the list. */
5568 if (i < KEX_MAX - 1) {
5569 s->preferred_kex[s->n_preferred_kex++] = NULL;
5570 }
5571 break;
5572 }
5573 }
83e7d008 5574
83e7d008 5575 /*
51470298 5576 * Set up the preferred ciphers. (NULL => warn below here)
5577 */
5578 s->n_preferred_ciphers = 0;
5579 for (i = 0; i < CIPHER_MAX; i++) {
4a693cfc 5580 switch (conf_get_int_int(ssh->conf, CONF_ssh_cipherlist, i)) {
51470298 5581 case CIPHER_BLOWFISH:
5582 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_blowfish;
5583 break;
5584 case CIPHER_DES:
4a693cfc 5585 if (conf_get_int(ssh->conf, CONF_ssh2_des_cbc)) {
51470298 5586 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_des;
5587 }
5588 break;
5589 case CIPHER_3DES:
5590 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_3des;
5591 break;
5592 case CIPHER_AES:
5593 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_aes;
5594 break;
a2add208 5595 case CIPHER_ARCFOUR:
5596 s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_arcfour;
5597 break;
51470298 5598 case CIPHER_WARN:
5599 /* Flag for later. Don't bother if it's the last in
5600 * the list. */
5601 if (i < CIPHER_MAX - 1) {
5602 s->preferred_ciphers[s->n_preferred_ciphers++] = NULL;
5603 }
5604 break;
ca20bfcf 5605 }
ca20bfcf 5606 }
7591b9ff 5607
e13bba36 5608 /*
5609 * Set up preferred compression.
5610 */
4a693cfc 5611 if (conf_get_int(ssh->conf, CONF_compression))
e13bba36 5612 s->preferred_comp = &ssh_zlib;
5613 else
5614 s->preferred_comp = &ssh_comp_none;
51470298 5615
5616 /*
590f6a5f 5617 * Enable queueing of outgoing auth- or connection-layer
5618 * packets while we are in the middle of a key exchange.
5619 */
5620 ssh->queueing = TRUE;
5621
5622 /*
9442dd57 5623 * Flag that KEX is in progress.
5624 */
5625 ssh->kex_in_progress = TRUE;
5626
5627 /*
51470298 5628 * Construct and send our key exchange packet.
5629 */
ff3187f6 5630 s->pktout = ssh2_pkt_init(SSH2_MSG_KEXINIT);
51470298 5631 for (i = 0; i < 16; i++)
ff3187f6 5632 ssh2_pkt_addbyte(s->pktout, (unsigned char) random_byte());
51470298 5633 /* List key exchange algorithms. */
ff3187f6 5634 ssh2_pkt_addstring_start(s->pktout);
83e7d008 5635 commalist_started = 0;
5636 for (i = 0; i < s->n_preferred_kex; i++) {
34557659 5637 const struct ssh_kexes *k = s->preferred_kex[i];
83e7d008 5638 if (!k) continue; /* warning flag */
34557659 5639 for (j = 0; j < k->nkexes; j++) {
5640 if (commalist_started)
5641 ssh2_pkt_addstring_str(s->pktout, ",");
5642 ssh2_pkt_addstring_str(s->pktout, k->list[j]->name);
5643 commalist_started = 1;
5644 }
32874aea 5645 }
51470298 5646 /* List server host key algorithms. */
ff3187f6 5647 ssh2_pkt_addstring_start(s->pktout);
51470298 5648 for (i = 0; i < lenof(hostkey_algs); i++) {
ff3187f6 5649 ssh2_pkt_addstring_str(s->pktout, hostkey_algs[i]->name);
51470298 5650 if (i < lenof(hostkey_algs) - 1)
ff3187f6 5651 ssh2_pkt_addstring_str(s->pktout, ",");
32874aea 5652 }
cc18f256 5653 /* List encryption algorithms (client->server then server->client). */
5654 for (k = 0; k < 2; k++) {
5655 ssh2_pkt_addstring_start(s->pktout);
5656 commalist_started = 0;
5657 for (i = 0; i < s->n_preferred_ciphers; i++) {
5658 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5659 if (!c) continue; /* warning flag */
5660 for (j = 0; j < c->nciphers; j++) {
5661 if (commalist_started)
5662 ssh2_pkt_addstring_str(s->pktout, ",");
5663 ssh2_pkt_addstring_str(s->pktout, c->list[j]->name);
5664 commalist_started = 1;
5665 }
51470298 5666 }
5667 }
cc18f256 5668 /* List MAC algorithms (client->server then server->client). */
5669 for (j = 0; j < 2; j++) {
5670 ssh2_pkt_addstring_start(s->pktout);
5671 for (i = 0; i < s->nmacs; i++) {
5672 ssh2_pkt_addstring_str(s->pktout, s->maclist[i]->name);
5673 if (i < s->nmacs - 1)
ff3187f6 5674 ssh2_pkt_addstring_str(s->pktout, ",");
51470298 5675 }
5676 }
ab18ccff 5677 /* List client->server compression algorithms,
5678 * then server->client compression algorithms. (We use the
5679 * same set twice.) */
5680 for (j = 0; j < 2; j++) {
5681 ssh2_pkt_addstring_start(s->pktout);
5682 assert(lenof(compressions) > 1);
5683 /* Prefer non-delayed versions */
5684 ssh2_pkt_addstring_str(s->pktout, s->preferred_comp->name);
5685 /* We don't even list delayed versions of algorithms until
5686 * they're allowed to be used, to avoid a race. See the end of
5687 * this function. */
5688 if (s->userauth_succeeded && s->preferred_comp->delayed_name) {
ff3187f6 5689 ssh2_pkt_addstring_str(s->pktout, ",");
ab18ccff 5690 ssh2_pkt_addstring_str(s->pktout,
5691 s->preferred_comp->delayed_name);
f6e0abe2 5692 }
ab18ccff 5693 for (i = 0; i < lenof(compressions); i++) {
5694 const struct ssh_compress *c = compressions[i];
5695 if (c != s->preferred_comp) {
5696 ssh2_pkt_addstring_str(s->pktout, ",");
5697 ssh2_pkt_addstring_str(s->pktout, c->name);
5698 if (s->userauth_succeeded && c->delayed_name) {
5699 ssh2_pkt_addstring_str(s->pktout, ",");
5700 ssh2_pkt_addstring_str(s->pktout, c->delayed_name);
5701 }
5702 }
f6e0abe2 5703 }
51470298 5704 }
5705 /* List client->server languages. Empty list. */
ff3187f6 5706 ssh2_pkt_addstring_start(s->pktout);
51470298 5707 /* List server->client languages. Empty list. */
ff3187f6 5708 ssh2_pkt_addstring_start(s->pktout);
51470298 5709 /* First KEX packet does _not_ follow, because we're not that brave. */
ff3187f6 5710 ssh2_pkt_addbool(s->pktout, FALSE);
51470298 5711 /* Reserved. */
ff3187f6 5712 ssh2_pkt_adduint32(s->pktout, 0);
e5574168 5713 }
0db56f73 5714
3dc9a6a7 5715 s->our_kexinitlen = s->pktout->length - 5;
5716 s->our_kexinit = snewn(s->our_kexinitlen, unsigned char);
5717 memcpy(s->our_kexinit, s->pktout->data + 5, s->our_kexinitlen);
0db56f73 5718
590f6a5f 5719 ssh2_pkt_send_noqueue(ssh, s->pktout);
e5574168 5720
ff3187f6 5721 if (!pktin)
0b106f61 5722 crWaitUntilV(pktin);
e5574168 5723
5724 /*
5725 * Now examine the other side's KEXINIT to see what we're up
5726 * to.
5727 */
51470298 5728 {
4763c1c2 5729 char *str, *preferred;
3d9449a1 5730 int i, j, len;
51470298 5731
ff3187f6 5732 if (pktin->type != SSH2_MSG_KEXINIT) {
6b5cf8b4 5733 bombout(("expected key exchange packet from server"));
0b106f61 5734 crStopV;
32874aea 5735 }
51470298 5736 ssh->kex = NULL;
5737 ssh->hostkey = NULL;
5738 s->cscipher_tobe = NULL;
5739 s->sccipher_tobe = NULL;
5740 s->csmac_tobe = NULL;
5741 s->scmac_tobe = NULL;
5742 s->cscomp_tobe = NULL;
5743 s->sccomp_tobe = NULL;
4763c1c2 5744 s->warn_kex = s->warn_cscipher = s->warn_sccipher = FALSE;
5745
ff3187f6 5746 pktin->savedpos += 16; /* skip garbage cookie */
5747 ssh_pkt_getstring(pktin, &str, &len); /* key exchange algorithms */
4763c1c2 5748
5749 preferred = NULL;
83e7d008 5750 for (i = 0; i < s->n_preferred_kex; i++) {
34557659 5751 const struct ssh_kexes *k = s->preferred_kex[i];
83e7d008 5752 if (!k) {
4763c1c2 5753 s->warn_kex = TRUE;
5754 } else {
34557659 5755 for (j = 0; j < k->nkexes; j++) {
5756 if (!preferred) preferred = k->list[j]->name;
5757 if (in_commasep_string(k->list[j]->name, str, len)) {
5758 ssh->kex = k->list[j];
5759 break;
5760 }
5761 }
83e7d008 5762 }
4763c1c2 5763 if (ssh->kex)
51470298 5764 break;
32874aea 5765 }
83e7d008 5766 if (!ssh->kex) {
5767 bombout(("Couldn't agree a key exchange algorithm (available: %s)",
5768 str ? str : "(null)"));
0b106f61 5769 crStopV;
83e7d008 5770 }
b59743d5 5771 /*
5772 * Note that the server's guess is considered wrong if it doesn't match
5773 * the first algorithm in our list, even if it's still the algorithm
5774 * we end up using.
5775 */
4763c1c2 5776 s->guessok = first_in_commasep_string(preferred, str, len);
ff3187f6 5777 ssh_pkt_getstring(pktin, &str, &len); /* host key algorithms */
51470298 5778 for (i = 0; i < lenof(hostkey_algs); i++) {
5779 if (in_commasep_string(hostkey_algs[i]->name, str, len)) {
5780 ssh->hostkey = hostkey_algs[i];
5781 break;
5782 }
5783 }
fc40b431 5784 if (!ssh->hostkey) {
5785 bombout(("Couldn't agree a host key algorithm (available: %s)",
5786 str ? str : "(null)"));
0b106f61 5787 crStopV;
fc40b431 5788 }
5789
3d9449a1 5790 s->guessok = s->guessok &&
b59743d5 5791 first_in_commasep_string(hostkey_algs[0]->name, str, len);
ff3187f6 5792 ssh_pkt_getstring(pktin, &str, &len); /* client->server cipher */
51470298 5793 for (i = 0; i < s->n_preferred_ciphers; i++) {
5794 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5795 if (!c) {
4763c1c2 5796 s->warn_cscipher = TRUE;
51470298 5797 } else {
5798 for (j = 0; j < c->nciphers; j++) {
5799 if (in_commasep_string(c->list[j]->name, str, len)) {
5800 s->cscipher_tobe = c->list[j];
5801 break;
5802 }
ca20bfcf 5803 }
32874aea 5804 }
4763c1c2 5805 if (s->cscipher_tobe)
51470298 5806 break;
32874aea 5807 }
51470298 5808 if (!s->cscipher_tobe) {
6b5cf8b4 5809 bombout(("Couldn't agree a client-to-server cipher (available: %s)",
57356d63 5810 str ? str : "(null)"));
0b106f61 5811 crStopV;
ca20bfcf 5812 }
0ef8f407 5813
ff3187f6 5814 ssh_pkt_getstring(pktin, &str, &len); /* server->client cipher */
51470298 5815 for (i = 0; i < s->n_preferred_ciphers; i++) {
5816 const struct ssh2_ciphers *c = s->preferred_ciphers[i];
5817 if (!c) {
4763c1c2 5818 s->warn_sccipher = TRUE;
51470298 5819 } else {
5820 for (j = 0; j < c->nciphers; j++) {
5821 if (in_commasep_string(c->list[j]->name, str, len)) {
5822 s->sccipher_tobe = c->list[j];
5823 break;
5824 }
ca20bfcf 5825 }
32874aea 5826 }
4763c1c2 5827 if (s->sccipher_tobe)
51470298 5828 break;
32874aea 5829 }
51470298 5830 if (!s->sccipher_tobe) {
6b5cf8b4 5831 bombout(("Couldn't agree a server-to-client cipher (available: %s)",
57356d63 5832 str ? str : "(null)"));
0b106f61 5833 crStopV;
ca20bfcf 5834 }
0ef8f407 5835
ff3187f6 5836 ssh_pkt_getstring(pktin, &str, &len); /* client->server mac */
51470298 5837 for (i = 0; i < s->nmacs; i++) {
5838 if (in_commasep_string(s->maclist[i]->name, str, len)) {
5839 s->csmac_tobe = s->maclist[i];
5840 break;
5841 }
32874aea 5842 }
ff3187f6 5843 ssh_pkt_getstring(pktin, &str, &len); /* server->client mac */
51470298 5844 for (i = 0; i < s->nmacs; i++) {
5845 if (in_commasep_string(s->maclist[i]->name, str, len)) {
5846 s->scmac_tobe = s->maclist[i];
5847 break;
5848 }
32874aea 5849 }
ff3187f6 5850 ssh_pkt_getstring(pktin, &str, &len); /* client->server compression */
51470298 5851 for (i = 0; i < lenof(compressions) + 1; i++) {
5852 const struct ssh_compress *c =
5853 i == 0 ? s->preferred_comp : compressions[i - 1];
5854 if (in_commasep_string(c->name, str, len)) {
5855 s->cscomp_tobe = c;
5856 break;
ab18ccff 5857 } else if (in_commasep_string(c->delayed_name, str, len)) {
5858 if (s->userauth_succeeded) {
5859 s->cscomp_tobe = c;
5860 break;
5861 } else {
5862 s->pending_compression = TRUE; /* try this later */
5863 }
51470298 5864 }
32874aea 5865 }
ff3187f6 5866 ssh_pkt_getstring(pktin, &str, &len); /* server->client compression */
51470298 5867 for (i = 0; i < lenof(compressions) + 1; i++) {
5868 const struct ssh_compress *c =
5869 i == 0 ? s->preferred_comp : compressions[i - 1];
5870 if (in_commasep_string(c->name, str, len)) {
5871 s->sccomp_tobe = c;
5872 break;
ab18ccff 5873 } else if (in_commasep_string(c->delayed_name, str, len)) {
5874 if (s->userauth_succeeded) {
5875 s->sccomp_tobe = c;
5876 break;
5877 } else {
5878 s->pending_compression = TRUE; /* try this later */
5879 }
51470298 5880 }
32874aea 5881 }
ab18ccff 5882 if (s->pending_compression) {
5883 logevent("Server supports delayed compression; "
5884 "will try this later");
5885 }
b59743d5 5886 ssh_pkt_getstring(pktin, &str, &len); /* client->server language */
5887 ssh_pkt_getstring(pktin, &str, &len); /* server->client language */
4763c1c2 5888 s->ignorepkt = ssh2_pkt_getbool(pktin) && !s->guessok;
5889
5890 if (s->warn_kex) {
5891 ssh_set_frozen(ssh, 1);
5892 s->dlgret = askalg(ssh->frontend, "key-exchange algorithm",
5893 ssh->kex->name,
5894 ssh_dialog_callback, ssh);
5895 if (s->dlgret < 0) {
5896 do {
0b106f61 5897 crReturnV;
4763c1c2 5898 if (pktin) {
5899 bombout(("Unexpected data from server while"
5900 " waiting for user response"));
0b106f61 5901 crStopV;
4763c1c2 5902 }
5903 } while (pktin || inlen > 0);
5904 s->dlgret = ssh->user_response;
5905 }
5906 ssh_set_frozen(ssh, 0);
5907 if (s->dlgret == 0) {
9e296bfa 5908 ssh_disconnect(ssh, "User aborted at kex warning", NULL,
5909 0, TRUE);
0b106f61 5910 crStopV;
4763c1c2 5911 }
5912 }
5913
5914 if (s->warn_cscipher) {
5915 ssh_set_frozen(ssh, 1);
5916 s->dlgret = askalg(ssh->frontend,
5917 "client-to-server cipher",
5918 s->cscipher_tobe->name,
5919 ssh_dialog_callback, ssh);
5920 if (s->dlgret < 0) {
5921 do {
0b106f61 5922 crReturnV;
4763c1c2 5923 if (pktin) {
5924 bombout(("Unexpected data from server while"
5925 " waiting for user response"));
0b106f61 5926 crStopV;
4763c1c2 5927 }
5928 } while (pktin || inlen > 0);
5929 s->dlgret = ssh->user_response;
5930 }
5931 ssh_set_frozen(ssh, 0);
5932 if (s->dlgret == 0) {
9e296bfa 5933 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
5934 0, TRUE);
0b106f61 5935 crStopV;
4763c1c2 5936 }
5937 }
5938
5939 if (s->warn_sccipher) {
5940 ssh_set_frozen(ssh, 1);
5941 s->dlgret = askalg(ssh->frontend,
5942 "server-to-client cipher",
5943 s->sccipher_tobe->name,
5944 ssh_dialog_callback, ssh);
5945 if (s->dlgret < 0) {
5946 do {
0b106f61 5947 crReturnV;
4763c1c2 5948 if (pktin) {
5949 bombout(("Unexpected data from server while"
5950 " waiting for user response"));
0b106f61 5951 crStopV;
4763c1c2 5952 }
5953 } while (pktin || inlen > 0);
5954 s->dlgret = ssh->user_response;
5955 }
5956 ssh_set_frozen(ssh, 0);
5957 if (s->dlgret == 0) {
9e296bfa 5958 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
5959 0, TRUE);
0b106f61 5960 crStopV;
4763c1c2 5961 }
5962 }
5963
b672f405 5964 ssh->exhash = ssh->kex->hash->init();
5965 hash_string(ssh->kex->hash, ssh->exhash, ssh->v_c, strlen(ssh->v_c));
5966 hash_string(ssh->kex->hash, ssh->exhash, ssh->v_s, strlen(ssh->v_s));
5967 hash_string(ssh->kex->hash, ssh->exhash,
5968 s->our_kexinit, s->our_kexinitlen);
3dc9a6a7 5969 sfree(s->our_kexinit);
5970 if (pktin->length > 5)
b672f405 5971 hash_string(ssh->kex->hash, ssh->exhash,
5972 pktin->data + 5, pktin->length - 5);
3dc9a6a7 5973
4763c1c2 5974 if (s->ignorepkt) /* first_kex_packet_follows */
0b106f61 5975 crWaitUntilV(pktin); /* Ignore packet */
e5574168 5976 }
e5574168 5977
fae1a71b 5978 if (ssh->kex->main_type == KEXTYPE_DH) {
30774ba3 5979 /*
5980 * Work out the number of bits of key we will need from the
5981 * key exchange. We start with the maximum key length of
5982 * either cipher...
5983 */
5984 {
5985 int csbits, scbits;
5986
5987 csbits = s->cscipher_tobe->keylen;
5988 scbits = s->sccipher_tobe->keylen;
5989 s->nbits = (csbits > scbits ? csbits : scbits);
5990 }
5991 /* The keys only have hlen-bit entropy, since they're based on
5992 * a hash. So cap the key size at hlen bits. */
5993 if (s->nbits > ssh->kex->hash->hlen * 8)
5994 s->nbits = ssh->kex->hash->hlen * 8;
5995
5996 /*
5997 * If we're doing Diffie-Hellman group exchange, start by
5998 * requesting a group.
5999 */
6000 if (!ssh->kex->pdata) {
6001 logevent("Doing Diffie-Hellman group exchange");
acab36bc 6002 ssh->pkt_kctx = SSH2_PKTCTX_DHGEX;
30774ba3 6003 /*
6004 * Work out how big a DH group we will need to allow that
6005 * much data.
6006 */
6007 s->pbits = 512 << ((s->nbits - 1) / 64);
6008 s->pktout = ssh2_pkt_init(SSH2_MSG_KEX_DH_GEX_REQUEST);
6009 ssh2_pkt_adduint32(s->pktout, s->pbits);
6010 ssh2_pkt_send_noqueue(ssh, s->pktout);
6011
0b106f61 6012 crWaitUntilV(pktin);
30774ba3 6013 if (pktin->type != SSH2_MSG_KEX_DH_GEX_GROUP) {
6014 bombout(("expected key exchange group packet from server"));
0b106f61 6015 crStopV;
30774ba3 6016 }
6017 s->p = ssh2_pkt_getmp(pktin);
6018 s->g = ssh2_pkt_getmp(pktin);
6019 if (!s->p || !s->g) {
6020 bombout(("unable to read mp-ints from incoming group packet"));
0b106f61 6021 crStopV;
30774ba3 6022 }
6023 ssh->kex_ctx = dh_setup_gex(s->p, s->g);
6024 s->kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
6025 s->kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
6026 } else {
acab36bc 6027 ssh->pkt_kctx = SSH2_PKTCTX_DHGROUP;
30774ba3 6028 ssh->kex_ctx = dh_setup_group(ssh->kex);
6029 s->kex_init_value = SSH2_MSG_KEXDH_INIT;
6030 s->kex_reply_value = SSH2_MSG_KEXDH_REPLY;
6031 logeventf(ssh, "Using Diffie-Hellman with standard group \"%s\"",
6032 ssh->kex->groupname);
6033 }
e5574168 6034
30774ba3 6035 logeventf(ssh, "Doing Diffie-Hellman key exchange with hash %s",
6036 ssh->kex->hash->text_name);
6037 /*
6038 * Now generate and send e for Diffie-Hellman.
6039 */
6040 set_busy_status(ssh->frontend, BUSY_CPU); /* this can take a while */
6041 s->e = dh_create_e(ssh->kex_ctx, s->nbits * 2);
6042 s->pktout = ssh2_pkt_init(s->kex_init_value);
6043 ssh2_pkt_addmp(s->pktout, s->e);
6044 ssh2_pkt_send_noqueue(ssh, s->pktout);
6045
6046 set_busy_status(ssh->frontend, BUSY_WAITING); /* wait for server */
0b106f61 6047 crWaitUntilV(pktin);
30774ba3 6048 if (pktin->type != s->kex_reply_value) {
6049 bombout(("expected key exchange reply packet from server"));
0b106f61 6050 crStopV;
30774ba3 6051 }
6052 set_busy_status(ssh->frontend, BUSY_CPU); /* cogitate */
6053 ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
6054 s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
6055 s->f = ssh2_pkt_getmp(pktin);
6056 if (!s->f) {
6057 bombout(("unable to parse key exchange reply packet"));
0b106f61 6058 crStopV;
30774ba3 6059 }
6060 ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
e5574168 6061
30774ba3 6062 s->K = dh_find_K(ssh->kex_ctx, s->f);
e5574168 6063
30774ba3 6064 /* We assume everything from now on will be quick, and it might
6065 * involve user interaction. */
6066 set_busy_status(ssh->frontend, BUSY_NOT);
755e0524 6067
30774ba3 6068 hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen);
6069 if (!ssh->kex->pdata) {
6070 hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits);
6071 hash_mpint(ssh->kex->hash, ssh->exhash, s->p);
6072 hash_mpint(ssh->kex->hash, ssh->exhash, s->g);
6073 }
6074 hash_mpint(ssh->kex->hash, ssh->exhash, s->e);
6075 hash_mpint(ssh->kex->hash, ssh->exhash, s->f);
6076
6077 dh_cleanup(ssh->kex_ctx);
6078 freebn(s->f);
6079 if (!ssh->kex->pdata) {
6080 freebn(s->g);
6081 freebn(s->p);
6082 }
fae1a71b 6083 } else {
6084 logeventf(ssh, "Doing RSA key exchange with hash %s",
6085 ssh->kex->hash->text_name);
acab36bc 6086 ssh->pkt_kctx = SSH2_PKTCTX_RSAKEX;
fae1a71b 6087 /*
6088 * RSA key exchange. First expect a KEXRSA_PUBKEY packet
6089 * from the server.
6090 */
0b106f61 6091 crWaitUntilV(pktin);
fae1a71b 6092 if (pktin->type != SSH2_MSG_KEXRSA_PUBKEY) {
6093 bombout(("expected RSA public key packet from server"));
0b106f61 6094 crStopV;
fae1a71b 6095 }
6096
6097 ssh_pkt_getstring(pktin, &s->hostkeydata, &s->hostkeylen);
6098 hash_string(ssh->kex->hash, ssh->exhash,
6099 s->hostkeydata, s->hostkeylen);
6100 s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen);
6101
6102 {
6103 char *keydata;
6104 ssh_pkt_getstring(pktin, &keydata, &s->rsakeylen);
6105 s->rsakeydata = snewn(s->rsakeylen, char);
6106 memcpy(s->rsakeydata, keydata, s->rsakeylen);
6107 }
6108
6109 s->rsakey = ssh_rsakex_newkey(s->rsakeydata, s->rsakeylen);
6110 if (!s->rsakey) {
6111 sfree(s->rsakeydata);
6112 bombout(("unable to parse RSA public key from server"));
0b106f61 6113 crStopV;
fae1a71b 6114 }
6115
6116 hash_string(ssh->kex->hash, ssh->exhash, s->rsakeydata, s->rsakeylen);
6117
6118 /*
6119 * Next, set up a shared secret K, of precisely KLEN -
6120 * 2*HLEN - 49 bits, where KLEN is the bit length of the
6121 * RSA key modulus and HLEN is the bit length of the hash
6122 * we're using.
6123 */
6124 {
6125 int klen = ssh_rsakex_klen(s->rsakey);
6126 int nbits = klen - (2*ssh->kex->hash->hlen*8 + 49);
6127 int i, byte = 0;
6128 unsigned char *kstr1, *kstr2, *outstr;
6129 int kstr1len, kstr2len, outstrlen;
6130
6131 s->K = bn_power_2(nbits - 1);
6132
6133 for (i = 0; i < nbits; i++) {
6134 if ((i & 7) == 0) {
6135 byte = random_byte();
6136 }
6137 bignum_set_bit(s->K, i, (byte >> (i & 7)) & 1);
6138 }
6139
6140 /*
6141 * Encode this as an mpint.
6142 */
6143 kstr1 = ssh2_mpint_fmt(s->K, &kstr1len);
6144 kstr2 = snewn(kstr2len = 4 + kstr1len, unsigned char);
6145 PUT_32BIT(kstr2, kstr1len);
6146 memcpy(kstr2 + 4, kstr1, kstr1len);
6147
6148 /*
6149 * Encrypt it with the given RSA key.
6150 */
6151 outstrlen = (klen + 7) / 8;
6152 outstr = snewn(outstrlen, unsigned char);
6153 ssh_rsakex_encrypt(ssh->kex->hash, kstr2, kstr2len,
6154 outstr, outstrlen, s->rsakey);
6155
6156 /*
6157 * And send it off in a return packet.
6158 */
6159 s->pktout = ssh2_pkt_init(SSH2_MSG_KEXRSA_SECRET);
6160 ssh2_pkt_addstring_start(s->pktout);
7108a872 6161 ssh2_pkt_addstring_data(s->pktout, (char *)outstr, outstrlen);
fae1a71b 6162 ssh2_pkt_send_noqueue(ssh, s->pktout);
6163
6164 hash_string(ssh->kex->hash, ssh->exhash, outstr, outstrlen);
6165
6166 sfree(kstr2);
6167 sfree(kstr1);
6168 sfree(outstr);
6169 }
6170
6171 ssh_rsakex_freekey(s->rsakey);
6172
0b106f61 6173 crWaitUntilV(pktin);
fae1a71b 6174 if (pktin->type != SSH2_MSG_KEXRSA_DONE) {
6175 sfree(s->rsakeydata);
6176 bombout(("expected signature packet from server"));
0b106f61 6177 crStopV;
fae1a71b 6178 }
6179
6180 ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
6181
6182 sfree(s->rsakeydata);
6183 }
6184
b672f405 6185 hash_mpint(ssh->kex->hash, ssh->exhash, s->K);
6186 assert(ssh->kex->hash->hlen <= sizeof(s->exchange_hash));
6187 ssh->kex->hash->final(ssh->exhash, s->exchange_hash);
e5574168 6188
fabd1805 6189 ssh->kex_ctx = NULL;
3709bfe9 6190
7cca0d81 6191#if 0
765c4200 6192 debug(("Exchange hash is:\n"));
b672f405 6193 dmemdump(s->exchange_hash, ssh->kex->hash->hlen);
7cca0d81 6194#endif
6195
51470298 6196 if (!s->hkey ||
6197 !ssh->hostkey->verifysig(s->hkey, s->sigdata, s->siglen,
b672f405 6198 (char *)s->exchange_hash,
6199 ssh->kex->hash->hlen)) {
6b5cf8b4 6200 bombout(("Server's host key did not match the signature supplied"));
0b106f61 6201 crStopV;
8d5de777 6202 }
e5574168 6203
6204 /*
7cca0d81 6205 * Authenticate remote host: verify host key. (We've already
6206 * checked the signature of the exchange hash.)
e5574168 6207 */
51470298 6208 s->keystr = ssh->hostkey->fmtkey(s->hkey);
6209 s->fingerprint = ssh->hostkey->fingerprint(s->hkey);
3d9449a1 6210 ssh_set_frozen(ssh, 1);
6211 s->dlgret = verify_ssh_host_key(ssh->frontend,
6212 ssh->savedhost, ssh->savedport,
6213 ssh->hostkey->keytype, s->keystr,
6214 s->fingerprint,
6215 ssh_dialog_callback, ssh);
6216 if (s->dlgret < 0) {
6217 do {
0b106f61 6218 crReturnV;
3d9449a1 6219 if (pktin) {
6220 bombout(("Unexpected data from server while waiting"
6221 " for user host key response"));
0b106f61 6222 crStopV;
3d9449a1 6223 }
6224 } while (pktin || inlen > 0);
6225 s->dlgret = ssh->user_response;
6226 }
6227 ssh_set_frozen(ssh, 0);
6228 if (s->dlgret == 0) {
9e296bfa 6229 ssh_disconnect(ssh, "User aborted at host key verification", NULL,
6230 0, TRUE);
0b106f61 6231 crStopV;
3d9449a1 6232 }
e13bba36 6233 if (!s->got_session_id) { /* don't bother logging this in rekeys */
5e0d7cb8 6234 logevent("Host key fingerprint is:");
51470298 6235 logevent(s->fingerprint);
5e0d7cb8 6236 }
51470298 6237 sfree(s->fingerprint);
6238 sfree(s->keystr);
6239 ssh->hostkey->freekey(s->hkey);
d39f364a 6240
6241 /*
9442dd57 6242 * The exchange hash from the very first key exchange is also
6243 * the session id, used in session key construction and
6244 * authentication.
6245 */
e13bba36 6246 if (!s->got_session_id) {
b672f405 6247 assert(sizeof(s->exchange_hash) <= sizeof(ssh->v2_session_id));
9442dd57 6248 memcpy(ssh->v2_session_id, s->exchange_hash,
6249 sizeof(s->exchange_hash));
b672f405 6250 ssh->v2_session_id_len = ssh->kex->hash->hlen;
6052bb76 6251 assert(ssh->v2_session_id_len <= sizeof(ssh->v2_session_id));
e13bba36 6252 s->got_session_id = TRUE;
6253 }
9442dd57 6254
6255 /*
7cca0d81 6256 * Send SSH2_MSG_NEWKEYS.
d39f364a 6257 */
ff3187f6 6258 s->pktout = ssh2_pkt_init(SSH2_MSG_NEWKEYS);
590f6a5f 6259 ssh2_pkt_send_noqueue(ssh, s->pktout);
9442dd57 6260 ssh->outgoing_data_size = 0; /* start counting from here */
6261
6262 /*
6263 * We've sent client NEWKEYS, so create and initialise
c64fe7d4 6264 * client-to-server session keys.
9442dd57 6265 */
6266 if (ssh->cs_cipher_ctx)
6267 ssh->cscipher->free_context(ssh->cs_cipher_ctx);
6268 ssh->cscipher = s->cscipher_tobe;
6269 ssh->cs_cipher_ctx = ssh->cscipher->make_context();
6270
6271 if (ssh->cs_mac_ctx)
6272 ssh->csmac->free_context(ssh->cs_mac_ctx);
6273 ssh->csmac = s->csmac_tobe;
6274 ssh->cs_mac_ctx = ssh->csmac->make_context();
6275
6276 if (ssh->cs_comp_ctx)
6277 ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
6278 ssh->cscomp = s->cscomp_tobe;
6279 ssh->cs_comp_ctx = ssh->cscomp->compress_init();
6280
6281 /*
6282 * Set IVs on client-to-server keys. Here we use the exchange
6283 * hash from the _first_ key exchange.
6284 */
6285 {
754c0df9 6286 unsigned char keyspace[SSH2_KEX_MAX_HASH_LEN * SSH2_MKKEY_ITERS];
6287 assert(sizeof(keyspace) >= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
b672f405 6288 ssh2_mkkey(ssh,s->K,s->exchange_hash,'C',keyspace);
754c0df9 6289 assert((ssh->cscipher->keylen+7) / 8 <=
6290 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
9442dd57 6291 ssh->cscipher->setkey(ssh->cs_cipher_ctx, keyspace);
b672f405 6292 ssh2_mkkey(ssh,s->K,s->exchange_hash,'A',keyspace);
754c0df9 6293 assert(ssh->cscipher->blksize <=
6294 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
9442dd57 6295 ssh->cscipher->setiv(ssh->cs_cipher_ctx, keyspace);
b672f405 6296 ssh2_mkkey(ssh,s->K,s->exchange_hash,'E',keyspace);
754c0df9 6297 assert(ssh->csmac->len <=
6298 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
9442dd57 6299 ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace);
dfb88efd 6300 smemclr(keyspace, sizeof(keyspace));
9442dd57 6301 }
6302
6303 logeventf(ssh, "Initialised %.200s client->server encryption",
6304 ssh->cscipher->text_name);
6305 logeventf(ssh, "Initialised %.200s client->server MAC algorithm",
6306 ssh->csmac->text_name);
6307 if (ssh->cscomp->text_name)
6308 logeventf(ssh, "Initialised %s compression",
6309 ssh->cscomp->text_name);
590f6a5f 6310
6311 /*
6312 * Now our end of the key exchange is complete, we can send all
6313 * our queued higher-layer packets.
6314 */
6315 ssh->queueing = FALSE;
6316 ssh2_pkt_queuesend(ssh);
d39f364a 6317
6318 /*
8406eaf9 6319 * Expect SSH2_MSG_NEWKEYS from server.
6320 */
0b106f61 6321 crWaitUntilV(pktin);
ff3187f6 6322 if (pktin->type != SSH2_MSG_NEWKEYS) {
6b5cf8b4 6323 bombout(("expected new-keys packet from server"));
0b106f61 6324 crStopV;
8406eaf9 6325 }
9442dd57 6326 ssh->incoming_data_size = 0; /* start counting from here */
8406eaf9 6327
6328 /*
9442dd57 6329 * We've seen server NEWKEYS, so create and initialise
6330 * server-to-client session keys.
d39f364a 6331 */
371e569c 6332 if (ssh->sc_cipher_ctx)
6333 ssh->sccipher->free_context(ssh->sc_cipher_ctx);
51470298 6334 ssh->sccipher = s->sccipher_tobe;
371e569c 6335 ssh->sc_cipher_ctx = ssh->sccipher->make_context();
e0e1a00d 6336
e0e1a00d 6337 if (ssh->sc_mac_ctx)
6338 ssh->scmac->free_context(ssh->sc_mac_ctx);
51470298 6339 ssh->scmac = s->scmac_tobe;
e0e1a00d 6340 ssh->sc_mac_ctx = ssh->scmac->make_context();
6341
5366aed8 6342 if (ssh->sc_comp_ctx)
6343 ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
51470298 6344 ssh->sccomp = s->sccomp_tobe;
5366aed8 6345 ssh->sc_comp_ctx = ssh->sccomp->decompress_init();
6346
d39f364a 6347 /*
9442dd57 6348 * Set IVs on server-to-client keys. Here we use the exchange
6349 * hash from the _first_ key exchange.
d39f364a 6350 */
51470298 6351 {
754c0df9 6352 unsigned char keyspace[SSH2_KEX_MAX_HASH_LEN * SSH2_MKKEY_ITERS];
6353 assert(sizeof(keyspace) >= ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
b672f405 6354 ssh2_mkkey(ssh,s->K,s->exchange_hash,'D',keyspace);
754c0df9 6355 assert((ssh->sccipher->keylen+7) / 8 <=
6356 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
371e569c 6357 ssh->sccipher->setkey(ssh->sc_cipher_ctx, keyspace);
b672f405 6358 ssh2_mkkey(ssh,s->K,s->exchange_hash,'B',keyspace);
754c0df9 6359 assert(ssh->sccipher->blksize <=
6360 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
371e569c 6361 ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace);
b672f405 6362 ssh2_mkkey(ssh,s->K,s->exchange_hash,'F',keyspace);
754c0df9 6363 assert(ssh->scmac->len <=
6364 ssh->kex->hash->hlen * SSH2_MKKEY_ITERS);
e0e1a00d 6365 ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace);
dfb88efd 6366 smemclr(keyspace, sizeof(keyspace));
51470298 6367 }
57356d63 6368 logeventf(ssh, "Initialised %.200s server->client encryption",
6369 ssh->sccipher->text_name);
6c135243 6370 logeventf(ssh, "Initialised %.200s server->client MAC algorithm",
6371 ssh->scmac->text_name);
57356d63 6372 if (ssh->sccomp->text_name)
6373 logeventf(ssh, "Initialised %s decompression",
6374 ssh->sccomp->text_name);
9442dd57 6375
6376 /*
fae1a71b 6377 * Free shared secret.
9442dd57 6378 */
679539d7 6379 freebn(s->K);
d39f364a 6380
033b4cef 6381 /*
e13bba36 6382 * Key exchange is over. Loop straight back round if we have a
6383 * deferred rekey reason.
6384 */
6385 if (ssh->deferred_rekey_reason) {
6386 logevent(ssh->deferred_rekey_reason);
6387 pktin = NULL;
6388 ssh->deferred_rekey_reason = NULL;
6389 goto begin_key_exchange;
6390 }
6391
6392 /*
6393 * Otherwise, schedule a timer for our next rekey.
9442dd57 6394 */
6395 ssh->kex_in_progress = FALSE;
e6c1536e 6396 ssh->last_rekey = GETTICKCOUNT();
4a693cfc 6397 if (conf_get_int(ssh->conf, CONF_ssh_rekey_time) != 0)
6398 ssh->next_rekey = schedule_timer(conf_get_int(ssh->conf, CONF_ssh_rekey_time)*60*TICKSPERSEC,
d57f70af 6399 ssh2_timer, ssh);
e13bba36 6400
9442dd57 6401 /*
7cca0d81 6402 * Now we're encrypting. Begin returning 1 to the protocol main
6403 * function so that other things can run on top of the
6404 * transport. If we ever see a KEXINIT, we must go back to the
6405 * start.
9442dd57 6406 *
6407 * We _also_ go back to the start if we see pktin==NULL and
ab18ccff 6408 * inlen negative, because this is a special signal meaning
9442dd57 6409 * `initiate client-driven rekey', and `in' contains a message
6410 * giving the reason for the rekey.
ab18ccff 6411 *
6412 * inlen==-1 means always initiate a rekey;
6413 * inlen==-2 means that userauth has completed successfully and
6414 * we should consider rekeying (for delayed compression).
033b4cef 6415 */
9442dd57 6416 while (!((pktin && pktin->type == SSH2_MSG_KEXINIT) ||
ab18ccff 6417 (!pktin && inlen < 0))) {
f382c87d 6418 wait_for_rekey:
bc074147 6419 if (!ssh->protocol_initial_phase_done) {
6420 ssh->protocol_initial_phase_done = TRUE;
6421 /*
6422 * Allow authconn to initialise itself.
6423 */
6424 do_ssh2_authconn(ssh, NULL, 0, NULL);
6425 }
0b106f61 6426 crReturnV;
e96adf72 6427 }
9442dd57 6428 if (pktin) {
6429 logevent("Server initiated key re-exchange");
6430 } else {
ab18ccff 6431 if (inlen == -2) {
6432 /*
6433 * authconn has seen a USERAUTH_SUCCEEDED. Time to enable
6434 * delayed compression, if it's available.
6435 *
6436 * draft-miller-secsh-compression-delayed-00 says that you
6437 * negotiate delayed compression in the first key exchange, and
6438 * both sides start compressing when the server has sent
6439 * USERAUTH_SUCCESS. This has a race condition -- the server
6440 * can't know when the client has seen it, and thus which incoming
6441 * packets it should treat as compressed.
6442 *
6443 * Instead, we do the initial key exchange without offering the
6444 * delayed methods, but note if the server offers them; when we
6445 * get here, if a delayed method was available that was higher
6446 * on our list than what we got, we initiate a rekey in which we
6447 * _do_ list the delayed methods (and hopefully get it as a
6448 * result). Subsequent rekeys will do the same.
6449 */
6450 assert(!s->userauth_succeeded); /* should only happen once */
6451 s->userauth_succeeded = TRUE;
6452 if (!s->pending_compression)
6453 /* Can't see any point rekeying. */
6454 goto wait_for_rekey; /* this is utterly horrid */
6455 /* else fall through to rekey... */
6456 s->pending_compression = FALSE;
6457 }
f382c87d 6458 /*
ab18ccff 6459 * Now we've decided to rekey.
6460 *
f382c87d 6461 * Special case: if the server bug is set that doesn't
6462 * allow rekeying, we give a different log message and
6463 * continue waiting. (If such a server _initiates_ a rekey,
6464 * we process it anyway!)
6465 */
6466 if ((ssh->remote_bugs & BUG_SSH2_REKEY)) {
6467 logeventf(ssh, "Server bug prevents key re-exchange (%s)",
6468 (char *)in);
6469 /* Reset the counters, so that at least this message doesn't
6470 * hit the event log _too_ often. */
6471 ssh->outgoing_data_size = 0;
6472 ssh->incoming_data_size = 0;
4a693cfc 6473 if (conf_get_int(ssh->conf, CONF_ssh_rekey_time) != 0) {
f382c87d 6474 ssh->next_rekey =
4a693cfc 6475 schedule_timer(conf_get_int(ssh->conf, CONF_ssh_rekey_time)*60*TICKSPERSEC,
f382c87d 6476 ssh2_timer, ssh);
6477 }
ab18ccff 6478 goto wait_for_rekey; /* this is still utterly horrid */
f382c87d 6479 } else {
6480 logeventf(ssh, "Initiating key re-exchange (%s)", (char *)in);
f382c87d 6481 }
9442dd57 6482 }
7cca0d81 6483 goto begin_key_exchange;
e5574168 6484
0b106f61 6485 crFinishV;
e5574168 6486}
6487
7cca0d81 6488/*
2e85c969 6489 * Add data to an SSH-2 channel output buffer.
783415f8 6490 */
32874aea 6491static void ssh2_add_channel_data(struct ssh_channel *c, char *buf,
6492 int len)
6493{
5471d09a 6494 bufchain_add(&c->v.v2.outbuffer, buf, len);
783415f8 6495}
6496
6497/*
2e85c969 6498 * Attempt to send data on an SSH-2 channel.
783415f8 6499 */
5471d09a 6500static int ssh2_try_send(struct ssh_channel *c)
32874aea 6501{
51470298 6502 Ssh ssh = c->ssh;
ff3187f6 6503 struct Packet *pktout;
bc06669b 6504 int ret;
51470298 6505
5471d09a 6506 while (c->v.v2.remwindow > 0 && bufchain_size(&c->v.v2.outbuffer) > 0) {
6507 int len;
6508 void *data;
6509 bufchain_prefix(&c->v.v2.outbuffer, &data, &len);
6510 if ((unsigned)len > c->v.v2.remwindow)
6511 len = c->v.v2.remwindow;
6512 if ((unsigned)len > c->v.v2.remmaxpkt)
6513 len = c->v.v2.remmaxpkt;
ff3187f6 6514 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
6515 ssh2_pkt_adduint32(pktout, c->remoteid);
ff3187f6 6516 ssh2_pkt_addstring_start(pktout);
a2724fba 6517 dont_log_data(ssh, pktout, PKTLOG_OMIT);
ff3187f6 6518 ssh2_pkt_addstring_data(pktout, data, len);
6519 end_log_omission(ssh, pktout);
6520 ssh2_pkt_send(ssh, pktout);
5471d09a 6521 bufchain_consume(&c->v.v2.outbuffer, len);
6522 c->v.v2.remwindow -= len;
6523 }
6524
6525 /*
6526 * After having sent as much data as we can, return the amount
6527 * still buffered.
6528 */
bc06669b 6529 ret = bufchain_size(&c->v.v2.outbuffer);
6530
6531 /*
6532 * And if there's no data pending but we need to send an EOF, send
6533 * it.
6534 */
6535 if (!ret && c->pending_eof)
6536 ssh_channel_try_eof(c);
6537
6538 return ret;
5471d09a 6539}
6540
78280721 6541static void ssh2_try_send_and_unthrottle(Ssh ssh, struct ssh_channel *c)
1bfc7e93 6542{
6543 int bufsize;
bc06669b 6544 if (c->closes & CLOSES_SENT_EOF)
6545 return; /* don't send on channels we've EOFed */
1bfc7e93 6546 bufsize = ssh2_try_send(c);
6547 if (bufsize == 0) {
6548 switch (c->type) {
6549 case CHAN_MAINSESSION:
6550 /* stdin need not receive an unthrottle
6551 * notification since it will be polled */
6552 break;
6553 case CHAN_X11:
6554 x11_unthrottle(c->u.x11.s);
6555 break;
6556 case CHAN_AGENT:
6557 /* agent sockets are request/response and need no
6558 * buffer management */
6559 break;
6560 case CHAN_SOCKDATA:
6561 pfd_unthrottle(c->u.pfd.s);
6562 break;
6563 }
6564 }
6565}
6566
5471d09a 6567/*
94bdfe40 6568 * Set up most of a new ssh_channel for SSH-2.
6569 */
6570static void ssh2_channel_init(struct ssh_channel *c)
6571{
6572 Ssh ssh = c->ssh;
6573 c->localid = alloc_channel_id(ssh);
6574 c->closes = 0;
bc06669b 6575 c->pending_eof = FALSE;
94bdfe40 6576 c->throttling_conn = FALSE;
6577 c->v.v2.locwindow = c->v.v2.locmaxwin = c->v.v2.remlocwin =
4a693cfc 6578 conf_get_int(ssh->conf, CONF_ssh_simple) ? OUR_V2_BIGWIN : OUR_V2_WINSIZE;
39d830e4 6579 c->v.v2.chanreq_head = NULL;
94bdfe40 6580 c->v.v2.throttle_state = UNTHROTTLED;
6581 bufchain_init(&c->v.v2.outbuffer);
6582}
6583
6584/*
4a62c66d 6585 * Construct the common parts of a CHANNEL_OPEN.
6586 */
6587static struct Packet *ssh2_chanopen_init(struct ssh_channel *c, char *type)
6588{
6589 struct Packet *pktout;
6590
6591 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
6592 ssh2_pkt_addstring(pktout, type);
6593 ssh2_pkt_adduint32(pktout, c->localid);
6594 ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);/* our window size */
6595 ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
6596 return pktout;
6597}
6598
6599/*
39d830e4 6600 * CHANNEL_FAILURE doesn't come with any indication of what message
6601 * caused it, so we have to keep track of the outstanding
6602 * CHANNEL_REQUESTs ourselves.
6603 */
6604static void ssh2_queue_chanreq_handler(struct ssh_channel *c,
6605 cchandler_fn_t handler, void *ctx)
6606{
6607 struct outstanding_channel_request *ocr =
6608 snew(struct outstanding_channel_request);
6609
3620f307 6610 assert(!(c->closes & (CLOSES_SENT_CLOSE | CLOSES_RCVD_CLOSE)));
39d830e4 6611 ocr->handler = handler;
6612 ocr->ctx = ctx;
6613 ocr->next = NULL;
6614 if (!c->v.v2.chanreq_head)
6615 c->v.v2.chanreq_head = ocr;
6616 else
6617 c->v.v2.chanreq_tail->next = ocr;
6618 c->v.v2.chanreq_tail = ocr;
6619}
6620
6621/*
134f5ece 6622 * Construct the common parts of a CHANNEL_REQUEST. If handler is not
6623 * NULL then a reply will be requested and the handler will be called
6624 * when it arrives. The returned packet is ready to have any
6625 * request-specific data added and be sent. Note that if a handler is
6626 * provided, it's essential that the request actually be sent.
3620f307 6627 *
6628 * The handler will usually be passed the response packet in pktin.
6629 * If pktin is NULL, this means that no reply will ever be forthcoming
6630 * (e.g. because the entire connection is being destroyed) and the
6631 * handler should free any storage it's holding.
134f5ece 6632 */
6633static struct Packet *ssh2_chanreq_init(struct ssh_channel *c, char *type,
6634 cchandler_fn_t handler, void *ctx)
6635{
6636 struct Packet *pktout;
6637
3620f307 6638 assert(!(c->closes & (CLOSES_SENT_CLOSE | CLOSES_RCVD_CLOSE)));
134f5ece 6639 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
6640 ssh2_pkt_adduint32(pktout, c->remoteid);
6641 ssh2_pkt_addstring(pktout, type);
6642 ssh2_pkt_addbool(pktout, handler != NULL);
6643 if (handler != NULL)
6644 ssh2_queue_chanreq_handler(c, handler, ctx);
6645 return pktout;
6646}
6647
6648/*
2e85c969 6649 * Potentially enlarge the window on an SSH-2 channel.
5471d09a 6650 */
39d830e4 6651static void ssh2_handle_winadj_response(struct ssh_channel *, struct Packet *,
6652 void *);
9fca3f8c 6653static void ssh2_set_window(struct ssh_channel *c, int newwin)
5471d09a 6654{
51470298 6655 Ssh ssh = c->ssh;
6656
6b69f42e 6657 /*
bc06669b 6658 * Never send WINDOW_ADJUST for a channel that the remote side has
6659 * already sent EOF on; there's no point, since it won't be
beff003a 6660 * sending any more data anyway. Ditto if _we've_ already sent
6661 * CLOSE.
6b69f42e 6662 */
beff003a 6663 if (c->closes & (CLOSES_RCVD_EOF | CLOSES_SENT_CLOSE))
6b69f42e 6664 return;
6665
d252310a 6666 /*
c9739dba 6667 * If the remote end has a habit of ignoring maxpkt, limit the
6668 * window so that it has no choice (assuming it doesn't ignore the
6669 * window as well).
6670 */
6671 if ((ssh->remote_bugs & BUG_SSH2_MAXPKT) && newwin > OUR_V2_MAXPKT)
6672 newwin = OUR_V2_MAXPKT;
c9739dba 6673
6674 /*
d252310a 6675 * Only send a WINDOW_ADJUST if there's significantly more window
6676 * available than the other end thinks there is. This saves us
6677 * sending a WINDOW_ADJUST for every character in a shell session.
6678 *
6679 * "Significant" is arbitrarily defined as half the window size.
6680 */
3361b80a 6681 if (newwin / 2 >= c->v.v2.locwindow) {
ff3187f6 6682 struct Packet *pktout;
39d830e4 6683 unsigned *up;
ff3187f6 6684
0e443c99 6685 /*
6686 * In order to keep track of how much window the client
6687 * actually has available, we'd like it to acknowledge each
6688 * WINDOW_ADJUST. We can't do that directly, so we accompany
6689 * it with a CHANNEL_REQUEST that has to be acknowledged.
6690 *
6691 * This is only necessary if we're opening the window wide.
6692 * If we're not, then throughput is being constrained by
6693 * something other than the maximum window size anyway.
0e443c99 6694 */
6695 if (newwin == c->v.v2.locmaxwin &&
2e0aae4f 6696 !(ssh->remote_bugs & BUG_CHOKES_ON_WINADJ)) {
39d830e4 6697 up = snew(unsigned);
6698 *up = newwin - c->v.v2.locwindow;
134f5ece 6699 pktout = ssh2_chanreq_init(c, "winadj@putty.projects.tartarus.org",
6700 ssh2_handle_winadj_response, up);
6701 ssh2_pkt_send(ssh, pktout);
6702
0e443c99 6703 if (c->v.v2.throttle_state != UNTHROTTLED)
6704 c->v.v2.throttle_state = UNTHROTTLING;
6705 } else {
6706 /* Pretend the WINDOW_ADJUST was acked immediately. */
6707 c->v.v2.remlocwin = newwin;
6708 c->v.v2.throttle_state = THROTTLED;
6709 }
ff3187f6 6710 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
6711 ssh2_pkt_adduint32(pktout, c->remoteid);
6712 ssh2_pkt_adduint32(pktout, newwin - c->v.v2.locwindow);
6713 ssh2_pkt_send(ssh, pktout);
5471d09a 6714 c->v.v2.locwindow = newwin;
783415f8 6715 }
6716}
6717
e223b7c7 6718/*
6719 * Find the channel associated with a message. If there's no channel,
6720 * or it's not properly open, make a noise about it and return NULL.
6721 */
6722static struct ssh_channel *ssh2_channel_msg(Ssh ssh, struct Packet *pktin)
6723{
6724 unsigned localid = ssh_pkt_getuint32(pktin);
6725 struct ssh_channel *c;
6726
6727 c = find234(ssh->channels, &localid, ssh_channelfind);
6728 if (!c ||
6729 (c->halfopen && pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION &&
6730 pktin->type != SSH2_MSG_CHANNEL_OPEN_FAILURE)) {
6731 char *buf = dupprintf("Received %s for %s channel %u",
6732 ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx,
6733 pktin->type),
6734 c ? "half-open" : "nonexistent", localid);
6735 ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6736 sfree(buf);
6737 return NULL;
6738 }
6739 return c;
6740}
6741
39d830e4 6742static void ssh2_handle_winadj_response(struct ssh_channel *c,
6743 struct Packet *pktin, void *ctx)
e030765f 6744{
39d830e4 6745 unsigned *sizep = ctx;
6746
6747 /*
6748 * Winadj responses should always be failures. However, at least
6749 * one server ("boks_sshd") is known to return SUCCESS for channel
6750 * requests it's never heard of, such as "winadj@putty". Raised
6751 * with foxt.com as bug 090916-090424, but for the sake of a quiet
6752 * life, we don't worry about what kind of response we got.
6753 */
6754
6755 c->v.v2.remlocwin += *sizep;
6756 sfree(sizep);
e030765f 6757 /*
6758 * winadj messages are only sent when the window is fully open, so
6759 * if we get an ack of one, we know any pending unthrottle is
6760 * complete.
6761 */
6762 if (c->v.v2.throttle_state == UNTHROTTLING)
6763 c->v.v2.throttle_state = UNTHROTTLED;
e030765f 6764}
6765
39d830e4 6766static void ssh2_msg_channel_response(Ssh ssh, struct Packet *pktin)
837d6ba6 6767{
39d830e4 6768 struct ssh_channel *c = ssh2_channel_msg(ssh, pktin);
6769 struct outstanding_channel_request *ocr;
837d6ba6 6770
39d830e4 6771 if (!c) return;
6772 ocr = c->v.v2.chanreq_head;
6773 if (!ocr) {
6774 ssh2_msg_unexpected(ssh, pktin);
837d6ba6 6775 return;
39d830e4 6776 }
6777 ocr->handler(c, pktin, ocr->ctx);
6778 c->v.v2.chanreq_head = ocr->next;
6779 sfree(ocr);
0e443c99 6780 /*
39d830e4 6781 * We may now initiate channel-closing procedures, if that
6782 * CHANNEL_REQUEST was the last thing outstanding before we send
6783 * CHANNEL_CLOSE.
0e443c99 6784 */
39d830e4 6785 ssh2_channel_check_close(c);
0e443c99 6786}
6787
51df0ab5 6788static void ssh2_msg_channel_window_adjust(Ssh ssh, struct Packet *pktin)
b09eaa88 6789{
b09eaa88 6790 struct ssh_channel *c;
e223b7c7 6791 c = ssh2_channel_msg(ssh, pktin);
6792 if (!c)
6793 return;
bc06669b 6794 if (!(c->closes & CLOSES_SENT_EOF)) {
b09eaa88 6795 c->v.v2.remwindow += ssh_pkt_getuint32(pktin);
78280721 6796 ssh2_try_send_and_unthrottle(ssh, c);
1bfc7e93 6797 }
b09eaa88 6798}
6799
51df0ab5 6800static void ssh2_msg_channel_data(Ssh ssh, struct Packet *pktin)
6801{
6802 char *data;
6d44acc9 6803 int length;
51df0ab5 6804 struct ssh_channel *c;
e223b7c7 6805 c = ssh2_channel_msg(ssh, pktin);
51df0ab5 6806 if (!c)
e223b7c7 6807 return;
51df0ab5 6808 if (pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
6809 ssh_pkt_getuint32(pktin) != SSH2_EXTENDED_DATA_STDERR)
6810 return; /* extended but not stderr */
6811 ssh_pkt_getstring(pktin, &data, &length);
6812 if (data) {
6813 int bufsize = 0;
6814 c->v.v2.locwindow -= length;
0e443c99 6815 c->v.v2.remlocwin -= length;
51df0ab5 6816 switch (c->type) {
6817 case CHAN_MAINSESSION:
6818 bufsize =
6819 from_backend(ssh->frontend, pktin->type ==
6820 SSH2_MSG_CHANNEL_EXTENDED_DATA,
6821 data, length);
6822 break;
6823 case CHAN_X11:
6824 bufsize = x11_send(c->u.x11.s, data, length);
6825 break;
6826 case CHAN_SOCKDATA:
6827 bufsize = pfd_send(c->u.pfd.s, data, length);
6828 break;
6829 case CHAN_AGENT:
6830 while (length > 0) {
6831 if (c->u.a.lensofar < 4) {
62ddb51e 6832 unsigned int l = min(4 - c->u.a.lensofar,
6833 (unsigned)length);
51df0ab5 6834 memcpy(c->u.a.msglen + c->u.a.lensofar,
6835 data, l);
6836 data += l;
6837 length -= l;
6838 c->u.a.lensofar += l;
6839 }
6840 if (c->u.a.lensofar == 4) {
6841 c->u.a.totallen =
6842 4 + GET_32BIT(c->u.a.msglen);
6843 c->u.a.message = snewn(c->u.a.totallen,
6844 unsigned char);
6845 memcpy(c->u.a.message, c->u.a.msglen, 4);
6846 }
6847 if (c->u.a.lensofar >= 4 && length > 0) {
aa63ab7e 6848 unsigned int l =
51df0ab5 6849 min(c->u.a.totallen - c->u.a.lensofar,
62ddb51e 6850 (unsigned)length);
51df0ab5 6851 memcpy(c->u.a.message + c->u.a.lensofar,
6852 data, l);
6853 data += l;
6854 length -= l;
6855 c->u.a.lensofar += l;
6856 }
6857 if (c->u.a.lensofar == c->u.a.totallen) {
6858 void *reply;
6859 int replylen;
be3f980d 6860 c->u.a.outstanding_requests++;
51df0ab5 6861 if (agent_query(c->u.a.message,
6862 c->u.a.totallen,
6863 &reply, &replylen,
6864 ssh_agentf_callback, c))
6865 ssh_agentf_callback(c, reply, replylen);
6866 sfree(c->u.a.message);
bc06669b 6867 c->u.a.message = NULL;
51df0ab5 6868 c->u.a.lensofar = 0;
6869 }
6870 }
6871 bufsize = 0;
6872 break;
6873 }
6874 /*
0e443c99 6875 * If it looks like the remote end hit the end of its window,
6876 * and we didn't want it to do that, think about using a
6877 * larger window.
6878 */
6879 if (c->v.v2.remlocwin <= 0 && c->v.v2.throttle_state == UNTHROTTLED &&
6880 c->v.v2.locmaxwin < 0x40000000)
6881 c->v.v2.locmaxwin += OUR_V2_WINSIZE;
6882 /*
51df0ab5 6883 * If we are not buffering too much data,
6884 * enlarge the window again at the remote side.
467e064d 6885 * If we are buffering too much, we may still
6886 * need to adjust the window if the server's
6887 * sent excess data.
51df0ab5 6888 */
9b53e9b8 6889 ssh2_set_window(c, bufsize < c->v.v2.locmaxwin ?
6890 c->v.v2.locmaxwin - bufsize : 0);
ff68564b 6891 /*
6892 * If we're either buffering way too much data, or if we're
6893 * buffering anything at all and we're in "simple" mode,
6894 * throttle the whole channel.
6895 */
6896 if ((bufsize > c->v.v2.locmaxwin ||
4a693cfc 6897 (conf_get_int(ssh->conf, CONF_ssh_simple) && bufsize > 0)) &&
ff68564b 6898 !c->throttling_conn) {
6899 c->throttling_conn = 1;
6900 ssh_throttle_conn(ssh, +1);
6901 }
51df0ab5 6902 }
6903}
6904
bc06669b 6905static void ssh_channel_destroy(struct ssh_channel *c)
51df0ab5 6906{
bc06669b 6907 Ssh ssh = c->ssh;
51df0ab5 6908
bc06669b 6909 switch (c->type) {
6910 case CHAN_MAINSESSION:
6911 ssh->mainchan = NULL;
6912 update_specials_menu(ssh->frontend);
6913 break;
6914 case CHAN_X11:
6915 if (c->u.x11.s != NULL)
6916 x11_close(c->u.x11.s);
6917 logevent("Forwarded X11 connection terminated");
6918 break;
6919 case CHAN_AGENT:
6920 sfree(c->u.a.message);
6921 break;
6922 case CHAN_SOCKDATA:
6923 if (c->u.pfd.s != NULL)
6924 pfd_close(c->u.pfd.s);
6925 logevent("Forwarded port closed");
6926 break;
6927 }
6928
6929 del234(ssh->channels, c);
3620f307 6930 if (ssh->version == 2) {
bc06669b 6931 bufchain_clear(&c->v.v2.outbuffer);
3620f307 6932 assert(c->v.v2.chanreq_head == NULL);
6933 }
bc06669b 6934 sfree(c);
6935
6936 /*
6937 * See if that was the last channel left open.
6938 * (This is only our termination condition if we're
6939 * not running in -N mode.)
6940 */
6941 if (ssh->version == 2 &&
6942 !conf_get_int(ssh->conf, CONF_ssh_no_shell) &&
6943 count234(ssh->channels) == 0) {
6944 /*
6945 * We used to send SSH_MSG_DISCONNECT here,
6946 * because I'd believed that _every_ conforming
6947 * SSH-2 connection had to end with a disconnect
6948 * being sent by at least one side; apparently
6949 * I was wrong and it's perfectly OK to
6950 * unceremoniously slam the connection shut
6951 * when you're done, and indeed OpenSSH feels
6952 * this is more polite than sending a
6953 * DISCONNECT. So now we don't.
6954 */
6955 ssh_disconnect(ssh, "All channels closed", NULL, 0, TRUE);
6956 }
6957}
6958
6959static void ssh2_channel_check_close(struct ssh_channel *c)
6960{
6961 Ssh ssh = c->ssh;
6962 struct Packet *pktout;
6963
04120005 6964 if ((!((CLOSES_SENT_EOF | CLOSES_RCVD_EOF) & ~c->closes) ||
6965 c->type == CHAN_ZOMBIE) &&
6966 !c->v.v2.chanreq_head &&
6967 !(c->closes & CLOSES_SENT_CLOSE)) {
bc06669b 6968 /*
04120005 6969 * We have both sent and received EOF (or the channel is a
6970 * zombie), and we have no outstanding channel requests, which
6971 * means the channel is in final wind-up. But we haven't sent
6972 * CLOSE, so let's do so now.
bc06669b 6973 */
6974 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6975 ssh2_pkt_adduint32(pktout, c->remoteid);
6976 ssh2_pkt_send(ssh, pktout);
04120005 6977 c->closes |= CLOSES_SENT_EOF | CLOSES_SENT_CLOSE;
bc06669b 6978 }
6979
6980 if (!((CLOSES_SENT_CLOSE | CLOSES_RCVD_CLOSE) & ~c->closes)) {
3620f307 6981 assert(c->v.v2.chanreq_head == NULL);
bc06669b 6982 /*
6983 * We have both sent and received CLOSE, which means we're
6984 * completely done with the channel.
6985 */
6986 ssh_channel_destroy(c);
6987 }
6988}
6989
6990static void ssh2_channel_got_eof(struct ssh_channel *c)
6991{
6992 if (c->closes & CLOSES_RCVD_EOF)
6993 return; /* already seen EOF */
6994 c->closes |= CLOSES_RCVD_EOF;
51df0ab5 6995
6996 if (c->type == CHAN_X11) {
bc06669b 6997 x11_send_eof(c->u.x11.s);
51df0ab5 6998 } else if (c->type == CHAN_AGENT) {
be3f980d 6999 if (c->u.a.outstanding_requests == 0) {
7000 /* Manufacture an outgoing EOF in response to the incoming one. */
7001 sshfwd_write_eof(c);
7002 }
51df0ab5 7003 } else if (c->type == CHAN_SOCKDATA) {
bc06669b 7004 pfd_send_eof(c->u.pfd.s);
7005 } else if (c->type == CHAN_MAINSESSION) {
7006 Ssh ssh = c->ssh;
7007
4a202fc6 7008 if (!ssh->sent_console_eof &&
7009 (from_backend_eof(ssh->frontend) || ssh->got_pty)) {
bc06669b 7010 /*
4a202fc6 7011 * Either from_backend_eof told us that the front end
7012 * wants us to close the outgoing side of the connection
7013 * as soon as we see EOF from the far end, or else we've
7014 * unilaterally decided to do that because we've allocated
7015 * a remote pty and hence EOF isn't a particularly
7016 * meaningful concept.
bc06669b 7017 */
7018 sshfwd_write_eof(c);
7019 }
7020 ssh->sent_console_eof = TRUE;
51df0ab5 7021 }
bc06669b 7022
7023 ssh2_channel_check_close(c);
7024}
7025
7026static void ssh2_msg_channel_eof(Ssh ssh, struct Packet *pktin)
7027{
7028 struct ssh_channel *c;
7029
7030 c = ssh2_channel_msg(ssh, pktin);
7031 if (!c)
7032 return;
7033 ssh2_channel_got_eof(c);
51df0ab5 7034}
7035
7036static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
7037{
51df0ab5 7038 struct ssh_channel *c;
51df0ab5 7039
e223b7c7 7040 c = ssh2_channel_msg(ssh, pktin);
7041 if (!c)
51df0ab5 7042 return;
51df0ab5 7043
7044 /*
bc06669b 7045 * When we receive CLOSE on a channel, we assume it comes with an
7046 * implied EOF if we haven't seen EOF yet.
51df0ab5 7047 */
bc06669b 7048 ssh2_channel_got_eof(c);
7049
7050 /*
3effbcf2 7051 * And we also send an outgoing EOF, if we haven't already, on the
7052 * assumption that CLOSE is a pretty forceful announcement that
7053 * the remote side is doing away with the entire channel. (If it
7054 * had wanted to send us EOF and continue receiving data from us,
7055 * it would have just sent CHANNEL_EOF.)
3effbcf2 7056 */
a699eb41 7057 if (!(c->closes & CLOSES_SENT_EOF)) {
7058 /*
7059 * Make sure we don't read any more from whatever our local
7060 * data source is for this channel.
7061 */
7062 switch (c->type) {
7063 case CHAN_MAINSESSION:
7064 ssh->send_ok = 0; /* stop trying to read from stdin */
7065 break;
7066 case CHAN_X11:
7067 x11_override_throttle(c->u.x11.s, 1);
7068 break;
7069 case CHAN_SOCKDATA:
7070 pfd_override_throttle(c->u.pfd.s, 1);
7071 break;
7072 }
7073
7074 /*
7075 * Send outgoing EOF.
7076 */
7539afa2 7077 sshfwd_write_eof(c);
3effbcf2 7078 }
7079
7080 /*
bc06669b 7081 * Now process the actual close.
7082 */
7083 if (!(c->closes & CLOSES_RCVD_CLOSE)) {
7084 c->closes |= CLOSES_RCVD_CLOSE;
7085 ssh2_channel_check_close(c);
51df0ab5 7086 }
7087}
7088
7089static void ssh2_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
7090{
51df0ab5 7091 struct ssh_channel *c;
51df0ab5 7092
e223b7c7 7093 c = ssh2_channel_msg(ssh, pktin);
51df0ab5 7094 if (!c)
e223b7c7 7095 return;
51df0ab5 7096 if (c->type != CHAN_SOCKDATA_DORMANT)
7097 return; /* dunno why they're confirming this */
7098 c->remoteid = ssh_pkt_getuint32(pktin);
64d6ff88 7099 c->halfopen = FALSE;
51df0ab5 7100 c->type = CHAN_SOCKDATA;
7101 c->v.v2.remwindow = ssh_pkt_getuint32(pktin);
7102 c->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
7103 if (c->u.pfd.s)
7104 pfd_confirm(c->u.pfd.s);
bc06669b 7105 if (c->pending_eof)
7106 ssh_channel_try_eof(c);
51df0ab5 7107}
7108
7109static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
7110{
7111 static const char *const reasons[] = {
7112 "<unknown reason code>",
7113 "Administratively prohibited",
7114 "Connect failed",
7115 "Unknown channel type",
7116 "Resource shortage",
7117 };
51df0ab5 7118 unsigned reason_code;
7119 char *reason_string;
7120 int reason_length;
51df0ab5 7121 struct ssh_channel *c;
e223b7c7 7122 c = ssh2_channel_msg(ssh, pktin);
51df0ab5 7123 if (!c)
e223b7c7 7124 return;
51df0ab5 7125 if (c->type != CHAN_SOCKDATA_DORMANT)
7126 return; /* dunno why they're failing this */
7127
7128 reason_code = ssh_pkt_getuint32(pktin);
7129 if (reason_code >= lenof(reasons))
7130 reason_code = 0; /* ensure reasons[reason_code] in range */
7131 ssh_pkt_getstring(pktin, &reason_string, &reason_length);
fb983202 7132 logeventf(ssh, "Forwarded connection refused by server: %s [%.*s]",
7133 reasons[reason_code], reason_length, reason_string);
51df0ab5 7134
7135 pfd_close(c->u.pfd.s);
7136
7137 del234(ssh->channels, c);
7138 sfree(c);
7139}
7140
7141static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin)
7142{
51df0ab5 7143 char *type;
7144 int typelen, want_reply;
7145 int reply = SSH2_MSG_CHANNEL_FAILURE; /* default */
7146 struct ssh_channel *c;
7147 struct Packet *pktout;
7148
e223b7c7 7149 c = ssh2_channel_msg(ssh, pktin);
7150 if (!c)
7151 return;
51df0ab5 7152 ssh_pkt_getstring(pktin, &type, &typelen);
7153 want_reply = ssh2_pkt_getbool(pktin);
7154
7155 /*
51df0ab5 7156 * Having got the channel number, we now look at
7157 * the request type string to see if it's something
7158 * we recognise.
7159 */
7160 if (c == ssh->mainchan) {
7161 /*
7162 * We recognise "exit-status" and "exit-signal" on
7163 * the primary channel.
7164 */
7165 if (typelen == 11 &&
7166 !memcmp(type, "exit-status", 11)) {
7167
7168 ssh->exitcode = ssh_pkt_getuint32(pktin);
7169 logeventf(ssh, "Server sent command exit status %d",
7170 ssh->exitcode);
7171 reply = SSH2_MSG_CHANNEL_SUCCESS;
7172
7173 } else if (typelen == 11 &&
7174 !memcmp(type, "exit-signal", 11)) {
7175
7176 int is_plausible = TRUE, is_int = FALSE;
7177 char *fmt_sig = "", *fmt_msg = "";
7178 char *msg;
7179 int msglen = 0, core = FALSE;
7180 /* ICK: older versions of OpenSSH (e.g. 3.4p1)
7181 * provide an `int' for the signal, despite its
bccbeb71 7182 * having been a `string' in the drafts of RFC 4254 since at
51df0ab5 7183 * least 2001. (Fixed in session.c 1.147.) Try to
7184 * infer which we can safely parse it as. */
7185 {
7186 unsigned char *p = pktin->body +
7187 pktin->savedpos;
7188 long len = pktin->length - pktin->savedpos;
7189 unsigned long num = GET_32BIT(p); /* what is it? */
7190 /* If it's 0, it hardly matters; assume string */
7191 if (num == 0) {
7192 is_int = FALSE;
7193 } else {
7194 int maybe_int = FALSE, maybe_str = FALSE;
7195#define CHECK_HYPOTHESIS(offset, result) \
7196 do { \
7197 long q = offset; \
7198 if (q >= 0 && q+4 <= len) { \
7199 q = q + 4 + GET_32BIT(p+q); \
7200 if (q >= 0 && q+4 <= len && \
c849ff23 7201 ((q = q + 4 + GET_32BIT(p+q))!= 0) && q == len) \
51df0ab5 7202 result = TRUE; \
7203 } \
7204 } while(0)
7205 CHECK_HYPOTHESIS(4+1, maybe_int);
7206 CHECK_HYPOTHESIS(4+num+1, maybe_str);
7207#undef CHECK_HYPOTHESIS
7208 if (maybe_int && !maybe_str)
7209 is_int = TRUE;
7210 else if (!maybe_int && maybe_str)
7211 is_int = FALSE;
7212 else
7213 /* Crikey. Either or neither. Panic. */
7214 is_plausible = FALSE;
7215 }
7216 }
d051d1b4 7217 ssh->exitcode = 128; /* means `unknown signal' */
51df0ab5 7218 if (is_plausible) {
7219 if (is_int) {
7220 /* Old non-standard OpenSSH. */
7221 int signum = ssh_pkt_getuint32(pktin);
7222 fmt_sig = dupprintf(" %d", signum);
d051d1b4 7223 ssh->exitcode = 128 + signum;
51df0ab5 7224 } else {
bccbeb71 7225 /* As per RFC 4254. */
51df0ab5 7226 char *sig;
7227 int siglen;
7228 ssh_pkt_getstring(pktin, &sig, &siglen);
7229 /* Signal name isn't supposed to be blank, but
7230 * let's cope gracefully if it is. */
7231 if (siglen) {
7232 fmt_sig = dupprintf(" \"%.*s\"",
7233 siglen, sig);
7234 }
d051d1b4 7235
7236 /*
7237 * Really hideous method of translating the
7238 * signal description back into a locally
7239 * meaningful number.
7240 */
7241
7242 if (0)
7243 ;
b707973a 7244#define TRANSLATE_SIGNAL(s) \
7245 else if (siglen == lenof(#s)-1 && !memcmp(sig, #s, siglen)) \
7246 ssh->exitcode = 128 + SIG ## s
d051d1b4 7247#ifdef SIGABRT
b707973a 7248 TRANSLATE_SIGNAL(ABRT);
d051d1b4 7249#endif
7250#ifdef SIGALRM
b707973a 7251 TRANSLATE_SIGNAL(ALRM);
d051d1b4 7252#endif
7253#ifdef SIGFPE
b707973a 7254 TRANSLATE_SIGNAL(FPE);
d051d1b4 7255#endif
7256#ifdef SIGHUP
b707973a 7257 TRANSLATE_SIGNAL(HUP);
d051d1b4 7258#endif
7259#ifdef SIGILL
b707973a 7260 TRANSLATE_SIGNAL(ILL);
d051d1b4 7261#endif
7262#ifdef SIGINT
b707973a 7263 TRANSLATE_SIGNAL(INT);
d051d1b4 7264#endif
7265#ifdef SIGKILL
b707973a 7266 TRANSLATE_SIGNAL(KILL);
d051d1b4 7267#endif
7268#ifdef SIGPIPE
b707973a 7269 TRANSLATE_SIGNAL(PIPE);
d051d1b4 7270#endif
7271#ifdef SIGQUIT
b707973a 7272 TRANSLATE_SIGNAL(QUIT);
d051d1b4 7273#endif
7274#ifdef SIGSEGV
b707973a 7275 TRANSLATE_SIGNAL(SEGV);
d051d1b4 7276#endif
7277#ifdef SIGTERM
b707973a 7278 TRANSLATE_SIGNAL(TERM);
d051d1b4 7279#endif
7280#ifdef SIGUSR1
b707973a 7281 TRANSLATE_SIGNAL(USR1);
d051d1b4 7282#endif
7283#ifdef SIGUSR2
b707973a 7284 TRANSLATE_SIGNAL(USR2);
d051d1b4 7285#endif
b707973a 7286#undef TRANSLATE_SIGNAL
d051d1b4 7287 else
7288 ssh->exitcode = 128;
51df0ab5 7289 }
7290 core = ssh2_pkt_getbool(pktin);
7291 ssh_pkt_getstring(pktin, &msg, &msglen);
7292 if (msglen) {
7293 fmt_msg = dupprintf(" (\"%.*s\")", msglen, msg);
7294 }
7295 /* ignore lang tag */
7296 } /* else don't attempt to parse */
7297 logeventf(ssh, "Server exited on signal%s%s%s",
7298 fmt_sig, core ? " (core dumped)" : "",
7299 fmt_msg);
7300 if (*fmt_sig) sfree(fmt_sig);
7301 if (*fmt_msg) sfree(fmt_msg);
7302 reply = SSH2_MSG_CHANNEL_SUCCESS;
7303
7304 }
7305 } else {
7306 /*
7307 * This is a channel request we don't know
7308 * about, so we now either ignore the request
7309 * or respond with CHANNEL_FAILURE, depending
7310 * on want_reply.
7311 */
7312 reply = SSH2_MSG_CHANNEL_FAILURE;
7313 }
7314 if (want_reply) {
7315 pktout = ssh2_pkt_init(reply);
7316 ssh2_pkt_adduint32(pktout, c->remoteid);
7317 ssh2_pkt_send(ssh, pktout);
7318 }
7319}
7320
7321static void ssh2_msg_global_request(Ssh ssh, struct Packet *pktin)
7322{
7323 char *type;
7324 int typelen, want_reply;
7325 struct Packet *pktout;
7326
7327 ssh_pkt_getstring(pktin, &type, &typelen);
7328 want_reply = ssh2_pkt_getbool(pktin);
7329
7330 /*
7331 * We currently don't support any global requests
7332 * at all, so we either ignore the request or
7333 * respond with REQUEST_FAILURE, depending on
7334 * want_reply.
7335 */
7336 if (want_reply) {
7337 pktout = ssh2_pkt_init(SSH2_MSG_REQUEST_FAILURE);
7338 ssh2_pkt_send(ssh, pktout);
7339 }
7340}
7341
7342static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin)
7343{
7344 char *type;
7345 int typelen;
7346 char *peeraddr;
7347 int peeraddrlen;
7348 int peerport;
7349 char *error = NULL;
7350 struct ssh_channel *c;
7351 unsigned remid, winsize, pktsize;
7352 struct Packet *pktout;
7353
7354 ssh_pkt_getstring(pktin, &type, &typelen);
7355 c = snew(struct ssh_channel);
7356 c->ssh = ssh;
7357
7358 remid = ssh_pkt_getuint32(pktin);
7359 winsize = ssh_pkt_getuint32(pktin);
7360 pktsize = ssh_pkt_getuint32(pktin);
7361
7362 if (typelen == 3 && !memcmp(type, "x11", 3)) {
7363 char *addrstr;
5907ebda 7364 const char *x11err;
51df0ab5 7365
7366 ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
7367 addrstr = snewn(peeraddrlen+1, char);
7368 memcpy(addrstr, peeraddr, peeraddrlen);
7369 addrstr[peeraddrlen] = '\0';
7370 peerport = ssh_pkt_getuint32(pktin);
7371
7372 logeventf(ssh, "Received X11 connect request from %s:%d",
7373 addrstr, peerport);
7374
7375 if (!ssh->X11_fwd_enabled)
7376 error = "X11 forwarding is not enabled";
5907ebda 7377 else if ((x11err = x11_init(&c->u.x11.s, ssh->x11disp, c,
4a693cfc 7378 addrstr, peerport, ssh->conf)) != NULL) {
5907ebda 7379 logeventf(ssh, "Local X11 connection failed: %s", x11err);
51df0ab5 7380 error = "Unable to open an X11 connection";
7381 } else {
7382 logevent("Opening X11 forward connection succeeded");
7383 c->type = CHAN_X11;
7384 }
7385
7386 sfree(addrstr);
7387 } else if (typelen == 15 &&
7388 !memcmp(type, "forwarded-tcpip", 15)) {
7389 struct ssh_rportfwd pf, *realpf;
7390 char *dummy;
7391 int dummylen;
7392 ssh_pkt_getstring(pktin, &dummy, &dummylen);/* skip address */
7393 pf.sport = ssh_pkt_getuint32(pktin);
7394 ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
7395 peerport = ssh_pkt_getuint32(pktin);
7396 realpf = find234(ssh->rportfwds, &pf, NULL);
7397 logeventf(ssh, "Received remote port %d open request "
7398 "from %s:%d", pf.sport, peeraddr, peerport);
7399 if (realpf == NULL) {
7400 error = "Remote port is not recognised";
7401 } else {
7402 const char *e = pfd_newconnect(&c->u.pfd.s,
7403 realpf->dhost,
7404 realpf->dport, c,
4a693cfc 7405 ssh->conf,
05581745 7406 realpf->pfrec->addressfamily);
51df0ab5 7407 logeventf(ssh, "Attempting to forward remote port to "
7408 "%s:%d", realpf->dhost, realpf->dport);
7409 if (e != NULL) {
7410 logeventf(ssh, "Port open failed: %s", e);
7411 error = "Port open failed";
7412 } else {
7413 logevent("Forwarded port opened successfully");
7414 c->type = CHAN_SOCKDATA;
7415 }
7416 }
7417 } else if (typelen == 22 &&
c49cf994 7418 !memcmp(type, "auth-agent@openssh.com", 22)) {
51df0ab5 7419 if (!ssh->agentfwd_enabled)
7420 error = "Agent forwarding is not enabled";
7421 else {
7422 c->type = CHAN_AGENT; /* identify channel type */
7423 c->u.a.lensofar = 0;
be3f980d 7424 c->u.a.outstanding_requests = 0;
51df0ab5 7425 }
7426 } else {
7427 error = "Unsupported channel type requested";
7428 }
7429
7430 c->remoteid = remid;
64d6ff88 7431 c->halfopen = FALSE;
51df0ab5 7432 if (error) {
7433 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_FAILURE);
7434 ssh2_pkt_adduint32(pktout, c->remoteid);
7435 ssh2_pkt_adduint32(pktout, SSH2_OPEN_CONNECT_FAILED);
7436 ssh2_pkt_addstring(pktout, error);
7437 ssh2_pkt_addstring(pktout, "en"); /* language tag */
7438 ssh2_pkt_send(ssh, pktout);
7439 logeventf(ssh, "Rejected channel open: %s", error);
7440 sfree(c);
7441 } else {
94bdfe40 7442 ssh2_channel_init(c);
51df0ab5 7443 c->v.v2.remwindow = winsize;
7444 c->v.v2.remmaxpkt = pktsize;
51df0ab5 7445 add234(ssh->channels, c);
7446 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
7447 ssh2_pkt_adduint32(pktout, c->remoteid);
7448 ssh2_pkt_adduint32(pktout, c->localid);
7449 ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);
954d5c5a 7450 ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
51df0ab5 7451 ssh2_pkt_send(ssh, pktout);
7452 }
7453}
7454
6bbce591 7455/*
adb6167a 7456 * Buffer banner messages for later display at some convenient point,
7457 * if we're going to display them.
6bbce591 7458 */
7459static void ssh2_msg_userauth_banner(Ssh ssh, struct Packet *pktin)
7460{
7461 /* Arbitrary limit to prevent unbounded inflation of buffer */
4a693cfc 7462 if (conf_get_int(ssh->conf, CONF_ssh_show_banner) &&
adb6167a 7463 bufchain_size(&ssh->banner) <= 131072) {
6bbce591 7464 char *banner = NULL;
7465 int size = 0;
7466 ssh_pkt_getstring(pktin, &banner, &size);
7467 if (banner)
7468 bufchain_add(&ssh->banner, banner, size);
7469 }
7470}
7471
c6ccd5c2 7472/* Helper function to deal with sending tty modes for "pty-req" */
7473static void ssh2_send_ttymode(void *data, char *mode, char *val)
7474{
7475 struct Packet *pktout = (struct Packet *)data;
7476 int i = 0;
7477 unsigned int arg = 0;
7478 while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
7479 if (i == lenof(ssh_ttymodes)) return;
7480 switch (ssh_ttymodes[i].type) {
7481 case TTY_OP_CHAR:
7482 arg = ssh_tty_parse_specchar(val);
7483 break;
7484 case TTY_OP_BOOL:
7485 arg = ssh_tty_parse_boolean(val);
7486 break;
7487 }
7488 ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
7489 ssh2_pkt_adduint32(pktout, arg);
7490}
7491
67a9ec92 7492static void ssh2_setup_x11(struct ssh_channel *c, struct Packet *pktin,
7493 void *ctx)
ebbc254d 7494{
67a9ec92 7495 struct ssh2_setup_x11_state {
ebbc254d 7496 int crLine;
7497 };
7498 Ssh ssh = c->ssh;
7499 struct Packet *pktout;
67a9ec92 7500 crStateP(ssh2_setup_x11_state, ctx);
ebbc254d 7501
7502 crBeginState;
7503
67a9ec92 7504 logevent("Requesting X11 forwarding");
7505 pktout = ssh2_chanreq_init(ssh->mainchan, "x11-req",
7506 ssh2_setup_x11, s);
7507 ssh2_pkt_addbool(pktout, 0); /* many connections */
7508 ssh2_pkt_addstring(pktout, ssh->x11disp->remoteauthprotoname);
ebbc254d 7509 /*
67a9ec92 7510 * Note that while we blank the X authentication data here, we don't
7511 * take any special action to blank the start of an X11 channel,
7512 * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
7513 * without having session blanking enabled is likely to leak your
7514 * cookie into the log.
ebbc254d 7515 */
67a9ec92 7516 dont_log_password(ssh, pktout, PKTLOG_BLANK);
7517 ssh2_pkt_addstring(pktout, ssh->x11disp->remoteauthdatastring);
7518 end_log_omission(ssh, pktout);
7519 ssh2_pkt_adduint32(pktout, ssh->x11disp->screennum);
7520 ssh2_pkt_send(ssh, pktout);
ebbc254d 7521
67a9ec92 7522 crWaitUntilV(pktin);
ebbc254d 7523
67a9ec92 7524 if (pktin) {
7525 if (pktin->type == SSH2_MSG_CHANNEL_SUCCESS) {
7526 logevent("X11 forwarding enabled");
7527 ssh->X11_fwd_enabled = TRUE;
7528 } else
7529 logevent("X11 forwarding refused");
ebbc254d 7530 }
67a9ec92 7531
0d201bfb 7532 crFinishFreeV;
ebbc254d 7533}
7534
67a9ec92 7535static void ssh2_setup_agent(struct ssh_channel *c, struct Packet *pktin,
ebbc254d 7536 void *ctx)
7537{
67a9ec92 7538 struct ssh2_setup_agent_state {
ebbc254d 7539 int crLine;
7540 };
7541 Ssh ssh = c->ssh;
7542 struct Packet *pktout;
67a9ec92 7543 crStateP(ssh2_setup_agent_state, ctx);
ebbc254d 7544
7545 crBeginState;
7546
67a9ec92 7547 logevent("Requesting OpenSSH-style agent forwarding");
7548 pktout = ssh2_chanreq_init(ssh->mainchan, "auth-agent-req@openssh.com",
7549 ssh2_setup_agent, s);
7550 ssh2_pkt_send(ssh, pktout);
ebbc254d 7551
67a9ec92 7552 crWaitUntilV(pktin);
ebbc254d 7553
67a9ec92 7554 if (pktin) {
7555 if (pktin->type == SSH2_MSG_CHANNEL_SUCCESS) {
7556 logevent("Agent forwarding enabled");
7557 ssh->agentfwd_enabled = TRUE;
7558 } else
7559 logevent("Agent forwarding refused");
ebbc254d 7560 }
67a9ec92 7561
0d201bfb 7562 crFinishFreeV;
ebbc254d 7563}
7564
67a9ec92 7565static void ssh2_setup_pty(struct ssh_channel *c, struct Packet *pktin,
ebbc254d 7566 void *ctx)
7567{
67a9ec92 7568 struct ssh2_setup_pty_state {
ebbc254d 7569 int crLine;
7570 };
7571 Ssh ssh = c->ssh;
7572 struct Packet *pktout;
67a9ec92 7573 crStateP(ssh2_setup_pty_state, ctx);
ebbc254d 7574
7575 crBeginState;
7576
67a9ec92 7577 /* Unpick the terminal-speed string. */
7578 /* XXX perhaps we should allow no speeds to be sent. */
7579 ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
7580 sscanf(conf_get_str(ssh->conf, CONF_termspeed), "%d,%d", &ssh->ospeed, &ssh->ispeed);
7581 /* Build the pty request. */
7582 pktout = ssh2_chanreq_init(ssh->mainchan, "pty-req",
7583 ssh2_setup_pty, s);
7584 ssh2_pkt_addstring(pktout, conf_get_str(ssh->conf, CONF_termtype));
7585 ssh2_pkt_adduint32(pktout, ssh->term_width);
7586 ssh2_pkt_adduint32(pktout, ssh->term_height);
7587 ssh2_pkt_adduint32(pktout, 0); /* pixel width */
7588 ssh2_pkt_adduint32(pktout, 0); /* pixel height */
7589 ssh2_pkt_addstring_start(pktout);
7590 parse_ttymodes(ssh, ssh2_send_ttymode, (void *)pktout);
7591 ssh2_pkt_addbyte(pktout, SSH2_TTY_OP_ISPEED);
7592 ssh2_pkt_adduint32(pktout, ssh->ispeed);
7593 ssh2_pkt_addbyte(pktout, SSH2_TTY_OP_OSPEED);
7594 ssh2_pkt_adduint32(pktout, ssh->ospeed);
7595 ssh2_pkt_addstring_data(pktout, "\0", 1); /* TTY_OP_END */
7596 ssh2_pkt_send(ssh, pktout);
7597 ssh->state = SSH_STATE_INTERMED;
ebbc254d 7598
67a9ec92 7599 crWaitUntilV(pktin);
ebbc254d 7600
67a9ec92 7601 if (pktin) {
7602 if (pktin->type == SSH2_MSG_CHANNEL_SUCCESS) {
7603 logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
7604 ssh->ospeed, ssh->ispeed);
7605 ssh->got_pty = TRUE;
7606 } else {
7607 c_write_str(ssh, "Server refused to allocate pty\r\n");
7608 ssh->editing = ssh->echoing = 1;
7609 }
ebbc254d 7610 }
67a9ec92 7611
0d201bfb 7612 crFinishFreeV;
ebbc254d 7613}
7614
7615static void ssh2_setup_env(struct ssh_channel *c, struct Packet *pktin,
7616 void *ctx)
7617{
7618 struct ssh2_setup_env_state {
7619 int crLine;
7620 int num_env, env_left, env_ok;
7621 };
7622 Ssh ssh = c->ssh;
7623 struct Packet *pktout;
7624 crStateP(ssh2_setup_env_state, ctx);
7625
7626 crBeginState;
7627
7628 /*
7629 * Send environment variables.
7630 *
7631 * Simplest thing here is to send all the requests at once, and
7632 * then wait for a whole bunch of successes or failures.
7633 */
7634 s->num_env = 0;
67a9ec92 7635 {
ebbc254d 7636 char *key, *val;
7637
7638 for (val = conf_get_str_strs(ssh->conf, CONF_environmt, NULL, &key);
7639 val != NULL;
7640 val = conf_get_str_strs(ssh->conf, CONF_environmt, key, &key)) {
134f5ece 7641 pktout = ssh2_chanreq_init(ssh->mainchan, "env", ssh2_setup_env, s);
ebbc254d 7642 ssh2_pkt_addstring(pktout, key);
7643 ssh2_pkt_addstring(pktout, val);
7644 ssh2_pkt_send(ssh, pktout);
ebbc254d 7645
7646 s->num_env++;
7647 }
7648 if (s->num_env)
7649 logeventf(ssh, "Sent %d environment variables", s->num_env);
7650 }
7651
7652 if (s->num_env) {
7653 s->env_ok = 0;
7654 s->env_left = s->num_env;
7655
7656 while (s->env_left > 0) {
7657 crWaitUntilV(pktin);
3620f307 7658 if (!pktin) goto out;
c330b1cc 7659 if (pktin->type == SSH2_MSG_CHANNEL_SUCCESS)
ebbc254d 7660 s->env_ok++;
ebbc254d 7661 s->env_left--;
7662 }
7663
7664 if (s->env_ok == s->num_env) {
7665 logevent("All environment variables successfully set");
7666 } else if (s->env_ok == 0) {
7667 logevent("All environment variables refused");
7668 c_write_str(ssh, "Server refused to set environment variables\r\n");
7669 } else {
7670 logeventf(ssh, "%d environment variables refused",
7671 s->num_env - s->env_ok);
7672 c_write_str(ssh, "Server refused to set all environment variables\r\n");
7673 }
7674 }
5ca12719 7675 out:;
0d201bfb 7676 crFinishFreeV;
ebbc254d 7677}
7678
783415f8 7679/*
2e85c969 7680 * Handle the SSH-2 userauth and connection layers.
7cca0d81 7681 */
bc074147 7682static void ssh2_msg_authconn(Ssh ssh, struct Packet *pktin)
7683{
7684 do_ssh2_authconn(ssh, NULL, 0, pktin);
7685}
7686
ebbc254d 7687static void ssh2_response_authconn(struct ssh_channel *c, struct Packet *pktin,
7688 void *ctx)
7689{
7690 do_ssh2_authconn(c->ssh, NULL, 0, pktin);
7691}
7692
ff3187f6 7693static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
7694 struct Packet *pktin)
7cca0d81 7695{
51470298 7696 struct do_ssh2_authconn_state {
30919997 7697 int crLine;
51470298 7698 enum {
51470298 7699 AUTH_TYPE_NONE,
7700 AUTH_TYPE_PUBLICKEY,
7701 AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
7702 AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
7703 AUTH_TYPE_PASSWORD,
8221906d 7704 AUTH_TYPE_GSSAPI, /* always QUIET */
51470298 7705 AUTH_TYPE_KEYBOARD_INTERACTIVE,
7706 AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
7707 } type;
a1a1fae4 7708 int done_service_req;
51470298 7709 int gotit, need_pw, can_pubkey, can_passwd, can_keyb_inter;
94cd7c3a 7710 int tried_pubkey_config, done_agent;
bf84a03a 7711#ifndef NO_GSSAPI
42af6a67 7712 int can_gssapi;
7713 int tried_gssapi;
bf84a03a 7714#endif
edd0cb8a 7715 int kbd_inter_refused;
ab18ccff 7716 int we_are_in, userauth_success;
edd0cb8a 7717 prompts_t *cur_prompt;
7718 int num_prompts;
4a693cfc 7719 char *username;
e955d348 7720 char *password;
51470298 7721 int got_username;
51470298 7722 void *publickey_blob;
7723 int publickey_bloblen;
edd0cb8a 7724 int publickey_encrypted;
7725 char *publickey_algorithm;
7726 char *publickey_comment;
94cd7c3a 7727 unsigned char agent_request[5], *agent_response, *agentp;
7728 int agent_responselen;
7729 unsigned char *pkblob_in_agent;
51470298 7730 int keyi, nkeys;
51470298 7731 char *pkblob, *alg, *commentp;
7732 int pklen, alglen, commentlen;
7733 int siglen, retlen, len;
7734 char *q, *agentreq, *ret;
7735 int try_send;
ff3187f6 7736 struct Packet *pktout;
4a693cfc 7737 Filename *keyfile;
bf84a03a 7738#ifndef NO_GSSAPI
b3d375b2 7739 struct ssh_gss_library *gsslib;
42af6a67 7740 Ssh_gss_ctx gss_ctx;
7741 Ssh_gss_buf gss_buf;
7742 Ssh_gss_buf gss_rcvtok, gss_sndtok;
7743 Ssh_gss_name gss_srv_name;
7744 Ssh_gss_stat gss_stat;
bf84a03a 7745#endif
51470298 7746 };
7747 crState(do_ssh2_authconn_state);
7748
30919997 7749 crBeginState;
e5574168 7750
bc074147 7751 /* Register as a handler for all the messages this coroutine handles. */
7752 ssh->packet_dispatch[SSH2_MSG_SERVICE_ACCEPT] = ssh2_msg_authconn;
7753 ssh->packet_dispatch[SSH2_MSG_USERAUTH_REQUEST] = ssh2_msg_authconn;
7754 ssh->packet_dispatch[SSH2_MSG_USERAUTH_FAILURE] = ssh2_msg_authconn;
7755 ssh->packet_dispatch[SSH2_MSG_USERAUTH_SUCCESS] = ssh2_msg_authconn;
7756 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = ssh2_msg_authconn;
7757 ssh->packet_dispatch[SSH2_MSG_USERAUTH_PK_OK] = ssh2_msg_authconn;
7758 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ] = ssh2_msg_authconn; duplicate case value */
7759 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_REQUEST] = ssh2_msg_authconn; duplicate case value */
7760 ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_RESPONSE] = ssh2_msg_authconn;
7761 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] = ssh2_msg_authconn;
7762 ssh->packet_dispatch[SSH2_MSG_REQUEST_SUCCESS] = ssh2_msg_authconn;
7763 ssh->packet_dispatch[SSH2_MSG_REQUEST_FAILURE] = ssh2_msg_authconn;
7764 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = ssh2_msg_authconn;
7765 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] = ssh2_msg_authconn;
7766 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] = ssh2_msg_authconn;
7767 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] = ssh2_msg_authconn;
7768 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] = ssh2_msg_authconn;
7769 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] = ssh2_msg_authconn;
7770 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_authconn;
7771 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_authconn;
bc074147 7772
a1a1fae4 7773 s->done_service_req = FALSE;
ab18ccff 7774 s->we_are_in = s->userauth_success = FALSE;
bf84a03a 7775#ifndef NO_GSSAPI
42af6a67 7776 s->tried_gssapi = FALSE;
bf84a03a 7777#endif
42af6a67 7778
4a693cfc 7779 if (!conf_get_int(ssh->conf, CONF_ssh_no_userauth)) {
a1a1fae4 7780 /*
7781 * Request userauth protocol, and await a response to it.
7782 */
7783 s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
7784 ssh2_pkt_addstring(s->pktout, "ssh-userauth");
7785 ssh2_pkt_send(ssh, s->pktout);
7786 crWaitUntilV(pktin);
7787 if (pktin->type == SSH2_MSG_SERVICE_ACCEPT)
7788 s->done_service_req = TRUE;
7789 }
7790 if (!s->done_service_req) {
7791 /*
7792 * Request connection protocol directly, without authentication.
7793 */
7794 s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
7795 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7796 ssh2_pkt_send(ssh, s->pktout);
7797 crWaitUntilV(pktin);
7798 if (pktin->type == SSH2_MSG_SERVICE_ACCEPT) {
7799 s->we_are_in = TRUE; /* no auth required */
7800 } else {
7801 bombout(("Server refused service request"));
7802 crStopV;
7803 }
8d5de777 7804 }
7cca0d81 7805
94cd7c3a 7806 /* Arrange to be able to deal with any BANNERs that come in.
7807 * (We do this now as packets may come in during the next bit.) */
7808 bufchain_init(&ssh->banner);
7809 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] =
7810 ssh2_msg_userauth_banner;
7811
7cca0d81 7812 /*
edd0cb8a 7813 * Misc one-time setup for authentication.
7814 */
7815 s->publickey_blob = NULL;
7816 if (!s->we_are_in) {
7817
7818 /*
7819 * Load the public half of any configured public key file
7820 * for later use.
7821 */
4a693cfc 7822 s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
962468d4 7823 if (!filename_is_null(s->keyfile)) {
edd0cb8a 7824 int keytype;
7825 logeventf(ssh, "Reading private key file \"%.150s\"",
4a693cfc 7826 filename_to_str(s->keyfile));
7827 keytype = key_type(s->keyfile);
edd0cb8a 7828 if (keytype == SSH_KEYTYPE_SSH2) {
7829 const char *error;
7830 s->publickey_blob =
4a693cfc 7831 ssh2_userkey_loadpub(s->keyfile,
edd0cb8a 7832 &s->publickey_algorithm,
7833 &s->publickey_bloblen,
7834 &s->publickey_comment, &error);
7835 if (s->publickey_blob) {
7836 s->publickey_encrypted =
4a693cfc 7837 ssh2_userkey_encrypted(s->keyfile, NULL);
edd0cb8a 7838 } else {
7839 char *msgbuf;
7840 logeventf(ssh, "Unable to load private key (%s)",
7841 error);
7842 msgbuf = dupprintf("Unable to load private key file "
7843 "\"%.150s\" (%s)\r\n",
4a693cfc 7844 filename_to_str(s->keyfile),
edd0cb8a 7845 error);
7846 c_write_str(ssh, msgbuf);
7847 sfree(msgbuf);
7848 }
7849 } else {
7850 char *msgbuf;
7851 logeventf(ssh, "Unable to use this key file (%s)",
7852 key_type_to_str(keytype));
7853 msgbuf = dupprintf("Unable to use key file \"%.150s\""
7854 " (%s)\r\n",
4a693cfc 7855 filename_to_str(s->keyfile),
edd0cb8a 7856 key_type_to_str(keytype));
7857 c_write_str(ssh, msgbuf);
7858 sfree(msgbuf);
7859 s->publickey_blob = NULL;
7860 }
7861 }
7862
94cd7c3a 7863 /*
7864 * Find out about any keys Pageant has (but if there's a
7865 * public key configured, filter out all others).
7866 */
7867 s->nkeys = 0;
7868 s->agent_response = NULL;
7869 s->pkblob_in_agent = NULL;
4a693cfc 7870 if (conf_get_int(ssh->conf, CONF_tryagent) && agent_exists()) {
94cd7c3a 7871
7872 void *r;
7873
7874 logevent("Pageant is running. Requesting keys.");
7875
7876 /* Request the keys held by the agent. */
7877 PUT_32BIT(s->agent_request, 1);
7878 s->agent_request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
7879 if (!agent_query(s->agent_request, 5, &r, &s->agent_responselen,
7880 ssh_agent_callback, ssh)) {
7881 do {
7882 crReturnV;
7883 if (pktin) {
7884 bombout(("Unexpected data from server while"
7885 " waiting for agent response"));
7886 crStopV;
7887 }
7888 } while (pktin || inlen > 0);
7889 r = ssh->agent_response;
7890 s->agent_responselen = ssh->agent_response_len;
7891 }
7892 s->agent_response = (unsigned char *) r;
7893 if (s->agent_response && s->agent_responselen >= 5 &&
7894 s->agent_response[4] == SSH2_AGENT_IDENTITIES_ANSWER) {
7895 int keyi;
7896 unsigned char *p;
7897 p = s->agent_response + 5;
7898 s->nkeys = GET_32BIT(p);
7899 p += 4;
7900 logeventf(ssh, "Pageant has %d SSH-2 keys", s->nkeys);
7901 if (s->publickey_blob) {
7902 /* See if configured key is in agent. */
7903 for (keyi = 0; keyi < s->nkeys; keyi++) {
7904 s->pklen = GET_32BIT(p);
7905 if (s->pklen == s->publickey_bloblen &&
7906 !memcmp(p+4, s->publickey_blob,
7907 s->publickey_bloblen)) {
7908 logeventf(ssh, "Pageant key #%d matches "
7909 "configured key file", keyi);
7910 s->keyi = keyi;
7911 s->pkblob_in_agent = p;
7912 break;
7913 }
7914 p += 4 + s->pklen;
7915 p += GET_32BIT(p) + 4; /* comment */
7916 }
7917 if (!s->pkblob_in_agent) {
7918 logevent("Configured key file not in Pageant");
7919 s->nkeys = 0;
7920 }
7921 }
5ff99b8e 7922 } else {
7923 logevent("Failed to get reply from Pageant");
94cd7c3a 7924 }
7925 }
7926
edd0cb8a 7927 }
7928
7929 /*
1408a877 7930 * We repeat this whole loop, including the username prompt,
7931 * until we manage a successful authentication. If the user
51470298 7932 * types the wrong _password_, they can be sent back to the
7933 * beginning to try another username, if this is configured on.
7934 * (If they specify a username in the config, they are never
7935 * asked, even if they do give a wrong password.)
1408a877 7936 *
7937 * I think this best serves the needs of
7938 *
7939 * - the people who have no configuration, no keys, and just
7940 * want to try repeated (username,password) pairs until they
7941 * type both correctly
7942 *
7943 * - people who have keys and configuration but occasionally
7944 * need to fall back to passwords
7945 *
7946 * - people with a key held in Pageant, who might not have
7947 * logged in to a particular machine before; so they want to
7948 * type a username, and then _either_ their key will be
7949 * accepted, _or_ they will type a password. If they mistype
7950 * the username they will want to be able to get back and
7951 * retype it!
7cca0d81 7952 */
51470298 7953 s->got_username = FALSE;
a1a1fae4 7954 while (!s->we_are_in) {
1408a877 7955 /*
7956 * Get a username.
7957 */
4a693cfc 7958 if (s->got_username && !conf_get_int(ssh->conf, CONF_change_username)) {
5bb641e1 7959 /*
7960 * We got a username last time round this loop, and
7961 * with change_username turned off we don't try to get
7962 * it again.
7963 */
4a693cfc 7964 } else if ((ssh->username = get_remote_username(ssh->conf)) == NULL) {
edd0cb8a 7965 int ret; /* need not be kept over crReturn */
7966 s->cur_prompt = new_prompts(ssh->frontend);
7967 s->cur_prompt->to_server = TRUE;
7968 s->cur_prompt->name = dupstr("SSH login name");
b61f81bc 7969 add_prompt(s->cur_prompt, dupstr("login as: "), TRUE);
edd0cb8a 7970 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7971 while (ret < 0) {
51470298 7972 ssh->send_ok = 1;
edd0cb8a 7973 crWaitUntilV(!pktin);
7974 ret = get_userpass_input(s->cur_prompt, in, inlen);
7975 ssh->send_ok = 0;
32874aea 7976 }
edd0cb8a 7977 if (!ret) {
7978 /*
7979 * get_userpass_input() failed to get a username.
7980 * Terminate.
7981 */
7982 free_prompts(s->cur_prompt);
7983 ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
7984 crStopV;
7985 }
4a693cfc 7986 ssh->username = dupstr(s->cur_prompt->prompts[0]->result);
edd0cb8a 7987 free_prompts(s->cur_prompt);
7cca0d81 7988 } else {
57356d63 7989 char *stuff;
65a22376 7990 if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
4a693cfc 7991 stuff = dupprintf("Using username \"%s\".\r\n", ssh->username);
51470298 7992 c_write_str(ssh, stuff);
57356d63 7993 sfree(stuff);
7cca0d81 7994 }
7995 }
51470298 7996 s->got_username = TRUE;
7cca0d81 7997
65a22376 7998 /*
1408a877 7999 * Send an authentication request using method "none": (a)
8000 * just in case it succeeds, and (b) so that we know what
8001 * authentication methods we can usefully try next.
65a22376 8002 */
acab36bc 8003 ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
51470298 8004
ff3187f6 8005 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
4a693cfc 8006 ssh2_pkt_addstring(s->pktout, ssh->username);
ff3187f6 8007 ssh2_pkt_addstring(s->pktout, "ssh-connection");/* service requested */
8008 ssh2_pkt_addstring(s->pktout, "none"); /* method */
8009 ssh2_pkt_send(ssh, s->pktout);
51470298 8010 s->type = AUTH_TYPE_NONE;
8011 s->gotit = FALSE;
8012 s->we_are_in = FALSE;
8013
8014 s->tried_pubkey_config = FALSE;
6ac3a551 8015 s->kbd_inter_refused = FALSE;
65a22376 8016
94cd7c3a 8017 /* Reset agent request state. */
8018 s->done_agent = FALSE;
8019 if (s->agent_response) {
8020 if (s->pkblob_in_agent) {
8021 s->agentp = s->pkblob_in_agent;
8022 } else {
8023 s->agentp = s->agent_response + 5 + 4;
8024 s->keyi = 0;
8025 }
8026 }
8027
1408a877 8028 while (1) {
854caca5 8029 char *methods = NULL;
8030 int methlen = 0;
8031
1408a877 8032 /*
8033 * Wait for the result of the last authentication request.
8034 */
51470298 8035 if (!s->gotit)
ff3187f6 8036 crWaitUntilV(pktin);
6bbce591 8037 /*
8038 * Now is a convenient point to spew any banner material
8039 * that we've accumulated. (This should ensure that when
8040 * we exit the auth loop, we haven't any left to deal
8041 * with.)
8042 */
8043 {
8044 int size = bufchain_size(&ssh->banner);
32874aea 8045 /*
8046 * Don't show the banner if we're operating in
8047 * non-verbose non-interactive mode. (It's probably
8048 * a script, which means nobody will read the
8049 * banner _anyway_, and moreover the printing of
8050 * the banner will screw up processing on the
8051 * output of (say) plink.)
8052 */
6bbce591 8053 if (size && (flags & (FLAG_VERBOSE | FLAG_INTERACTIVE))) {
8054 char *banner = snewn(size, char);
8055 bufchain_fetch(&ssh->banner, banner, size);
8056 c_write_untrusted(ssh, banner, size);
8057 sfree(banner);
32874aea 8058 }
6bbce591 8059 bufchain_clear(&ssh->banner);
1408a877 8060 }
ff3187f6 8061 if (pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
1408a877 8062 logevent("Access granted");
ab18ccff 8063 s->we_are_in = s->userauth_success = TRUE;
1408a877 8064 break;
8065 }
65a22376 8066
42af6a67 8067 if (pktin->type != SSH2_MSG_USERAUTH_FAILURE && s->type != AUTH_TYPE_GSSAPI) {
e955d348 8068 bombout(("Strange packet received during authentication: "
8069 "type %d", pktin->type));
7ffdbc1a 8070 crStopV;
65a22376 8071 }
8072
51470298 8073 s->gotit = FALSE;
65a22376 8074
1408a877 8075 /*
8076 * OK, we're now sitting on a USERAUTH_FAILURE message, so
8077 * we can look at the string in it and know what we can
8078 * helpfully try next.
8079 */
ff3187f6 8080 if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
ff3187f6 8081 ssh_pkt_getstring(pktin, &methods, &methlen);
ff3187f6 8082 if (!ssh2_pkt_getbool(pktin)) {
1408a877 8083 /*
8084 * We have received an unequivocal Access
8085 * Denied. This can translate to a variety of
8221906d 8086 * messages, or no message at all.
8087 *
8088 * For forms of authentication which are attempted
8089 * implicitly, by which I mean without printing
8090 * anything in the window indicating that we're
8091 * trying them, we should never print 'Access
8092 * denied'.
8093 *
8094 * If we do print a message saying that we're
8095 * attempting some kind of authentication, it's OK
8096 * to print a followup message saying it failed -
8097 * but the message may sometimes be more specific
8098 * than simply 'Access denied'.
8099 *
1408a877 8100 * Additionally, if we'd just tried password
8101 * authentication, we should break out of this
8102 * whole loop so as to go back to the username
91f57d1f 8103 * prompt (iff we're configured to allow
8104 * username change attempts).
1408a877 8105 */
51470298 8106 if (s->type == AUTH_TYPE_NONE) {
1408a877 8107 /* do nothing */
51470298 8108 } else if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
8109 s->type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
8110 if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
8111 c_write_str(ssh, "Server refused our key\r\n");
8221906d 8112 logevent("Server refused our key");
8113 } else if (s->type == AUTH_TYPE_PUBLICKEY) {
8114 /* This _shouldn't_ happen except by a
8115 * protocol bug causing client and server to
8116 * disagree on what is a correct signature. */
8117 c_write_str(ssh, "Server refused public-key signature"
8118 " despite accepting key!\r\n");
8119 logevent("Server refused public-key signature"
8120 " despite accepting key!");
51470298 8121 } else if (s->type==AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET) {
8221906d 8122 /* quiet, so no c_write */
8123 logevent("Server refused keyboard-interactive authentication");
8124 } else if (s->type==AUTH_TYPE_GSSAPI) {
8125 /* always quiet, so no c_write */
2af4fe8f 8126 /* also, the code down in the GSSAPI block has
8127 * already logged this in the Event Log */
8221906d 8128 } else if (s->type == AUTH_TYPE_KEYBOARD_INTERACTIVE) {
8129 logevent("Keyboard-interactive authentication failed");
8130 c_write_str(ssh, "Access denied\r\n");
8131 } else {
8132 assert(s->type == AUTH_TYPE_PASSWORD);
8133 logevent("Password authentication failed");
51470298 8134 c_write_str(ssh, "Access denied\r\n");
8221906d 8135
8136 if (conf_get_int(ssh->conf, CONF_change_username)) {
6c9dce7c 8137 /* XXX perhaps we should allow
8138 * keyboard-interactive to do this too? */
51470298 8139 s->we_are_in = FALSE;
1408a877 8140 break;
8141 }
8142 }
8143 } else {
51470298 8144 c_write_str(ssh, "Further authentication required\r\n");
1408a877 8145 logevent("Further authentication required");
8146 }
65a22376 8147
51470298 8148 s->can_pubkey =
32874aea 8149 in_commasep_string("publickey", methods, methlen);
51470298 8150 s->can_passwd =
32874aea 8151 in_commasep_string("password", methods, methlen);
4a693cfc 8152 s->can_keyb_inter = conf_get_int(ssh->conf, CONF_try_ki_auth) &&
761187b6 8153 in_commasep_string("keyboard-interactive", methods, methlen);
1e00c92b 8154#ifndef NO_GSSAPI
8155 if (!ssh->gsslibs)
4a693cfc 8156 ssh->gsslibs = ssh_gss_setup(ssh->conf);
8157 s->can_gssapi = conf_get_int(ssh->conf, CONF_try_gssapi_auth) &&
b3d375b2 8158 in_commasep_string("gssapi-with-mic", methods, methlen) &&
1e00c92b 8159 ssh->gsslibs->nlibraries > 0;
42af6a67 8160#endif
1408a877 8161 }
65a22376 8162
acab36bc 8163 ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
65a22376 8164
94cd7c3a 8165 if (s->can_pubkey && !s->done_agent && s->nkeys) {
0405e71f 8166
1983e559 8167 /*
94cd7c3a 8168 * Attempt public-key authentication using a key from Pageant.
1983e559 8169 */
1983e559 8170
acab36bc 8171 ssh->pkt_actx = SSH2_PKTCTX_PUBLICKEY;
00db133f 8172
94cd7c3a 8173 logeventf(ssh, "Trying Pageant key #%d", s->keyi);
8174
8175 /* Unpack key from agent response */
8176 s->pklen = GET_32BIT(s->agentp);
8177 s->agentp += 4;
8178 s->pkblob = (char *)s->agentp;
8179 s->agentp += s->pklen;
8180 s->alglen = GET_32BIT(s->pkblob);
8181 s->alg = s->pkblob + 4;
8182 s->commentlen = GET_32BIT(s->agentp);
8183 s->agentp += 4;
8184 s->commentp = (char *)s->agentp;
8185 s->agentp += s->commentlen;
8186 /* s->agentp now points at next key, if any */
8187
8188 /* See if server will accept it */
8189 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
4a693cfc 8190 ssh2_pkt_addstring(s->pktout, ssh->username);
94cd7c3a 8191 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8192 /* service requested */
8193 ssh2_pkt_addstring(s->pktout, "publickey");
8194 /* method */
8195 ssh2_pkt_addbool(s->pktout, FALSE); /* no signature included */
8196 ssh2_pkt_addstring_start(s->pktout);
8197 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
8198 ssh2_pkt_addstring_start(s->pktout);
8199 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
8200 ssh2_pkt_send(ssh, s->pktout);
8201 s->type = AUTH_TYPE_PUBLICKEY_OFFER_QUIET;
1983e559 8202
94cd7c3a 8203 crWaitUntilV(pktin);
8204 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
1983e559 8205
94cd7c3a 8206 /* Offer of key refused. */
8207 s->gotit = TRUE;
1983e559 8208
94cd7c3a 8209 } else {
8210
8211 void *vret;
1983e559 8212
94cd7c3a 8213 if (flags & FLAG_VERBOSE) {
8214 c_write_str(ssh, "Authenticating with "
8215 "public key \"");
8216 c_write(ssh, s->commentp, s->commentlen);
8217 c_write_str(ssh, "\" from agent\r\n");
8218 }
1983e559 8219
94cd7c3a 8220 /*
8221 * Server is willing to accept the key.
8222 * Construct a SIGN_REQUEST.
8223 */
8224 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
4a693cfc 8225 ssh2_pkt_addstring(s->pktout, ssh->username);
94cd7c3a 8226 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8227 /* service requested */
8228 ssh2_pkt_addstring(s->pktout, "publickey");
8229 /* method */
8230 ssh2_pkt_addbool(s->pktout, TRUE); /* signature included */
8231 ssh2_pkt_addstring_start(s->pktout);
8232 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
8233 ssh2_pkt_addstring_start(s->pktout);
8234 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
8235
8236 /* Ask agent for signature. */
8237 s->siglen = s->pktout->length - 5 + 4 +
8238 ssh->v2_session_id_len;
8239 if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
8240 s->siglen -= 4;
8241 s->len = 1; /* message type */
8242 s->len += 4 + s->pklen; /* key blob */
8243 s->len += 4 + s->siglen; /* data to sign */
8244 s->len += 4; /* flags */
8245 s->agentreq = snewn(4 + s->len, char);
8246 PUT_32BIT(s->agentreq, s->len);
8247 s->q = s->agentreq + 4;
8248 *s->q++ = SSH2_AGENTC_SIGN_REQUEST;
8249 PUT_32BIT(s->q, s->pklen);
8250 s->q += 4;
8251 memcpy(s->q, s->pkblob, s->pklen);
8252 s->q += s->pklen;
8253 PUT_32BIT(s->q, s->siglen);
8254 s->q += 4;
8255 /* Now the data to be signed... */
8256 if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
8257 PUT_32BIT(s->q, ssh->v2_session_id_len);
51470298 8258 s->q += 4;
94cd7c3a 8259 }
8260 memcpy(s->q, ssh->v2_session_id,
8261 ssh->v2_session_id_len);
8262 s->q += ssh->v2_session_id_len;
8263 memcpy(s->q, s->pktout->data + 5,
8264 s->pktout->length - 5);
8265 s->q += s->pktout->length - 5;
8266 /* And finally the (zero) flags word. */
8267 PUT_32BIT(s->q, 0);
8268 if (!agent_query(s->agentreq, s->len + 4,
8269 &vret, &s->retlen,
8270 ssh_agent_callback, ssh)) {
8271 do {
8272 crReturnV;
8273 if (pktin) {
8274 bombout(("Unexpected data from server"
8275 " while waiting for agent"
8276 " response"));
8277 crStopV;
1983e559 8278 }
94cd7c3a 8279 } while (pktin || inlen > 0);
8280 vret = ssh->agent_response;
8281 s->retlen = ssh->agent_response_len;
8282 }
8283 s->ret = vret;
8284 sfree(s->agentreq);
8285 if (s->ret) {
8286 if (s->ret[4] == SSH2_AGENT_SIGN_RESPONSE) {
8287 logevent("Sending Pageant's response");
8288 ssh2_add_sigblob(ssh, s->pktout,
8289 s->pkblob, s->pklen,
8290 s->ret + 9,
8291 GET_32BIT(s->ret + 5));
8292 ssh2_pkt_send(ssh, s->pktout);
8293 s->type = AUTH_TYPE_PUBLICKEY;
8294 } else {
8295 /* FIXME: less drastic response */
8296 bombout(("Pageant failed to answer challenge"));
8297 crStopV;
1983e559 8298 }
8299 }
1983e559 8300 }
94cd7c3a 8301
8302 /* Do we have any keys left to try? */
8303 if (s->pkblob_in_agent) {
8304 s->done_agent = TRUE;
8305 s->tried_pubkey_config = TRUE;
8306 } else {
8307 s->keyi++;
8308 if (s->keyi >= s->nkeys)
8309 s->done_agent = TRUE;
8310 }
1983e559 8311
edd0cb8a 8312 } else if (s->can_pubkey && s->publickey_blob &&
8313 !s->tried_pubkey_config) {
65a22376 8314
edd0cb8a 8315 struct ssh2_userkey *key; /* not live over crReturn */
8316 char *passphrase; /* not live over crReturn */
65a22376 8317
acab36bc 8318 ssh->pkt_actx = SSH2_PKTCTX_PUBLICKEY;
00db133f 8319
edd0cb8a 8320 s->tried_pubkey_config = TRUE;
8321
65a22376 8322 /*
1408a877 8323 * Try the public key supplied in the configuration.
8324 *
8325 * First, offer the public blob to see if the server is
8326 * willing to accept it.
65a22376 8327 */
ff3187f6 8328 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
4a693cfc 8329 ssh2_pkt_addstring(s->pktout, ssh->username);
edd0cb8a 8330 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8331 /* service requested */
8332 ssh2_pkt_addstring(s->pktout, "publickey"); /* method */
8333 ssh2_pkt_addbool(s->pktout, FALSE);
8334 /* no signature included */
8335 ssh2_pkt_addstring(s->pktout, s->publickey_algorithm);
8336 ssh2_pkt_addstring_start(s->pktout);
8337 ssh2_pkt_addstring_data(s->pktout,
8338 (char *)s->publickey_blob,
8339 s->publickey_bloblen);
ff3187f6 8340 ssh2_pkt_send(ssh, s->pktout);
edd0cb8a 8341 logevent("Offered public key");
ff3187f6 8342
8343 crWaitUntilV(pktin);
edd0cb8a 8344 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
8345 /* Key refused. Give up. */
8346 s->gotit = TRUE; /* reconsider message next loop */
8347 s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
8348 continue; /* process this new message */
45068b27 8349 }
edd0cb8a 8350 logevent("Offer of public key accepted");
af659722 8351
45068b27 8352 /*
edd0cb8a 8353 * Actually attempt a serious authentication using
8354 * the key.
45068b27 8355 */
edd0cb8a 8356 if (flags & FLAG_VERBOSE) {
8357 c_write_str(ssh, "Authenticating with public key \"");
8358 c_write_str(ssh, s->publickey_comment);
8359 c_write_str(ssh, "\"\r\n");
8360 }
8361 key = NULL;
8362 while (!key) {
8363 const char *error; /* not live over crReturn */
8364 if (s->publickey_encrypted) {
8365 /*
8366 * Get a passphrase from the user.
8367 */
8368 int ret; /* need not be kept over crReturn */
8369 s->cur_prompt = new_prompts(ssh->frontend);
8370 s->cur_prompt->to_server = FALSE;
8371 s->cur_prompt->name = dupstr("SSH key passphrase");
8372 add_prompt(s->cur_prompt,
8373 dupprintf("Passphrase for key \"%.100s\": ",
8374 s->publickey_comment),
b61f81bc 8375 FALSE);
edd0cb8a 8376 ret = get_userpass_input(s->cur_prompt, NULL, 0);
8377 while (ret < 0) {
8378 ssh->send_ok = 1;
8379 crWaitUntilV(!pktin);
8380 ret = get_userpass_input(s->cur_prompt,
8381 in, inlen);
8382 ssh->send_ok = 0;
8383 }
8384 if (!ret) {
8385 /* Failed to get a passphrase. Terminate. */
8386 free_prompts(s->cur_prompt);
8387 ssh_disconnect(ssh, NULL,
8388 "Unable to authenticate",
8389 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
8390 TRUE);
8391 crStopV;
85fdbe25 8392 }
edd0cb8a 8393 passphrase =
8394 dupstr(s->cur_prompt->prompts[0]->result);
8395 free_prompts(s->cur_prompt);
45068b27 8396 } else {
edd0cb8a 8397 passphrase = NULL; /* no passphrase needed */
45068b27 8398 }
1408a877 8399
edd0cb8a 8400 /*
8401 * Try decrypting the key.
8402 */
4a693cfc 8403 s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
8404 key = ssh2_load_userkey(s->keyfile, passphrase, &error);
edd0cb8a 8405 if (passphrase) {
8406 /* burn the evidence */
dfb88efd 8407 smemclr(passphrase, strlen(passphrase));
edd0cb8a 8408 sfree(passphrase);
8409 }
8410 if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
8411 if (passphrase &&
8412 (key == SSH2_WRONG_PASSPHRASE)) {
8413 c_write_str(ssh, "Wrong passphrase\r\n");
8414 key = NULL;
8415 /* and loop again */
8416 } else {
8417 c_write_str(ssh, "Unable to load private key (");
8418 c_write_str(ssh, error);
8419 c_write_str(ssh, ")\r\n");
8420 key = NULL;
8421 break; /* try something else */
8422 }
1408a877 8423 }
65a22376 8424 }
65a22376 8425
edd0cb8a 8426 if (key) {
1dd353b5 8427 unsigned char *pkblob, *sigblob, *sigdata;
8428 int pkblob_len, sigblob_len, sigdata_len;
edd0cb8a 8429 int p;
65a22376 8430
1408a877 8431 /*
8432 * We have loaded the private key and the server
8433 * has announced that it's willing to accept it.
8434 * Hallelujah. Generate a signature and send it.
8435 */
ff3187f6 8436 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
4a693cfc 8437 ssh2_pkt_addstring(s->pktout, ssh->username);
edd0cb8a 8438 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8439 /* service requested */
8440 ssh2_pkt_addstring(s->pktout, "publickey");
8441 /* method */
ff3187f6 8442 ssh2_pkt_addbool(s->pktout, TRUE);
edd0cb8a 8443 /* signature follows */
ff3187f6 8444 ssh2_pkt_addstring(s->pktout, key->alg->name);
edd0cb8a 8445 pkblob = key->alg->public_blob(key->data,
8446 &pkblob_len);
ff3187f6 8447 ssh2_pkt_addstring_start(s->pktout);
edd0cb8a 8448 ssh2_pkt_addstring_data(s->pktout, (char *)pkblob,
8449 pkblob_len);
1408a877 8450
8451 /*
8452 * The data to be signed is:
8453 *
8454 * string session-id
8455 *
8456 * followed by everything so far placed in the
8457 * outgoing packet.
8458 */
b672f405 8459 sigdata_len = s->pktout->length - 5 + 4 +
8460 ssh->v2_session_id_len;
edd0cb8a 8461 if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
8462 sigdata_len -= 4;
92d60585 8463 sigdata = snewn(sigdata_len, unsigned char);
edd0cb8a 8464 p = 0;
8465 if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
8466 PUT_32BIT(sigdata+p, ssh->v2_session_id_len);
8467 p += 4;
8468 }
b672f405 8469 memcpy(sigdata+p, ssh->v2_session_id,
8470 ssh->v2_session_id_len);
8471 p += ssh->v2_session_id_len;
ff3187f6 8472 memcpy(sigdata+p, s->pktout->data + 5,
8473 s->pktout->length - 5);
edd0cb8a 8474 p += s->pktout->length - 5;
8475 assert(p == sigdata_len);
d8baa528 8476 sigblob = key->alg->sign(key->data, (char *)sigdata,
1dd353b5 8477 sigdata_len, &sigblob_len);
ff3187f6 8478 ssh2_add_sigblob(ssh, s->pktout, pkblob, pkblob_len,
1dd353b5 8479 sigblob, sigblob_len);
8480 sfree(pkblob);
8481 sfree(sigblob);
1408a877 8482 sfree(sigdata);
8483
ff3187f6 8484 ssh2_pkt_send(ssh, s->pktout);
8221906d 8485 logevent("Sent public key signature");
51470298 8486 s->type = AUTH_TYPE_PUBLICKEY;
75374b2f 8487 key->alg->freekey(key->data);
1408a877 8488 }
edd0cb8a 8489
42af6a67 8490#ifndef NO_GSSAPI
8491 } else if (s->can_gssapi && !s->tried_gssapi) {
8492
8493 /* GSSAPI Authentication */
8494
86557057 8495 int micoffset, len;
8496 char *data;
42af6a67 8497 Ssh_gss_buf mic;
8498 s->type = AUTH_TYPE_GSSAPI;
8499 s->tried_gssapi = TRUE;
8500 s->gotit = TRUE;
8501 ssh->pkt_actx = SSH2_PKTCTX_GSSAPI;
8502
b3d375b2 8503 /*
8504 * Pick the highest GSS library on the preference
8505 * list.
8506 */
8507 {
8508 int i, j;
8509 s->gsslib = NULL;
8510 for (i = 0; i < ngsslibs; i++) {
4a693cfc 8511 int want_id = conf_get_int_int(ssh->conf,
8512 CONF_ssh_gsslist, i);
1e00c92b 8513 for (j = 0; j < ssh->gsslibs->nlibraries; j++)
8514 if (ssh->gsslibs->libraries[j].id == want_id) {
8515 s->gsslib = &ssh->gsslibs->libraries[j];
b3d375b2 8516 goto got_gsslib; /* double break */
8517 }
8518 }
8519 got_gsslib:
8520 /*
8521 * We always expect to have found something in
8522 * the above loop: we only came here if there
8523 * was at least one viable GSS library, and the
8524 * preference list should always mention
8525 * everything and only change the order.
8526 */
8527 assert(s->gsslib);
8528 }
8529
8530 if (s->gsslib->gsslogmsg)
8531 logevent(s->gsslib->gsslogmsg);
8532
42af6a67 8533 /* Sending USERAUTH_REQUEST with "gssapi-with-mic" method */
8534 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
4a693cfc 8535 ssh2_pkt_addstring(s->pktout, ssh->username);
42af6a67 8536 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8537 ssh2_pkt_addstring(s->pktout, "gssapi-with-mic");
8221906d 8538 logevent("Attempting GSSAPI authentication");
42af6a67 8539
8540 /* add mechanism info */
b3d375b2 8541 s->gsslib->indicate_mech(s->gsslib, &s->gss_buf);
42af6a67 8542
8543 /* number of GSSAPI mechanisms */
8544 ssh2_pkt_adduint32(s->pktout,1);
8545
8546 /* length of OID + 2 */
86557057 8547 ssh2_pkt_adduint32(s->pktout, s->gss_buf.length + 2);
42af6a67 8548 ssh2_pkt_addbyte(s->pktout, SSH2_GSS_OIDTYPE);
8549
8550 /* length of OID */
86557057 8551 ssh2_pkt_addbyte(s->pktout, (unsigned char) s->gss_buf.length);
42af6a67 8552
86557057 8553 ssh_pkt_adddata(s->pktout, s->gss_buf.value,
8554 s->gss_buf.length);
42af6a67 8555 ssh2_pkt_send(ssh, s->pktout);
8556 crWaitUntilV(pktin);
8557 if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_RESPONSE) {
8558 logevent("GSSAPI authentication request refused");
8559 continue;
8560 }
8561
8562 /* check returned packet ... */
8563
86557057 8564 ssh_pkt_getstring(pktin, &data, &len);
8565 s->gss_rcvtok.value = data;
8566 s->gss_rcvtok.length = len;
8567 if (s->gss_rcvtok.length != s->gss_buf.length + 2 ||
8568 ((char *)s->gss_rcvtok.value)[0] != SSH2_GSS_OIDTYPE ||
8569 ((char *)s->gss_rcvtok.value)[1] != s->gss_buf.length ||
8570 memcmp((char *)s->gss_rcvtok.value + 2,
8571 s->gss_buf.value,s->gss_buf.length) ) {
42af6a67 8572 logevent("GSSAPI authentication - wrong response from server");
8573 continue;
8574 }
8575
8576 /* now start running */
b3d375b2 8577 s->gss_stat = s->gsslib->import_name(s->gsslib,
8578 ssh->fullhostname,
8579 &s->gss_srv_name);
42af6a67 8580 if (s->gss_stat != SSH_GSS_OK) {
8581 if (s->gss_stat == SSH_GSS_BAD_HOST_NAME)
8582 logevent("GSSAPI import name failed - Bad service name");
8583 else
8584 logevent("GSSAPI import name failed");
8585 continue;
8586 }
8587
8588 /* fetch TGT into GSS engine */
b3d375b2 8589 s->gss_stat = s->gsslib->acquire_cred(s->gsslib, &s->gss_ctx);
42af6a67 8590
8591 if (s->gss_stat != SSH_GSS_OK) {
8592 logevent("GSSAPI authentication failed to get credentials");
b3d375b2 8593 s->gsslib->release_name(s->gsslib, &s->gss_srv_name);
42af6a67 8594 continue;
8595 }
8596
8597 /* initial tokens are empty */
86557057 8598 SSH_GSS_CLEAR_BUF(&s->gss_rcvtok);
99a3b3c9 8599 SSH_GSS_CLEAR_BUF(&s->gss_sndtok);
42af6a67 8600
8601 /* now enter the loop */
8602 do {
b3d375b2 8603 s->gss_stat = s->gsslib->init_sec_context
8604 (s->gsslib,
8605 &s->gss_ctx,
8606 s->gss_srv_name,
4a693cfc 8607 conf_get_int(ssh->conf, CONF_gssapifwd),
b3d375b2 8608 &s->gss_rcvtok,
8609 &s->gss_sndtok);
42af6a67 8610
8611 if (s->gss_stat!=SSH_GSS_S_COMPLETE &&
8612 s->gss_stat!=SSH_GSS_S_CONTINUE_NEEDED) {
8613 logevent("GSSAPI authentication initialisation failed");
8614
b3d375b2 8615 if (s->gsslib->display_status(s->gsslib, s->gss_ctx,
8616 &s->gss_buf) == SSH_GSS_OK) {
86557057 8617 logevent(s->gss_buf.value);
8618 sfree(s->gss_buf.value);
42af6a67 8619 }
8620
8621 break;
8622 }
8623 logevent("GSSAPI authentication initialised");
8624
8625 /* Client and server now exchange tokens until GSSAPI
8626 * no longer says CONTINUE_NEEDED */
8627
86557057 8628 if (s->gss_sndtok.length != 0) {
42af6a67 8629 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
8630 ssh_pkt_addstring_start(s->pktout);
86557057 8631 ssh_pkt_addstring_data(s->pktout,s->gss_sndtok.value,s->gss_sndtok.length);
42af6a67 8632 ssh2_pkt_send(ssh, s->pktout);
b3d375b2 8633 s->gsslib->free_tok(s->gsslib, &s->gss_sndtok);
42af6a67 8634 }
8635
8636 if (s->gss_stat == SSH_GSS_S_CONTINUE_NEEDED) {
8637 crWaitUntilV(pktin);
8638 if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_TOKEN) {
8639 logevent("GSSAPI authentication - bad server response");
8640 s->gss_stat = SSH_GSS_FAILURE;
8641 break;
8642 }
86557057 8643 ssh_pkt_getstring(pktin, &data, &len);
8644 s->gss_rcvtok.value = data;
8645 s->gss_rcvtok.length = len;
42af6a67 8646 }
8647 } while (s-> gss_stat == SSH_GSS_S_CONTINUE_NEEDED);
8648
8649 if (s->gss_stat != SSH_GSS_OK) {
b3d375b2 8650 s->gsslib->release_name(s->gsslib, &s->gss_srv_name);
8651 s->gsslib->release_cred(s->gsslib, &s->gss_ctx);
42af6a67 8652 continue;
8653 }
8654 logevent("GSSAPI authentication loop finished OK");
8655
8656 /* Now send the MIC */
8657
8658 s->pktout = ssh2_pkt_init(0);
8659 micoffset = s->pktout->length;
8660 ssh_pkt_addstring_start(s->pktout);
8661 ssh_pkt_addstring_data(s->pktout, (char *)ssh->v2_session_id, ssh->v2_session_id_len);
8662 ssh_pkt_addbyte(s->pktout, SSH2_MSG_USERAUTH_REQUEST);
4a693cfc 8663 ssh_pkt_addstring(s->pktout, ssh->username);
42af6a67 8664 ssh_pkt_addstring(s->pktout, "ssh-connection");
8665 ssh_pkt_addstring(s->pktout, "gssapi-with-mic");
8666
86557057 8667 s->gss_buf.value = (char *)s->pktout->data + micoffset;
8668 s->gss_buf.length = s->pktout->length - micoffset;
42af6a67 8669
b3d375b2 8670 s->gsslib->get_mic(s->gsslib, s->gss_ctx, &s->gss_buf, &mic);
42af6a67 8671 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_GSSAPI_MIC);
8672 ssh_pkt_addstring_start(s->pktout);
86557057 8673 ssh_pkt_addstring_data(s->pktout, mic.value, mic.length);
42af6a67 8674 ssh2_pkt_send(ssh, s->pktout);
b3d375b2 8675 s->gsslib->free_mic(s->gsslib, &mic);
42af6a67 8676
8677 s->gotit = FALSE;
8678
b3d375b2 8679 s->gsslib->release_name(s->gsslib, &s->gss_srv_name);
8680 s->gsslib->release_cred(s->gsslib, &s->gss_ctx);
42af6a67 8681 continue;
8682#endif
edd0cb8a 8683 } else if (s->can_keyb_inter && !s->kbd_inter_refused) {
8684
8685 /*
8686 * Keyboard-interactive authentication.
8687 */
edd0cb8a 8688
edd0cb8a 8689 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
8690
acab36bc 8691 ssh->pkt_actx = SSH2_PKTCTX_KBDINTER;
edd0cb8a 8692
8693 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
4a693cfc 8694 ssh2_pkt_addstring(s->pktout, ssh->username);
edd0cb8a 8695 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8696 /* service requested */
8697 ssh2_pkt_addstring(s->pktout, "keyboard-interactive");
8698 /* method */
8699 ssh2_pkt_addstring(s->pktout, ""); /* lang */
8700 ssh2_pkt_addstring(s->pktout, ""); /* submethods */
8701 ssh2_pkt_send(ssh, s->pktout);
8221906d 8702
8703 logevent("Attempting keyboard-interactive authentication");
edd0cb8a 8704
8705 crWaitUntilV(pktin);
8706 if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
8707 /* Server is not willing to do keyboard-interactive
b8e3173d 8708 * at all (or, bizarrely but legally, accepts the
8709 * user without actually issuing any prompts).
8710 * Give up on it entirely. */
edd0cb8a 8711 s->gotit = TRUE;
edd0cb8a 8712 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
8713 s->kbd_inter_refused = TRUE; /* don't try it again */
8714 continue;
8715 }
8716
8717 /*
b8e3173d 8718 * Loop while the server continues to send INFO_REQUESTs.
edd0cb8a 8719 */
b8e3173d 8720 while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
edd0cb8a 8721
b8e3173d 8722 char *name, *inst, *lang;
8723 int name_len, inst_len, lang_len;
8724 int i;
8725
8726 /*
8727 * We've got a fresh USERAUTH_INFO_REQUEST.
8728 * Get the preamble and start building a prompt.
8729 */
8730 ssh_pkt_getstring(pktin, &name, &name_len);
8731 ssh_pkt_getstring(pktin, &inst, &inst_len);
8732 ssh_pkt_getstring(pktin, &lang, &lang_len);
8733 s->cur_prompt = new_prompts(ssh->frontend);
8734 s->cur_prompt->to_server = TRUE;
edd0cb8a 8735
b8e3173d 8736 /*
9ea10e78 8737 * Get any prompt(s) from the packet.
b8e3173d 8738 */
8739 s->num_prompts = ssh_pkt_getuint32(pktin);
8740 for (i = 0; i < s->num_prompts; i++) {
8741 char *prompt;
8742 int prompt_len;
8743 int echo;
8744 static char noprompt[] =
8745 "<server failed to send prompt>: ";
8746
8747 ssh_pkt_getstring(pktin, &prompt, &prompt_len);
8748 echo = ssh2_pkt_getbool(pktin);
8749 if (!prompt_len) {
8750 prompt = noprompt;
8751 prompt_len = lenof(noprompt)-1;
8752 }
8753 add_prompt(s->cur_prompt,
8754 dupprintf("%.*s", prompt_len, prompt),
b61f81bc 8755 echo);
edd0cb8a 8756 }
b8e3173d 8757
9874c9d7 8758 if (name_len) {
8759 /* FIXME: better prefix to distinguish from
8760 * local prompts? */
8761 s->cur_prompt->name =
8762 dupprintf("SSH server: %.*s", name_len, name);
8763 s->cur_prompt->name_reqd = TRUE;
8764 } else {
8765 s->cur_prompt->name =
8766 dupstr("SSH server authentication");
8767 s->cur_prompt->name_reqd = FALSE;
8768 }
8769 /* We add a prefix to try to make it clear that a prompt
8770 * has come from the server.
8771 * FIXME: ugly to print "Using..." in prompt _every_
8772 * time round. Can this be done more subtly? */
8773 /* Special case: for reasons best known to themselves,
8774 * some servers send k-i requests with no prompts and
8775 * nothing to display. Keep quiet in this case. */
8776 if (s->num_prompts || name_len || inst_len) {
8777 s->cur_prompt->instruction =
8778 dupprintf("Using keyboard-interactive authentication.%s%.*s",
8779 inst_len ? "\n" : "", inst_len, inst);
8780 s->cur_prompt->instr_reqd = TRUE;
8781 } else {
8782 s->cur_prompt->instr_reqd = FALSE;
8783 }
8784
b8e3173d 8785 /*
9ea10e78 8786 * Display any instructions, and get the user's
8787 * response(s).
b8e3173d 8788 */
9ea10e78 8789 {
b8e3173d 8790 int ret; /* not live over crReturn */
8791 ret = get_userpass_input(s->cur_prompt, NULL, 0);
8792 while (ret < 0) {
8793 ssh->send_ok = 1;
8794 crWaitUntilV(!pktin);
8795 ret = get_userpass_input(s->cur_prompt, in, inlen);
8796 ssh->send_ok = 0;
8797 }
8798 if (!ret) {
8799 /*
8800 * Failed to get responses. Terminate.
8801 */
8802 free_prompts(s->cur_prompt);
8803 ssh_disconnect(ssh, NULL, "Unable to authenticate",
8804 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
8805 TRUE);
8806 crStopV;
8807 }
edd0cb8a 8808 }
b8e3173d 8809
8810 /*
9ea10e78 8811 * Send the response(s) to the server.
b8e3173d 8812 */
8813 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_INFO_RESPONSE);
b8e3173d 8814 ssh2_pkt_adduint32(s->pktout, s->num_prompts);
8815 for (i=0; i < s->num_prompts; i++) {
8816 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
8817 ssh2_pkt_addstring(s->pktout,
8818 s->cur_prompt->prompts[i]->result);
8819 end_log_omission(ssh, s->pktout);
8820 }
18524056 8821 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
b8e3173d 8822
c69784c0 8823 /*
8824 * Free the prompts structure from this iteration.
8825 * If there's another, a new one will be allocated
8826 * when we return to the top of this while loop.
8827 */
8828 free_prompts(s->cur_prompt);
8829
b8e3173d 8830 /*
8831 * Get the next packet in case it's another
8832 * INFO_REQUEST.
8833 */
8834 crWaitUntilV(pktin);
8835
edd0cb8a 8836 }
8837
8838 /*
b8e3173d 8839 * We should have SUCCESS or FAILURE now.
edd0cb8a 8840 */
b8e3173d 8841 s->gotit = TRUE;
edd0cb8a 8842
8843 } else if (s->can_passwd) {
8844
8845 /*
8846 * Plain old password authentication.
8847 */
8848 int ret; /* not live over crReturn */
e955d348 8849 int changereq_first_time; /* not live over crReturn */
edd0cb8a 8850
acab36bc 8851 ssh->pkt_actx = SSH2_PKTCTX_PASSWORD;
edd0cb8a 8852
8853 s->cur_prompt = new_prompts(ssh->frontend);
8854 s->cur_prompt->to_server = TRUE;
8855 s->cur_prompt->name = dupstr("SSH password");
4a693cfc 8856 add_prompt(s->cur_prompt, dupprintf("%s@%s's password: ",
8857 ssh->username,
edd0cb8a 8858 ssh->savedhost),
b61f81bc 8859 FALSE);
edd0cb8a 8860
8861 ret = get_userpass_input(s->cur_prompt, NULL, 0);
8862 while (ret < 0) {
8863 ssh->send_ok = 1;
8864 crWaitUntilV(!pktin);
8865 ret = get_userpass_input(s->cur_prompt, in, inlen);
8866 ssh->send_ok = 0;
8867 }
8868 if (!ret) {
8869 /*
8870 * Failed to get responses. Terminate.
8871 */
8872 free_prompts(s->cur_prompt);
8873 ssh_disconnect(ssh, NULL, "Unable to authenticate",
8874 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
8875 TRUE);
8876 crStopV;
8877 }
e955d348 8878 /*
8879 * Squirrel away the password. (We may need it later if
8880 * asked to change it.)
8881 */
8882 s->password = dupstr(s->cur_prompt->prompts[0]->result);
8883 free_prompts(s->cur_prompt);
edd0cb8a 8884
8885 /*
8886 * Send the password packet.
8887 *
95d2d262 8888 * We pad out the password packet to 256 bytes to make
8889 * it harder for an attacker to find the length of the
8890 * user's password.
1408a877 8891 *
95d2d262 8892 * Anyone using a password longer than 256 bytes
8893 * probably doesn't have much to worry about from
1408a877 8894 * people who find out how long their password is!
65a22376 8895 */
ff3187f6 8896 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
4a693cfc 8897 ssh2_pkt_addstring(s->pktout, ssh->username);
edd0cb8a 8898 ssh2_pkt_addstring(s->pktout, "ssh-connection");
8899 /* service requested */
ff3187f6 8900 ssh2_pkt_addstring(s->pktout, "password");
8901 ssh2_pkt_addbool(s->pktout, FALSE);
8902 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
e955d348 8903 ssh2_pkt_addstring(s->pktout, s->password);
ff3187f6 8904 end_log_omission(ssh, s->pktout);
18524056 8905 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
0d43337a 8906 logevent("Sent password");
28f4d4f0 8907 s->type = AUTH_TYPE_PASSWORD;
edd0cb8a 8908
e955d348 8909 /*
8910 * Wait for next packet, in case it's a password change
8911 * request.
8912 */
8913 crWaitUntilV(pktin);
8914 changereq_first_time = TRUE;
8915
8916 while (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
8917
8918 /*
8919 * We're being asked for a new password
8920 * (perhaps not for the first time).
8921 * Loop until the server accepts it.
8922 */
8923
8924 int got_new = FALSE; /* not live over crReturn */
8925 char *prompt; /* not live over crReturn */
8926 int prompt_len; /* not live over crReturn */
8927
8928 {
8929 char *msg;
8930 if (changereq_first_time)
8931 msg = "Server requested password change";
8932 else
8933 msg = "Server rejected new password";
8934 logevent(msg);
8935 c_write_str(ssh, msg);
8936 c_write_str(ssh, "\r\n");
8937 }
8938
8939 ssh_pkt_getstring(pktin, &prompt, &prompt_len);
8940
8941 s->cur_prompt = new_prompts(ssh->frontend);
8942 s->cur_prompt->to_server = TRUE;
8943 s->cur_prompt->name = dupstr("New SSH password");
8944 s->cur_prompt->instruction =
8945 dupprintf("%.*s", prompt_len, prompt);
8946 s->cur_prompt->instr_reqd = TRUE;
d9add7bc 8947 /*
8948 * There's no explicit requirement in the protocol
8949 * for the "old" passwords in the original and
8950 * password-change messages to be the same, and
8951 * apparently some Cisco kit supports password change
8952 * by the user entering a blank password originally
8953 * and the real password subsequently, so,
8954 * reluctantly, we prompt for the old password again.
8955 *
8956 * (On the other hand, some servers don't even bother
8957 * to check this field.)
8958 */
8959 add_prompt(s->cur_prompt,
8960 dupstr("Current password (blank for previously entered password): "),
b61f81bc 8961 FALSE);
e955d348 8962 add_prompt(s->cur_prompt, dupstr("Enter new password: "),
b61f81bc 8963 FALSE);
e955d348 8964 add_prompt(s->cur_prompt, dupstr("Confirm new password: "),
b61f81bc 8965 FALSE);
e955d348 8966
8967 /*
8968 * Loop until the user manages to enter the same
8969 * password twice.
8970 */
8971 while (!got_new) {
8972
8973 ret = get_userpass_input(s->cur_prompt, NULL, 0);
8974 while (ret < 0) {
8975 ssh->send_ok = 1;
8976 crWaitUntilV(!pktin);
8977 ret = get_userpass_input(s->cur_prompt, in, inlen);
8978 ssh->send_ok = 0;
8979 }
8980 if (!ret) {
8981 /*
8982 * Failed to get responses. Terminate.
8983 */
8984 /* burn the evidence */
8985 free_prompts(s->cur_prompt);
dfb88efd 8986 smemclr(s->password, strlen(s->password));
e955d348 8987 sfree(s->password);
8988 ssh_disconnect(ssh, NULL, "Unable to authenticate",
8989 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
8990 TRUE);
8991 crStopV;
8992 }
8993
8994 /*
d9add7bc 8995 * If the user specified a new original password
8996 * (IYSWIM), overwrite any previously specified
8997 * one.
8998 * (A side effect is that the user doesn't have to
8999 * re-enter it if they louse up the new password.)
9000 */
9001 if (s->cur_prompt->prompts[0]->result[0]) {
dfb88efd 9002 smemclr(s->password, strlen(s->password));
d9add7bc 9003 /* burn the evidence */
9004 sfree(s->password);
9005 s->password =
9006 dupstr(s->cur_prompt->prompts[0]->result);
9007 }
9008
9009 /*
9010 * Check the two new passwords match.
e955d348 9011 */
d9add7bc 9012 got_new = (strcmp(s->cur_prompt->prompts[1]->result,
9013 s->cur_prompt->prompts[2]->result)
e955d348 9014 == 0);
9015 if (!got_new)
9016 /* They don't. Silly user. */
9017 c_write_str(ssh, "Passwords do not match\r\n");
9018
9019 }
9020
9021 /*
9022 * Send the new password (along with the old one).
9023 * (see above for padding rationale)
9024 */
9025 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
4a693cfc 9026 ssh2_pkt_addstring(s->pktout, ssh->username);
e955d348 9027 ssh2_pkt_addstring(s->pktout, "ssh-connection");
9028 /* service requested */
9029 ssh2_pkt_addstring(s->pktout, "password");
9030 ssh2_pkt_addbool(s->pktout, TRUE);
9031 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
9032 ssh2_pkt_addstring(s->pktout, s->password);
9033 ssh2_pkt_addstring(s->pktout,
d9add7bc 9034 s->cur_prompt->prompts[1]->result);
e955d348 9035 free_prompts(s->cur_prompt);
9036 end_log_omission(ssh, s->pktout);
18524056 9037 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
e955d348 9038 logevent("Sent new password");
9039
9040 /*
9041 * Now see what the server has to say about it.
9042 * (If it's CHANGEREQ again, it's not happy with the
9043 * new password.)
9044 */
9045 crWaitUntilV(pktin);
9046 changereq_first_time = FALSE;
9047
9048 }
9049
9050 /*
9051 * We need to reexamine the current pktin at the top
9052 * of the loop. Either:
9053 * - we weren't asked to change password at all, in
9054 * which case it's a SUCCESS or FAILURE with the
9055 * usual meaning
9056 * - we sent a new password, and the server was
9057 * either OK with it (SUCCESS or FAILURE w/partial
9058 * success) or unhappy with the _old_ password
9059 * (FAILURE w/o partial success)
9060 * In any of these cases, we go back to the top of
9061 * the loop and start again.
9062 */
9063 s->gotit = TRUE;
9064
9065 /*
9066 * We don't need the old password any more, in any
9067 * case. Burn the evidence.
9068 */
dfb88efd 9069 smemclr(s->password, strlen(s->password));
e955d348 9070 sfree(s->password);
9071
1408a877 9072 } else {
854caca5 9073 char *str = dupprintf("No supported authentication methods available"
9074 " (server sent: %.*s)",
9075 methlen, methods);
edd0cb8a 9076
854caca5 9077 ssh_disconnect(ssh, str,
9e296bfa 9078 "No supported authentication methods available",
9079 SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
9080 FALSE);
854caca5 9081 sfree(str);
9082
7ffdbc1a 9083 crStopV;
edd0cb8a 9084
65a22376 9085 }
edd0cb8a 9086
65a22376 9087 }
a1a1fae4 9088 }
6bbce591 9089 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
7cca0d81 9090
edd0cb8a 9091 /* Clear up various bits and pieces from authentication. */
9092 if (s->publickey_blob) {
9093 sfree(s->publickey_blob);
9094 sfree(s->publickey_comment);
9095 }
94cd7c3a 9096 if (s->agent_response)
9097 sfree(s->agent_response);
edd0cb8a 9098
ab18ccff 9099 if (s->userauth_success) {
9100 /*
9101 * We've just received USERAUTH_SUCCESS, and we haven't sent any
9102 * packets since. Signal the transport layer to consider enacting
9103 * delayed compression.
9104 *
9105 * (Relying on we_are_in is not sufficient, as
9106 * draft-miller-secsh-compression-delayed is quite clear that it
9107 * triggers on USERAUTH_SUCCESS specifically, and we_are_in can
9108 * become set for other reasons.)
9109 */
9110 do_ssh2_transport(ssh, "enabling delayed compression", -2, NULL);
9111 }
9112
7cca0d81 9113 /*
a1a1fae4 9114 * Now the connection protocol has started, one way or another.
7cca0d81 9115 */
9116
0ed48730 9117 ssh->channels = newtree234(ssh_channelcmp);
9118
7cca0d81 9119 /*
b09eaa88 9120 * Set up handlers for some connection protocol messages, so we
9121 * don't have to handle them repeatedly in this coroutine.
9122 */
9123 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] =
9124 ssh2_msg_channel_window_adjust;
51df0ab5 9125 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] =
9126 ssh2_msg_global_request;
b09eaa88 9127
9128 /*
0ed48730 9129 * Create the main session channel.
7cca0d81 9130 */
4a693cfc 9131 if (conf_get_int(ssh->conf, CONF_ssh_no_shell)) {
feb02b4e 9132 ssh->mainchan = NULL;
4e63d9b2 9133 } else {
feb02b4e 9134 ssh->mainchan = snew(struct ssh_channel);
9135 ssh->mainchan->ssh = ssh;
94bdfe40 9136 ssh2_channel_init(ssh->mainchan);
feb02b4e 9137
4e63d9b2 9138 if (*conf_get_str(ssh->conf, CONF_ssh_nc_host)) {
9139 /*
9140 * Just start a direct-tcpip channel and use it as the main
9141 * channel.
9142 */
9143 ssh_send_port_open(ssh->mainchan,
9144 conf_get_str(ssh->conf, CONF_ssh_nc_host),
9145 conf_get_int(ssh->conf, CONF_ssh_nc_port),
9146 "main channel");
9147 ssh->ncmode = TRUE;
9148 } else {
9149 s->pktout = ssh2_chanopen_init(ssh->mainchan, "session");
9150 logevent("Opening session as main channel");
9151 ssh2_pkt_send(ssh, s->pktout);
9152 ssh->ncmode = FALSE;
feb02b4e 9153 }
ff3187f6 9154 crWaitUntilV(pktin);
9155 if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
4e63d9b2 9156 bombout(("Server refused to open channel"));
0ed48730 9157 crStopV;
9158 /* FIXME: error data comes back in FAILURE packet */
9159 }
ff3187f6 9160 if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
0ed48730 9161 bombout(("Server's channel confirmation cited wrong channel"));
9162 crStopV;
9163 }
ff3187f6 9164 ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
64d6ff88 9165 ssh->mainchan->halfopen = FALSE;
0ed48730 9166 ssh->mainchan->type = CHAN_MAINSESSION;
ff3187f6 9167 ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
9168 ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
0ed48730 9169 add234(ssh->channels, ssh->mainchan);
62638676 9170 update_specials_menu(ssh->frontend);
4e63d9b2 9171 logevent("Opened main channel");
feb02b4e 9172 }
7cca0d81 9173
9174 /*
51df0ab5 9175 * Now we have a channel, make dispatch table entries for
9176 * general channel-based messages.
9177 */
9178 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] =
9179 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] =
9180 ssh2_msg_channel_data;
9181 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_channel_eof;
9182 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_channel_close;
9183 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] =
9184 ssh2_msg_channel_open_confirmation;
9185 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] =
9186 ssh2_msg_channel_open_failure;
9187 ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] =
9188 ssh2_msg_channel_request;
9189 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] =
9190 ssh2_msg_channel_open;
ebbc254d 9191 ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = ssh2_msg_channel_response;
9192 ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = ssh2_msg_channel_response;
9193
51df0ab5 9194
4a693cfc 9195 if (ssh->mainchan && conf_get_int(ssh->conf, CONF_ssh_simple)) {
3361b80a 9196 /*
9197 * This message indicates to the server that we promise
9198 * not to try to run any other channel in parallel with
9199 * this one, so it's safe for it to advertise a very large
9200 * window and leave the flow control to TCP.
9201 */
134f5ece 9202 s->pktout = ssh2_chanreq_init(ssh->mainchan,
9203 "simple@putty.projects.tartarus.org",
9204 NULL, NULL);
3361b80a 9205 ssh2_pkt_send(ssh, s->pktout);
9206 }
9207
51df0ab5 9208 /*
c99deca4 9209 * Enable port forwardings.
9210 */
9211 ssh_setup_portfwd(ssh, ssh->conf);
9212
e03299cb 9213 if (ssh->mainchan && !ssh->ncmode) {
9214 /*
9215 * Send the CHANNEL_REQUESTS for the main session channel.
9216 * Each one is handled by its own little asynchronous
9217 * co-routine.
9218 */
c99deca4 9219
e03299cb 9220 /* Potentially enable X11 forwarding. */
9221 if (conf_get_int(ssh->conf, CONF_x11_forward) &&
9222 (ssh->x11disp =
9223 x11_setup_display(conf_get_str(ssh->conf, CONF_x11_display),
9224 conf_get_int(ssh->conf, CONF_x11_auth),
9225 ssh->conf)))
9226 ssh2_setup_x11(ssh->mainchan, NULL, NULL);
bc240b21 9227
e03299cb 9228 /* Potentially enable agent forwarding. */
9229 if (conf_get_int(ssh->conf, CONF_agentfwd) && agent_exists())
9230 ssh2_setup_agent(ssh->mainchan, NULL, NULL);
36c2a3e9 9231
e03299cb 9232 /* Now allocate a pty for the session. */
9233 if (!conf_get_int(ssh->conf, CONF_nopty))
9234 ssh2_setup_pty(ssh->mainchan, NULL, NULL);
7cca0d81 9235
e03299cb 9236 /* Send environment variables. */
9237 ssh2_setup_env(ssh->mainchan, NULL, NULL);
73feed4f 9238
e03299cb 9239 /*
9240 * Start a shell or a remote command. We may have to attempt
9241 * this twice if the config data has provided a second choice
9242 * of command.
9243 */
9244 while (1) {
9245 int subsys;
9246 char *cmd;
fd5e5847 9247
e03299cb 9248 if (ssh->fallback_cmd) {
9249 subsys = conf_get_int(ssh->conf, CONF_ssh_subsys2);
9250 cmd = conf_get_str(ssh->conf, CONF_remote_cmd2);
9251 } else {
9252 subsys = conf_get_int(ssh->conf, CONF_ssh_subsys);
9253 cmd = conf_get_str(ssh->conf, CONF_remote_cmd);
9254 }
fd5e5847 9255
e03299cb 9256 if (subsys) {
9257 s->pktout = ssh2_chanreq_init(ssh->mainchan, "subsystem",
9258 ssh2_response_authconn, NULL);
9259 ssh2_pkt_addstring(s->pktout, cmd);
9260 } else if (*cmd) {
9261 s->pktout = ssh2_chanreq_init(ssh->mainchan, "exec",
9262 ssh2_response_authconn, NULL);
9263 ssh2_pkt_addstring(s->pktout, cmd);
9264 } else {
9265 s->pktout = ssh2_chanreq_init(ssh->mainchan, "shell",
9266 ssh2_response_authconn, NULL);
9267 }
9268 ssh2_pkt_send(ssh, s->pktout);
b09eaa88 9269
e03299cb 9270 crWaitUntilV(pktin);
b09eaa88 9271
e03299cb 9272 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
9273 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
9274 bombout(("Unexpected response to shell/command request:"
9275 " packet type %d", pktin->type));
9276 crStopV;
9277 }
9278 /*
9279 * We failed to start the command. If this is the
9280 * fallback command, we really are finished; if it's
9281 * not, and if the fallback command exists, try falling
9282 * back to it before complaining.
9283 */
9284 if (!ssh->fallback_cmd &&
9285 *conf_get_str(ssh->conf, CONF_remote_cmd2)) {
9286 logevent("Primary command failed; attempting fallback");
9287 ssh->fallback_cmd = TRUE;
9288 continue;
9289 }
9290 bombout(("Server refused to start a shell/command"));
7ffdbc1a 9291 crStopV;
e03299cb 9292 } else {
9293 logevent("Started a shell/command");
fd5e5847 9294 }
e03299cb 9295 break;
32874aea 9296 }
e03299cb 9297 } else {
9298 ssh->editing = ssh->echoing = TRUE;
7cca0d81 9299 }
9300
51470298 9301 ssh->state = SSH_STATE_SESSION;
9302 if (ssh->size_needed)
9303 ssh_size(ssh, ssh->term_width, ssh->term_height);
9304 if (ssh->eof_needed)
9305 ssh_special(ssh, TS_EOF);
6e48c3fe 9306
7cca0d81 9307 /*
9308 * Transfer data!
9309 */
b9d7bcad 9310 if (ssh->ldisc)
9311 ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
0ed48730 9312 if (ssh->mainchan)
9313 ssh->send_ok = 1;
7cca0d81 9314 while (1) {
e5574168 9315 crReturnV;
51470298 9316 s->try_send = FALSE;
ff3187f6 9317 if (pktin) {
2b7540a7 9318
51df0ab5 9319 /*
9320 * _All_ the connection-layer packets we expect to
9321 * receive are now handled by the dispatch table.
9322 * Anything that reaches here must be bogus.
9323 */
32874aea 9324
51df0ab5 9325 bombout(("Strange packet received: type %d", pktin->type));
9326 crStopV;
0ed48730 9327 } else if (ssh->mainchan) {
32874aea 9328 /*
9329 * We have spare data. Add it to the channel buffer.
9330 */
d8baa528 9331 ssh2_add_channel_data(ssh->mainchan, (char *)in, inlen);
51470298 9332 s->try_send = TRUE;
32874aea 9333 }
51470298 9334 if (s->try_send) {
32874aea 9335 int i;
9336 struct ssh_channel *c;
9337 /*
9338 * Try to send data on all channels if we can.
9339 */
1bfc7e93 9340 for (i = 0; NULL != (c = index234(ssh->channels, i)); i++)
78280721 9341 ssh2_try_send_and_unthrottle(ssh, c);
7cca0d81 9342 }
e5574168 9343 }
9344
9345 crFinishV;
9346}
9347
9348/*
2e85c969 9349 * Handlers for SSH-2 messages that might arrive at any moment.
b09eaa88 9350 */
409bfa77 9351static void ssh2_msg_disconnect(Ssh ssh, struct Packet *pktin)
b09eaa88 9352{
9353 /* log reason code in disconnect message */
9354 char *buf, *msg;
60860bc3 9355 int reason, msglen;
b09eaa88 9356
9357 reason = ssh_pkt_getuint32(pktin);
9358 ssh_pkt_getstring(pktin, &msg, &msglen);
9359
9360 if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {
9361 buf = dupprintf("Received disconnect message (%s)",
9362 ssh2_disconnect_reasons[reason]);
9363 } else {
9364 buf = dupprintf("Received disconnect message (unknown"
9365 " type %d)", reason);
9366 }
9367 logevent(buf);
9368 sfree(buf);
60860bc3 9369 buf = dupprintf("Disconnection message text: %.*s",
9370 msglen, msg);
b09eaa88 9371 logevent(buf);
60860bc3 9372 bombout(("Server sent disconnect message\ntype %d (%s):\n\"%.*s\"",
b09eaa88 9373 reason,
9374 (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?
9375 ssh2_disconnect_reasons[reason] : "unknown",
60860bc3 9376 msglen, msg));
b09eaa88 9377 sfree(buf);
9378}
9379
409bfa77 9380static void ssh2_msg_debug(Ssh ssh, struct Packet *pktin)
b09eaa88 9381{
9382 /* log the debug message */
fb983202 9383 char *msg;
b09eaa88 9384 int msglen;
b09eaa88 9385
3ab79841 9386 /* XXX maybe we should actually take notice of the return value */
9387 ssh2_pkt_getbool(pktin);
b09eaa88 9388 ssh_pkt_getstring(pktin, &msg, &msglen);
9389
fb983202 9390 logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
b09eaa88 9391}
9392
bc074147 9393static void ssh2_msg_transport(Ssh ssh, struct Packet *pktin)
9394{
9395 do_ssh2_transport(ssh, NULL, 0, pktin);
9396}
9397
9398/*
9399 * Called if we receive a packet that isn't allowed by the protocol.
9400 * This only applies to packets whose meaning PuTTY understands.
9401 * Entirely unknown packets are handled below.
9402 */
9403static void ssh2_msg_unexpected(Ssh ssh, struct Packet *pktin)
9404{
9405 char *buf = dupprintf("Server protocol violation: unexpected %s packet",
9406 ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx,
9407 pktin->type));
9408 ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
1418b055 9409 sfree(buf);
bc074147 9410}
9411
409bfa77 9412static void ssh2_msg_something_unimplemented(Ssh ssh, struct Packet *pktin)
b09eaa88 9413{
9414 struct Packet *pktout;
9415 pktout = ssh2_pkt_init(SSH2_MSG_UNIMPLEMENTED);
9416 ssh2_pkt_adduint32(pktout, pktin->sequence);
9417 /*
9418 * UNIMPLEMENTED messages MUST appear in the same order as the
9419 * messages they respond to. Hence, never queue them.
9420 */
9421 ssh2_pkt_send_noqueue(ssh, pktout);
9422}
9423
9424/*
2e85c969 9425 * Handle the top-level SSH-2 protocol.
7cca0d81 9426 */
b09eaa88 9427static void ssh2_protocol_setup(Ssh ssh)
9428{
9429 int i;
9430
9431 /*
9432 * Most messages cause SSH2_MSG_UNIMPLEMENTED.
9433 */
9434 for (i = 0; i < 256; i++)
9435 ssh->packet_dispatch[i] = ssh2_msg_something_unimplemented;
9436
9437 /*
bc074147 9438 * Initially, we only accept transport messages (and a few generic
9439 * ones). do_ssh2_authconn will add more when it starts.
9440 * Messages that are understood but not currently acceptable go to
9441 * ssh2_msg_unexpected.
b09eaa88 9442 */
bc074147 9443 ssh->packet_dispatch[SSH2_MSG_UNIMPLEMENTED] = ssh2_msg_unexpected;
9444 ssh->packet_dispatch[SSH2_MSG_SERVICE_REQUEST] = ssh2_msg_unexpected;
9445 ssh->packet_dispatch[SSH2_MSG_SERVICE_ACCEPT] = ssh2_msg_unexpected;
9446 ssh->packet_dispatch[SSH2_MSG_KEXINIT] = ssh2_msg_transport;
9447 ssh->packet_dispatch[SSH2_MSG_NEWKEYS] = ssh2_msg_transport;
9448 ssh->packet_dispatch[SSH2_MSG_KEXDH_INIT] = ssh2_msg_transport;
9449 ssh->packet_dispatch[SSH2_MSG_KEXDH_REPLY] = ssh2_msg_transport;
9450 /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REQUEST] = ssh2_msg_transport; duplicate case value */
9451 /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_GROUP] = ssh2_msg_transport; duplicate case value */
9452 ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_INIT] = ssh2_msg_transport;
9453 ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REPLY] = ssh2_msg_transport;
9454 ssh->packet_dispatch[SSH2_MSG_USERAUTH_REQUEST] = ssh2_msg_unexpected;
9455 ssh->packet_dispatch[SSH2_MSG_USERAUTH_FAILURE] = ssh2_msg_unexpected;
9456 ssh->packet_dispatch[SSH2_MSG_USERAUTH_SUCCESS] = ssh2_msg_unexpected;
9457 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = ssh2_msg_unexpected;
9458 ssh->packet_dispatch[SSH2_MSG_USERAUTH_PK_OK] = ssh2_msg_unexpected;
9459 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ] = ssh2_msg_unexpected; duplicate case value */
9460 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_REQUEST] = ssh2_msg_unexpected; duplicate case value */
9461 ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_RESPONSE] = ssh2_msg_unexpected;
9462 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] = ssh2_msg_unexpected;
9463 ssh->packet_dispatch[SSH2_MSG_REQUEST_SUCCESS] = ssh2_msg_unexpected;
9464 ssh->packet_dispatch[SSH2_MSG_REQUEST_FAILURE] = ssh2_msg_unexpected;
9465 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = ssh2_msg_unexpected;
9466 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] = ssh2_msg_unexpected;
9467 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] = ssh2_msg_unexpected;
9468 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] = ssh2_msg_unexpected;
9469 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] = ssh2_msg_unexpected;
9470 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] = ssh2_msg_unexpected;
9471 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_unexpected;
9472 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_unexpected;
9473 ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] = ssh2_msg_unexpected;
9474 ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = ssh2_msg_unexpected;
9475 ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = ssh2_msg_unexpected;
b09eaa88 9476
9477 /*
bc074147 9478 * These messages have a special handler from the start.
b09eaa88 9479 */
9480 ssh->packet_dispatch[SSH2_MSG_DISCONNECT] = ssh2_msg_disconnect;
2e85c969 9481 ssh->packet_dispatch[SSH2_MSG_IGNORE] = ssh_msg_ignore; /* shared with SSH-1 */
b09eaa88 9482 ssh->packet_dispatch[SSH2_MSG_DEBUG] = ssh2_msg_debug;
9483}
9484
d719927e 9485static void ssh2_timer(void *ctx, unsigned long now)
9442dd57 9486{
9487 Ssh ssh = (Ssh)ctx;
9488
ecbb0000 9489 if (ssh->state == SSH_STATE_CLOSED)
9490 return;
9491
4a693cfc 9492 if (!ssh->kex_in_progress && conf_get_int(ssh->conf, CONF_ssh_rekey_time) != 0 &&
d719927e 9493 now == ssh->next_rekey) {
f382c87d 9494 do_ssh2_transport(ssh, "timeout", -1, NULL);
9442dd57 9495 }
9496}
9497
1c1a7262 9498static void ssh2_protocol(Ssh ssh, void *vin, int inlen,
ff3187f6 9499 struct Packet *pktin)
7cca0d81 9500{
1c1a7262 9501 unsigned char *in = (unsigned char *)vin;
b09eaa88 9502 if (ssh->state == SSH_STATE_CLOSED)
9503 return;
9504
9442dd57 9505 if (pktin) {
9506 ssh->incoming_data_size += pktin->encrypted_len;
9507 if (!ssh->kex_in_progress &&
d57f70af 9508 ssh->max_data_size != 0 &&
9509 ssh->incoming_data_size > ssh->max_data_size)
f382c87d 9510 do_ssh2_transport(ssh, "too much data received", -1, NULL);
9442dd57 9511 }
9512
bc074147 9513 if (pktin)
b09eaa88 9514 ssh->packet_dispatch[pktin->type](ssh, pktin);
bc074147 9515 else if (!ssh->protocol_initial_phase_done)
9516 do_ssh2_transport(ssh, in, inlen, pktin);
9517 else
b09eaa88 9518 do_ssh2_authconn(ssh, in, inlen, pktin);
7cca0d81 9519}
9520
4a693cfc 9521static void ssh_cache_conf_values(Ssh ssh)
9522{
9523 ssh->logomitdata = conf_get_int(ssh->conf, CONF_logomitdata);
9524}
9525
7cca0d81 9526/*
8df7a775 9527 * Called to set up the connection.
374330e2 9528 *
9529 * Returns an error message, or NULL on success.
374330e2 9530 */
cbe2d68f 9531static const char *ssh_init(void *frontend_handle, void **backend_handle,
4a693cfc 9532 Conf *conf, char *host, int port, char **realhost,
9533 int nodelay, int keepalive)
32874aea 9534{
cbe2d68f 9535 const char *p;
51470298 9536 Ssh ssh;
9537
3d88e64d 9538 ssh = snew(struct ssh_tag);
4a693cfc 9539 ssh->conf = conf_copy(conf);
9540 ssh_cache_conf_values(ssh);
125105d1 9541 ssh->version = 0; /* when not ready yet */
51470298 9542 ssh->s = NULL;
9543 ssh->cipher = NULL;
371e569c 9544 ssh->v1_cipher_ctx = NULL;
0183b242 9545 ssh->crcda_ctx = NULL;
51470298 9546 ssh->cscipher = NULL;
371e569c 9547 ssh->cs_cipher_ctx = NULL;
51470298 9548 ssh->sccipher = NULL;
371e569c 9549 ssh->sc_cipher_ctx = NULL;
51470298 9550 ssh->csmac = NULL;
a8327734 9551 ssh->cs_mac_ctx = NULL;
51470298 9552 ssh->scmac = NULL;
e0e1a00d 9553 ssh->sc_mac_ctx = NULL;
51470298 9554 ssh->cscomp = NULL;
5366aed8 9555 ssh->cs_comp_ctx = NULL;
51470298 9556 ssh->sccomp = NULL;
5366aed8 9557 ssh->sc_comp_ctx = NULL;
51470298 9558 ssh->kex = NULL;
389aa499 9559 ssh->kex_ctx = NULL;
51470298 9560 ssh->hostkey = NULL;
9561 ssh->exitcode = -1;
ac934965 9562 ssh->close_expected = FALSE;
9e296bfa 9563 ssh->clean_exit = FALSE;
51470298 9564 ssh->state = SSH_STATE_PREPACKET;
9565 ssh->size_needed = FALSE;
9566 ssh->eof_needed = FALSE;
b9d7bcad 9567 ssh->ldisc = NULL;
a8327734 9568 ssh->logctx = NULL;
51470298 9569 ssh->deferred_send_data = NULL;
9570 ssh->deferred_len = 0;
9571 ssh->deferred_size = 0;
9572 ssh->fallback_cmd = 0;
acab36bc 9573 ssh->pkt_kctx = SSH2_PKTCTX_NOKEX;
9574 ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
8def70c3 9575 ssh->x11disp = NULL;
be738459 9576 ssh->v1_compressing = FALSE;
51470298 9577 ssh->v2_outgoing_sequence = 0;
9578 ssh->ssh1_rdpkt_crstate = 0;
9579 ssh->ssh2_rdpkt_crstate = 0;
51470298 9580 ssh->ssh_gotdata_crstate = 0;
b09eaa88 9581 ssh->do_ssh1_connection_crstate = 0;
51470298 9582 ssh->do_ssh_init_state = NULL;
9583 ssh->do_ssh1_login_state = NULL;
9584 ssh->do_ssh2_transport_state = NULL;
9585 ssh->do_ssh2_authconn_state = NULL;
4320baf7 9586 ssh->v_c = NULL;
9587 ssh->v_s = NULL;
6571dbfd 9588 ssh->mainchan = NULL;
968d2d92 9589 ssh->throttled_all = 0;
9590 ssh->v1_stdout_throttling = 0;
590f6a5f 9591 ssh->queue = NULL;
9592 ssh->queuelen = ssh->queuesize = 0;
9593 ssh->queueing = FALSE;
06fadff5 9594 ssh->qhead = ssh->qtail = NULL;
e13bba36 9595 ssh->deferred_rekey_reason = NULL;
3d9449a1 9596 bufchain_init(&ssh->queued_incoming_data);
9597 ssh->frozen = FALSE;
4a693cfc 9598 ssh->username = NULL;
bc06669b 9599 ssh->sent_console_eof = FALSE;
4a202fc6 9600 ssh->got_pty = FALSE;
51470298 9601
9602 *backend_handle = ssh;
32874aea 9603
8f203108 9604#ifdef MSCRYPTOAPI
32874aea 9605 if (crypto_startup() == 0)
8f203108 9606 return "Microsoft high encryption pack not installed!";
9607#endif
374330e2 9608
51470298 9609 ssh->frontend = frontend_handle;
4a693cfc 9610 ssh->term_width = conf_get_int(ssh->conf, CONF_width);
9611 ssh->term_height = conf_get_int(ssh->conf, CONF_height);
887035a5 9612
fabd1805 9613 ssh->channels = NULL;
9614 ssh->rportfwds = NULL;
f47a5ffb 9615 ssh->portfwds = NULL;
fabd1805 9616
51470298 9617 ssh->send_ok = 0;
9618 ssh->editing = 0;
9619 ssh->echoing = 0;
ff68564b 9620 ssh->conn_throttle_count = 0;
51470298 9621 ssh->overall_bufsize = 0;
9622 ssh->fallback_cmd = 0;
8df7a775 9623
3648d4c5 9624 ssh->protocol = NULL;
9625
b09eaa88 9626 ssh->protocol_initial_phase_done = FALSE;
9627
39934deb 9628 ssh->pinger = NULL;
9629
9442dd57 9630 ssh->incoming_data_size = ssh->outgoing_data_size =
9631 ssh->deferred_data_size = 0L;
4a693cfc 9632 ssh->max_data_size = parse_blocksize(conf_get_str(ssh->conf,
9633 CONF_ssh_rekey_data));
9442dd57 9634 ssh->kex_in_progress = FALSE;
9635
1e00c92b 9636#ifndef NO_GSSAPI
9637 ssh->gsslibs = NULL;
9638#endif
9639
79bf227b 9640 p = connect_to_host(ssh, host, port, realhost, nodelay, keepalive);
fb09bf1c 9641 if (p != NULL)
9642 return p;
374330e2 9643
5d17ccfc 9644 random_ref();
9645
374330e2 9646 return NULL;
9647}
9648
fabd1805 9649static void ssh_free(void *handle)
9650{
9651 Ssh ssh = (Ssh) handle;
9652 struct ssh_channel *c;
9653 struct ssh_rportfwd *pf;
9654
9655 if (ssh->v1_cipher_ctx)
9656 ssh->cipher->free_context(ssh->v1_cipher_ctx);
9657 if (ssh->cs_cipher_ctx)
9658 ssh->cscipher->free_context(ssh->cs_cipher_ctx);
9659 if (ssh->sc_cipher_ctx)
9660 ssh->sccipher->free_context(ssh->sc_cipher_ctx);
9661 if (ssh->cs_mac_ctx)
9662 ssh->csmac->free_context(ssh->cs_mac_ctx);
9663 if (ssh->sc_mac_ctx)
9664 ssh->scmac->free_context(ssh->sc_mac_ctx);
29b1d0b3 9665 if (ssh->cs_comp_ctx) {
9666 if (ssh->cscomp)
9667 ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
9668 else
9669 zlib_compress_cleanup(ssh->cs_comp_ctx);
9670 }
9671 if (ssh->sc_comp_ctx) {
9672 if (ssh->sccomp)
9673 ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
9674 else
9675 zlib_decompress_cleanup(ssh->sc_comp_ctx);
9676 }
fabd1805 9677 if (ssh->kex_ctx)
9678 dh_cleanup(ssh->kex_ctx);
9679 sfree(ssh->savedhost);
9680
590f6a5f 9681 while (ssh->queuelen-- > 0)
9682 ssh_free_packet(ssh->queue[ssh->queuelen]);
9683 sfree(ssh->queue);
9684
06fadff5 9685 while (ssh->qhead) {
9686 struct queued_handler *qh = ssh->qhead;
9687 ssh->qhead = qh->next;
9688 sfree(ssh->qhead);
9689 }
9690 ssh->qhead = ssh->qtail = NULL;
9691
fabd1805 9692 if (ssh->channels) {
9693 while ((c = delpos234(ssh->channels, 0)) != NULL) {
9694 switch (c->type) {
9695 case CHAN_X11:
9696 if (c->u.x11.s != NULL)
9697 x11_close(c->u.x11.s);
9698 break;
9699 case CHAN_SOCKDATA:
409eca86 9700 case CHAN_SOCKDATA_DORMANT:
fabd1805 9701 if (c->u.pfd.s != NULL)
9702 pfd_close(c->u.pfd.s);
9703 break;
9704 }
3620f307 9705 if (ssh->version == 2) {
9706 struct outstanding_channel_request *ocr, *nocr;
9707 ocr = c->v.v2.chanreq_head;
9708 while (ocr) {
9709 ocr->handler(c, NULL, ocr->ctx);
9710 nocr = ocr->next;
9711 sfree(ocr);
9712 ocr = nocr;
9713 }
9714 bufchain_clear(&c->v.v2.outbuffer);
9715 }
fabd1805 9716 sfree(c);
9717 }
9718 freetree234(ssh->channels);
cdb52705 9719 ssh->channels = NULL;
fabd1805 9720 }
9721
9722 if (ssh->rportfwds) {
9723 while ((pf = delpos234(ssh->rportfwds, 0)) != NULL)
8aea57fd 9724 free_rportfwd(pf);
fabd1805 9725 freetree234(ssh->rportfwds);
cdb52705 9726 ssh->rportfwds = NULL;
fabd1805 9727 }
9728 sfree(ssh->deferred_send_data);
8def70c3 9729 if (ssh->x11disp)
9730 x11_free_display(ssh->x11disp);
fabd1805 9731 sfree(ssh->do_ssh_init_state);
9732 sfree(ssh->do_ssh1_login_state);
9733 sfree(ssh->do_ssh2_transport_state);
9734 sfree(ssh->do_ssh2_authconn_state);
4320baf7 9735 sfree(ssh->v_c);
9736 sfree(ssh->v_s);
42af6a67 9737 sfree(ssh->fullhostname);
679539d7 9738 if (ssh->crcda_ctx) {
9739 crcda_free_context(ssh->crcda_ctx);
9740 ssh->crcda_ctx = NULL;
9741 }
fabd1805 9742 if (ssh->s)
ac934965 9743 ssh_do_close(ssh, TRUE);
9442dd57 9744 expire_timer_context(ssh);
39934deb 9745 if (ssh->pinger)
9746 pinger_free(ssh->pinger);
3d9449a1 9747 bufchain_clear(&ssh->queued_incoming_data);
4a693cfc 9748 sfree(ssh->username);
9749 conf_free(ssh->conf);
1e00c92b 9750#ifndef NO_GSSAPI
9751 if (ssh->gsslibs)
9752 ssh_gss_cleanup(ssh->gsslibs);
9753#endif
ee50e8b6 9754 sfree(ssh);
5d17ccfc 9755
9756 random_unref();
fabd1805 9757}
9758
374330e2 9759/*
86916870 9760 * Reconfigure the SSH backend.
86916870 9761 */
4a693cfc 9762static void ssh_reconfig(void *handle, Conf *conf)
86916870 9763{
9764 Ssh ssh = (Ssh) handle;
e13bba36 9765 char *rekeying = NULL, rekey_mandatory = FALSE;
e6c1536e 9766 unsigned long old_max_data_size;
4a693cfc 9767 int i, rekey_time;
e6c1536e 9768
4a693cfc 9769 pinger_reconfig(ssh->pinger, ssh->conf, conf);
3b6606c7 9770 if (ssh->portfwds)
4a693cfc 9771 ssh_setup_portfwd(ssh, conf);
e6c1536e 9772
4a693cfc 9773 rekey_time = conf_get_int(conf, CONF_ssh_rekey_time);
9774 if (conf_get_int(ssh->conf, CONF_ssh_rekey_time) != rekey_time &&
9775 rekey_time != 0) {
d719927e 9776 unsigned long new_next = ssh->last_rekey + rekey_time*60*TICKSPERSEC;
9777 unsigned long now = GETTICKCOUNT();
e6c1536e 9778
d719927e 9779 if (now - ssh->last_rekey > rekey_time*60*TICKSPERSEC) {
f382c87d 9780 rekeying = "timeout shortened";
e6c1536e 9781 } else {
9782 ssh->next_rekey = schedule_timer(new_next - now, ssh2_timer, ssh);
9783 }
9784 }
9785
9786 old_max_data_size = ssh->max_data_size;
4a693cfc 9787 ssh->max_data_size = parse_blocksize(conf_get_str(ssh->conf,
9788 CONF_ssh_rekey_data));
e6c1536e 9789 if (old_max_data_size != ssh->max_data_size &&
9790 ssh->max_data_size != 0) {
9791 if (ssh->outgoing_data_size > ssh->max_data_size ||
9792 ssh->incoming_data_size > ssh->max_data_size)
f382c87d 9793 rekeying = "data limit lowered";
e6c1536e 9794 }
9795
4a693cfc 9796 if (conf_get_int(ssh->conf, CONF_compression) !=
9797 conf_get_int(conf, CONF_compression)) {
f382c87d 9798 rekeying = "compression setting changed";
e13bba36 9799 rekey_mandatory = TRUE;
9800 }
9801
4a693cfc 9802 for (i = 0; i < CIPHER_MAX; i++)
9803 if (conf_get_int_int(ssh->conf, CONF_ssh_cipherlist, i) !=
9804 conf_get_int_int(conf, CONF_ssh_cipherlist, i)) {
9805 rekeying = "cipher settings changed";
9806 rekey_mandatory = TRUE;
9807 }
9808 if (conf_get_int(ssh->conf, CONF_ssh2_des_cbc) !=
9809 conf_get_int(conf, CONF_ssh2_des_cbc)) {
f382c87d 9810 rekeying = "cipher settings changed";
e13bba36 9811 rekey_mandatory = TRUE;
e6c1536e 9812 }
9813
4a693cfc 9814 conf_free(ssh->conf);
9815 ssh->conf = conf_copy(conf);
9816 ssh_cache_conf_values(ssh);
e13bba36 9817
9818 if (rekeying) {
9819 if (!ssh->kex_in_progress) {
9820 do_ssh2_transport(ssh, rekeying, -1, NULL);
9821 } else if (rekey_mandatory) {
9822 ssh->deferred_rekey_reason = rekeying;
9823 }
9824 }
86916870 9825}
9826
9827/*
86dc445a 9828 * Called to send data down the SSH connection.
374330e2 9829 */
51470298 9830static int ssh_send(void *handle, char *buf, int len)
32874aea 9831{
51470298 9832 Ssh ssh = (Ssh) handle;
9833
9834 if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
5471d09a 9835 return 0;
374330e2 9836
d8baa528 9837 ssh->protocol(ssh, (unsigned char *)buf, len, 0);
5471d09a 9838
51470298 9839 return ssh_sendbuffer(ssh);
5471d09a 9840}
9841
9842/*
9843 * Called to query the current amount of buffered stdin data.
9844 */
51470298 9845static int ssh_sendbuffer(void *handle)
5471d09a 9846{
51470298 9847 Ssh ssh = (Ssh) handle;
5471d09a 9848 int override_value;
9849
51470298 9850 if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
5471d09a 9851 return 0;
9852
9853 /*
9854 * If the SSH socket itself has backed up, add the total backup
9855 * size on that to any individual buffer on the stdin channel.
9856 */
9857 override_value = 0;
51470298 9858 if (ssh->throttled_all)
9859 override_value = ssh->overall_bufsize;
5471d09a 9860
51470298 9861 if (ssh->version == 1) {
5471d09a 9862 return override_value;
51470298 9863 } else if (ssh->version == 2) {
bc06669b 9864 if (!ssh->mainchan)
5471d09a 9865 return override_value;
9866 else
51470298 9867 return (override_value +
9868 bufchain_size(&ssh->mainchan->v.v2.outbuffer));
5471d09a 9869 }
9870
9871 return 0;
374330e2 9872}
9873
9874/*
6e48c3fe 9875 * Called to set the size of the window from SSH's POV.
374330e2 9876 */
51470298 9877static void ssh_size(void *handle, int width, int height)
32874aea 9878{
51470298 9879 Ssh ssh = (Ssh) handle;
ff3187f6 9880 struct Packet *pktout;
51470298 9881
9882 ssh->term_width = width;
9883 ssh->term_height = height;
f278d6f8 9884
51470298 9885 switch (ssh->state) {
374330e2 9886 case SSH_STATE_BEFORE_SIZE:
3687d221 9887 case SSH_STATE_PREPACKET:
21248260 9888 case SSH_STATE_CLOSED:
374330e2 9889 break; /* do nothing */
9890 case SSH_STATE_INTERMED:
51470298 9891 ssh->size_needed = TRUE; /* buffer for later */
374330e2 9892 break;
9893 case SSH_STATE_SESSION:
4a693cfc 9894 if (!conf_get_int(ssh->conf, CONF_nopty)) {
51470298 9895 if (ssh->version == 1) {
9896 send_packet(ssh, SSH1_CMSG_WINDOW_SIZE,
9897 PKT_INT, ssh->term_height,
9898 PKT_INT, ssh->term_width,
32874aea 9899 PKT_INT, 0, PKT_INT, 0, PKT_END);
0ed48730 9900 } else if (ssh->mainchan) {
134f5ece 9901 pktout = ssh2_chanreq_init(ssh->mainchan, "window-change",
9902 NULL, NULL);
ff3187f6 9903 ssh2_pkt_adduint32(pktout, ssh->term_width);
9904 ssh2_pkt_adduint32(pktout, ssh->term_height);
9905 ssh2_pkt_adduint32(pktout, 0);
9906 ssh2_pkt_adduint32(pktout, 0);
9907 ssh2_pkt_send(ssh, pktout);
32874aea 9908 }
9909 }
9910 break;
374330e2 9911 }
9912}
9913
9914/*
125105d1 9915 * Return a list of the special codes that make sense in this
9916 * protocol.
9917 */
9918static const struct telnet_special *ssh_get_specials(void *handle)
9919{
786ba75e 9920 static const struct telnet_special ssh1_ignore_special[] = {
9921 {"IGNORE message", TS_NOP}
9922 };
cf6ddb95 9923 static const struct telnet_special ssh2_ignore_special[] = {
62638676 9924 {"IGNORE message", TS_NOP},
cf6ddb95 9925 };
9926 static const struct telnet_special ssh2_rekey_special[] = {
9442dd57 9927 {"Repeat key exchange", TS_REKEY},
62638676 9928 };
9929 static const struct telnet_special ssh2_session_specials[] = {
6f2d0cde 9930 {NULL, TS_SEP},
9931 {"Break", TS_BRK},
bccbeb71 9932 /* These are the signal names defined by RFC 4254.
6f2d0cde 9933 * They include all the ISO C signals, but are a subset of the POSIX
9934 * required signals. */
9935 {"SIGINT (Interrupt)", TS_SIGINT},
9936 {"SIGTERM (Terminate)", TS_SIGTERM},
9937 {"SIGKILL (Kill)", TS_SIGKILL},
9938 {"SIGQUIT (Quit)", TS_SIGQUIT},
9939 {"SIGHUP (Hangup)", TS_SIGHUP},
9940 {"More signals", TS_SUBMENU},
9941 {"SIGABRT", TS_SIGABRT}, {"SIGALRM", TS_SIGALRM},
9942 {"SIGFPE", TS_SIGFPE}, {"SIGILL", TS_SIGILL},
9943 {"SIGPIPE", TS_SIGPIPE}, {"SIGSEGV", TS_SIGSEGV},
9944 {"SIGUSR1", TS_SIGUSR1}, {"SIGUSR2", TS_SIGUSR2},
9945 {NULL, TS_EXITMENU}
62638676 9946 };
9947 static const struct telnet_special specials_end[] = {
6f2d0cde 9948 {NULL, TS_EXITMENU}
62638676 9949 };
786ba75e 9950 /* XXX review this length for any changes: */
cf6ddb95 9951 static struct telnet_special ssh_specials[lenof(ssh2_ignore_special) +
9952 lenof(ssh2_rekey_special) +
62638676 9953 lenof(ssh2_session_specials) +
9954 lenof(specials_end)];
125105d1 9955 Ssh ssh = (Ssh) handle;
62638676 9956 int i = 0;
9957#define ADD_SPECIALS(name) \
9958 do { \
9959 assert((i + lenof(name)) <= lenof(ssh_specials)); \
9960 memcpy(&ssh_specials[i], name, sizeof name); \
9961 i += lenof(name); \
9962 } while(0)
125105d1 9963
9964 if (ssh->version == 1) {
62638676 9965 /* Don't bother offering IGNORE if we've decided the remote
9966 * won't cope with it, since we wouldn't bother sending it if
9967 * asked anyway. */
9968 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
786ba75e 9969 ADD_SPECIALS(ssh1_ignore_special);
125105d1 9970 } else if (ssh->version == 2) {
cf6ddb95 9971 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE))
9972 ADD_SPECIALS(ssh2_ignore_special);
9973 if (!(ssh->remote_bugs & BUG_SSH2_REKEY))
9974 ADD_SPECIALS(ssh2_rekey_special);
62638676 9975 if (ssh->mainchan)
9976 ADD_SPECIALS(ssh2_session_specials);
9977 } /* else we're not ready yet */
9978
9979 if (i) {
9980 ADD_SPECIALS(specials_end);
9981 return ssh_specials;
9982 } else {
125105d1 9983 return NULL;
62638676 9984 }
9985#undef ADD_SPECIALS
125105d1 9986}
9987
9988/*
86dc445a 9989 * Send special codes. TS_EOF is useful for `plink', so you
6abbf9e3 9990 * can send an EOF and collect resulting output (e.g. `plink
9991 * hostname sort').
374330e2 9992 */
51470298 9993static void ssh_special(void *handle, Telnet_Special code)
32874aea 9994{
51470298 9995 Ssh ssh = (Ssh) handle;
ff3187f6 9996 struct Packet *pktout;
51470298 9997
6abbf9e3 9998 if (code == TS_EOF) {
51470298 9999 if (ssh->state != SSH_STATE_SESSION) {
32874aea 10000 /*
10001 * Buffer the EOF in case we are pre-SESSION, so we can
10002 * send it as soon as we reach SESSION.
10003 */
10004 if (code == TS_EOF)
51470298 10005 ssh->eof_needed = TRUE;
32874aea 10006 return;
10007 }
51470298 10008 if (ssh->version == 1) {
10009 send_packet(ssh, SSH1_CMSG_EOF, PKT_END);
0ed48730 10010 } else if (ssh->mainchan) {
bc06669b 10011 sshfwd_write_eof(ssh->mainchan);
00a0b113 10012 ssh->send_ok = 0; /* now stop trying to read from stdin */
32874aea 10013 }
10014 logevent("Sent EOF message");
125105d1 10015 } else if (code == TS_PING || code == TS_NOP) {
51470298 10016 if (ssh->state == SSH_STATE_CLOSED
10017 || ssh->state == SSH_STATE_PREPACKET) return;
10018 if (ssh->version == 1) {
10019 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
10020 send_packet(ssh, SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
32874aea 10021 } else {
cf6ddb95 10022 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE)) {
10023 pktout = ssh2_pkt_init(SSH2_MSG_IGNORE);
10024 ssh2_pkt_addstring_start(pktout);
10025 ssh2_pkt_send_noqueue(ssh, pktout);
10026 }
32874aea 10027 }
9442dd57 10028 } else if (code == TS_REKEY) {
10029 if (!ssh->kex_in_progress && ssh->version == 2) {
f382c87d 10030 do_ssh2_transport(ssh, "at user request", -1, NULL);
9442dd57 10031 }
125105d1 10032 } else if (code == TS_BRK) {
10033 if (ssh->state == SSH_STATE_CLOSED
10034 || ssh->state == SSH_STATE_PREPACKET) return;
10035 if (ssh->version == 1) {
2e85c969 10036 logevent("Unable to send BREAK signal in SSH-1");
0ed48730 10037 } else if (ssh->mainchan) {
134f5ece 10038 pktout = ssh2_chanreq_init(ssh->mainchan, "break", NULL, NULL);
ff3187f6 10039 ssh2_pkt_adduint32(pktout, 0); /* default break length */
10040 ssh2_pkt_send(ssh, pktout);
125105d1 10041 }
6abbf9e3 10042 } else {
6f2d0cde 10043 /* Is is a POSIX signal? */
10044 char *signame = NULL;
10045 if (code == TS_SIGABRT) signame = "ABRT";
10046 if (code == TS_SIGALRM) signame = "ALRM";
10047 if (code == TS_SIGFPE) signame = "FPE";
10048 if (code == TS_SIGHUP) signame = "HUP";
10049 if (code == TS_SIGILL) signame = "ILL";
10050 if (code == TS_SIGINT) signame = "INT";
10051 if (code == TS_SIGKILL) signame = "KILL";
10052 if (code == TS_SIGPIPE) signame = "PIPE";
10053 if (code == TS_SIGQUIT) signame = "QUIT";
10054 if (code == TS_SIGSEGV) signame = "SEGV";
10055 if (code == TS_SIGTERM) signame = "TERM";
10056 if (code == TS_SIGUSR1) signame = "USR1";
10057 if (code == TS_SIGUSR2) signame = "USR2";
10058 /* The SSH-2 protocol does in principle support arbitrary named
10059 * signals, including signame@domain, but we don't support those. */
10060 if (signame) {
10061 /* It's a signal. */
10062 if (ssh->version == 2 && ssh->mainchan) {
134f5ece 10063 pktout = ssh2_chanreq_init(ssh->mainchan, "signal", NULL, NULL);
ff3187f6 10064 ssh2_pkt_addstring(pktout, signame);
10065 ssh2_pkt_send(ssh, pktout);
6f2d0cde 10066 logeventf(ssh, "Sent signal SIG%s", signame);
10067 }
10068 } else {
10069 /* Never heard of it. Do nothing */
10070 }
6abbf9e3 10071 }
374330e2 10072}
10073
51470298 10074void *new_sock_channel(void *handle, Socket s)
d74d141c 10075{
51470298 10076 Ssh ssh = (Ssh) handle;
d74d141c 10077 struct ssh_channel *c;
3d88e64d 10078 c = snew(struct ssh_channel);
d74d141c 10079
70c0cbe1 10080 c->ssh = ssh;
10081 ssh2_channel_init(c);
10082 c->halfopen = TRUE;
10083 c->type = CHAN_SOCKDATA_DORMANT;/* identify channel type */
10084 c->u.pfd.s = s;
10085 add234(ssh->channels, c);
d74d141c 10086 return c;
10087}
10088
5471d09a 10089/*
10090 * This is called when stdout/stderr (the entity to which
10091 * from_backend sends data) manages to clear some backlog.
10092 */
ae9ae89f 10093static void ssh_unthrottle(void *handle, int bufsize)
5471d09a 10094{
51470298 10095 Ssh ssh = (Ssh) handle;
ff68564b 10096 int buflimit;
10097
51470298 10098 if (ssh->version == 1) {
10099 if (ssh->v1_stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
10100 ssh->v1_stdout_throttling = 0;
ff68564b 10101 ssh_throttle_conn(ssh, -1);
5471d09a 10102 }
10103 } else {
ff68564b 10104 if (ssh->mainchan) {
ab87bf1d 10105 ssh2_set_window(ssh->mainchan,
ff68564b 10106 bufsize < ssh->mainchan->v.v2.locmaxwin ?
10107 ssh->mainchan->v.v2.locmaxwin - bufsize : 0);
4a693cfc 10108 if (conf_get_int(ssh->conf, CONF_ssh_simple))
ff68564b 10109 buflimit = 0;
10110 else
10111 buflimit = ssh->mainchan->v.v2.locmaxwin;
10112 if (ssh->mainchan->throttling_conn && bufsize <= buflimit) {
10113 ssh->mainchan->throttling_conn = 0;
10114 ssh_throttle_conn(ssh, -1);
10115 }
10116 }
5471d09a 10117 }
78e71de1 10118
10119 /*
10120 * Now process any SSH connection data that was stashed in our
10121 * queue while we were frozen.
10122 */
10123 ssh_process_queued_incoming_data(ssh);
5471d09a 10124}
10125
6b78788a 10126void ssh_send_port_open(void *channel, char *hostname, int port, char *org)
d74d141c 10127{
10128 struct ssh_channel *c = (struct ssh_channel *)channel;
6b78788a 10129 Ssh ssh = c->ssh;
ff3187f6 10130 struct Packet *pktout;
d74d141c 10131
4e63d9b2 10132 logeventf(ssh, "Opening connection to %s:%d for %s", hostname, port, org);
d74d141c 10133
51470298 10134 if (ssh->version == 1) {
10135 send_packet(ssh, SSH1_MSG_PORT_OPEN,
bc240b21 10136 PKT_INT, c->localid,
10137 PKT_STR, hostname,
10138 PKT_INT, port,
31fb1866 10139 /* PKT_STR, <org:orgport>, */
bc240b21 10140 PKT_END);
10141 } else {
4a62c66d 10142 pktout = ssh2_chanopen_init(c, "direct-tcpip");
ff3187f6 10143 ssh2_pkt_addstring(pktout, hostname);
10144 ssh2_pkt_adduint32(pktout, port);
bc240b21 10145 /*
10146 * We make up values for the originator data; partly it's
10147 * too much hassle to keep track, and partly I'm not
10148 * convinced the server should be told details like that
10149 * about my local network configuration.
1f182589 10150 * The "originator IP address" is syntactically a numeric
10151 * IP address, and some servers (e.g., Tectia) get upset
10152 * if it doesn't match this syntax.
bc240b21 10153 */
1f182589 10154 ssh2_pkt_addstring(pktout, "0.0.0.0");
ff3187f6 10155 ssh2_pkt_adduint32(pktout, 0);
10156 ssh2_pkt_send(ssh, pktout);
bc240b21 10157 }
d74d141c 10158}
10159
6226c939 10160static int ssh_connected(void *handle)
32874aea 10161{
51470298 10162 Ssh ssh = (Ssh) handle;
6226c939 10163 return ssh->s != NULL;
32874aea 10164}
8ccc75b0 10165
51470298 10166static int ssh_sendok(void *handle)
32874aea 10167{
51470298 10168 Ssh ssh = (Ssh) handle;
10169 return ssh->send_ok;
32874aea 10170}
fb09bf1c 10171
51470298 10172static int ssh_ldisc(void *handle, int option)
32874aea 10173{
51470298 10174 Ssh ssh = (Ssh) handle;
32874aea 10175 if (option == LD_ECHO)
51470298 10176 return ssh->echoing;
32874aea 10177 if (option == LD_EDIT)
51470298 10178 return ssh->editing;
0965bee0 10179 return FALSE;
10180}
10181
b9d7bcad 10182static void ssh_provide_ldisc(void *handle, void *ldisc)
10183{
10184 Ssh ssh = (Ssh) handle;
10185 ssh->ldisc = ldisc;
10186}
10187
a8327734 10188static void ssh_provide_logctx(void *handle, void *logctx)
10189{
10190 Ssh ssh = (Ssh) handle;
10191 ssh->logctx = logctx;
10192}
10193
51470298 10194static int ssh_return_exitcode(void *handle)
10195{
10196 Ssh ssh = (Ssh) handle;
3bb2f322 10197 if (ssh->s != NULL)
10198 return -1;
10199 else
3c112d53 10200 return (ssh->exitcode >= 0 ? ssh->exitcode : INT_MAX);
51470298 10201}
10202
10203/*
f89c3294 10204 * cfg_info for SSH is the currently running version of the
10205 * protocol. (1 for 1; 2 for 2; 0 for not-decided-yet.)
10206 */
10207static int ssh_cfg_info(void *handle)
10208{
10209 Ssh ssh = (Ssh) handle;
10210 return ssh->version;
10211}
10212
10213/*
51470298 10214 * Gross hack: pscp will try to start SFTP but fall back to scp1 if
10215 * that fails. This variable is the means by which scp.c can reach
10216 * into the SSH code and find out which one it got.
10217 */
10218extern int ssh_fallback_cmd(void *handle)
d8d6c7e5 10219{
51470298 10220 Ssh ssh = (Ssh) handle;
10221 return ssh->fallback_cmd;
d8d6c7e5 10222}
10223
374330e2 10224Backend ssh_backend = {
10225 ssh_init,
fabd1805 10226 ssh_free,
86916870 10227 ssh_reconfig,
374330e2 10228 ssh_send,
5471d09a 10229 ssh_sendbuffer,
374330e2 10230 ssh_size,
4017be6d 10231 ssh_special,
125105d1 10232 ssh_get_specials,
6226c939 10233 ssh_connected,
d8d6c7e5 10234 ssh_return_exitcode,
97db3be4 10235 ssh_sendok,
0965bee0 10236 ssh_ldisc,
b9d7bcad 10237 ssh_provide_ldisc,
a8327734 10238 ssh_provide_logctx,
5471d09a 10239 ssh_unthrottle,
f89c3294 10240 ssh_cfg_info,
9e164d82 10241 "ssh",
10242 PROT_SSH,
97db3be4 10243 22
bc240b21 10244};