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