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