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