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