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