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