"CR implies LF" patch, based on one from Paul Coldrey.
[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;
467e064d 554 /* locwindow is signed so we can cope with excess data. */
555 int locwindow;
5471d09a 556 } v2;
557 } v;
dacbd0e8 558 union {
32874aea 559 struct ssh_agent_channel {
560 unsigned char *message;
561 unsigned char msglen[4];
a03c9f9c 562 unsigned lensofar, totallen;
32874aea 563 } a;
564 struct ssh_x11_channel {
565 Socket s;
566 } x11;
d74d141c 567 struct ssh_pfd_channel {
568 Socket s;
569 } pfd;
dacbd0e8 570 } u;
571};
57476f6b 572
d74d141c 573/*
2e85c969 574 * 2-3-4 tree storing remote->local port forwardings. SSH-1 and SSH-2
575 * use this structure in different ways, reflecting SSH-2's
bc240b21 576 * altogether saner approach to port forwarding.
577 *
2e85c969 578 * In SSH-1, you arrange a remote forwarding by sending the server
bc240b21 579 * the remote port number, and the local destination host:port.
580 * When a connection comes in, the server sends you back that
581 * host:port pair, and you connect to it. This is a ready-made
582 * security hole if you're not on the ball: a malicious server
583 * could send you back _any_ host:port pair, so if you trustingly
584 * connect to the address it gives you then you've just opened the
585 * entire inside of your corporate network just by connecting
586 * through it to a dodgy SSH server. Hence, we must store a list of
587 * host:port pairs we _are_ trying to forward to, and reject a
588 * connection request from the server if it's not in the list.
589 *
2e85c969 590 * In SSH-2, each side of the connection minds its own business and
bc240b21 591 * doesn't send unnecessary information to the other. You arrange a
592 * remote forwarding by sending the server just the remote port
593 * number. When a connection comes in, the server tells you which
594 * of its ports was connected to; and _you_ have to remember what
595 * local host:port pair went with that port number.
596 *
2e85c969 597 * Hence, in SSH-1 this structure is indexed by destination
598 * host:port pair, whereas in SSH-2 it is indexed by source port.
d74d141c 599 */
fda2feb1 600struct ssh_portfwd; /* forward declaration */
601
d74d141c 602struct ssh_rportfwd {
bc240b21 603 unsigned sport, dport;
604 char dhost[256];
06fadff5 605 char *sportdesc;
fda2feb1 606 struct ssh_portfwd *pfrec;
d74d141c 607};
fda2feb1 608#define free_rportfwd(pf) ( \
609 ((pf) ? (sfree((pf)->sportdesc)) : (void)0 ), sfree(pf) )
610
611/*
612 * Separately to the rportfwd tree (which is for looking up port
613 * open requests from the server), a tree of _these_ structures is
614 * used to keep track of all the currently open port forwardings,
615 * so that we can reconfigure in mid-session if the user requests
616 * it.
617 */
618struct ssh_portfwd {
84328ddb 619 enum { DESTROY, KEEP, CREATE } status;
fda2feb1 620 int type;
621 unsigned sport, dport;
622 char *saddr, *daddr;
3fe92132 623 char *sserv, *dserv;
fda2feb1 624 struct ssh_rportfwd *remote;
05581745 625 int addressfamily;
fda2feb1 626 void *local;
627};
628#define free_portfwd(pf) ( \
3fe92132 629 ((pf) ? (sfree((pf)->saddr), sfree((pf)->daddr), \
630 sfree((pf)->sserv), sfree((pf)->dserv)) : (void)0 ), sfree(pf) )
d74d141c 631
57476f6b 632struct Packet {
dacd8872 633 long length; /* length of `data' actually used */
634 long forcepad; /* SSH-2: force padding to at least this length */
635 int type; /* only used for incoming packets */
636 unsigned long sequence; /* SSH-2 incoming sequence number */
637 unsigned char *data; /* allocated storage */
638 unsigned char *body; /* offset of payload within `data' */
639 long savedpos; /* temporary index into `data' (for strings) */
640 long maxlen; /* amount of storage allocated for `data' */
641 long encrypted_len; /* for SSH-2 total-size counting */
ff3187f6 642
643 /*
644 * State associated with packet logging
645 */
646 int logmode;
647 int nblanks;
648 struct logblank_t *blanks;
57476f6b 649};
650
1c1a7262 651static void ssh1_protocol(Ssh ssh, void *vin, int inlen,
ff3187f6 652 struct Packet *pktin);
1c1a7262 653static void ssh2_protocol(Ssh ssh, void *vin, int inlen,
ff3187f6 654 struct Packet *pktin);
b09eaa88 655static void ssh1_protocol_setup(Ssh ssh);
656static void ssh2_protocol_setup(Ssh ssh);
51470298 657static void ssh_size(void *handle, int width, int height);
658static void ssh_special(void *handle, Telnet_Special);
5471d09a 659static int ssh2_try_send(struct ssh_channel *c);
51470298 660static void ssh2_add_channel_data(struct ssh_channel *c, char *buf, int len);
661static void ssh_throttle_all(Ssh ssh, int enable, int bufsize);
5471d09a 662static void ssh2_set_window(struct ssh_channel *c, unsigned newwin);
51470298 663static int ssh_sendbuffer(void *handle);
ac934965 664static int ssh_do_close(Ssh ssh, int notify_exit);
ff3187f6 665static unsigned long ssh_pkt_getuint32(struct Packet *pkt);
666static int ssh2_pkt_getbool(struct Packet *pkt);
667static void ssh_pkt_getstring(struct Packet *pkt, char **p, int *length);
9442dd57 668static void ssh2_timer(void *ctx, long now);
1c1a7262 669static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
9442dd57 670 struct Packet *pktin);
57476f6b 671
51470298 672struct rdpkt1_state_tag {
57476f6b 673 long len, pad, biglen, to_read;
674 unsigned long realcrc, gotcrc;
675 unsigned char *p;
676 int i;
677 int chunk;
ff3187f6 678 struct Packet *pktin;
51470298 679};
57476f6b 680
51470298 681struct rdpkt2_state_tag {
960e736a 682 long len, pad, payload, packetlen, maclen;
683 int i;
684 int cipherblk;
685 unsigned long incoming_sequence;
ff3187f6 686 struct Packet *pktin;
51470298 687};
688
b09eaa88 689typedef void (*handler_fn_t)(Ssh ssh, struct Packet *pktin);
06fadff5 690typedef void (*chandler_fn_t)(Ssh ssh, struct Packet *pktin, void *ctx);
691
692struct queued_handler;
693struct queued_handler {
694 int msg1, msg2;
695 chandler_fn_t handler;
696 void *ctx;
697 struct queued_handler *next;
698};
b09eaa88 699
51470298 700struct ssh_tag {
701 const struct plug_function_table *fn;
702 /* the above field _must_ be first in the structure */
703
4320baf7 704 char *v_c, *v_s;
b672f405 705 void *exhash;
51470298 706
707 Socket s;
708
b9d7bcad 709 void *ldisc;
a8327734 710 void *logctx;
b9d7bcad 711
51470298 712 unsigned char session_key[32];
713 int v1_compressing;
714 int v1_remote_protoflags;
715 int v1_local_protoflags;
716 int agentfwd_enabled;
717 int X11_fwd_enabled;
718 int remote_bugs;
719 const struct ssh_cipher *cipher;
371e569c 720 void *v1_cipher_ctx;
0183b242 721 void *crcda_ctx;
51470298 722 const struct ssh2_cipher *cscipher, *sccipher;
371e569c 723 void *cs_cipher_ctx, *sc_cipher_ctx;
51470298 724 const struct ssh_mac *csmac, *scmac;
e0e1a00d 725 void *cs_mac_ctx, *sc_mac_ctx;
51470298 726 const struct ssh_compress *cscomp, *sccomp;
5366aed8 727 void *cs_comp_ctx, *sc_comp_ctx;
51470298 728 const struct ssh_kex *kex;
729 const struct ssh_signkey *hostkey;
754c0df9 730 unsigned char v2_session_id[SSH2_KEX_MAX_HASH_LEN];
b672f405 731 int v2_session_id_len;
27cd7fc2 732 void *kex_ctx;
51470298 733
734 char *savedhost;
735 int savedport;
736 int send_ok;
737 int echoing, editing;
738
739 void *frontend;
740
db219738 741 int ospeed, ispeed; /* temporaries */
51470298 742 int term_width, term_height;
743
744 tree234 *channels; /* indexed by local id */
745 struct ssh_channel *mainchan; /* primary session channel */
feb02b4e 746 int ncmode; /* is primary channel direct-tcpip? */
51470298 747 int exitcode;
ac934965 748 int close_expected;
9e296bfa 749 int clean_exit;
51470298 750
fda2feb1 751 tree234 *rportfwds, *portfwds;
51470298 752
753 enum {
754 SSH_STATE_PREPACKET,
755 SSH_STATE_BEFORE_SIZE,
756 SSH_STATE_INTERMED,
757 SSH_STATE_SESSION,
758 SSH_STATE_CLOSED
759 } state;
760
761 int size_needed, eof_needed;
762
590f6a5f 763 struct Packet **queue;
764 int queuelen, queuesize;
765 int queueing;
51470298 766 unsigned char *deferred_send_data;
767 int deferred_len, deferred_size;
768
769 /*
770 * Gross hack: pscp will try to start SFTP but fall back to
771 * scp1 if that fails. This variable is the means by which
772 * scp.c can reach into the SSH code and find out which one it
773 * got.
774 */
775 int fallback_cmd;
776
6bbce591 777 bufchain banner; /* accumulates banners during do_ssh2_authconn */
51470298 778
acab36bc 779 Pkt_KCtx pkt_kctx;
780 Pkt_ACtx pkt_actx;
51470298 781
302121de 782 void *x11auth;
783
51470298 784 int version;
785 int v1_throttle_count;
786 int overall_bufsize;
787 int throttled_all;
788 int v1_stdout_throttling;
a8756193 789 unsigned long v2_outgoing_sequence;
51470298 790
791 int ssh1_rdpkt_crstate;
792 int ssh2_rdpkt_crstate;
793 int do_ssh_init_crstate;
794 int ssh_gotdata_crstate;
51470298 795 int do_ssh1_login_crstate;
b09eaa88 796 int do_ssh1_connection_crstate;
51470298 797 int do_ssh2_transport_crstate;
798 int do_ssh2_authconn_crstate;
799
800 void *do_ssh_init_state;
801 void *do_ssh1_login_state;
802 void *do_ssh2_transport_state;
803 void *do_ssh2_authconn_state;
804
805 struct rdpkt1_state_tag rdpkt1_state;
806 struct rdpkt2_state_tag rdpkt2_state;
807
2e85c969 808 /* SSH-1 and SSH-2 use this for different things, but both use it */
b09eaa88 809 int protocol_initial_phase_done;
810
1c1a7262 811 void (*protocol) (Ssh ssh, void *vin, int inlen,
ff3187f6 812 struct Packet *pkt);
813 struct Packet *(*s_rdpkt) (Ssh ssh, unsigned char **data, int *datalen);
86916870 814
815 /*
816 * We maintain a full _copy_ of a Config structure here, not
817 * merely a pointer to it. That way, when we're passed a new
818 * one for reconfiguration, we can check the differences and
819 * potentially reconfigure port forwardings etc in mid-session.
820 */
821 Config cfg;
839f10db 822
823 /*
3d9449a1 824 * Used to transfer data back from async callbacks.
839f10db 825 */
826 void *agent_response;
827 int agent_response_len;
3d9449a1 828 int user_response;
829
830 /*
831 * The SSH connection can be set as `frozen', meaning we are
832 * not currently accepting incoming data from the network. This
833 * is slightly more serious than setting the _socket_ as
834 * frozen, because we may already have had data passed to us
835 * from the network which we need to delay processing until
836 * after the freeze is lifted, so we also need a bufchain to
837 * store that data.
838 */
839 int frozen;
840 bufchain queued_incoming_data;
b09eaa88 841
842 /*
843 * Dispatch table for packet types that we may have to deal
844 * with at any time.
845 */
846 handler_fn_t packet_dispatch[256];
39934deb 847
848 /*
06fadff5 849 * Queues of one-off handler functions for success/failure
850 * indications from a request.
851 */
852 struct queued_handler *qhead, *qtail;
853
854 /*
39934deb 855 * This module deals with sending keepalives.
856 */
857 Pinger pinger;
9442dd57 858
859 /*
860 * Track incoming and outgoing data sizes and time, for
861 * size-based rekeys.
862 */
863 unsigned long incoming_data_size, outgoing_data_size, deferred_data_size;
d57f70af 864 unsigned long max_data_size;
9442dd57 865 int kex_in_progress;
e6c1536e 866 long next_rekey, last_rekey;
e13bba36 867 char *deferred_rekey_reason; /* points to STATIC string; don't free */
51470298 868};
960e736a 869
382908ad 870#define logevent(s) logevent(ssh->frontend, s)
a8327734 871
872/* logevent, only printf-formatted. */
cbe2d68f 873static void logeventf(Ssh ssh, const char *fmt, ...)
a8327734 874{
875 va_list ap;
57356d63 876 char *buf;
a8327734 877
878 va_start(ap, fmt);
57356d63 879 buf = dupvprintf(fmt, ap);
a8327734 880 va_end(ap);
57356d63 881 logevent(buf);
57356d63 882 sfree(buf);
a8327734 883}
884
6b5cf8b4 885#define bombout(msg) \
886 do { \
887 char *text = dupprintf msg; \
ac934965 888 ssh_do_close(ssh, FALSE); \
6b5cf8b4 889 logevent(text); \
890 connection_fatal(ssh->frontend, "%s", text); \
891 sfree(text); \
892 } while (0)
a8327734 893
9a10ecf4 894/* Functions to leave bits out of the SSH packet log file. */
895
ff3187f6 896static void dont_log_password(Ssh ssh, struct Packet *pkt, int blanktype)
9a10ecf4 897{
898 if (ssh->cfg.logomitpass)
ff3187f6 899 pkt->logmode = blanktype;
9a10ecf4 900}
901
ff3187f6 902static void dont_log_data(Ssh ssh, struct Packet *pkt, int blanktype)
9a10ecf4 903{
904 if (ssh->cfg.logomitdata)
ff3187f6 905 pkt->logmode = blanktype;
9a10ecf4 906}
907
ff3187f6 908static void end_log_omission(Ssh ssh, struct Packet *pkt)
9a10ecf4 909{
ff3187f6 910 pkt->logmode = PKTLOG_EMIT;
9a10ecf4 911}
912
c6ccd5c2 913/* Helper function for common bits of parsing cfg.ttymodes. */
914static void parse_ttymodes(Ssh ssh, char *modes,
915 void (*do_mode)(void *data, char *mode, char *val),
916 void *data)
917{
918 while (*modes) {
919 char *t = strchr(modes, '\t');
920 char *m = snewn(t-modes+1, char);
921 char *val;
922 strncpy(m, modes, t-modes);
923 m[t-modes] = '\0';
924 if (*(t+1) == 'A')
925 val = get_ttymode(ssh->frontend, m);
926 else
927 val = dupstr(t+2);
928 if (val)
929 do_mode(data, m, val);
930 sfree(m);
931 sfree(val);
932 modes += strlen(modes) + 1;
933 }
934}
935
32874aea 936static int ssh_channelcmp(void *av, void *bv)
937{
938 struct ssh_channel *a = (struct ssh_channel *) av;
939 struct ssh_channel *b = (struct ssh_channel *) bv;
940 if (a->localid < b->localid)
941 return -1;
942 if (a->localid > b->localid)
943 return +1;
dacbd0e8 944 return 0;
945}
32874aea 946static int ssh_channelfind(void *av, void *bv)
947{
948 unsigned *a = (unsigned *) av;
949 struct ssh_channel *b = (struct ssh_channel *) bv;
950 if (*a < b->localid)
951 return -1;
952 if (*a > b->localid)
953 return +1;
dacbd0e8 954 return 0;
955}
956
bc240b21 957static int ssh_rportcmp_ssh1(void *av, void *bv)
d74d141c 958{
959 struct ssh_rportfwd *a = (struct ssh_rportfwd *) av;
960 struct ssh_rportfwd *b = (struct ssh_rportfwd *) bv;
961 int i;
bc240b21 962 if ( (i = strcmp(a->dhost, b->dhost)) != 0)
d74d141c 963 return i < 0 ? -1 : +1;
bc240b21 964 if (a->dport > b->dport)
965 return +1;
966 if (a->dport < b->dport)
967 return -1;
968 return 0;
969}
970
971static int ssh_rportcmp_ssh2(void *av, void *bv)
972{
973 struct ssh_rportfwd *a = (struct ssh_rportfwd *) av;
974 struct ssh_rportfwd *b = (struct ssh_rportfwd *) bv;
cdcbdf3b 975
bc240b21 976 if (a->sport > b->sport)
d74d141c 977 return +1;
bc240b21 978 if (a->sport < b->sport)
979 return -1;
d74d141c 980 return 0;
981}
982
fda2feb1 983/*
984 * Special form of strcmp which can cope with NULL inputs. NULL is
985 * defined to sort before even the empty string.
986 */
987static int nullstrcmp(const char *a, const char *b)
988{
989 if (a == NULL && b == NULL)
990 return 0;
991 if (a == NULL)
992 return -1;
993 if (b == NULL)
994 return +1;
995 return strcmp(a, b);
996}
997
998static int ssh_portcmp(void *av, void *bv)
999{
1000 struct ssh_portfwd *a = (struct ssh_portfwd *) av;
1001 struct ssh_portfwd *b = (struct ssh_portfwd *) bv;
1002 int i;
1003 if (a->type > b->type)
1004 return +1;
1005 if (a->type < b->type)
1006 return -1;
84328ddb 1007 if (a->addressfamily > b->addressfamily)
1008 return +1;
1009 if (a->addressfamily < b->addressfamily)
1010 return -1;
fda2feb1 1011 if ( (i = nullstrcmp(a->saddr, b->saddr)) != 0)
1012 return i < 0 ? -1 : +1;
1013 if (a->sport > b->sport)
1014 return +1;
1015 if (a->sport < b->sport)
1016 return -1;
1017 if (a->type != 'D') {
1018 if ( (i = nullstrcmp(a->daddr, b->daddr)) != 0)
1019 return i < 0 ? -1 : +1;
1020 if (a->dport > b->dport)
1021 return +1;
1022 if (a->dport < b->dport)
1023 return -1;
1024 }
1025 return 0;
1026}
1027
51470298 1028static int alloc_channel_id(Ssh ssh)
32874aea 1029{
260f3dec 1030 const unsigned CHANNEL_NUMBER_OFFSET = 256;
1031 unsigned low, high, mid;
d2371c81 1032 int tsize;
1033 struct ssh_channel *c;
1034
1035 /*
1036 * First-fit allocation of channel numbers: always pick the
1037 * lowest unused one. To do this, binary-search using the
1038 * counted B-tree to find the largest channel ID which is in a
1039 * contiguous sequence from the beginning. (Precisely
1040 * everything in that sequence must have ID equal to its tree
1041 * index plus CHANNEL_NUMBER_OFFSET.)
1042 */
51470298 1043 tsize = count234(ssh->channels);
d2371c81 1044
32874aea 1045 low = -1;
1046 high = tsize;
d2371c81 1047 while (high - low > 1) {
1048 mid = (high + low) / 2;
51470298 1049 c = index234(ssh->channels, mid);
d2371c81 1050 if (c->localid == mid + CHANNEL_NUMBER_OFFSET)
1051 low = mid; /* this one is fine */
1052 else
1053 high = mid; /* this one is past it */
1054 }
1055 /*
1056 * Now low points to either -1, or the tree index of the
1057 * largest ID in the initial sequence.
1058 */
1059 {
1060 unsigned i = low + 1 + CHANNEL_NUMBER_OFFSET;
51470298 1061 assert(NULL == find234(ssh->channels, &i, ssh_channelfind));
d2371c81 1062 }
1063 return low + 1 + CHANNEL_NUMBER_OFFSET;
1064}
1065
edd0cb8a 1066static void c_write_stderr(int trusted, const char *buf, int len)
1067{
1068 int i;
1069 for (i = 0; i < len; i++)
667deca9 1070 if (buf[i] != '\r' && (trusted || buf[i] == '\n' || (buf[i] & 0x60)))
edd0cb8a 1071 fputc(buf[i], stderr);
1072}
1073
9fab77dc 1074static void c_write(Ssh ssh, const char *buf, int len)
32874aea 1075{
edd0cb8a 1076 if (flags & FLAG_STDERR)
1077 c_write_stderr(1, buf, len);
1078 else
1079 from_backend(ssh->frontend, 1, buf, len);
3bdaf79d 1080}
1081
9fab77dc 1082static void c_write_untrusted(Ssh ssh, const char *buf, int len)
32874aea 1083{
edd0cb8a 1084 if (flags & FLAG_STDERR)
1085 c_write_stderr(0, buf, len);
1086 else
1087 from_backend_untrusted(ssh->frontend, buf, len);
a209e957 1088}
1089
9fab77dc 1090static void c_write_str(Ssh ssh, const char *buf)
32874aea 1091{
51470298 1092 c_write(ssh, buf, strlen(buf));
1408a877 1093}
1094
ff3187f6 1095static void ssh_free_packet(struct Packet *pkt)
1096{
1097 sfree(pkt->data);
1098 sfree(pkt);
1099}
1100static struct Packet *ssh_new_packet(void)
1101{
1102 struct Packet *pkt = snew(struct Packet);
1103
dacd8872 1104 pkt->body = pkt->data = NULL;
ff3187f6 1105 pkt->maxlen = 0;
1106 pkt->logmode = PKTLOG_EMIT;
1107 pkt->nblanks = 0;
1108 pkt->blanks = NULL;
1109
1110 return pkt;
1111}
1112
fb09bf1c 1113/*
1114 * Collect incoming data in the incoming packet buffer.
e5574168 1115 * Decipher and verify the packet when it is completely read.
1116 * Drop SSH1_MSG_DEBUG and SSH1_MSG_IGNORE packets.
fb09bf1c 1117 * Update the *data and *datalen variables.
ff3187f6 1118 * Return a Packet structure when a packet is completed.
fb09bf1c 1119 */
ff3187f6 1120static struct Packet *ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen)
fb09bf1c 1121{
51470298 1122 struct rdpkt1_state_tag *st = &ssh->rdpkt1_state;
374330e2 1123
51470298 1124 crBegin(ssh->ssh1_rdpkt_crstate);
374330e2 1125
ff3187f6 1126 st->pktin = ssh_new_packet();
1127
1128 st->pktin->type = 0;
1129 st->pktin->length = 0;
374330e2 1130
57476f6b 1131 for (st->i = st->len = 0; st->i < 4; st->i++) {
fb09bf1c 1132 while ((*datalen) == 0)
ff3187f6 1133 crReturn(NULL);
57476f6b 1134 st->len = (st->len << 8) + **data;
fb09bf1c 1135 (*data)++, (*datalen)--;
1136 }
374330e2 1137
57476f6b 1138 st->pad = 8 - (st->len % 8);
1139 st->biglen = st->len + st->pad;
ff3187f6 1140 st->pktin->length = st->len - 5;
fb09bf1c 1141
ae0500e5 1142 if (st->biglen < 0) {
1143 bombout(("Extremely large packet length from server suggests"
1144 " data stream corruption"));
ff3187f6 1145 ssh_free_packet(st->pktin);
1146 crStop(NULL);
ae0500e5 1147 }
1148
ff3187f6 1149 st->pktin->maxlen = st->biglen;
1150 st->pktin->data = snewn(st->biglen + APIEXTRA, unsigned char);
374330e2 1151
57476f6b 1152 st->to_read = st->biglen;
ff3187f6 1153 st->p = st->pktin->data;
57476f6b 1154 while (st->to_read > 0) {
32874aea 1155 st->chunk = st->to_read;
fb09bf1c 1156 while ((*datalen) == 0)
ff3187f6 1157 crReturn(NULL);
57476f6b 1158 if (st->chunk > (*datalen))
1159 st->chunk = (*datalen);
1160 memcpy(st->p, *data, st->chunk);
1161 *data += st->chunk;
1162 *datalen -= st->chunk;
1163 st->p += st->chunk;
1164 st->to_read -= st->chunk;
fb09bf1c 1165 }
374330e2 1166
ff3187f6 1167 if (ssh->cipher && detect_attack(ssh->crcda_ctx, st->pktin->data,
0183b242 1168 st->biglen, NULL)) {
6b5cf8b4 1169 bombout(("Network attack (CRC compensation) detected!"));
ff3187f6 1170 ssh_free_packet(st->pktin);
1171 crStop(NULL);
9a3a93a5 1172 }
1173
51470298 1174 if (ssh->cipher)
ff3187f6 1175 ssh->cipher->decrypt(ssh->v1_cipher_ctx, st->pktin->data, st->biglen);
374330e2 1176
ff3187f6 1177 st->realcrc = crc32_compute(st->pktin->data, st->biglen - 4);
1178 st->gotcrc = GET_32BIT(st->pktin->data + st->biglen - 4);
57476f6b 1179 if (st->gotcrc != st->realcrc) {
6b5cf8b4 1180 bombout(("Incorrect CRC received on packet"));
ff3187f6 1181 ssh_free_packet(st->pktin);
1182 crStop(NULL);
fb09bf1c 1183 }
572f871e 1184
ff3187f6 1185 st->pktin->body = st->pktin->data + st->pad + 1;
1186 st->pktin->savedpos = 0;
4ba9b64b 1187
51470298 1188 if (ssh->v1_compressing) {
4ba9b64b 1189 unsigned char *decompblk;
1190 int decomplen;
36b8d9bb 1191 if (!zlib_decompress_block(ssh->sc_comp_ctx,
ff3187f6 1192 st->pktin->body - 1, st->pktin->length + 1,
36b8d9bb 1193 &decompblk, &decomplen)) {
1194 bombout(("Zlib decompression encountered invalid data"));
ff3187f6 1195 ssh_free_packet(st->pktin);
1196 crStop(NULL);
36b8d9bb 1197 }
4ba9b64b 1198
ff3187f6 1199 if (st->pktin->maxlen < st->pad + decomplen) {
1200 st->pktin->maxlen = st->pad + decomplen;
1201 st->pktin->data = sresize(st->pktin->data,
1202 st->pktin->maxlen + APIEXTRA,
3d88e64d 1203 unsigned char);
ff3187f6 1204 st->pktin->body = st->pktin->data + st->pad + 1;
4ba9b64b 1205 }
1206
ff3187f6 1207 memcpy(st->pktin->body - 1, decompblk, decomplen);
dcbde236 1208 sfree(decompblk);
ff3187f6 1209 st->pktin->length = decomplen - 1;
4ba9b64b 1210 }
1211
ff3187f6 1212 st->pktin->type = st->pktin->body[-1];
00db133f 1213
9a10ecf4 1214 /*
1215 * Log incoming packet, possibly omitting sensitive fields.
1216 */
1217 if (ssh->logctx) {
1218 int nblanks = 0;
1219 struct logblank_t blank;
1220 if (ssh->cfg.logomitdata) {
1221 int do_blank = FALSE, blank_prefix = 0;
1222 /* "Session data" packets - omit the data field */
ff3187f6 1223 if ((st->pktin->type == SSH1_SMSG_STDOUT_DATA) ||
1224 (st->pktin->type == SSH1_SMSG_STDERR_DATA)) {
9a10ecf4 1225 do_blank = TRUE; blank_prefix = 4;
a2724fba 1226 } else if (st->pktin->type == SSH1_MSG_CHANNEL_DATA) {
1227 do_blank = TRUE; blank_prefix = 8;
9a10ecf4 1228 }
1229 if (do_blank) {
1230 blank.offset = blank_prefix;
ff3187f6 1231 blank.len = st->pktin->length;
9a10ecf4 1232 blank.type = PKTLOG_OMIT;
1233 nblanks = 1;
1234 }
1235 }
a8327734 1236 log_packet(ssh->logctx,
ff3187f6 1237 PKT_INCOMING, st->pktin->type,
1238 ssh1_pkt_type(st->pktin->type),
1239 st->pktin->body, st->pktin->length,
9a10ecf4 1240 nblanks, &blank);
1241 }
00db133f 1242
ff3187f6 1243 crFinish(st->pktin);
fb09bf1c 1244}
1245
ff3187f6 1246static struct Packet *ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen)
e5574168 1247{
51470298 1248 struct rdpkt2_state_tag *st = &ssh->rdpkt2_state;
e5574168 1249
51470298 1250 crBegin(ssh->ssh2_rdpkt_crstate);
e5574168 1251
ff3187f6 1252 st->pktin = ssh_new_packet();
1253
1254 st->pktin->type = 0;
1255 st->pktin->length = 0;
51470298 1256 if (ssh->sccipher)
1257 st->cipherblk = ssh->sccipher->blksize;
e5574168 1258 else
32874aea 1259 st->cipherblk = 8;
960e736a 1260 if (st->cipherblk < 8)
32874aea 1261 st->cipherblk = 8;
960e736a 1262
ff3187f6 1263 st->pktin->data = snewn(st->cipherblk + APIEXTRA, unsigned char);
e5574168 1264
1265 /*
1266 * Acquire and decrypt the first block of the packet. This will
1267 * contain the length and padding details.
1268 */
32874aea 1269 for (st->i = st->len = 0; st->i < st->cipherblk; st->i++) {
e5574168 1270 while ((*datalen) == 0)
ff3187f6 1271 crReturn(NULL);
1272 st->pktin->data[st->i] = *(*data)++;
32874aea 1273 (*datalen)--;
e5574168 1274 }
4252c9cc 1275
51470298 1276 if (ssh->sccipher)
371e569c 1277 ssh->sccipher->decrypt(ssh->sc_cipher_ctx,
ff3187f6 1278 st->pktin->data, st->cipherblk);
e5574168 1279
1280 /*
1281 * Now get the length and padding figures.
1282 */
ff3187f6 1283 st->len = GET_32BIT(st->pktin->data);
1284 st->pad = st->pktin->data[4];
e5574168 1285
1286 /*
717dc483 1287 * _Completely_ silly lengths should be stomped on before they
1288 * do us any more damage.
1289 */
cba1e4b5 1290 if (st->len < 0 || st->len > 35000 || st->pad < 4 ||
1291 st->len - st->pad < 1 || (st->len + 4) % st->cipherblk != 0) {
6b5cf8b4 1292 bombout(("Incoming packet was garbled on decryption"));
ff3187f6 1293 ssh_free_packet(st->pktin);
1294 crStop(NULL);
717dc483 1295 }
1296
1297 /*
e5574168 1298 * This enables us to deduce the payload length.
1299 */
960e736a 1300 st->payload = st->len - st->pad - 1;
e5574168 1301
ff3187f6 1302 st->pktin->length = st->payload + 5;
e5574168 1303
1304 /*
1305 * So now we can work out the total packet length.
1306 */
960e736a 1307 st->packetlen = st->len + 4;
51470298 1308 st->maclen = ssh->scmac ? ssh->scmac->len : 0;
e5574168 1309
1310 /*
ff3187f6 1311 * Allocate memory for the rest of the packet.
e5574168 1312 */
ff3187f6 1313 st->pktin->maxlen = st->packetlen + st->maclen;
1314 st->pktin->data = sresize(st->pktin->data,
1315 st->pktin->maxlen + APIEXTRA,
1316 unsigned char);
e5574168 1317
1318 /*
1319 * Read and decrypt the remainder of the packet.
1320 */
32874aea 1321 for (st->i = st->cipherblk; st->i < st->packetlen + st->maclen;
1322 st->i++) {
e5574168 1323 while ((*datalen) == 0)
ff3187f6 1324 crReturn(NULL);
1325 st->pktin->data[st->i] = *(*data)++;
32874aea 1326 (*datalen)--;
e5574168 1327 }
1328 /* Decrypt everything _except_ the MAC. */
51470298 1329 if (ssh->sccipher)
371e569c 1330 ssh->sccipher->decrypt(ssh->sc_cipher_ctx,
ff3187f6 1331 st->pktin->data + st->cipherblk,
51470298 1332 st->packetlen - st->cipherblk);
e5574168 1333
9442dd57 1334 st->pktin->encrypted_len = st->packetlen;
1335
e5574168 1336 /*
1337 * Check the MAC.
1338 */
51470298 1339 if (ssh->scmac
ff3187f6 1340 && !ssh->scmac->verify(ssh->sc_mac_ctx, st->pktin->data, st->len + 4,
51470298 1341 st->incoming_sequence)) {
6b5cf8b4 1342 bombout(("Incorrect MAC received on packet"));
ff3187f6 1343 ssh_free_packet(st->pktin);
1344 crStop(NULL);
8d5de777 1345 }
b09eaa88 1346
1347 st->pktin->sequence = st->incoming_sequence++;
e5574168 1348
4ba9b64b 1349 /*
1350 * Decompress packet payload.
1351 */
1352 {
1353 unsigned char *newpayload;
1354 int newlen;
51470298 1355 if (ssh->sccomp &&
5366aed8 1356 ssh->sccomp->decompress(ssh->sc_comp_ctx,
ff3187f6 1357 st->pktin->data + 5, st->pktin->length - 5,
51470298 1358 &newpayload, &newlen)) {
ff3187f6 1359 if (st->pktin->maxlen < newlen + 5) {
1360 st->pktin->maxlen = newlen + 5;
1361 st->pktin->data = sresize(st->pktin->data,
1362 st->pktin->maxlen + APIEXTRA,
3d88e64d 1363 unsigned char);
4ba9b64b 1364 }
ff3187f6 1365 st->pktin->length = 5 + newlen;
1366 memcpy(st->pktin->data + 5, newpayload, newlen);
dcbde236 1367 sfree(newpayload);
4ba9b64b 1368 }
1369 }
1370
ff3187f6 1371 st->pktin->savedpos = 6;
1372 st->pktin->body = st->pktin->data;
1373 st->pktin->type = st->pktin->data[5];
e5574168 1374
9a10ecf4 1375 /*
1376 * Log incoming packet, possibly omitting sensitive fields.
1377 */
1378 if (ssh->logctx) {
1379 int nblanks = 0;
1380 struct logblank_t blank;
1381 if (ssh->cfg.logomitdata) {
1382 int do_blank = FALSE, blank_prefix = 0;
1383 /* "Session data" packets - omit the data field */
ff3187f6 1384 if (st->pktin->type == SSH2_MSG_CHANNEL_DATA) {
9a10ecf4 1385 do_blank = TRUE; blank_prefix = 8;
a2724fba 1386 } else if (st->pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
1387 do_blank = TRUE; blank_prefix = 12;
9a10ecf4 1388 }
1389 if (do_blank) {
1390 blank.offset = blank_prefix;
ff3187f6 1391 blank.len = (st->pktin->length-6) - blank_prefix;
9a10ecf4 1392 blank.type = PKTLOG_OMIT;
1393 nblanks = 1;
1394 }
1395 }
ff3187f6 1396 log_packet(ssh->logctx, PKT_INCOMING, st->pktin->type,
acab36bc 1397 ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx,
1398 st->pktin->type),
ff3187f6 1399 st->pktin->data+6, st->pktin->length-6,
9a10ecf4 1400 nblanks, &blank);
1401 }
00db133f 1402
ff3187f6 1403 crFinish(st->pktin);
e5574168 1404}
1405
dacd8872 1406static int s_wrpkt_prepare(Ssh ssh, struct Packet *pkt, int *offset_p)
32874aea 1407{
dacd8872 1408 int pad, biglen, i, pktoffs;
374330e2 1409 unsigned long crc;
fd7a4aad 1410#ifdef __SC__
1411 /*
1412 * XXX various versions of SC (including 8.8.4) screw up the
1413 * register allocation in this function and use the same register
1414 * (D6) for len and as a temporary, with predictable results. The
1415 * following sledgehammer prevents this.
1416 */
1417 volatile
1418#endif
1419 int len;
374330e2 1420
a8327734 1421 if (ssh->logctx)
dacd8872 1422 log_packet(ssh->logctx, PKT_OUTGOING, pkt->data[12],
1423 ssh1_pkt_type(pkt->data[12]),
1424 pkt->body, pkt->length - (pkt->body - pkt->data),
ff3187f6 1425 pkt->nblanks, pkt->blanks);
1426 sfree(pkt->blanks); pkt->blanks = NULL;
1427 pkt->nblanks = 0;
00db133f 1428
51470298 1429 if (ssh->v1_compressing) {
4ba9b64b 1430 unsigned char *compblk;
1431 int complen;
5366aed8 1432 zlib_compress_block(ssh->cs_comp_ctx,
dacd8872 1433 pkt->data + 12, pkt->length - 12,
4ba9b64b 1434 &compblk, &complen);
48406e6b 1435 ssh_pkt_ensure(pkt, complen + 2); /* just in case it's got bigger */
dacd8872 1436 memcpy(pkt->data + 12, compblk, complen);
dcbde236 1437 sfree(compblk);
dacd8872 1438 pkt->length = complen + 12;
4ba9b64b 1439 }
1440
dacd8872 1441 ssh_pkt_ensure(pkt, pkt->length + 4); /* space for CRC */
1442 pkt->length += 4;
1443 len = pkt->length - 4 - 8; /* len(type+data+CRC) */
32874aea 1444 pad = 8 - (len % 8);
dacd8872 1445 pktoffs = 8 - pad;
1446 biglen = len + pad; /* len(padding+type+data+CRC) */
374330e2 1447
dacd8872 1448 for (i = pktoffs; i < 4+8; i++)
1449 pkt->data[i] = random_byte();
1450 crc = crc32_compute(pkt->data + pktoffs + 4, biglen - 4); /* all ex len */
1451 PUT_32BIT(pkt->data + pktoffs + 4 + biglen - 4, crc);
1452 PUT_32BIT(pkt->data + pktoffs, len);
374330e2 1453
51470298 1454 if (ssh->cipher)
dacd8872 1455 ssh->cipher->encrypt(ssh->v1_cipher_ctx,
1456 pkt->data + pktoffs + 4, biglen);
374330e2 1457
dacd8872 1458 if (offset_p) *offset_p = pktoffs;
1459 return biglen + 4; /* len(length+padding+type+data+CRC) */
39065bed 1460}
1461
bf8a49a1 1462static int s_write(Ssh ssh, void *data, int len)
1463{
ff05dfef 1464 if (ssh->logctx)
1465 log_packet(ssh->logctx, PKT_OUTGOING, -1, NULL, data, len, 0, NULL);
bf8a49a1 1466 return sk_write(ssh->s, (char *)data, len);
1467}
1468
ff3187f6 1469static void s_wrpkt(Ssh ssh, struct Packet *pkt)
32874aea 1470{
dacd8872 1471 int len, backlog, offset;
1472 len = s_wrpkt_prepare(ssh, pkt, &offset);
bf8a49a1 1473 backlog = s_write(ssh, pkt->data + offset, len);
5471d09a 1474 if (backlog > SSH_MAX_BACKLOG)
51470298 1475 ssh_throttle_all(ssh, 1, backlog);
dacd8872 1476 ssh_free_packet(pkt);
39065bed 1477}
1478
ff3187f6 1479static void s_wrpkt_defer(Ssh ssh, struct Packet *pkt)
32874aea 1480{
dacd8872 1481 int len, offset;
1482 len = s_wrpkt_prepare(ssh, pkt, &offset);
51470298 1483 if (ssh->deferred_len + len > ssh->deferred_size) {
1484 ssh->deferred_size = ssh->deferred_len + len + 128;
3d88e64d 1485 ssh->deferred_send_data = sresize(ssh->deferred_send_data,
1486 ssh->deferred_size,
1487 unsigned char);
39065bed 1488 }
dacd8872 1489 memcpy(ssh->deferred_send_data + ssh->deferred_len,
1490 pkt->data + offset, len);
51470298 1491 ssh->deferred_len += len;
dacd8872 1492 ssh_free_packet(pkt);
374330e2 1493}
1494
fb09bf1c 1495/*
dacd8872 1496 * Construct a SSH-1 packet with the specified contents.
1497 * (This all-at-once interface used to be the only one, but now SSH-1
1498 * packets can also be constructed incrementally.)
fb09bf1c 1499 */
dacd8872 1500static struct Packet *construct_packet(Ssh ssh, int pkttype, va_list ap)
fb09bf1c 1501{
dacd8872 1502 int argtype;
7cca0d81 1503 Bignum bn;
ff3187f6 1504 struct Packet *pkt;
fb09bf1c 1505
dacd8872 1506 pkt = ssh1_pkt_init(pkttype);
fb09bf1c 1507
dacd8872 1508 while ((argtype = va_arg(ap, int)) != PKT_END) {
1509 unsigned char *argp, argchar;
8a9977e5 1510 char *sargp;
dacd8872 1511 unsigned long argint;
1512 int arglen;
fb09bf1c 1513 switch (argtype) {
9a10ecf4 1514 /* Actual fields in the packet */
fb09bf1c 1515 case PKT_INT:
dacd8872 1516 argint = va_arg(ap, int);
1517 ssh_pkt_adduint32(pkt, argint);
fb09bf1c 1518 break;
1519 case PKT_CHAR:
dacd8872 1520 argchar = (unsigned char) va_arg(ap, int);
1521 ssh_pkt_addbyte(pkt, argchar);
fb09bf1c 1522 break;
1523 case PKT_DATA:
dacd8872 1524 argp = va_arg(ap, unsigned char *);
1525 arglen = va_arg(ap, int);
1526 ssh_pkt_adddata(pkt, argp, arglen);
fb09bf1c 1527 break;
1528 case PKT_STR:
8a9977e5 1529 sargp = va_arg(ap, char *);
1530 ssh_pkt_addstring(pkt, sargp);
fb09bf1c 1531 break;
7cca0d81 1532 case PKT_BIGNUM:
dacd8872 1533 bn = va_arg(ap, Bignum);
1534 ssh1_pkt_addmp(pkt, bn);
9a10ecf4 1535 break;
1536 /* Tokens for modifications to packet logging */
1537 case PKTT_PASSWORD:
ff3187f6 1538 dont_log_password(ssh, pkt, PKTLOG_BLANK);
9a10ecf4 1539 break;
1540 case PKTT_DATA:
ff3187f6 1541 dont_log_data(ssh, pkt, PKTLOG_OMIT);
7cca0d81 1542 break;
9a10ecf4 1543 case PKTT_OTHER:
ff3187f6 1544 end_log_omission(ssh, pkt);
9a10ecf4 1545 break;
1546 }
fb09bf1c 1547 }
ff3187f6 1548
1549 return pkt;
39065bed 1550}
fb09bf1c 1551
51470298 1552static void send_packet(Ssh ssh, int pkttype, ...)
32874aea 1553{
ff3187f6 1554 struct Packet *pkt;
dacd8872 1555 va_list ap;
1556 va_start(ap, pkttype);
1557 pkt = construct_packet(ssh, pkttype, ap);
1558 va_end(ap);
ff3187f6 1559 s_wrpkt(ssh, pkt);
fb09bf1c 1560}
1561
51470298 1562static void defer_packet(Ssh ssh, int pkttype, ...)
32874aea 1563{
ff3187f6 1564 struct Packet *pkt;
dacd8872 1565 va_list ap;
1566 va_start(ap, pkttype);
1567 pkt = construct_packet(ssh, pkttype, ap);
1568 va_end(ap);
ff3187f6 1569 s_wrpkt_defer(ssh, pkt);
39065bed 1570}
1571
32874aea 1572static int ssh_versioncmp(char *a, char *b)
1573{
9697bfd2 1574 char *ae, *be;
1575 unsigned long av, bv;
1576
43aa02a7 1577 av = strtoul(a, &ae, 10);
1578 bv = strtoul(b, &be, 10);
32874aea 1579 if (av != bv)
1580 return (av < bv ? -1 : +1);
1581 if (*ae == '.')
1582 ae++;
1583 if (*be == '.')
1584 be++;
43aa02a7 1585 av = strtoul(ae, &ae, 10);
1586 bv = strtoul(be, &be, 10);
32874aea 1587 if (av != bv)
1588 return (av < bv ? -1 : +1);
9697bfd2 1589 return 0;
1590}
1591
e5574168 1592/*
a92dd380 1593 * Utility routines for putting an SSH-protocol `string' and
b672f405 1594 * `uint32' into a hash state.
e5574168 1595 */
b672f405 1596static void hash_string(const struct ssh_hash *h, void *s, void *str, int len)
32874aea 1597{
e5574168 1598 unsigned char lenblk[4];
e5574168 1599 PUT_32BIT(lenblk, len);
b672f405 1600 h->bytes(s, lenblk, 4);
1601 h->bytes(s, str, len);
e5574168 1602}
1603
b672f405 1604static void hash_uint32(const struct ssh_hash *h, void *s, unsigned i)
32874aea 1605{
a92dd380 1606 unsigned char intblk[4];
1607 PUT_32BIT(intblk, i);
b672f405 1608 h->bytes(s, intblk, 4);
a92dd380 1609}
1610
7cca0d81 1611/*
dacd8872 1612 * Packet construction functions. Mostly shared between SSH-1 and SSH-2.
7cca0d81 1613 */
dacd8872 1614static void ssh_pkt_ensure(struct Packet *pkt, int length)
32874aea 1615{
ff3187f6 1616 if (pkt->maxlen < length) {
dacd8872 1617 unsigned char *body = pkt->body;
3d71de0b 1618 int offset = body ? body - pkt->data : 0;
ff3187f6 1619 pkt->maxlen = length + 256;
1620 pkt->data = sresize(pkt->data, pkt->maxlen + APIEXTRA, unsigned char);
dacd8872 1621 if (body) pkt->body = pkt->data + offset;
7cca0d81 1622 }
783415f8 1623}
dacd8872 1624static void ssh_pkt_adddata(struct Packet *pkt, void *data, int len)
32874aea 1625{
ff3187f6 1626 if (pkt->logmode != PKTLOG_EMIT) {
1627 pkt->nblanks++;
1628 pkt->blanks = sresize(pkt->blanks, pkt->nblanks, struct logblank_t);
dacd8872 1629 assert(pkt->body);
1630 pkt->blanks[pkt->nblanks-1].offset = pkt->length -
1631 (pkt->body - pkt->data);
ff3187f6 1632 pkt->blanks[pkt->nblanks-1].len = len;
1633 pkt->blanks[pkt->nblanks-1].type = pkt->logmode;
1634 }
1635 pkt->length += len;
dacd8872 1636 ssh_pkt_ensure(pkt, pkt->length);
ff3187f6 1637 memcpy(pkt->data + pkt->length - len, data, len);
7cca0d81 1638}
dacd8872 1639static void ssh_pkt_addbyte(struct Packet *pkt, unsigned char byte)
32874aea 1640{
dacd8872 1641 ssh_pkt_adddata(pkt, &byte, 1);
7cca0d81 1642}
ff3187f6 1643static void ssh2_pkt_addbool(struct Packet *pkt, unsigned char value)
32874aea 1644{
dacd8872 1645 ssh_pkt_adddata(pkt, &value, 1);
7cca0d81 1646}
dacd8872 1647static void ssh_pkt_adduint32(struct Packet *pkt, unsigned long value)
32874aea 1648{
7cca0d81 1649 unsigned char x[4];
1650 PUT_32BIT(x, value);
dacd8872 1651 ssh_pkt_adddata(pkt, x, 4);
7cca0d81 1652}
dacd8872 1653static void ssh_pkt_addstring_start(struct Packet *pkt)
32874aea 1654{
dacd8872 1655 ssh_pkt_adduint32(pkt, 0);
ff3187f6 1656 pkt->savedpos = pkt->length;
7cca0d81 1657}
dacd8872 1658static void ssh_pkt_addstring_str(struct Packet *pkt, char *data)
32874aea 1659{
dacd8872 1660 ssh_pkt_adddata(pkt, data, strlen(data));
ff3187f6 1661 PUT_32BIT(pkt->data + pkt->savedpos - 4, pkt->length - pkt->savedpos);
7cca0d81 1662}
dacd8872 1663static void ssh_pkt_addstring_data(struct Packet *pkt, char *data, int len)
32874aea 1664{
dacd8872 1665 ssh_pkt_adddata(pkt, data, len);
ff3187f6 1666 PUT_32BIT(pkt->data + pkt->savedpos - 4, pkt->length - pkt->savedpos);
7cca0d81 1667}
dacd8872 1668static void ssh_pkt_addstring(struct Packet *pkt, char *data)
1669{
1670 ssh_pkt_addstring_start(pkt);
1671 ssh_pkt_addstring_str(pkt, data);
1672}
1673static void ssh1_pkt_addmp(struct Packet *pkt, Bignum b)
32874aea 1674{
dacd8872 1675 int len = ssh1_bignum_length(b);
8a9977e5 1676 unsigned char *data = snewn(len, unsigned char);
dacd8872 1677 (void) ssh1_write_bignum(data, b);
1678 ssh_pkt_adddata(pkt, data, len);
1679 sfree(data);
7cca0d81 1680}
d8baa528 1681static unsigned char *ssh2_mpint_fmt(Bignum b, int *len)
32874aea 1682{
7cca0d81 1683 unsigned char *p;
32874aea 1684 int i, n = (bignum_bitcount(b) + 7) / 8;
3d88e64d 1685 p = snewn(n + 1, unsigned char);
7cca0d81 1686 p[0] = 0;
3709bfe9 1687 for (i = 1; i <= n; i++)
32874aea 1688 p[i] = bignum_byte(b, n - i);
7cca0d81 1689 i = 0;
32874aea 1690 while (i <= n && p[i] == 0 && (p[i + 1] & 0x80) == 0)
1691 i++;
1692 memmove(p, p + i, n + 1 - i);
1693 *len = n + 1 - i;
7cca0d81 1694 return p;
1695}
ff3187f6 1696static void ssh2_pkt_addmp(struct Packet *pkt, Bignum b)
32874aea 1697{
7cca0d81 1698 unsigned char *p;
1699 int len;
1700 p = ssh2_mpint_fmt(b, &len);
dacd8872 1701 ssh_pkt_addstring_start(pkt);
1702 ssh_pkt_addstring_data(pkt, (char *)p, len);
dcbde236 1703 sfree(p);
7cca0d81 1704}
b185170a 1705
dacd8872 1706static struct Packet *ssh1_pkt_init(int pkt_type)
1707{
1708 struct Packet *pkt = ssh_new_packet();
1709 pkt->length = 4 + 8; /* space for length + max padding */
1710 ssh_pkt_addbyte(pkt, pkt_type);
1711 pkt->body = pkt->data + pkt->length;
1712 return pkt;
1713}
1714
1715/* For legacy code (SSH-1 and -2 packet construction used to be separate) */
1716#define ssh2_pkt_ensure(pkt, length) ssh_pkt_ensure(pkt, length)
1717#define ssh2_pkt_adddata(pkt, data, len) ssh_pkt_adddata(pkt, data, len)
1718#define ssh2_pkt_addbyte(pkt, byte) ssh_pkt_addbyte(pkt, byte)
1719#define ssh2_pkt_adduint32(pkt, value) ssh_pkt_adduint32(pkt, value)
1720#define ssh2_pkt_addstring_start(pkt) ssh_pkt_addstring_start(pkt)
1721#define ssh2_pkt_addstring_str(pkt, data) ssh_pkt_addstring_str(pkt, data)
1722#define ssh2_pkt_addstring_data(pkt, data, len) ssh_pkt_addstring_data(pkt, data, len)
1723#define ssh2_pkt_addstring(pkt, data) ssh_pkt_addstring(pkt, data)
1724
1725static struct Packet *ssh2_pkt_init(int pkt_type)
1726{
1727 struct Packet *pkt = ssh_new_packet();
3d71de0b 1728 pkt->length = 5; /* space for packet length + padding length */
dacd8872 1729 pkt->forcepad = 0;
1730 ssh_pkt_addbyte(pkt, (unsigned char) pkt_type);
3d71de0b 1731 pkt->body = pkt->data + pkt->length; /* after packet type */
dacd8872 1732 return pkt;
1733}
1734
b185170a 1735/*
2e85c969 1736 * Construct an SSH-2 final-form packet: compress it, encrypt it,
b185170a 1737 * put the MAC on it. Final packet, ready to be sent, is stored in
ff3187f6 1738 * pkt->data. Total length is returned.
b185170a 1739 */
ff3187f6 1740static int ssh2_pkt_construct(Ssh ssh, struct Packet *pkt)
32874aea 1741{
7cca0d81 1742 int cipherblk, maclen, padding, i;
7cca0d81 1743
a8327734 1744 if (ssh->logctx)
ff3187f6 1745 log_packet(ssh->logctx, PKT_OUTGOING, pkt->data[5],
acab36bc 1746 ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx, pkt->data[5]),
dacd8872 1747 pkt->body, pkt->length - (pkt->body - pkt->data),
ff3187f6 1748 pkt->nblanks, pkt->blanks);
1749 sfree(pkt->blanks); pkt->blanks = NULL;
1750 pkt->nblanks = 0;
00db133f 1751
7cca0d81 1752 /*
4ba9b64b 1753 * Compress packet payload.
1754 */
4ba9b64b 1755 {
1756 unsigned char *newpayload;
1757 int newlen;
51470298 1758 if (ssh->cscomp &&
ff3187f6 1759 ssh->cscomp->compress(ssh->cs_comp_ctx, pkt->data + 5,
1760 pkt->length - 5,
51470298 1761 &newpayload, &newlen)) {
ff3187f6 1762 pkt->length = 5;
1763 ssh2_pkt_adddata(pkt, newpayload, newlen);
dcbde236 1764 sfree(newpayload);
4ba9b64b 1765 }
1766 }
1767
1768 /*
7cca0d81 1769 * Add padding. At least four bytes, and must also bring total
1770 * length (minus MAC) up to a multiple of the block size.
95d2d262 1771 * If pkt->forcepad is set, make sure the packet is at least that size
1772 * after padding.
7cca0d81 1773 */
51470298 1774 cipherblk = ssh->cscipher ? ssh->cscipher->blksize : 8; /* block size */
32874aea 1775 cipherblk = cipherblk < 8 ? 8 : cipherblk; /* or 8 if blksize < 8 */
7cca0d81 1776 padding = 4;
95d2d262 1777 if (pkt->length + padding < pkt->forcepad)
1778 padding = pkt->forcepad - pkt->length;
32874aea 1779 padding +=
ff3187f6 1780 (cipherblk - (pkt->length + padding) % cipherblk) % cipherblk;
95d2d262 1781 assert(padding <= 255);
51470298 1782 maclen = ssh->csmac ? ssh->csmac->len : 0;
ff3187f6 1783 ssh2_pkt_ensure(pkt, pkt->length + padding + maclen);
1784 pkt->data[4] = padding;
7cca0d81 1785 for (i = 0; i < padding; i++)
ff3187f6 1786 pkt->data[pkt->length + i] = random_byte();
1787 PUT_32BIT(pkt->data, pkt->length + padding - 4);
51470298 1788 if (ssh->csmac)
ff3187f6 1789 ssh->csmac->generate(ssh->cs_mac_ctx, pkt->data,
1790 pkt->length + padding,
51470298 1791 ssh->v2_outgoing_sequence);
1792 ssh->v2_outgoing_sequence++; /* whether or not we MACed */
1793
1794 if (ssh->cscipher)
371e569c 1795 ssh->cscipher->encrypt(ssh->cs_cipher_ctx,
ff3187f6 1796 pkt->data, pkt->length + padding);
51470298 1797
9442dd57 1798 pkt->encrypted_len = pkt->length + padding;
1799
ff3187f6 1800 /* Ready-to-send packet starts at pkt->data. We return length. */
1801 return pkt->length + padding + maclen;
b185170a 1802}
1803
1804/*
590f6a5f 1805 * Routines called from the main SSH code to send packets. There
1806 * are quite a few of these, because we have two separate
1807 * mechanisms for delaying the sending of packets:
1808 *
1809 * - In order to send an IGNORE message and a password message in
1810 * a single fixed-length blob, we require the ability to
1811 * concatenate the encrypted forms of those two packets _into_ a
1812 * single blob and then pass it to our <network.h> transport
1813 * layer in one go. Hence, there's a deferment mechanism which
1814 * works after packet encryption.
1815 *
1816 * - In order to avoid sending any connection-layer messages
1817 * during repeat key exchange, we have to queue up any such
1818 * outgoing messages _before_ they are encrypted (and in
1819 * particular before they're allocated sequence numbers), and
1820 * then send them once we've finished.
1821 *
1822 * I call these mechanisms `defer' and `queue' respectively, so as
1823 * to distinguish them reasonably easily.
1824 *
1825 * The functions send_noqueue() and defer_noqueue() free the packet
1826 * structure they are passed. Every outgoing packet goes through
1827 * precisely one of these functions in its life; packets passed to
1828 * ssh2_pkt_send() or ssh2_pkt_defer() either go straight to one of
1829 * these or get queued, and then when the queue is later emptied
1830 * the packets are all passed to defer_noqueue().
97ab28d7 1831 *
1832 * When using a CBC-mode cipher, it's necessary to ensure that an
1833 * attacker can't provide data to be encrypted using an IV that they
1834 * know. We ensure this by prefixing each packet that might contain
1835 * user data with an SSH_MSG_IGNORE. This is done using the deferral
1836 * mechanism, so in this case send_noqueue() ends up redirecting to
1837 * defer_noqueue(). If you don't like this inefficiency, don't use
1838 * CBC.
b185170a 1839 */
590f6a5f 1840
97ab28d7 1841static void ssh2_pkt_defer_noqueue(Ssh, struct Packet *, int);
1842static void ssh_pkt_defersend(Ssh);
1843
590f6a5f 1844/*
2e85c969 1845 * Send an SSH-2 packet immediately, without queuing or deferring.
590f6a5f 1846 */
1847static void ssh2_pkt_send_noqueue(Ssh ssh, struct Packet *pkt)
32874aea 1848{
5471d09a 1849 int len;
1850 int backlog;
97ab28d7 1851 if (ssh->cscipher != NULL && (ssh->cscipher->flags & SSH_CIPHER_IS_CBC)) {
1852 /* We need to send two packets, so use the deferral mechanism. */
1853 ssh2_pkt_defer_noqueue(ssh, pkt, FALSE);
1854 ssh_pkt_defersend(ssh);
1855 return;
1856 }
ff3187f6 1857 len = ssh2_pkt_construct(ssh, pkt);
bf8a49a1 1858 backlog = s_write(ssh, pkt->data, len);
5471d09a 1859 if (backlog > SSH_MAX_BACKLOG)
51470298 1860 ssh_throttle_all(ssh, 1, backlog);
9442dd57 1861
1862 ssh->outgoing_data_size += pkt->encrypted_len;
1863 if (!ssh->kex_in_progress &&
d57f70af 1864 ssh->max_data_size != 0 &&
1865 ssh->outgoing_data_size > ssh->max_data_size)
f382c87d 1866 do_ssh2_transport(ssh, "too much data sent", -1, NULL);
9442dd57 1867
ff3187f6 1868 ssh_free_packet(pkt);
b185170a 1869}
1870
1871/*
2e85c969 1872 * Defer an SSH-2 packet.
b185170a 1873 */
97ab28d7 1874static void ssh2_pkt_defer_noqueue(Ssh ssh, struct Packet *pkt, int noignore)
32874aea 1875{
97ab28d7 1876 int len;
1877 if (ssh->cscipher != NULL && (ssh->cscipher->flags & SSH_CIPHER_IS_CBC) &&
1878 ssh->deferred_len == 0 && !noignore) {
1879 /*
1880 * Interpose an SSH_MSG_IGNORE to ensure that user data don't
1881 * get encrypted with a known IV.
1882 */
1883 struct Packet *ipkt = ssh2_pkt_init(SSH2_MSG_IGNORE);
27311cc7 1884 ssh2_pkt_addstring_start(ipkt);
97ab28d7 1885 ssh2_pkt_defer_noqueue(ssh, ipkt, TRUE);
1886 }
1887 len = ssh2_pkt_construct(ssh, pkt);
51470298 1888 if (ssh->deferred_len + len > ssh->deferred_size) {
1889 ssh->deferred_size = ssh->deferred_len + len + 128;
3d88e64d 1890 ssh->deferred_send_data = sresize(ssh->deferred_send_data,
1891 ssh->deferred_size,
1892 unsigned char);
b185170a 1893 }
ff3187f6 1894 memcpy(ssh->deferred_send_data + ssh->deferred_len, pkt->data, len);
51470298 1895 ssh->deferred_len += len;
9442dd57 1896 ssh->deferred_data_size += pkt->encrypted_len;
ff3187f6 1897 ssh_free_packet(pkt);
b185170a 1898}
1899
1900/*
2e85c969 1901 * Queue an SSH-2 packet.
590f6a5f 1902 */
1903static void ssh2_pkt_queue(Ssh ssh, struct Packet *pkt)
1904{
1905 assert(ssh->queueing);
1906
1907 if (ssh->queuelen >= ssh->queuesize) {
1908 ssh->queuesize = ssh->queuelen + 32;
1909 ssh->queue = sresize(ssh->queue, ssh->queuesize, struct Packet *);
1910 }
1911
1912 ssh->queue[ssh->queuelen++] = pkt;
1913}
1914
1915/*
1916 * Either queue or send a packet, depending on whether queueing is
1917 * set.
1918 */
1919static void ssh2_pkt_send(Ssh ssh, struct Packet *pkt)
1920{
1921 if (ssh->queueing)
1922 ssh2_pkt_queue(ssh, pkt);
1923 else
1924 ssh2_pkt_send_noqueue(ssh, pkt);
1925}
1926
1927/*
1928 * Either queue or defer a packet, depending on whether queueing is
1929 * set.
1930 */
1931static void ssh2_pkt_defer(Ssh ssh, struct Packet *pkt)
1932{
1933 if (ssh->queueing)
1934 ssh2_pkt_queue(ssh, pkt);
1935 else
97ab28d7 1936 ssh2_pkt_defer_noqueue(ssh, pkt, FALSE);
590f6a5f 1937}
1938
1939/*
b185170a 1940 * Send the whole deferred data block constructed by
2e85c969 1941 * ssh2_pkt_defer() or SSH-1's defer_packet().
590f6a5f 1942 *
1943 * The expected use of the defer mechanism is that you call
1944 * ssh2_pkt_defer() a few times, then call ssh_pkt_defersend(). If
1945 * not currently queueing, this simply sets up deferred_send_data
1946 * and then sends it. If we _are_ currently queueing, the calls to
1947 * ssh2_pkt_defer() put the deferred packets on to the queue
1948 * instead, and therefore ssh_pkt_defersend() has no deferred data
1949 * to send. Hence, there's no need to make it conditional on
1950 * ssh->queueing.
b185170a 1951 */
51470298 1952static void ssh_pkt_defersend(Ssh ssh)
32874aea 1953{
5471d09a 1954 int backlog;
bf8a49a1 1955 backlog = s_write(ssh, ssh->deferred_send_data, ssh->deferred_len);
51470298 1956 ssh->deferred_len = ssh->deferred_size = 0;
1957 sfree(ssh->deferred_send_data);
1958 ssh->deferred_send_data = NULL;
5471d09a 1959 if (backlog > SSH_MAX_BACKLOG)
51470298 1960 ssh_throttle_all(ssh, 1, backlog);
9442dd57 1961
1962 ssh->outgoing_data_size += ssh->deferred_data_size;
1963 if (!ssh->kex_in_progress &&
d57f70af 1964 ssh->max_data_size != 0 &&
1965 ssh->outgoing_data_size > ssh->max_data_size)
f382c87d 1966 do_ssh2_transport(ssh, "too much data sent", -1, NULL);
9442dd57 1967 ssh->deferred_data_size = 0;
7cca0d81 1968}
1969
590f6a5f 1970/*
18524056 1971 * Send a packet whose length needs to be disguised (typically
1972 * passwords or keyboard-interactive responses).
1973 */
1974static void ssh2_pkt_send_with_padding(Ssh ssh, struct Packet *pkt,
1975 int padsize)
1976{
1977#if 0
1978 if (0) {
1979 /*
1980 * The simplest way to do this is to adjust the
1981 * variable-length padding field in the outgoing packet.
1982 *
1983 * Currently compiled out, because some Cisco SSH servers
1984 * don't like excessively padded packets (bah, why's it
1985 * always Cisco?)
1986 */
1987 pkt->forcepad = padsize;
1988 ssh2_pkt_send(ssh, pkt);
1989 } else
1990#endif
1991 {
1992 /*
1993 * If we can't do that, however, an alternative approach is
1994 * to use the pkt_defer mechanism to bundle the packet
1995 * tightly together with an SSH_MSG_IGNORE such that their
1996 * combined length is a constant. So first we construct the
1997 * final form of this packet and defer its sending.
1998 */
1999 ssh2_pkt_defer(ssh, pkt);
2000
2001 /*
2002 * Now construct an SSH_MSG_IGNORE which includes a string
2003 * that's an exact multiple of the cipher block size. (If
2004 * the cipher is NULL so that the block size is
2005 * unavailable, we don't do this trick at all, because we
2006 * gain nothing by it.)
2007 */
2008 if (ssh->cscipher) {
2009 int stringlen, i;
2010
2011 stringlen = (256 - ssh->deferred_len);
2012 stringlen += ssh->cscipher->blksize - 1;
2013 stringlen -= (stringlen % ssh->cscipher->blksize);
2014 if (ssh->cscomp) {
2015 /*
2016 * Temporarily disable actual compression, so we
2017 * can guarantee to get this string exactly the
2018 * length we want it. The compression-disabling
2019 * routine should return an integer indicating how
2020 * many bytes we should adjust our string length
2021 * by.
2022 */
2023 stringlen -=
2024 ssh->cscomp->disable_compression(ssh->cs_comp_ctx);
2025 }
2026 pkt = ssh2_pkt_init(SSH2_MSG_IGNORE);
2027 ssh2_pkt_addstring_start(pkt);
2028 for (i = 0; i < stringlen; i++) {
2029 char c = (char) random_byte();
2030 ssh2_pkt_addstring_data(pkt, &c, 1);
2031 }
2032 ssh2_pkt_defer(ssh, pkt);
2033 }
2034 ssh_pkt_defersend(ssh);
2035 }
2036}
2037
2038/*
2e85c969 2039 * Send all queued SSH-2 packets. We send them by means of
590f6a5f 2040 * ssh2_pkt_defer_noqueue(), in case they included a pair of
2041 * packets that needed to be lumped together.
2042 */
2043static void ssh2_pkt_queuesend(Ssh ssh)
2044{
2045 int i;
2046
2047 assert(!ssh->queueing);
2048
2049 for (i = 0; i < ssh->queuelen; i++)
97ab28d7 2050 ssh2_pkt_defer_noqueue(ssh, ssh->queue[i], FALSE);
590f6a5f 2051 ssh->queuelen = 0;
2052
2053 ssh_pkt_defersend(ssh);
2054}
2055
7cca0d81 2056#if 0
32874aea 2057void bndebug(char *string, Bignum b)
2058{
7cca0d81 2059 unsigned char *p;
2060 int i, len;
2061 p = ssh2_mpint_fmt(b, &len);
2062 debug(("%s", string));
2063 for (i = 0; i < len; i++)
32874aea 2064 debug((" %02x", p[i]));
765c4200 2065 debug(("\n"));
dcbde236 2066 sfree(p);
7cca0d81 2067}
2068#endif
2069
b672f405 2070static void hash_mpint(const struct ssh_hash *h, void *s, Bignum b)
32874aea 2071{
7cca0d81 2072 unsigned char *p;
2073 int len;
2074 p = ssh2_mpint_fmt(b, &len);
b672f405 2075 hash_string(h, s, p, len);
dcbde236 2076 sfree(p);
7cca0d81 2077}
2078
2079/*
2e85c969 2080 * Packet decode functions for both SSH-1 and SSH-2.
7cca0d81 2081 */
ff3187f6 2082static unsigned long ssh_pkt_getuint32(struct Packet *pkt)
32874aea 2083{
7cca0d81 2084 unsigned long value;
ff3187f6 2085 if (pkt->length - pkt->savedpos < 4)
32874aea 2086 return 0; /* arrgh, no way to decline (FIXME?) */
ff3187f6 2087 value = GET_32BIT(pkt->body + pkt->savedpos);
2088 pkt->savedpos += 4;
7cca0d81 2089 return value;
2090}
ff3187f6 2091static int ssh2_pkt_getbool(struct Packet *pkt)
32874aea 2092{
65a22376 2093 unsigned long value;
ff3187f6 2094 if (pkt->length - pkt->savedpos < 1)
32874aea 2095 return 0; /* arrgh, no way to decline (FIXME?) */
ff3187f6 2096 value = pkt->body[pkt->savedpos] != 0;
2097 pkt->savedpos++;
65a22376 2098 return value;
2099}
ff3187f6 2100static void ssh_pkt_getstring(struct Packet *pkt, char **p, int *length)
32874aea 2101{
57356d63 2102 int len;
7cca0d81 2103 *p = NULL;
45068b27 2104 *length = 0;
ff3187f6 2105 if (pkt->length - pkt->savedpos < 4)
32874aea 2106 return;
ff3187f6 2107 len = GET_32BIT(pkt->body + pkt->savedpos);
57356d63 2108 if (len < 0)
2109 return;
2110 *length = len;
ff3187f6 2111 pkt->savedpos += 4;
2112 if (pkt->length - pkt->savedpos < *length)
32874aea 2113 return;
ff3187f6 2114 *p = (char *)(pkt->body + pkt->savedpos);
2115 pkt->savedpos += *length;
7cca0d81 2116}
ff3187f6 2117static void *ssh_pkt_getdata(struct Packet *pkt, int length)
0016d70b 2118{
ff3187f6 2119 if (pkt->length - pkt->savedpos < length)
0016d70b 2120 return NULL;
ff3187f6 2121 pkt->savedpos += length;
2122 return pkt->body + (pkt->savedpos - length);
0016d70b 2123}
ff3187f6 2124static int ssh1_pkt_getrsakey(struct Packet *pkt, struct RSAKey *key,
0016d70b 2125 unsigned char **keystr)
2126{
2127 int j;
2128
ff3187f6 2129 j = makekey(pkt->body + pkt->savedpos,
2130 pkt->length - pkt->savedpos,
0016d70b 2131 key, keystr, 0);
2132
2133 if (j < 0)
2134 return FALSE;
2135
ff3187f6 2136 pkt->savedpos += j;
2137 assert(pkt->savedpos < pkt->length);
0016d70b 2138
2139 return TRUE;
2140}
ff3187f6 2141static Bignum ssh1_pkt_getmp(struct Packet *pkt)
0016d70b 2142{
2143 int j;
2144 Bignum b;
2145
ff3187f6 2146 j = ssh1_read_bignum(pkt->body + pkt->savedpos,
2147 pkt->length - pkt->savedpos, &b);
0016d70b 2148
2149 if (j < 0)
2150 return NULL;
2151
ff3187f6 2152 pkt->savedpos += j;
0016d70b 2153 return b;
2154}
ff3187f6 2155static Bignum ssh2_pkt_getmp(struct Packet *pkt)
32874aea 2156{
7cca0d81 2157 char *p;
3709bfe9 2158 int length;
7cca0d81 2159 Bignum b;
2160
ff3187f6 2161 ssh_pkt_getstring(pkt, &p, &length);
7cca0d81 2162 if (!p)
32874aea 2163 return NULL;
ff3187f6 2164 if (p[0] & 0x80)
32874aea 2165 return NULL;
d8baa528 2166 b = bignum_from_bytes((unsigned char *)p, length);
7cca0d81 2167 return b;
2168}
2169
7d503c31 2170/*
2e85c969 2171 * Helper function to add an SSH-2 signature blob to a packet.
1dd353b5 2172 * Expects to be shown the public key blob as well as the signature
2173 * blob. Normally works just like ssh2_pkt_addstring, but will
2174 * fiddle with the signature packet if necessary for
2175 * BUG_SSH2_RSA_PADDING.
2176 */
ff3187f6 2177static void ssh2_add_sigblob(Ssh ssh, struct Packet *pkt,
2178 void *pkblob_v, int pkblob_len,
1dd353b5 2179 void *sigblob_v, int sigblob_len)
2180{
2181 unsigned char *pkblob = (unsigned char *)pkblob_v;
2182 unsigned char *sigblob = (unsigned char *)sigblob_v;
2183
2184 /* dmemdump(pkblob, pkblob_len); */
2185 /* dmemdump(sigblob, sigblob_len); */
2186
2187 /*
2188 * See if this is in fact an ssh-rsa signature and a buggy
2189 * server; otherwise we can just do this the easy way.
2190 */
51470298 2191 if ((ssh->remote_bugs & BUG_SSH2_RSA_PADDING) &&
1dd353b5 2192 (GET_32BIT(pkblob) == 7 && !memcmp(pkblob+4, "ssh-rsa", 7))) {
2193 int pos, len, siglen;
2194
2195 /*
2196 * Find the byte length of the modulus.
2197 */
2198
2199 pos = 4+7; /* skip over "ssh-rsa" */
2200 pos += 4 + GET_32BIT(pkblob+pos); /* skip over exponent */
2201 len = GET_32BIT(pkblob+pos); /* find length of modulus */
2202 pos += 4; /* find modulus itself */
2203 while (len > 0 && pkblob[pos] == 0)
2204 len--, pos++;
2205 /* debug(("modulus length is %d\n", len)); */
2206
2207 /*
2208 * Now find the signature integer.
2209 */
2210 pos = 4+7; /* skip over "ssh-rsa" */
2211 siglen = GET_32BIT(sigblob+pos);
2212 /* debug(("signature length is %d\n", siglen)); */
2213
2214 if (len != siglen) {
2215 unsigned char newlen[4];
ff3187f6 2216 ssh2_pkt_addstring_start(pkt);
2217 ssh2_pkt_addstring_data(pkt, (char *)sigblob, pos);
1dd353b5 2218 /* dmemdump(sigblob, pos); */
2219 pos += 4; /* point to start of actual sig */
2220 PUT_32BIT(newlen, len);
ff3187f6 2221 ssh2_pkt_addstring_data(pkt, (char *)newlen, 4);
1dd353b5 2222 /* dmemdump(newlen, 4); */
2223 newlen[0] = 0;
2224 while (len-- > siglen) {
ff3187f6 2225 ssh2_pkt_addstring_data(pkt, (char *)newlen, 1);
1dd353b5 2226 /* dmemdump(newlen, 1); */
2227 }
ff3187f6 2228 ssh2_pkt_addstring_data(pkt, (char *)(sigblob+pos), siglen);
1dd353b5 2229 /* dmemdump(sigblob+pos, siglen); */
2230 return;
2231 }
2232
2233 /* Otherwise fall through and do it the easy way. */
2234 }
2235
ff3187f6 2236 ssh2_pkt_addstring_start(pkt);
2237 ssh2_pkt_addstring_data(pkt, (char *)sigblob, sigblob_len);
1dd353b5 2238}
2239
2240/*
7d503c31 2241 * Examine the remote side's version string and compare it against
2242 * a list of known buggy implementations.
2243 */
51470298 2244static void ssh_detect_bugs(Ssh ssh, char *vstring)
32874aea 2245{
2246 char *imp; /* pointer to implementation part */
7d503c31 2247 imp = vstring;
2248 imp += strcspn(imp, "-");
bd358db1 2249 if (*imp) imp++;
7d503c31 2250 imp += strcspn(imp, "-");
bd358db1 2251 if (*imp) imp++;
7d503c31 2252
51470298 2253 ssh->remote_bugs = 0;
7d503c31 2254
bf982899 2255 /*
2256 * General notes on server version strings:
2257 * - Not all servers reporting "Cisco-1.25" have all the bugs listed
2258 * here -- in particular, we've heard of one that's perfectly happy
2259 * with SSH1_MSG_IGNOREs -- but this string never seems to change,
2260 * so we can't distinguish them.
2261 */
5ecd7ad0 2262 if (ssh->cfg.sshbug_ignore1 == FORCE_ON ||
2263 (ssh->cfg.sshbug_ignore1 == AUTO &&
2c9c6388 2264 (!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") ||
2265 !strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") ||
46ac09aa 2266 !strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25") ||
bd0b4caf 2267 !strcmp(imp, "OSU_1.4alpha3") || !strcmp(imp, "OSU_1.5alpha4")))) {
32874aea 2268 /*
2269 * These versions don't support SSH1_MSG_IGNORE, so we have
2270 * to use a different defence against password length
2271 * sniffing.
2272 */
51470298 2273 ssh->remote_bugs |= BUG_CHOKES_ON_SSH1_IGNORE;
2e85c969 2274 logevent("We believe remote version has SSH-1 ignore bug");
7d503c31 2275 }
2276
5ecd7ad0 2277 if (ssh->cfg.sshbug_plainpw1 == FORCE_ON ||
2278 (ssh->cfg.sshbug_plainpw1 == AUTO &&
46ac09aa 2279 (!strcmp(imp, "Cisco-1.25") || !strcmp(imp, "OSU_1.4alpha3")))) {
bd358db1 2280 /*
2281 * These versions need a plain password sent; they can't
2282 * handle having a null and a random length of data after
2283 * the password.
2284 */
51470298 2285 ssh->remote_bugs |= BUG_NEEDS_SSH1_PLAIN_PASSWORD;
2e85c969 2286 logevent("We believe remote version needs a plain SSH-1 password");
bd358db1 2287 }
2288
5ecd7ad0 2289 if (ssh->cfg.sshbug_rsa1 == FORCE_ON ||
2290 (ssh->cfg.sshbug_rsa1 == AUTO &&
2c9c6388 2291 (!strcmp(imp, "Cisco-1.25")))) {
0df73905 2292 /*
2293 * These versions apparently have no clue whatever about
2294 * RSA authentication and will panic and die if they see
2295 * an AUTH_RSA message.
2296 */
51470298 2297 ssh->remote_bugs |= BUG_CHOKES_ON_RSA;
19f47a7d 2298 logevent("We believe remote version can't handle SSH-1 RSA authentication");
0df73905 2299 }
2300
5ecd7ad0 2301 if (ssh->cfg.sshbug_hmac2 == FORCE_ON ||
2302 (ssh->cfg.sshbug_hmac2 == AUTO &&
b9f387af 2303 !wc_match("* VShell", imp) &&
831301f6 2304 (wc_match("2.1.0*", imp) || wc_match("2.0.*", imp) ||
2305 wc_match("2.2.0*", imp) || wc_match("2.3.0*", imp) ||
2306 wc_match("2.1 *", imp)))) {
32874aea 2307 /*
2308 * These versions have the HMAC bug.
2309 */
51470298 2310 ssh->remote_bugs |= BUG_SSH2_HMAC;
2e85c969 2311 logevent("We believe remote version has SSH-2 HMAC bug");
7d503c31 2312 }
1dd353b5 2313
5ecd7ad0 2314 if (ssh->cfg.sshbug_derivekey2 == FORCE_ON ||
2315 (ssh->cfg.sshbug_derivekey2 == AUTO &&
b9f387af 2316 !wc_match("* VShell", imp) &&
2856a1b9 2317 (wc_match("2.0.0*", imp) || wc_match("2.0.10*", imp) ))) {
088bde77 2318 /*
2319 * These versions have the key-derivation bug (failing to
2320 * include the literal shared secret in the hashes that
2321 * generate the keys).
2322 */
51470298 2323 ssh->remote_bugs |= BUG_SSH2_DERIVEKEY;
2e85c969 2324 logevent("We believe remote version has SSH-2 key-derivation bug");
088bde77 2325 }
2326
5ecd7ad0 2327 if (ssh->cfg.sshbug_rsapad2 == FORCE_ON ||
2328 (ssh->cfg.sshbug_rsapad2 == AUTO &&
831301f6 2329 (wc_match("OpenSSH_2.[5-9]*", imp) ||
2330 wc_match("OpenSSH_3.[0-2]*", imp)))) {
1dd353b5 2331 /*
2e85c969 2332 * These versions have the SSH-2 RSA padding bug.
1dd353b5 2333 */
51470298 2334 ssh->remote_bugs |= BUG_SSH2_RSA_PADDING;
2e85c969 2335 logevent("We believe remote version has SSH-2 RSA padding bug");
1dd353b5 2336 }
8e975795 2337
dda87a28 2338 if (ssh->cfg.sshbug_pksessid2 == FORCE_ON ||
2339 (ssh->cfg.sshbug_pksessid2 == AUTO &&
2340 wc_match("OpenSSH_2.[0-2]*", imp))) {
2341 /*
2e85c969 2342 * These versions have the SSH-2 session-ID bug in
dda87a28 2343 * public-key authentication.
2344 */
2345 ssh->remote_bugs |= BUG_SSH2_PK_SESSIONID;
2e85c969 2346 logevent("We believe remote version has SSH-2 public-key-session-ID bug");
dda87a28 2347 }
f382c87d 2348
2349 if (ssh->cfg.sshbug_rekey2 == FORCE_ON ||
2350 (ssh->cfg.sshbug_rekey2 == AUTO &&
39b8712f 2351 (wc_match("DigiSSH_2.0", imp) ||
2352 wc_match("OpenSSH_2.[0-4]*", imp) ||
e12d95a5 2353 wc_match("OpenSSH_2.5.[0-3]*", imp) ||
2354 wc_match("Sun_SSH_1.0", imp) ||
f4275b53 2355 wc_match("Sun_SSH_1.0.1", imp) ||
96bd26de 2356 /* All versions <= 1.2.6 (they changed their format in 1.2.7) */
2357 wc_match("WeOnlyDo-*", imp)))) {
f382c87d 2358 /*
2e85c969 2359 * These versions have the SSH-2 rekey bug.
f382c87d 2360 */
2361 ssh->remote_bugs |= BUG_SSH2_REKEY;
2e85c969 2362 logevent("We believe remote version has SSH-2 rekey bug");
f382c87d 2363 }
7d503c31 2364}
2365
d38d6a1f 2366/*
2367 * The `software version' part of an SSH version string is required
2368 * to contain no spaces or minus signs.
2369 */
2370static void ssh_fix_verstring(char *str)
2371{
2372 /* Eat "SSH-<protoversion>-". */
2373 assert(*str == 'S'); str++;
2374 assert(*str == 'S'); str++;
2375 assert(*str == 'H'); str++;
2376 assert(*str == '-'); str++;
2377 while (*str && *str != '-') str++;
2378 assert(*str == '-'); str++;
2379
2380 /* Convert minus signs and spaces in the remaining string into
2381 * underscores. */
2382 while (*str) {
2383 if (*str == '-' || *str == ' ')
2384 *str = '_';
2385 str++;
2386 }
2387}
2388
1fcd0d98 2389/*
2390 * Send an appropriate SSH version string.
2391 */
2392static void ssh_send_verstring(Ssh ssh, char *svers)
2393{
2394 char *verstring;
2395
2396 if (ssh->version == 2) {
2397 /*
2398 * Construct a v2 version string.
2399 */
2400 verstring = dupprintf("SSH-2.0-%s\015\012", sshver);
2401 } else {
2402 /*
2403 * Construct a v1 version string.
2404 */
2405 verstring = dupprintf("SSH-%s-%s\012",
2406 (ssh_versioncmp(svers, "1.5") <= 0 ?
2407 svers : "1.5"),
2408 sshver);
2409 }
2410
2411 ssh_fix_verstring(verstring);
2412
2413 if (ssh->version == 2) {
2414 size_t len;
2415 /*
2416 * Record our version string.
2417 */
2418 len = strcspn(verstring, "\015\012");
2419 ssh->v_c = snewn(len + 1, char);
2420 memcpy(ssh->v_c, verstring, len);
2421 ssh->v_c[len] = 0;
2422 }
2423
2424 logeventf(ssh, "We claim version: %.*s",
2425 strcspn(verstring, "\015\012"), verstring);
2426 s_write(ssh, verstring, strlen(verstring));
2427 sfree(verstring);
2428}
2429
51470298 2430static int do_ssh_init(Ssh ssh, unsigned char c)
32874aea 2431{
51470298 2432 struct do_ssh_init_state {
2433 int vslen;
2434 char version[10];
2435 char *vstring;
2436 int vstrsize;
2437 int i;
2438 int proto1, proto2;
2439 };
2440 crState(do_ssh_init_state);
374330e2 2441
51470298 2442 crBegin(ssh->do_ssh_init_crstate);
8df7a775 2443
8c1835c0 2444 /* Search for a line beginning with the string "SSH-" in the input. */
2445 for (;;) {
2446 if (c != 'S') goto no;
2447 crReturn(1);
2448 if (c != 'S') goto no;
2449 crReturn(1);
2450 if (c != 'H') goto no;
2451 crReturn(1);
2452 if (c != '-') goto no;
2453 break;
2454 no:
2455 while (c != '\012')
2456 crReturn(1);
2457 crReturn(1);
374330e2 2458 }
8df7a775 2459
51470298 2460 s->vstrsize = 16;
3d88e64d 2461 s->vstring = snewn(s->vstrsize, char);
51470298 2462 strcpy(s->vstring, "SSH-");
2463 s->vslen = 4;
2464 s->i = 0;
374330e2 2465 while (1) {
8df7a775 2466 crReturn(1); /* get another char */
51470298 2467 if (s->vslen >= s->vstrsize - 1) {
2468 s->vstrsize += 16;
3d88e64d 2469 s->vstring = sresize(s->vstring, s->vstrsize, char);
32874aea 2470 }
51470298 2471 s->vstring[s->vslen++] = c;
2472 if (s->i >= 0) {
374330e2 2473 if (c == '-') {
51470298 2474 s->version[s->i] = '\0';
2475 s->i = -1;
2476 } else if (s->i < sizeof(s->version) - 1)
2477 s->version[s->i++] = c;
c4ffc4d0 2478 } else if (c == '\012')
374330e2 2479 break;
2480 }
2481
51470298 2482 ssh->agentfwd_enabled = FALSE;
2483 ssh->rdpkt2_state.incoming_sequence = 0;
960e736a 2484
51470298 2485 s->vstring[s->vslen] = 0;
a7d4653a 2486 s->vstring[strcspn(s->vstring, "\015\012")] = '\0';/* remove EOL chars */
fb983202 2487 logeventf(ssh, "Server version: %s", s->vstring);
51470298 2488 ssh_detect_bugs(ssh, s->vstring);
c5e9c988 2489
adf799dd 2490 /*
38d228a2 2491 * Decide which SSH protocol version to support.
adf799dd 2492 */
38d228a2 2493
2494 /* Anything strictly below "2.0" means protocol 1 is supported. */
51470298 2495 s->proto1 = ssh_versioncmp(s->version, "2.0") < 0;
38d228a2 2496 /* Anything greater or equal to "1.99" means protocol 2 is supported. */
51470298 2497 s->proto2 = ssh_versioncmp(s->version, "1.99") >= 0;
38d228a2 2498
86916870 2499 if (ssh->cfg.sshprot == 0 && !s->proto1) {
6b5cf8b4 2500 bombout(("SSH protocol version 1 required by user but not provided by server"));
7ffdbc1a 2501 crStop(0);
38d228a2 2502 }
86916870 2503 if (ssh->cfg.sshprot == 3 && !s->proto2) {
6b5cf8b4 2504 bombout(("SSH protocol version 2 required by user but not provided by server"));
7ffdbc1a 2505 crStop(0);
38d228a2 2506 }
2507
1fcd0d98 2508 if (s->proto2 && (ssh->cfg.sshprot >= 2 || !s->proto1))
2509 ssh->version = 2;
2510 else
2511 ssh->version = 1;
d38d6a1f 2512
2513 logeventf(ssh, "Using SSH protocol version %d", ssh->version);
2514
1fcd0d98 2515 /* Send the version string, if we haven't already */
2516 if (ssh->cfg.sshprot != 3)
2517 ssh_send_verstring(ssh, s->version);
2518
2519 if (ssh->version == 2) {
2520 size_t len;
2521 /*
2522 * Record their version string.
2523 */
2524 len = strcspn(s->vstring, "\015\012");
2525 ssh->v_s = snewn(len + 1, char);
2526 memcpy(ssh->v_s, s->vstring, len);
2527 ssh->v_s[len] = 0;
2528
2529 /*
2530 * Initialise SSH-2 protocol.
2531 */
2532 ssh->protocol = ssh2_protocol;
2533 ssh2_protocol_setup(ssh);
2534 ssh->s_rdpkt = ssh2_rdpkt;
2535 } else {
2536 /*
2537 * Initialise SSH-1 protocol.
2538 */
2539 ssh->protocol = ssh1_protocol;
2540 ssh1_protocol_setup(ssh);
2541 ssh->s_rdpkt = ssh1_rdpkt;
2542 }
2543 if (ssh->version == 2)
2544 do_ssh2_transport(ssh, NULL, -1, NULL);
2545
125105d1 2546 update_specials_menu(ssh->frontend);
51470298 2547 ssh->state = SSH_STATE_BEFORE_SIZE;
39934deb 2548 ssh->pinger = pinger_new(&ssh->cfg, &ssh_backend, ssh);
8df7a775 2549
51470298 2550 sfree(s->vstring);
50526e47 2551
8df7a775 2552 crFinish(0);
2553}
2554
3d9449a1 2555static void ssh_process_incoming_data(Ssh ssh,
2556 unsigned char **data, int *datalen)
2557{
bf8a49a1 2558 struct Packet *pktin;
2559
2560 pktin = ssh->s_rdpkt(ssh, data, datalen);
3d9449a1 2561 if (pktin) {
2562 ssh->protocol(ssh, NULL, 0, pktin);
2563 ssh_free_packet(pktin);
2564 }
2565}
2566
2567static void ssh_queue_incoming_data(Ssh ssh,
2568 unsigned char **data, int *datalen)
2569{
2570 bufchain_add(&ssh->queued_incoming_data, *data, *datalen);
2571 *data += *datalen;
2572 *datalen = 0;
2573}
2574
2575static void ssh_process_queued_incoming_data(Ssh ssh)
2576{
2577 void *vdata;
2578 unsigned char *data;
2579 int len, origlen;
2580
2581 while (!ssh->frozen && bufchain_size(&ssh->queued_incoming_data)) {
2582 bufchain_prefix(&ssh->queued_incoming_data, &vdata, &len);
2583 data = vdata;
2584 origlen = len;
2585
2586 while (!ssh->frozen && len > 0)
2587 ssh_process_incoming_data(ssh, &data, &len);
2588
2589 if (origlen > len)
2590 bufchain_consume(&ssh->queued_incoming_data, origlen - len);
2591 }
2592}
2593
2594static void ssh_set_frozen(Ssh ssh, int frozen)
2595{
a5a6f839 2596 if (ssh->s)
2597 sk_set_frozen(ssh->s, frozen);
3d9449a1 2598 ssh->frozen = frozen;
2599}
2600
51470298 2601static void ssh_gotdata(Ssh ssh, unsigned char *data, int datalen)
8df7a775 2602{
bf8a49a1 2603 /* Log raw data, if we're in that mode. */
ff05dfef 2604 if (ssh->logctx)
2605 log_packet(ssh->logctx, PKT_INCOMING, -1, NULL, data, datalen,
2606 0, NULL);
bf8a49a1 2607
51470298 2608 crBegin(ssh->ssh_gotdata_crstate);
8df7a775 2609
2610 /*
2611 * To begin with, feed the characters one by one to the
2612 * protocol initialisation / selection function do_ssh_init().
2613 * When that returns 0, we're done with the initial greeting
2614 * exchange and can move on to packet discipline.
2615 */
2616 while (1) {
51470298 2617 int ret; /* need not be kept across crReturn */
8df7a775 2618 if (datalen == 0)
2619 crReturnV; /* more data please */
51470298 2620 ret = do_ssh_init(ssh, *data);
32874aea 2621 data++;
2622 datalen--;
8df7a775 2623 if (ret == 0)
2624 break;
2625 }
2626
2627 /*
2628 * We emerge from that loop when the initial negotiation is
2629 * over and we have selected an s_rdpkt function. Now pass
2630 * everything to s_rdpkt, and then pass the resulting packets
2631 * to the proper protocol handler.
2632 */
3d9449a1 2633
8df7a775 2634 while (1) {
e375106c 2635 while (bufchain_size(&ssh->queued_incoming_data) > 0 || datalen > 0) {
2636 if (ssh->frozen) {
3d9449a1 2637 ssh_queue_incoming_data(ssh, &data, &datalen);
e375106c 2638 /* This uses up all data and cannot cause anything interesting
2639 * to happen; indeed, for anything to happen at all, we must
2640 * return, so break out. */
2641 break;
2642 } else if (bufchain_size(&ssh->queued_incoming_data) > 0) {
2643 /* This uses up some or all data, and may freeze the
2644 * session. */
2645 ssh_process_queued_incoming_data(ssh);
2646 } else {
2647 /* This uses up some or all data, and may freeze the
2648 * session. */
2649 ssh_process_incoming_data(ssh, &data, &datalen);
2650 }
2651 /* FIXME this is probably EBW. */
ff3187f6 2652 if (ssh->state == SSH_STATE_CLOSED)
2653 return;
8df7a775 2654 }
e375106c 2655 /* We're out of data. Go and get some more. */
8df7a775 2656 crReturnV;
2657 }
2658 crFinishV;
2659}
2660
ac934965 2661static int ssh_do_close(Ssh ssh, int notify_exit)
32874aea 2662{
80ffa58b 2663 int ret = 0;
36f94d1f 2664 struct ssh_channel *c;
2665
51470298 2666 ssh->state = SSH_STATE_CLOSED;
ecbb0000 2667 expire_timer_context(ssh);
51470298 2668 if (ssh->s) {
2669 sk_close(ssh->s);
2670 ssh->s = NULL;
ac934965 2671 if (notify_exit)
2672 notify_remote_exit(ssh->frontend);
2673 else
2674 ret = 1;
f3ab576e 2675 }
36f94d1f 2676 /*
80ffa58b 2677 * Now we must shut down any port- and X-forwarded channels going
36f94d1f 2678 * through this connection.
2679 */
74a98066 2680 if (ssh->channels) {
80ffa58b 2681 while (NULL != (c = index234(ssh->channels, 0))) {
74a98066 2682 switch (c->type) {
2683 case CHAN_X11:
2684 x11_close(c->u.x11.s);
2685 break;
2686 case CHAN_SOCKDATA:
2687 pfd_close(c->u.pfd.s);
2688 break;
2689 }
80ffa58b 2690 del234(ssh->channels, c); /* moving next one to index 0 */
74a98066 2691 if (ssh->version == 2)
2692 bufchain_clear(&c->v.v2.outbuffer);
2693 sfree(c);
36f94d1f 2694 }
36f94d1f 2695 }
f8c9f9df 2696 /*
2697 * Go through port-forwardings, and close any associated
2698 * listening sockets.
2699 */
2700 if (ssh->portfwds) {
2701 struct ssh_portfwd *pf;
2702 while (NULL != (pf = index234(ssh->portfwds, 0))) {
2703 /* Dispose of any listening socket. */
2704 if (pf->local)
2705 pfd_terminate(pf->local);
2706 del234(ssh->portfwds, pf); /* moving next one to index 0 */
2707 free_portfwd(pf);
2708 }
2709 }
ac934965 2710
2711 return ret;
36f94d1f 2712}
2713
7555d6a5 2714static void ssh_log(Plug plug, int type, SockAddr addr, int port,
2715 const char *error_msg, int error_code)
2716{
2717 Ssh ssh = (Ssh) plug;
2718 char addrbuf[256], *msg;
2719
2720 sk_getaddr(addr, addrbuf, lenof(addrbuf));
2721
2722 if (type == 0)
2723 msg = dupprintf("Connecting to %s port %d", addrbuf, port);
2724 else
2725 msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg);
2726
2727 logevent(msg);
fb983202 2728 sfree(msg);
7555d6a5 2729}
2730
cbe2d68f 2731static int ssh_closing(Plug plug, const char *error_msg, int error_code,
36f94d1f 2732 int calling_back)
2733{
2734 Ssh ssh = (Ssh) plug;
ac934965 2735 int need_notify = ssh_do_close(ssh, FALSE);
2736
9e296bfa 2737 if (!error_msg) {
2738 if (!ssh->close_expected)
2739 error_msg = "Server unexpectedly closed network connection";
2740 else
2741 error_msg = "Server closed network connection";
ac934965 2742 }
2743
d051d1b4 2744 if (ssh->close_expected && ssh->clean_exit && ssh->exitcode < 0)
2745 ssh->exitcode = 0;
2746
2425184b 2747 if (need_notify)
2748 notify_remote_exit(ssh->frontend);
2749
9e296bfa 2750 if (error_msg)
247308b5 2751 logevent(error_msg);
9e296bfa 2752 if (!ssh->close_expected || !ssh->clean_exit)
971bcc0a 2753 connection_fatal(ssh->frontend, "%s", error_msg);
7e78000d 2754 return 0;
2755}
2756
32874aea 2757static int ssh_receive(Plug plug, int urgent, char *data, int len)
2758{
51470298 2759 Ssh ssh = (Ssh) plug;
d8baa528 2760 ssh_gotdata(ssh, (unsigned char *)data, len);
51470298 2761 if (ssh->state == SSH_STATE_CLOSED) {
ac934965 2762 ssh_do_close(ssh, TRUE);
32874aea 2763 return 0;
3257deae 2764 }
fef97f43 2765 return 1;
374330e2 2766}
2767
5471d09a 2768static void ssh_sent(Plug plug, int bufsize)
2769{
51470298 2770 Ssh ssh = (Ssh) plug;
5471d09a 2771 /*
2772 * If the send backlog on the SSH socket itself clears, we
2773 * should unthrottle the whole world if it was throttled.
2774 */
2775 if (bufsize < SSH_MAX_BACKLOG)
51470298 2776 ssh_throttle_all(ssh, 0, bufsize);
5471d09a 2777}
2778
fb09bf1c 2779/*
8df7a775 2780 * Connect to specified host and port.
2781 * Returns an error message, or NULL on success.
6e1ebb76 2782 * Also places the canonical host name into `realhost'. It must be
2783 * freed by the caller.
8df7a775 2784 */
cbe2d68f 2785static const char *connect_to_host(Ssh ssh, char *host, int port,
79bf227b 2786 char **realhost, int nodelay, int keepalive)
8df7a775 2787{
51470298 2788 static const struct plug_function_table fn_table = {
7555d6a5 2789 ssh_log,
7e78000d 2790 ssh_closing,
5471d09a 2791 ssh_receive,
2792 ssh_sent,
2793 NULL
51470298 2794 };
7e78000d 2795
8df7a775 2796 SockAddr addr;
cbe2d68f 2797 const char *err;
8df7a775 2798
3d88e64d 2799 ssh->savedhost = snewn(1 + strlen(host), char);
51470298 2800 strcpy(ssh->savedhost, host);
8df7a775 2801
2802 if (port < 0)
2803 port = 22; /* default ssh port */
51470298 2804 ssh->savedport = port;
8df7a775 2805
2806 /*
2807 * Try to find host.
2808 */
05581745 2809 logeventf(ssh, "Looking up host \"%s\"%s", host,
2810 (ssh->cfg.addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
2811 (ssh->cfg.addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" : "")));
2812 addr = name_lookup(host, port, realhost, &ssh->cfg,
2813 ssh->cfg.addressfamily);
170c1e6e 2814 if ((err = sk_addr_error(addr)) != NULL) {
2815 sk_addr_free(addr);
8df7a775 2816 return err;
170c1e6e 2817 }
8df7a775 2818
8df7a775 2819 /*
2820 * Open socket.
2821 */
51470298 2822 ssh->fn = &fn_table;
e8fa8f62 2823 ssh->s = new_connection(addr, *realhost, port,
79bf227b 2824 0, 1, nodelay, keepalive, (Plug) ssh, &ssh->cfg);
70e5d0fd 2825 if ((err = sk_socket_error(ssh->s)) != NULL) {
51470298 2826 ssh->s = NULL;
39934deb 2827 notify_remote_exit(ssh->frontend);
8df7a775 2828 return err;
67c4ba2e 2829 }
8df7a775 2830
ff05dfef 2831 /*
2832 * If the SSH version number's fixed, set it now, and if it's SSH-2,
2833 * send the version string too.
2834 */
2835 if (ssh->cfg.sshprot == 0)
2836 ssh->version = 1;
2837 if (ssh->cfg.sshprot == 3) {
2838 ssh->version = 2;
2839 ssh_send_verstring(ssh, NULL);
2840 }
2841
8df7a775 2842 return NULL;
2843}
2844
2845/*
5471d09a 2846 * Throttle or unthrottle the SSH connection.
2847 */
51470298 2848static void ssh1_throttle(Ssh ssh, int adjust)
5471d09a 2849{
51470298 2850 int old_count = ssh->v1_throttle_count;
2851 ssh->v1_throttle_count += adjust;
2852 assert(ssh->v1_throttle_count >= 0);
2853 if (ssh->v1_throttle_count && !old_count) {
3d9449a1 2854 ssh_set_frozen(ssh, 1);
51470298 2855 } else if (!ssh->v1_throttle_count && old_count) {
3d9449a1 2856 ssh_set_frozen(ssh, 0);
5471d09a 2857 }
2858}
2859
2860/*
2861 * Throttle or unthrottle _all_ local data streams (for when sends
2862 * on the SSH connection itself back up).
2863 */
51470298 2864static void ssh_throttle_all(Ssh ssh, int enable, int bufsize)
5471d09a 2865{
2866 int i;
2867 struct ssh_channel *c;
2868
51470298 2869 if (enable == ssh->throttled_all)
5471d09a 2870 return;
51470298 2871 ssh->throttled_all = enable;
2872 ssh->overall_bufsize = bufsize;
2873 if (!ssh->channels)
5471d09a 2874 return;
51470298 2875 for (i = 0; NULL != (c = index234(ssh->channels, i)); i++) {
5471d09a 2876 switch (c->type) {
2877 case CHAN_MAINSESSION:
2878 /*
2879 * This is treated separately, outside the switch.
2880 */
2881 break;
2882 case CHAN_X11:
2883 x11_override_throttle(c->u.x11.s, enable);
2884 break;
2885 case CHAN_AGENT:
2886 /* Agent channels require no buffer management. */
2887 break;
2888 case CHAN_SOCKDATA:
36f94d1f 2889 pfd_override_throttle(c->u.pfd.s, enable);
5471d09a 2890 break;
2891 }
2892 }
2893}
2894
f11d78f2 2895static void ssh_agent_callback(void *sshv, void *reply, int replylen)
839f10db 2896{
2897 Ssh ssh = (Ssh) sshv;
2898
2899 ssh->agent_response = reply;
2900 ssh->agent_response_len = replylen;
2901
2902 if (ssh->version == 1)
ff3187f6 2903 do_ssh1_login(ssh, NULL, -1, NULL);
839f10db 2904 else
ff3187f6 2905 do_ssh2_authconn(ssh, NULL, -1, NULL);
839f10db 2906}
2907
3d9449a1 2908static void ssh_dialog_callback(void *sshv, int ret)
2909{
2910 Ssh ssh = (Ssh) sshv;
2911
2912 ssh->user_response = ret;
2913
2914 if (ssh->version == 1)
2915 do_ssh1_login(ssh, NULL, -1, NULL);
2916 else
2917 do_ssh2_transport(ssh, NULL, -1, NULL);
2918
2919 /*
2920 * This may have unfrozen the SSH connection, so do a
2921 * queued-data run.
2922 */
2923 ssh_process_queued_incoming_data(ssh);
2924}
2925
f11d78f2 2926static void ssh_agentf_callback(void *cv, void *reply, int replylen)
839f10db 2927{
2928 struct ssh_channel *c = (struct ssh_channel *)cv;
2929 Ssh ssh = c->ssh;
2930 void *sentreply = reply;
2931
2932 if (!sentreply) {
2933 /* Fake SSH_AGENT_FAILURE. */
2934 sentreply = "\0\0\0\1\5";
2935 replylen = 5;
2936 }
2937 if (ssh->version == 2) {
2938 ssh2_add_channel_data(c, sentreply, replylen);
2939 ssh2_try_send(c);
2940 } else {
2941 send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
2942 PKT_INT, c->remoteid,
2943 PKT_INT, replylen,
a2724fba 2944 PKTT_DATA,
839f10db 2945 PKT_DATA, sentreply, replylen,
9a10ecf4 2946 PKTT_OTHER,
839f10db 2947 PKT_END);
2948 }
2949 if (reply)
2950 sfree(reply);
2951}
2952
0405e71f 2953/*
9e296bfa 2954 * Client-initiated disconnection. Send a DISCONNECT if `wire_reason'
2955 * non-NULL, otherwise just close the connection. `client_reason' == NULL
2956 * => log `wire_reason'.
2957 */
2958static void ssh_disconnect(Ssh ssh, char *client_reason, char *wire_reason,
2959 int code, int clean_exit)
2960{
2961 char *error;
2962 if (!client_reason)
2963 client_reason = wire_reason;
2964 if (client_reason)
2965 error = dupprintf("Disconnected: %s", client_reason);
2966 else
2967 error = dupstr("Disconnected");
2968 if (wire_reason) {
2969 if (ssh->version == 1) {
2970 send_packet(ssh, SSH1_MSG_DISCONNECT, PKT_STR, wire_reason,
2971 PKT_END);
2972 } else if (ssh->version == 2) {
2973 struct Packet *pktout = ssh2_pkt_init(SSH2_MSG_DISCONNECT);
2974 ssh2_pkt_adduint32(pktout, code);
2975 ssh2_pkt_addstring(pktout, wire_reason);
2976 ssh2_pkt_addstring(pktout, "en"); /* language tag */
2977 ssh2_pkt_send_noqueue(ssh, pktout);
2978 }
2979 }
2980 ssh->close_expected = TRUE;
2981 ssh->clean_exit = clean_exit;
2982 ssh_closing((Plug)ssh, error, 0, 0);
2983 sfree(error);
2984}
2985
2986/*
fb09bf1c 2987 * Handle the key exchange and user authentication phases.
2988 */
ff3187f6 2989static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
2990 struct Packet *pktin)
fb09bf1c 2991{
0016d70b 2992 int i, j, ret;
2993 unsigned char cookie[8], *ptr;
374330e2 2994 struct RSAKey servkey, hostkey;
2995 struct MD5Context md5c;
51470298 2996 struct do_ssh1_login_state {
2997 int len;
2998 unsigned char *rsabuf, *keystr1, *keystr2;
2999 unsigned long supported_ciphers_mask, supported_auths_mask;
3000 int tried_publickey, tried_agent;
3001 int tis_auth_refused, ccard_auth_refused;
3002 unsigned char session_id[16];
3003 int cipher_type;
3004 char username[100];
3005 void *publickey_blob;
3006 int publickey_bloblen;
edd0cb8a 3007 char *publickey_comment;
3008 int publickey_encrypted;
3009 prompts_t *cur_prompt;
51470298 3010 char c;
3011 int pwpkt_type;
3012 unsigned char request[5], *response, *p;
3013 int responselen;
3014 int keyi, nkeys;
3015 int authed;
3016 struct RSAKey key;
3017 Bignum challenge;
3018 char *commentp;
3019 int commentlen;
3d9449a1 3020 int dlgret;
51470298 3021 };
3022 crState(do_ssh1_login_state);
3023
3024 crBegin(ssh->do_ssh1_login_crstate);
374330e2 3025
ff3187f6 3026 if (!pktin)
3027 crWaitUntil(pktin);
374330e2 3028
ff3187f6 3029 if (pktin->type != SSH1_SMSG_PUBLIC_KEY) {
6b5cf8b4 3030 bombout(("Public key packet not received"));
7ffdbc1a 3031 crStop(0);
8d5de777 3032 }
374330e2 3033
c5e9c988 3034 logevent("Received public keys");
374330e2 3035
ff3187f6 3036 ptr = ssh_pkt_getdata(pktin, 8);
0016d70b 3037 if (!ptr) {
2e85c969 3038 bombout(("SSH-1 public key packet stopped before random cookie"));
0016d70b 3039 crStop(0);
3040 }
3041 memcpy(cookie, ptr, 8);
374330e2 3042
ff3187f6 3043 if (!ssh1_pkt_getrsakey(pktin, &servkey, &s->keystr1) ||
3044 !ssh1_pkt_getrsakey(pktin, &hostkey, &s->keystr2)) {
2e85c969 3045 bombout(("Failed to read SSH-1 public keys from public key packet"));
0016d70b 3046 crStop(0);
3047 }
374330e2 3048
c5e9c988 3049 /*
1c2a93c4 3050 * Log the host key fingerprint.
c5e9c988 3051 */
c5e9c988 3052 {
3053 char logmsg[80];
1c2a93c4 3054 logevent("Host key fingerprint is:");
c5e9c988 3055 strcpy(logmsg, " ");
32874aea 3056 hostkey.comment = NULL;
3057 rsa_fingerprint(logmsg + strlen(logmsg),
3058 sizeof(logmsg) - strlen(logmsg), &hostkey);
c5e9c988 3059 logevent(logmsg);
3060 }
3061
ff3187f6 3062 ssh->v1_remote_protoflags = ssh_pkt_getuint32(pktin);
3063 s->supported_ciphers_mask = ssh_pkt_getuint32(pktin);
3064 s->supported_auths_mask = ssh_pkt_getuint32(pktin);
bea1ef5f 3065
51470298 3066 ssh->v1_local_protoflags =
3067 ssh->v1_remote_protoflags & SSH1_PROTOFLAGS_SUPPORTED;
3068 ssh->v1_local_protoflags |= SSH1_PROTOFLAG_SCREEN_NUMBER;
b96dc54c 3069
c5e9c988 3070 MD5Init(&md5c);
51470298 3071 MD5Update(&md5c, s->keystr2, hostkey.bytes);
3072 MD5Update(&md5c, s->keystr1, servkey.bytes);
0016d70b 3073 MD5Update(&md5c, cookie, 8);
51470298 3074 MD5Final(s->session_id, &md5c);
374330e2 3075
32874aea 3076 for (i = 0; i < 32; i++)
51470298 3077 ssh->session_key[i] = random_byte();
374330e2 3078
0016d70b 3079 /*
3080 * Verify that the `bits' and `bytes' parameters match.
3081 */
3082 if (hostkey.bits > hostkey.bytes * 8 ||
3083 servkey.bits > servkey.bytes * 8) {
2e85c969 3084 bombout(("SSH-1 public keys were badly formatted"));
0016d70b 3085 crStop(0);
3086 }
3087
51470298 3088 s->len = (hostkey.bytes > servkey.bytes ? hostkey.bytes : servkey.bytes);
374330e2 3089
3d88e64d 3090 s->rsabuf = snewn(s->len, unsigned char);
374330e2 3091
89ee5268 3092 /*
3093 * Verify the host key.
3094 */
3095 {
32874aea 3096 /*
3097 * First format the key into a string.
3098 */
3099 int len = rsastr_len(&hostkey);
3100 char fingerprint[100];
3d88e64d 3101 char *keystr = snewn(len, char);
32874aea 3102 rsastr_fmt(keystr, &hostkey);
3103 rsa_fingerprint(fingerprint, sizeof(fingerprint), &hostkey);
3d9449a1 3104
3105 ssh_set_frozen(ssh, 1);
3106 s->dlgret = verify_ssh_host_key(ssh->frontend,
3107 ssh->savedhost, ssh->savedport,
3108 "rsa", keystr, fingerprint,
3109 ssh_dialog_callback, ssh);
32874aea 3110 sfree(keystr);
3d9449a1 3111 if (s->dlgret < 0) {
3112 do {
3113 crReturn(0);
3114 if (pktin) {
3115 bombout(("Unexpected data from server while waiting"
3116 " for user host key response"));
3117 crStop(0);
3118 }
3119 } while (pktin || inlen > 0);
3120 s->dlgret = ssh->user_response;
3121 }
3122 ssh_set_frozen(ssh, 0);
3123
3124 if (s->dlgret == 0) {
9e296bfa 3125 ssh_disconnect(ssh, "User aborted at host key verification",
3126 NULL, 0, TRUE);
2b3f6c19 3127 crStop(0);
3d9449a1 3128 }
32874aea 3129 }
3130
3131 for (i = 0; i < 32; i++) {
51470298 3132 s->rsabuf[i] = ssh->session_key[i];
374330e2 3133 if (i < 16)
51470298 3134 s->rsabuf[i] ^= s->session_id[i];
374330e2 3135 }
3136
3137 if (hostkey.bytes > servkey.bytes) {
0016d70b 3138 ret = rsaencrypt(s->rsabuf, 32, &servkey);
3139 if (ret)
3140 ret = rsaencrypt(s->rsabuf, servkey.bytes, &hostkey);
374330e2 3141 } else {
0016d70b 3142 ret = rsaencrypt(s->rsabuf, 32, &hostkey);
3143 if (ret)
3144 ret = rsaencrypt(s->rsabuf, hostkey.bytes, &servkey);
3145 }
3146 if (!ret) {
2e85c969 3147 bombout(("SSH-1 public key encryptions failed due to bad formatting"));
0016d70b 3148 crStop(0);
374330e2 3149 }
3150
c5e9c988 3151 logevent("Encrypted session key");
3152
ca20bfcf 3153 {
3154 int cipher_chosen = 0, warn = 0;
3155 char *cipher_string = NULL;
51470298 3156 int i;
ca20bfcf 3157 for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) {
86916870 3158 int next_cipher = ssh->cfg.ssh_cipherlist[i];
ca20bfcf 3159 if (next_cipher == CIPHER_WARN) {
3160 /* If/when we choose a cipher, warn about it */
3161 warn = 1;
3162 } else if (next_cipher == CIPHER_AES) {
3163 /* XXX Probably don't need to mention this. */
2e85c969 3164 logevent("AES not supported in SSH-1, skipping");
ca20bfcf 3165 } else {
3166 switch (next_cipher) {
51470298 3167 case CIPHER_3DES: s->cipher_type = SSH_CIPHER_3DES;
ca20bfcf 3168 cipher_string = "3DES"; break;
51470298 3169 case CIPHER_BLOWFISH: s->cipher_type = SSH_CIPHER_BLOWFISH;
ca20bfcf 3170 cipher_string = "Blowfish"; break;
51470298 3171 case CIPHER_DES: s->cipher_type = SSH_CIPHER_DES;
ca20bfcf 3172 cipher_string = "single-DES"; break;
3173 }
51470298 3174 if (s->supported_ciphers_mask & (1 << s->cipher_type))
ca20bfcf 3175 cipher_chosen = 1;
3176 }
3177 }
3178 if (!cipher_chosen) {
51470298 3179 if ((s->supported_ciphers_mask & (1 << SSH_CIPHER_3DES)) == 0)
2e85c969 3180 bombout(("Server violates SSH-1 protocol by not "
ca20bfcf 3181 "supporting 3DES encryption"));
3182 else
3183 /* shouldn't happen */
6b5cf8b4 3184 bombout(("No supported ciphers found"));
7ffdbc1a 3185 crStop(0);
a99a05c0 3186 }
ca20bfcf 3187
3188 /* Warn about chosen cipher if necessary. */
bb348ab1 3189 if (warn) {
3d9449a1 3190 ssh_set_frozen(ssh, 1);
3191 s->dlgret = askalg(ssh->frontend, "cipher", cipher_string,
3192 ssh_dialog_callback, ssh);
3193 if (s->dlgret < 0) {
3194 do {
3195 crReturn(0);
3196 if (pktin) {
3197 bombout(("Unexpected data from server while waiting"
3198 " for user response"));
3199 crStop(0);
3200 }
3201 } while (pktin || inlen > 0);
3202 s->dlgret = ssh->user_response;
3203 }
3204 ssh_set_frozen(ssh, 0);
3205 if (s->dlgret == 0) {
9e296bfa 3206 ssh_disconnect(ssh, "User aborted at cipher warning", NULL,
3207 0, TRUE);
96ccde8b 3208 crStop(0);
3d9449a1 3209 }
bb348ab1 3210 }
bea1ef5f 3211 }
ca20bfcf 3212
51470298 3213 switch (s->cipher_type) {
32874aea 3214 case SSH_CIPHER_3DES:
3215 logevent("Using 3DES encryption");
3216 break;
3217 case SSH_CIPHER_DES:
3218 logevent("Using single-DES encryption");
3219 break;
3220 case SSH_CIPHER_BLOWFISH:
3221 logevent("Using Blowfish encryption");
3222 break;
c5e9c988 3223 }
bea1ef5f 3224
51470298 3225 send_packet(ssh, SSH1_CMSG_SESSION_KEY,
3226 PKT_CHAR, s->cipher_type,
32874aea 3227 PKT_DATA, cookie, 8,
51470298 3228 PKT_CHAR, (s->len * 8) >> 8, PKT_CHAR, (s->len * 8) & 0xFF,
3229 PKT_DATA, s->rsabuf, s->len,
3230 PKT_INT, ssh->v1_local_protoflags, PKT_END);
fb09bf1c 3231
c5e9c988 3232 logevent("Trying to enable encryption...");
374330e2 3233
51470298 3234 sfree(s->rsabuf);
374330e2 3235
51470298 3236 ssh->cipher = (s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
3237 s->cipher_type == SSH_CIPHER_DES ? &ssh_des :
3238 &ssh_3des);
371e569c 3239 ssh->v1_cipher_ctx = ssh->cipher->make_context();
3240 ssh->cipher->sesskey(ssh->v1_cipher_ctx, ssh->session_key);
57356d63 3241 logeventf(ssh, "Initialised %s encryption", ssh->cipher->text_name);
374330e2 3242
0183b242 3243 ssh->crcda_ctx = crcda_make_context();
3244 logevent("Installing CRC compensation attack detector");
3245
679539d7 3246 if (servkey.modulus) {
3247 sfree(servkey.modulus);
3248 servkey.modulus = NULL;
3249 }
3250 if (servkey.exponent) {
3251 sfree(servkey.exponent);
3252 servkey.exponent = NULL;
3253 }
3254 if (hostkey.modulus) {
3255 sfree(hostkey.modulus);
3256 hostkey.modulus = NULL;
3257 }
3258 if (hostkey.exponent) {
3259 sfree(hostkey.exponent);
3260 hostkey.exponent = NULL;
3261 }
ff3187f6 3262 crWaitUntil(pktin);
374330e2 3263
ff3187f6 3264 if (pktin->type != SSH1_SMSG_SUCCESS) {
6b5cf8b4 3265 bombout(("Encryption not successfully enabled"));
7ffdbc1a 3266 crStop(0);
8d5de777 3267 }
374330e2 3268
c5e9c988 3269 logevent("Successfully started encryption");
3270
edd0cb8a 3271 fflush(stdout); /* FIXME eh? */
374330e2 3272 {
aa09f7d0 3273 if (!*ssh->cfg.username) {
edd0cb8a 3274 int ret; /* need not be kept over crReturn */
3275 s->cur_prompt = new_prompts(ssh->frontend);
3276 s->cur_prompt->to_server = TRUE;
3277 s->cur_prompt->name = dupstr("SSH login name");
3278 add_prompt(s->cur_prompt, dupstr("login as: "), TRUE,
3279 lenof(s->username));
3280 ret = get_userpass_input(s->cur_prompt, NULL, 0);
3281 while (ret < 0) {
51470298 3282 ssh->send_ok = 1;
edd0cb8a 3283 crWaitUntil(!pktin);
3284 ret = get_userpass_input(s->cur_prompt, in, inlen);
3285 ssh->send_ok = 0;
3286 }
3287 if (!ret) {
3288 /*
3289 * Failed to get a username. Terminate.
3290 */
3291 free_prompts(s->cur_prompt);
3292 ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
3293 crStop(0);
32874aea 3294 }
edd0cb8a 3295 memcpy(s->username, s->cur_prompt->prompts[0]->result,
3296 lenof(s->username));
3297 free_prompts(s->cur_prompt);
32874aea 3298 } else {
86916870 3299 strncpy(s->username, ssh->cfg.username, sizeof(s->username));
51470298 3300 s->username[sizeof(s->username)-1] = '\0';
374330e2 3301 }
fb09bf1c 3302
51470298 3303 send_packet(ssh, SSH1_CMSG_USER, PKT_STR, s->username, PKT_END);
c5e9c988 3304 {
edd0cb8a 3305 char *userlog = dupprintf("Sent username \"%s\"", s->username);
c5e9c988 3306 logevent(userlog);
32874aea 3307 if (flags & FLAG_INTERACTIVE &&
3308 (!((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)))) {
51470298 3309 c_write_str(ssh, userlog);
edd0cb8a 3310 c_write_str(ssh, "\r\n");
3c8e959b 3311 }
edd0cb8a 3312 sfree(userlog);
c5e9c988 3313 }
374330e2 3314 }
3315
ff3187f6 3316 crWaitUntil(pktin);
374330e2 3317
51470298 3318 if ((ssh->remote_bugs & BUG_CHOKES_ON_RSA)) {
0df73905 3319 /* We must not attempt PK auth. Pretend we've already tried it. */
51470298 3320 s->tried_publickey = s->tried_agent = 1;
0df73905 3321 } else {
51470298 3322 s->tried_publickey = s->tried_agent = 0;
0df73905 3323 }
51470298 3324 s->tis_auth_refused = s->ccard_auth_refused = 0;
edd0cb8a 3325 /*
3326 * Load the public half of any configured keyfile for later use.
3327 */
9a30e26b 3328 if (!filename_is_null(ssh->cfg.keyfile)) {
edd0cb8a 3329 int keytype;
3330 logeventf(ssh, "Reading private key file \"%.150s\"",
3331 filename_to_str(&ssh->cfg.keyfile));
3332 keytype = key_type(&ssh->cfg.keyfile);
3333 if (keytype == SSH_KEYTYPE_SSH1) {
3334 const char *error;
3335 if (rsakey_pubblob(&ssh->cfg.keyfile,
3336 &s->publickey_blob, &s->publickey_bloblen,
3337 &s->publickey_comment, &error)) {
3338 s->publickey_encrypted = rsakey_encrypted(&ssh->cfg.keyfile,
3339 NULL);
3340 } else {
3341 char *msgbuf;
3342 logeventf(ssh, "Unable to load private key (%s)", error);
3343 msgbuf = dupprintf("Unable to load private key file "
3344 "\"%.150s\" (%s)\r\n",
3345 filename_to_str(&ssh->cfg.keyfile),
3346 error);
3347 c_write_str(ssh, msgbuf);
3348 sfree(msgbuf);
3349 s->publickey_blob = NULL;
3350 }
3351 } else {
3352 char *msgbuf;
3353 logeventf(ssh, "Unable to use this key file (%s)",
3354 key_type_to_str(keytype));
3355 msgbuf = dupprintf("Unable to use key file \"%.150s\""
3356 " (%s)\r\n",
3357 filename_to_str(&ssh->cfg.keyfile),
3358 key_type_to_str(keytype));
3359 c_write_str(ssh, msgbuf);
3360 sfree(msgbuf);
51470298 3361 s->publickey_blob = NULL;
edd0cb8a 3362 }
396778f1 3363 } else
51470298 3364 s->publickey_blob = NULL;
7cca0d81 3365
ff3187f6 3366 while (pktin->type == SSH1_SMSG_FAILURE) {
51470298 3367 s->pwpkt_type = SSH1_CMSG_AUTH_PASSWORD;
614a20a0 3368
973612f5 3369 if (ssh->cfg.tryagent && agent_exists() && !s->tried_agent) {
32874aea 3370 /*
3371 * Attempt RSA authentication using Pageant.
3372 */
32874aea 3373 void *r;
3374
51470298 3375 s->authed = FALSE;
3376 s->tried_agent = 1;
32874aea 3377 logevent("Pageant is running. Requesting keys.");
3378
3379 /* Request the keys held by the agent. */
51470298 3380 PUT_32BIT(s->request, 1);
3381 s->request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;
839f10db 3382 if (!agent_query(s->request, 5, &r, &s->responselen,
3383 ssh_agent_callback, ssh)) {
3384 do {
3385 crReturn(0);
ff3187f6 3386 if (pktin) {
839f10db 3387 bombout(("Unexpected data from server while waiting"
3388 " for agent response"));
3389 crStop(0);
3390 }
ff3187f6 3391 } while (pktin || inlen > 0);
839f10db 3392 r = ssh->agent_response;
3393 s->responselen = ssh->agent_response_len;
3394 }
51470298 3395 s->response = (unsigned char *) r;
3396 if (s->response && s->responselen >= 5 &&
3397 s->response[4] == SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
3398 s->p = s->response + 5;
3399 s->nkeys = GET_32BIT(s->p);
3400 s->p += 4;
2e85c969 3401 logeventf(ssh, "Pageant has %d SSH-1 keys", s->nkeys);
51470298 3402 for (s->keyi = 0; s->keyi < s->nkeys; s->keyi++) {
94cd7c3a 3403 unsigned char *pkblob = s->p;
51470298 3404 s->p += 4;
0016d70b 3405 {
3406 int n, ok = FALSE;
3407 do { /* do while (0) to make breaking easy */
3408 n = ssh1_read_bignum
3409 (s->p, s->responselen-(s->p-s->response),
3410 &s->key.exponent);
3411 if (n < 0)
3412 break;
3413 s->p += n;
3414 n = ssh1_read_bignum
3415 (s->p, s->responselen-(s->p-s->response),
3416 &s->key.modulus);
3417 if (n < 0)
3418 break;
3419 s->p += n;
3420 if (s->responselen - (s->p-s->response) < 4)
3421 break;
3422 s->commentlen = GET_32BIT(s->p);
3423 s->p += 4;
3424 if (s->responselen - (s->p-s->response) <
3425 s->commentlen)
3426 break;
3427 s->commentp = (char *)s->p;
3428 s->p += s->commentlen;
3429 ok = TRUE;
3430 } while (0);
3431 if (!ok) {
3432 logevent("Pageant key list packet was truncated");
3433 break;
3434 }
3435 }
94cd7c3a 3436 if (s->publickey_blob) {
3437 if (!memcmp(pkblob, s->publickey_blob,
3438 s->publickey_bloblen)) {
3439 logeventf(ssh, "Pageant key #%d matches "
3440 "configured key file", s->keyi);
3441 s->tried_publickey = 1;
3442 } else
3443 /* Skip non-configured key */
3444 continue;
3445 }
3446 logeventf(ssh, "Trying Pageant key #%d", s->keyi);
51470298 3447 send_packet(ssh, SSH1_CMSG_AUTH_RSA,
3448 PKT_BIGNUM, s->key.modulus, PKT_END);
ff3187f6 3449 crWaitUntil(pktin);
3450 if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
32874aea 3451 logevent("Key refused");
3452 continue;
3453 }
3454 logevent("Received RSA challenge");
ff3187f6 3455 if ((s->challenge = ssh1_pkt_getmp(pktin)) == NULL) {
0016d70b 3456 bombout(("Server's RSA challenge was badly formatted"));
3457 crStop(0);
3458 }
3459
32874aea 3460 {
3461 char *agentreq, *q, *ret;
2d466ffd 3462 void *vret;
32874aea 3463 int len, retlen;
3464 len = 1 + 4; /* message type, bit count */
51470298 3465 len += ssh1_bignum_length(s->key.exponent);
3466 len += ssh1_bignum_length(s->key.modulus);
3467 len += ssh1_bignum_length(s->challenge);
32874aea 3468 len += 16; /* session id */
3469 len += 4; /* response format */
3d88e64d 3470 agentreq = snewn(4 + len, char);
32874aea 3471 PUT_32BIT(agentreq, len);
3472 q = agentreq + 4;
3473 *q++ = SSH1_AGENTC_RSA_CHALLENGE;
51470298 3474 PUT_32BIT(q, bignum_bitcount(s->key.modulus));
32874aea 3475 q += 4;
51470298 3476 q += ssh1_write_bignum(q, s->key.exponent);
3477 q += ssh1_write_bignum(q, s->key.modulus);
3478 q += ssh1_write_bignum(q, s->challenge);
3479 memcpy(q, s->session_id, 16);
32874aea 3480 q += 16;
3481 PUT_32BIT(q, 1); /* response format */
839f10db 3482 if (!agent_query(agentreq, len + 4, &vret, &retlen,
3483 ssh_agent_callback, ssh)) {
3484 sfree(agentreq);
3485 do {
3486 crReturn(0);
ff3187f6 3487 if (pktin) {
839f10db 3488 bombout(("Unexpected data from server"
3489 " while waiting for agent"
3490 " response"));
3491 crStop(0);
3492 }
ff3187f6 3493 } while (pktin || inlen > 0);
839f10db 3494 vret = ssh->agent_response;
3495 retlen = ssh->agent_response_len;
3496 } else
3497 sfree(agentreq);
2d466ffd 3498 ret = vret;
32874aea 3499 if (ret) {
3500 if (ret[4] == SSH1_AGENT_RSA_RESPONSE) {
3501 logevent("Sending Pageant's response");
51470298 3502 send_packet(ssh, SSH1_CMSG_AUTH_RSA_RESPONSE,
32874aea 3503 PKT_DATA, ret + 5, 16,
3504 PKT_END);
3505 sfree(ret);
ff3187f6 3506 crWaitUntil(pktin);
3507 if (pktin->type == SSH1_SMSG_SUCCESS) {
32874aea 3508 logevent
3509 ("Pageant's response accepted");
3510 if (flags & FLAG_VERBOSE) {
51470298 3511 c_write_str(ssh, "Authenticated using"
3512 " RSA key \"");
3513 c_write(ssh, s->commentp,
3514 s->commentlen);
3515 c_write_str(ssh, "\" from agent\r\n");
32874aea 3516 }
51470298 3517 s->authed = TRUE;
32874aea 3518 } else
3519 logevent
3520 ("Pageant's response not accepted");
3521 } else {
3522 logevent
3523 ("Pageant failed to answer challenge");
3524 sfree(ret);
3525 }
3526 } else {
3527 logevent("No reply received from Pageant");
3528 }
3529 }
51470298 3530 freebn(s->key.exponent);
3531 freebn(s->key.modulus);
3532 freebn(s->challenge);
3533 if (s->authed)
32874aea 3534 break;
3535 }
29b1d0b3 3536 sfree(s->response);
94cd7c3a 3537 if (s->publickey_blob && !s->tried_publickey)
3538 logevent("Configured key file not in Pageant");
32874aea 3539 }
51470298 3540 if (s->authed)
32874aea 3541 break;
3542 }
edd0cb8a 3543 if (s->publickey_blob && !s->tried_publickey) {
3544 /*
3545 * Try public key authentication with the specified
3546 * key file.
3547 */
3548 int got_passphrase; /* need not be kept over crReturn */
3549 if (flags & FLAG_VERBOSE)
3550 c_write_str(ssh, "Trying public key authentication.\r\n");
3551 logeventf(ssh, "Trying public key \"%s\"",
3552 filename_to_str(&ssh->cfg.keyfile));
3553 s->tried_publickey = 1;
3554 got_passphrase = FALSE;
3555 while (!got_passphrase) {
3556 /*
3557 * Get a passphrase, if necessary.
3558 */
3559 char *passphrase = NULL; /* only written after crReturn */
3560 const char *error;
3561 if (!s->publickey_encrypted) {
3562 if (flags & FLAG_VERBOSE)
3563 c_write_str(ssh, "No passphrase required.\r\n");
3564 passphrase = NULL;
3565 } else {
3566 int ret; /* need not be kept over crReturn */
3567 s->cur_prompt = new_prompts(ssh->frontend);
3568 s->cur_prompt->to_server = FALSE;
3569 s->cur_prompt->name = dupstr("SSH key passphrase");
3570 add_prompt(s->cur_prompt,
3571 dupprintf("Passphrase for key \"%.100s\": ",
3572 s->publickey_comment),
3573 FALSE, SSH_MAX_PASSWORD_LEN);
3574 ret = get_userpass_input(s->cur_prompt, NULL, 0);
3575 while (ret < 0) {
3576 ssh->send_ok = 1;
3577 crWaitUntil(!pktin);
3578 ret = get_userpass_input(s->cur_prompt, in, inlen);
3579 ssh->send_ok = 0;
3580 }
3581 if (!ret) {
3582 /* Failed to get a passphrase. Terminate. */
3583 free_prompts(s->cur_prompt);
3584 ssh_disconnect(ssh, NULL, "Unable to authenticate",
3585 0, TRUE);
3586 crStop(0);
3587 }
3588 passphrase = dupstr(s->cur_prompt->prompts[0]->result);
3589 free_prompts(s->cur_prompt);
3590 }
3591 /*
3592 * Try decrypting key with passphrase.
3593 */
3594 ret = loadrsakey(&ssh->cfg.keyfile, &s->key, passphrase,
3595 &error);
3596 if (passphrase) {
3597 memset(passphrase, 0, strlen(passphrase));
3598 sfree(passphrase);
3599 }
3600 if (ret == 1) {
3601 /* Correct passphrase. */
3602 got_passphrase = TRUE;
3603 } else if (ret == 0) {
3604 c_write_str(ssh, "Couldn't load private key from ");
3605 c_write_str(ssh, filename_to_str(&ssh->cfg.keyfile));
3606 c_write_str(ssh, " (");
3607 c_write_str(ssh, error);
3608 c_write_str(ssh, ").\r\n");
3609 got_passphrase = FALSE;
3610 break; /* go and try something else */
3611 } else if (ret == -1) {
3612 c_write_str(ssh, "Wrong passphrase.\r\n"); /* FIXME */
edd0cb8a 3613 got_passphrase = FALSE;
3614 /* and try again */
43536490 3615 } else {
3616 assert(0 && "unexpected return from loadrsakey()");
edc23a8a 3617 got_passphrase = FALSE; /* placate optimisers */
edd0cb8a 3618 }
3619 }
3620
3621 if (got_passphrase) {
3622
3623 /*
3624 * Send a public key attempt.
3625 */
3626 send_packet(ssh, SSH1_CMSG_AUTH_RSA,
3627 PKT_BIGNUM, s->key.modulus, PKT_END);
3628
3629 crWaitUntil(pktin);
3630 if (pktin->type == SSH1_SMSG_FAILURE) {
3631 c_write_str(ssh, "Server refused our public key.\r\n");
7b575324 3632 continue; /* go and try something else */
edd0cb8a 3633 }
3634 if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
3635 bombout(("Bizarre response to offer of public key"));
3636 crStop(0);
3637 }
3638
3639 {
3640 int i;
3641 unsigned char buffer[32];
3642 Bignum challenge, response;
3643
3644 if ((challenge = ssh1_pkt_getmp(pktin)) == NULL) {
3645 bombout(("Server's RSA challenge was badly formatted"));
3646 crStop(0);
3647 }
3648 response = rsadecrypt(challenge, &s->key);
3649 freebn(s->key.private_exponent);/* burn the evidence */
3650
3651 for (i = 0; i < 32; i++) {
3652 buffer[i] = bignum_byte(response, 31 - i);
3653 }
3654
3655 MD5Init(&md5c);
3656 MD5Update(&md5c, buffer, 32);
3657 MD5Update(&md5c, s->session_id, 16);
3658 MD5Final(buffer, &md5c);
3659
3660 send_packet(ssh, SSH1_CMSG_AUTH_RSA_RESPONSE,
3661 PKT_DATA, buffer, 16, PKT_END);
3662
3663 freebn(challenge);
3664 freebn(response);
3665 }
3666
3667 crWaitUntil(pktin);
3668 if (pktin->type == SSH1_SMSG_FAILURE) {
3669 if (flags & FLAG_VERBOSE)
3670 c_write_str(ssh, "Failed to authenticate with"
3671 " our public key.\r\n");
7b575324 3672 continue; /* go and try something else */
edd0cb8a 3673 } else if (pktin->type != SSH1_SMSG_SUCCESS) {
3674 bombout(("Bizarre response to RSA authentication response"));
3675 crStop(0);
3676 }
3677
3678 break; /* we're through! */
3679 }
3680
3681 }
3682
3683 /*
3684 * Otherwise, try various forms of password-like authentication.
3685 */
3686 s->cur_prompt = new_prompts(ssh->frontend);
32874aea 3687
86916870 3688 if (ssh->cfg.try_tis_auth &&
51470298 3689 (s->supported_auths_mask & (1 << SSH1_AUTH_TIS)) &&
3690 !s->tis_auth_refused) {
3691 s->pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
32874aea 3692 logevent("Requested TIS authentication");
51470298 3693 send_packet(ssh, SSH1_CMSG_AUTH_TIS, PKT_END);
ff3187f6 3694 crWaitUntil(pktin);
3695 if (pktin->type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
32874aea 3696 logevent("TIS authentication declined");
3697 if (flags & FLAG_INTERACTIVE)
51470298 3698 c_write_str(ssh, "TIS authentication refused.\r\n");
3699 s->tis_auth_refused = 1;
614a20a0 3700 continue;
32874aea 3701 } else {
0016d70b 3702 char *challenge;
3703 int challengelen;
edd0cb8a 3704 char *instr_suf, *prompt;
0016d70b 3705
ff3187f6 3706 ssh_pkt_getstring(pktin, &challenge, &challengelen);
0016d70b 3707 if (!challenge) {
3708 bombout(("TIS challenge packet was badly formed"));
3709 crStop(0);
3710 }
32874aea 3711 logevent("Received TIS challenge");
edd0cb8a 3712 s->cur_prompt->to_server = TRUE;
3713 s->cur_prompt->name = dupstr("SSH TIS authentication");
614a20a0 3714 /* Prompt heuristic comes from OpenSSH */
edd0cb8a 3715 if (memchr(challenge, '\n', challengelen)) {
3716 instr_suf = dupstr("");
3717 prompt = dupprintf("%.*s", challengelen, challenge);
3718 } else {
3719 instr_suf = dupprintf("%.*s", challengelen, challenge);
3720 prompt = dupstr("Response: ");
3721 }
3722 s->cur_prompt->instruction =
3723 dupprintf("Using TIS authentication.%s%s",
3724 (*instr_suf) ? "\n" : "",
3725 instr_suf);
3726 s->cur_prompt->instr_reqd = TRUE;
3727 add_prompt(s->cur_prompt, prompt, FALSE, SSH_MAX_PASSWORD_LEN);
3728 sfree(instr_suf);
32874aea 3729 }
3730 }
86916870 3731 if (ssh->cfg.try_tis_auth &&
51470298 3732 (s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
3733 !s->ccard_auth_refused) {
3734 s->pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
32874aea 3735 logevent("Requested CryptoCard authentication");
51470298 3736 send_packet(ssh, SSH1_CMSG_AUTH_CCARD, PKT_END);
ff3187f6 3737 crWaitUntil(pktin);
3738 if (pktin->type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
32874aea 3739 logevent("CryptoCard authentication declined");
51470298 3740 c_write_str(ssh, "CryptoCard authentication refused.\r\n");
3741 s->ccard_auth_refused = 1;
614a20a0 3742 continue;
32874aea 3743 } else {
0016d70b 3744 char *challenge;
3745 int challengelen;
edd0cb8a 3746 char *instr_suf, *prompt;
0016d70b 3747
ff3187f6 3748 ssh_pkt_getstring(pktin, &challenge, &challengelen);
0016d70b 3749 if (!challenge) {
3750 bombout(("CryptoCard challenge packet was badly formed"));
3751 crStop(0);
3752 }
32874aea 3753 logevent("Received CryptoCard challenge");
edd0cb8a 3754 s->cur_prompt->to_server = TRUE;
3755 s->cur_prompt->name = dupstr("SSH CryptoCard authentication");
3756 s->cur_prompt->name_reqd = FALSE;
3757 /* Prompt heuristic comes from OpenSSH */
3758 if (memchr(challenge, '\n', challengelen)) {
3759 instr_suf = dupstr("");
3760 prompt = dupprintf("%.*s", challengelen, challenge);
3761 } else {
3762 instr_suf = dupprintf("%.*s", challengelen, challenge);
3763 prompt = dupstr("Response: ");
3764 }
3765 s->cur_prompt->instruction =
3766 dupprintf("Using CryptoCard authentication.%s%s",
3767 (*instr_suf) ? "\n" : "",
3768 instr_suf);
3769 s->cur_prompt->instr_reqd = TRUE;
3770 add_prompt(s->cur_prompt, prompt, FALSE, SSH_MAX_PASSWORD_LEN);
3771 sfree(instr_suf);
32874aea 3772 }
3773 }
51470298 3774 if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
edd0cb8a 3775 s->cur_prompt->to_server = TRUE;
3776 s->cur_prompt->name = dupstr("SSH password");
3777 add_prompt(s->cur_prompt, dupprintf("%.90s@%.90s's password: ",
3778 s->username, ssh->savedhost),
3779 FALSE, SSH_MAX_PASSWORD_LEN);
32874aea 3780 }
a52f067e 3781
614a20a0 3782 /*
3783 * Show password prompt, having first obtained it via a TIS
3784 * or CryptoCard exchange if we're doing TIS or CryptoCard
3785 * authentication.
3786 */
edd0cb8a 3787 {
3788 int ret; /* need not be kept over crReturn */
3789 ret = get_userpass_input(s->cur_prompt, NULL, 0);
3790 while (ret < 0) {
3791 ssh->send_ok = 1;
3792 crWaitUntil(!pktin);
3793 ret = get_userpass_input(s->cur_prompt, in, inlen);
3794 ssh->send_ok = 0;
3795 }
3796 if (!ret) {
32874aea 3797 /*
edd0cb8a 3798 * Failed to get a password (for example
32874aea 3799 * because one was supplied on the command line
3800 * which has already failed to work). Terminate.
3801 */
edd0cb8a 3802 free_prompts(s->cur_prompt);
3803 ssh_disconnect(ssh, NULL, "Unable to authenticate", 0, TRUE);
3804 crStop(0);
32874aea 3805 }
32874aea 3806 }
3807
edd0cb8a 3808 if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
32874aea 3809 /*
edd0cb8a 3810 * Defence against traffic analysis: we send a
3811 * whole bunch of packets containing strings of
3812 * different lengths. One of these strings is the
3813 * password, in a SSH1_CMSG_AUTH_PASSWORD packet.
3814 * The others are all random data in
3815 * SSH1_MSG_IGNORE packets. This way a passive
3816 * listener can't tell which is the password, and
3817 * hence can't deduce the password length.
3818 *
3819 * Anybody with a password length greater than 16
3820 * bytes is going to have enough entropy in their
3821 * password that a listener won't find it _that_
3822 * much help to know how long it is. So what we'll
3823 * do is:
3824 *
3825 * - if password length < 16, we send 15 packets
3826 * containing string lengths 1 through 15
3827 *
3828 * - otherwise, we let N be the nearest multiple
3829 * of 8 below the password length, and send 8
3830 * packets containing string lengths N through
3831 * N+7. This won't obscure the order of
3832 * magnitude of the password length, but it will
3833 * introduce a bit of extra uncertainty.
3834 *
bf982899 3835 * A few servers can't deal with SSH1_MSG_IGNORE, at
3836 * least in this context. For these servers, we need
3837 * an alternative defence. We make use of the fact
3838 * that the password is interpreted as a C string:
3839 * so we can append a NUL, then some random data.
edd0cb8a 3840 *
bf982899 3841 * A few servers can deal with neither SSH1_MSG_IGNORE
3842 * here _nor_ a padded password string.
3843 * For these servers we are left with no defences
edd0cb8a 3844 * against password length sniffing.
32874aea 3845 */
bf982899 3846 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE) &&
3847 !(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
32874aea 3848 /*
edd0cb8a 3849 * The server can deal with SSH1_MSG_IGNORE, so
3850 * we can use the primary defence.
32874aea 3851 */
edd0cb8a 3852 int bottom, top, pwlen, i;
3853 char *randomstr;
32874aea 3854
edd0cb8a 3855 pwlen = strlen(s->cur_prompt->prompts[0]->result);
3856 if (pwlen < 16) {
3857 bottom = 0; /* zero length passwords are OK! :-) */
3858 top = 15;
3859 } else {
3860 bottom = pwlen & ~7;
3861 top = bottom + 7;
3862 }
32874aea 3863
edd0cb8a 3864 assert(pwlen >= bottom && pwlen <= top);
32874aea 3865
edd0cb8a 3866 randomstr = snewn(top + 1, char);
32874aea 3867
edd0cb8a 3868 for (i = bottom; i <= top; i++) {
3869 if (i == pwlen) {
3870 defer_packet(ssh, s->pwpkt_type,
3871 PKTT_PASSWORD, PKT_STR,
3872 s->cur_prompt->prompts[0]->result,
3873 PKTT_OTHER, PKT_END);
3874 } else {
3875 for (j = 0; j < i; j++) {
3876 do {
3877 randomstr[j] = random_byte();
3878 } while (randomstr[j] == '\0');
32874aea 3879 }
edd0cb8a 3880 randomstr[i] = '\0';
3881 defer_packet(ssh, SSH1_MSG_IGNORE,
3882 PKT_STR, randomstr, PKT_END);
32874aea 3883 }
edd0cb8a 3884 }
3885 logevent("Sending password with camouflage packets");
3886 ssh_pkt_defersend(ssh);
3887 sfree(randomstr);
3888 }
3889 else if (!(ssh->remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
3890 /*
3891 * The server can't deal with SSH1_MSG_IGNORE
3892 * but can deal with padded passwords, so we
3893 * can use the secondary defence.
3894 */
3895 char string[64];
3896 char *ss;
3897 int len;
3898
3899 len = strlen(s->cur_prompt->prompts[0]->result);
3900 if (len < sizeof(string)) {
3901 ss = string;
3902 strcpy(string, s->cur_prompt->prompts[0]->result);
3903 len++; /* cover the zero byte */
3904 while (len < sizeof(string)) {
3905 string[len++] = (char) random_byte();
bd358db1 3906 }
bd358db1 3907 } else {
edd0cb8a 3908 ss = s->cur_prompt->prompts[0]->result;
32874aea 3909 }
edd0cb8a 3910 logevent("Sending length-padded password");
9a10ecf4 3911 send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
edd0cb8a 3912 PKT_INT, len, PKT_DATA, ss, len,
3913 PKTT_OTHER, PKT_END);
3914 } else {
3915 /*
bf982899 3916 * The server is believed unable to cope with
3917 * any of our password camouflage methods.
edd0cb8a 3918 */
3919 int len;
3920 len = strlen(s->cur_prompt->prompts[0]->result);
3921 logevent("Sending unpadded password");
3922 send_packet(ssh, s->pwpkt_type,
3923 PKTT_PASSWORD, PKT_INT, len,
3924 PKT_DATA, s->cur_prompt->prompts[0]->result, len,
3925 PKTT_OTHER, PKT_END);
32874aea 3926 }
edd0cb8a 3927 } else {
3928 send_packet(ssh, s->pwpkt_type, PKTT_PASSWORD,
3929 PKT_STR, s->cur_prompt->prompts[0]->result,
3930 PKTT_OTHER, PKT_END);
32874aea 3931 }
c5e9c988 3932 logevent("Sent password");
edd0cb8a 3933 free_prompts(s->cur_prompt);
ff3187f6 3934 crWaitUntil(pktin);
3935 if (pktin->type == SSH1_SMSG_FAILURE) {
32874aea 3936 if (flags & FLAG_VERBOSE)
51470298 3937 c_write_str(ssh, "Access denied\r\n");
c5e9c988 3938 logevent("Authentication refused");
ff3187f6 3939 } else if (pktin->type != SSH1_SMSG_SUCCESS) {
3940 bombout(("Strange packet received, type %d", pktin->type));
7ffdbc1a 3941 crStop(0);
374330e2 3942 }
3943 }
3944
edd0cb8a 3945 /* Clear up */
3946 if (s->publickey_blob) {
3947 sfree(s->publickey_blob);
3948 sfree(s->publickey_comment);
3949 }
3950
c5e9c988 3951 logevent("Authentication successful");
3952
fb09bf1c 3953 crFinish(1);
3954}
3955
32874aea 3956void sshfwd_close(struct ssh_channel *c)
3957{
51470298 3958 Ssh ssh = c->ssh;
3959
1ef619ae 3960 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 3961 return;
36f94d1f 3962
80e48603 3963 if (c && !c->closes) {
4ed34d25 3964 /*
64d6ff88 3965 * If halfopen is true, we have sent
4ed34d25 3966 * CHANNEL_OPEN for this channel, but it hasn't even been
3967 * acknowledged by the server. So we must set a close flag
3968 * on it now, and then when the server acks the channel
3969 * open, we can close it then.
3970 */
64d6ff88 3971 if (!c->halfopen) {
51470298 3972 if (ssh->version == 1) {
3973 send_packet(ssh, SSH1_MSG_CHANNEL_CLOSE, PKT_INT, c->remoteid,
4ed34d25 3974 PKT_END);
3975 } else {
ff3187f6 3976 struct Packet *pktout;
3977 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
3978 ssh2_pkt_adduint32(pktout, c->remoteid);
3979 ssh2_pkt_send(ssh, pktout);
4ed34d25 3980 }
32874aea 3981 }
0357890f 3982 c->closes = 1; /* sent MSG_CLOSE */
32874aea 3983 if (c->type == CHAN_X11) {
3984 c->u.x11.s = NULL;
d74d141c 3985 logevent("Forwarded X11 connection terminated");
4ed34d25 3986 } else if (c->type == CHAN_SOCKDATA ||
3987 c->type == CHAN_SOCKDATA_DORMANT) {
d74d141c 3988 c->u.pfd.s = NULL;
3989 logevent("Forwarded port closed");
32874aea 3990 }
3991 }
3992}
3993
5471d09a 3994int sshfwd_write(struct ssh_channel *c, char *buf, int len)
32874aea 3995{
51470298 3996 Ssh ssh = c->ssh;
3997
1ef619ae 3998 if (ssh->state == SSH_STATE_CLOSED)
36f94d1f 3999 return 0;
36f94d1f 4000
51470298 4001 if (ssh->version == 1) {
4002 send_packet(ssh, SSH1_MSG_CHANNEL_DATA,
32874aea 4003 PKT_INT, c->remoteid,
a2724fba 4004 PKT_INT, len, PKTT_DATA, PKT_DATA, buf, len,
9a10ecf4 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);
a2724fba 4975 send_packet(ssh, SSH1_CMSG_STDIN_DATA,
4976 PKT_INT, len, PKTT_DATA, PKT_DATA, in, len,
9a10ecf4 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);
ff3187f6 6126 ssh2_pkt_addstring_start(pktout);
a2724fba 6127 dont_log_data(ssh, pktout, PKTLOG_OMIT);
ff3187f6 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 */
15abfc2e 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.
467e064d 6287 * If we are buffering too much, we may still
6288 * need to adjust the window if the server's
6289 * sent excess data.
51df0ab5 6290 */
467e064d 6291 ssh2_set_window(c, bufsize < OUR_V2_WINSIZE ?
6292 OUR_V2_WINSIZE - bufsize : 0);
51df0ab5 6293 }
6294}
6295
6296static void ssh2_msg_channel_eof(Ssh ssh, struct Packet *pktin)
6297{
6298 unsigned i = ssh_pkt_getuint32(pktin);
6299 struct ssh_channel *c;
6300
6301 c = find234(ssh->channels, &i, ssh_channelfind);
6302 if (!c)
6303 return; /* nonexistent channel */
6304
6305 if (c->type == CHAN_X11) {
6306 /*
6307 * Remote EOF on an X11 channel means we should
6308 * wrap up and close the channel ourselves.
6309 */
6310 x11_close(c->u.x11.s);
6311 sshfwd_close(c);
6312 } else if (c->type == CHAN_AGENT) {
6313 sshfwd_close(c);
6314 } else if (c->type == CHAN_SOCKDATA) {
6315 pfd_close(c->u.pfd.s);
6316 sshfwd_close(c);
6317 }
6318}
6319
6320static void ssh2_msg_channel_close(Ssh ssh, struct Packet *pktin)
6321{
6322 unsigned i = ssh_pkt_getuint32(pktin);
6323 struct ssh_channel *c;
6324 struct Packet *pktout;
6325
6326 c = find234(ssh->channels, &i, ssh_channelfind);
64d6ff88 6327 if (!c || c->halfopen) {
51df0ab5 6328 bombout(("Received CHANNEL_CLOSE for %s channel %d\n",
6329 c ? "half-open" : "nonexistent", i));
6330 return;
6331 }
6332 /* Do pre-close processing on the channel. */
6333 switch (c->type) {
6334 case CHAN_MAINSESSION:
6335 ssh->mainchan = NULL;
6336 update_specials_menu(ssh->frontend);
6337 break;
6338 case CHAN_X11:
6339 if (c->u.x11.s != NULL)
6340 x11_close(c->u.x11.s);
6341 sshfwd_close(c);
6342 break;
6343 case CHAN_AGENT:
6344 sshfwd_close(c);
6345 break;
6346 case CHAN_SOCKDATA:
6347 if (c->u.pfd.s != NULL)
6348 pfd_close(c->u.pfd.s);
6349 sshfwd_close(c);
6350 break;
6351 }
6352 if (c->closes == 0) {
6353 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6354 ssh2_pkt_adduint32(pktout, c->remoteid);
6355 ssh2_pkt_send(ssh, pktout);
6356 }
6357 del234(ssh->channels, c);
6358 bufchain_clear(&c->v.v2.outbuffer);
6359 sfree(c);
6360
6361 /*
6362 * See if that was the last channel left open.
6363 * (This is only our termination condition if we're
6364 * not running in -N mode.)
6365 */
6366 if (!ssh->cfg.ssh_no_shell && count234(ssh->channels) == 0) {
51df0ab5 6367 /*
6368 * We used to send SSH_MSG_DISCONNECT here,
6369 * because I'd believed that _every_ conforming
2e85c969 6370 * SSH-2 connection had to end with a disconnect
51df0ab5 6371 * being sent by at least one side; apparently
6372 * I was wrong and it's perfectly OK to
6373 * unceremoniously slam the connection shut
6374 * when you're done, and indeed OpenSSH feels
6375 * this is more polite than sending a
6376 * DISCONNECT. So now we don't.
6377 */
9e296bfa 6378 ssh_disconnect(ssh, "All channels closed", NULL, 0, TRUE);
51df0ab5 6379 }
6380}
6381
6382static void ssh2_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
6383{
6384 unsigned i = ssh_pkt_getuint32(pktin);
6385 struct ssh_channel *c;
6386 struct Packet *pktout;
6387
6388 c = find234(ssh->channels, &i, ssh_channelfind);
6389 if (!c)
6390 return; /* nonexistent channel */
6391 if (c->type != CHAN_SOCKDATA_DORMANT)
6392 return; /* dunno why they're confirming this */
6393 c->remoteid = ssh_pkt_getuint32(pktin);
64d6ff88 6394 c->halfopen = FALSE;
51df0ab5 6395 c->type = CHAN_SOCKDATA;
6396 c->v.v2.remwindow = ssh_pkt_getuint32(pktin);
6397 c->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
6398 if (c->u.pfd.s)
6399 pfd_confirm(c->u.pfd.s);
6400 if (c->closes) {
6401 /*
6402 * We have a pending close on this channel,
6403 * which we decided on before the server acked
6404 * the channel open. So now we know the
6405 * remoteid, we can close it again.
6406 */
6407 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
6408 ssh2_pkt_adduint32(pktout, c->remoteid);
6409 ssh2_pkt_send(ssh, pktout);
6410 }
6411}
6412
6413static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
6414{
6415 static const char *const reasons[] = {
6416 "<unknown reason code>",
6417 "Administratively prohibited",
6418 "Connect failed",
6419 "Unknown channel type",
6420 "Resource shortage",
6421 };
6422 unsigned i = ssh_pkt_getuint32(pktin);
6423 unsigned reason_code;
6424 char *reason_string;
6425 int reason_length;
51df0ab5 6426 struct ssh_channel *c;
6427 c = find234(ssh->channels, &i, ssh_channelfind);
6428 if (!c)
6429 return; /* nonexistent channel */
6430 if (c->type != CHAN_SOCKDATA_DORMANT)
6431 return; /* dunno why they're failing this */
6432
6433 reason_code = ssh_pkt_getuint32(pktin);
6434 if (reason_code >= lenof(reasons))
6435 reason_code = 0; /* ensure reasons[reason_code] in range */
6436 ssh_pkt_getstring(pktin, &reason_string, &reason_length);
fb983202 6437 logeventf(ssh, "Forwarded connection refused by server: %s [%.*s]",
6438 reasons[reason_code], reason_length, reason_string);
51df0ab5 6439
6440 pfd_close(c->u.pfd.s);
6441
6442 del234(ssh->channels, c);
6443 sfree(c);
6444}
6445
6446static void ssh2_msg_channel_request(Ssh ssh, struct Packet *pktin)
6447{
6448 unsigned localid;
6449 char *type;
6450 int typelen, want_reply;
6451 int reply = SSH2_MSG_CHANNEL_FAILURE; /* default */
6452 struct ssh_channel *c;
6453 struct Packet *pktout;
6454
6455 localid = ssh_pkt_getuint32(pktin);
6456 ssh_pkt_getstring(pktin, &type, &typelen);
6457 want_reply = ssh2_pkt_getbool(pktin);
6458
6459 /*
6460 * First, check that the channel exists. Otherwise,
6461 * we can instantly disconnect with a rude message.
6462 */
6463 c = find234(ssh->channels, &localid, ssh_channelfind);
6464 if (!c) {
9e296bfa 6465 char *buf = dupprintf("Received channel request for nonexistent"
6466 " channel %d", localid);
6467 ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
6468 sfree(buf);
51df0ab5 6469 return;
6470 }
6471
6472 /*
6473 * Having got the channel number, we now look at
6474 * the request type string to see if it's something
6475 * we recognise.
6476 */
6477 if (c == ssh->mainchan) {
6478 /*
6479 * We recognise "exit-status" and "exit-signal" on
6480 * the primary channel.
6481 */
6482 if (typelen == 11 &&
6483 !memcmp(type, "exit-status", 11)) {
6484
6485 ssh->exitcode = ssh_pkt_getuint32(pktin);
6486 logeventf(ssh, "Server sent command exit status %d",
6487 ssh->exitcode);
6488 reply = SSH2_MSG_CHANNEL_SUCCESS;
6489
6490 } else if (typelen == 11 &&
6491 !memcmp(type, "exit-signal", 11)) {
6492
6493 int is_plausible = TRUE, is_int = FALSE;
6494 char *fmt_sig = "", *fmt_msg = "";
6495 char *msg;
6496 int msglen = 0, core = FALSE;
6497 /* ICK: older versions of OpenSSH (e.g. 3.4p1)
6498 * provide an `int' for the signal, despite its
6499 * having been a `string' in the drafts since at
6500 * least 2001. (Fixed in session.c 1.147.) Try to
6501 * infer which we can safely parse it as. */
6502 {
6503 unsigned char *p = pktin->body +
6504 pktin->savedpos;
6505 long len = pktin->length - pktin->savedpos;
6506 unsigned long num = GET_32BIT(p); /* what is it? */
6507 /* If it's 0, it hardly matters; assume string */
6508 if (num == 0) {
6509 is_int = FALSE;
6510 } else {
6511 int maybe_int = FALSE, maybe_str = FALSE;
6512#define CHECK_HYPOTHESIS(offset, result) \
6513 do { \
6514 long q = offset; \
6515 if (q >= 0 && q+4 <= len) { \
6516 q = q + 4 + GET_32BIT(p+q); \
6517 if (q >= 0 && q+4 <= len && \
c849ff23 6518 ((q = q + 4 + GET_32BIT(p+q))!= 0) && q == len) \
51df0ab5 6519 result = TRUE; \
6520 } \
6521 } while(0)
6522 CHECK_HYPOTHESIS(4+1, maybe_int);
6523 CHECK_HYPOTHESIS(4+num+1, maybe_str);
6524#undef CHECK_HYPOTHESIS
6525 if (maybe_int && !maybe_str)
6526 is_int = TRUE;
6527 else if (!maybe_int && maybe_str)
6528 is_int = FALSE;
6529 else
6530 /* Crikey. Either or neither. Panic. */
6531 is_plausible = FALSE;
6532 }
6533 }
d051d1b4 6534 ssh->exitcode = 128; /* means `unknown signal' */
51df0ab5 6535 if (is_plausible) {
6536 if (is_int) {
6537 /* Old non-standard OpenSSH. */
6538 int signum = ssh_pkt_getuint32(pktin);
6539 fmt_sig = dupprintf(" %d", signum);
d051d1b4 6540 ssh->exitcode = 128 + signum;
51df0ab5 6541 } else {
6542 /* As per the drafts. */
6543 char *sig;
6544 int siglen;
6545 ssh_pkt_getstring(pktin, &sig, &siglen);
6546 /* Signal name isn't supposed to be blank, but
6547 * let's cope gracefully if it is. */
6548 if (siglen) {
6549 fmt_sig = dupprintf(" \"%.*s\"",
6550 siglen, sig);
6551 }
d051d1b4 6552
6553 /*
6554 * Really hideous method of translating the
6555 * signal description back into a locally
6556 * meaningful number.
6557 */
6558
6559 if (0)
6560 ;
b707973a 6561#define TRANSLATE_SIGNAL(s) \
6562 else if (siglen == lenof(#s)-1 && !memcmp(sig, #s, siglen)) \
6563 ssh->exitcode = 128 + SIG ## s
d051d1b4 6564#ifdef SIGABRT
b707973a 6565 TRANSLATE_SIGNAL(ABRT);
d051d1b4 6566#endif
6567#ifdef SIGALRM
b707973a 6568 TRANSLATE_SIGNAL(ALRM);
d051d1b4 6569#endif
6570#ifdef SIGFPE
b707973a 6571 TRANSLATE_SIGNAL(FPE);
d051d1b4 6572#endif
6573#ifdef SIGHUP
b707973a 6574 TRANSLATE_SIGNAL(HUP);
d051d1b4 6575#endif
6576#ifdef SIGILL
b707973a 6577 TRANSLATE_SIGNAL(ILL);
d051d1b4 6578#endif
6579#ifdef SIGINT
b707973a 6580 TRANSLATE_SIGNAL(INT);
d051d1b4 6581#endif
6582#ifdef SIGKILL
b707973a 6583 TRANSLATE_SIGNAL(KILL);
d051d1b4 6584#endif
6585#ifdef SIGPIPE
b707973a 6586 TRANSLATE_SIGNAL(PIPE);
d051d1b4 6587#endif
6588#ifdef SIGQUIT
b707973a 6589 TRANSLATE_SIGNAL(QUIT);
d051d1b4 6590#endif
6591#ifdef SIGSEGV
b707973a 6592 TRANSLATE_SIGNAL(SEGV);
d051d1b4 6593#endif
6594#ifdef SIGTERM
b707973a 6595 TRANSLATE_SIGNAL(TERM);
d051d1b4 6596#endif
6597#ifdef SIGUSR1
b707973a 6598 TRANSLATE_SIGNAL(USR1);
d051d1b4 6599#endif
6600#ifdef SIGUSR2
b707973a 6601 TRANSLATE_SIGNAL(USR2);
d051d1b4 6602#endif
b707973a 6603#undef TRANSLATE_SIGNAL
d051d1b4 6604 else
6605 ssh->exitcode = 128;
51df0ab5 6606 }
6607 core = ssh2_pkt_getbool(pktin);
6608 ssh_pkt_getstring(pktin, &msg, &msglen);
6609 if (msglen) {
6610 fmt_msg = dupprintf(" (\"%.*s\")", msglen, msg);
6611 }
6612 /* ignore lang tag */
6613 } /* else don't attempt to parse */
6614 logeventf(ssh, "Server exited on signal%s%s%s",
6615 fmt_sig, core ? " (core dumped)" : "",
6616 fmt_msg);
6617 if (*fmt_sig) sfree(fmt_sig);
6618 if (*fmt_msg) sfree(fmt_msg);
6619 reply = SSH2_MSG_CHANNEL_SUCCESS;
6620
6621 }
6622 } else {
6623 /*
6624 * This is a channel request we don't know
6625 * about, so we now either ignore the request
6626 * or respond with CHANNEL_FAILURE, depending
6627 * on want_reply.
6628 */
6629 reply = SSH2_MSG_CHANNEL_FAILURE;
6630 }
6631 if (want_reply) {
6632 pktout = ssh2_pkt_init(reply);
6633 ssh2_pkt_adduint32(pktout, c->remoteid);
6634 ssh2_pkt_send(ssh, pktout);
6635 }
6636}
6637
6638static void ssh2_msg_global_request(Ssh ssh, struct Packet *pktin)
6639{
6640 char *type;
6641 int typelen, want_reply;
6642 struct Packet *pktout;
6643
6644 ssh_pkt_getstring(pktin, &type, &typelen);
6645 want_reply = ssh2_pkt_getbool(pktin);
6646
6647 /*
6648 * We currently don't support any global requests
6649 * at all, so we either ignore the request or
6650 * respond with REQUEST_FAILURE, depending on
6651 * want_reply.
6652 */
6653 if (want_reply) {
6654 pktout = ssh2_pkt_init(SSH2_MSG_REQUEST_FAILURE);
6655 ssh2_pkt_send(ssh, pktout);
6656 }
6657}
6658
6659static void ssh2_msg_channel_open(Ssh ssh, struct Packet *pktin)
6660{
6661 char *type;
6662 int typelen;
6663 char *peeraddr;
6664 int peeraddrlen;
6665 int peerport;
6666 char *error = NULL;
6667 struct ssh_channel *c;
6668 unsigned remid, winsize, pktsize;
6669 struct Packet *pktout;
6670
6671 ssh_pkt_getstring(pktin, &type, &typelen);
6672 c = snew(struct ssh_channel);
6673 c->ssh = ssh;
6674
6675 remid = ssh_pkt_getuint32(pktin);
6676 winsize = ssh_pkt_getuint32(pktin);
6677 pktsize = ssh_pkt_getuint32(pktin);
6678
6679 if (typelen == 3 && !memcmp(type, "x11", 3)) {
6680 char *addrstr;
6681
6682 ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
6683 addrstr = snewn(peeraddrlen+1, char);
6684 memcpy(addrstr, peeraddr, peeraddrlen);
6685 addrstr[peeraddrlen] = '\0';
6686 peerport = ssh_pkt_getuint32(pktin);
6687
6688 logeventf(ssh, "Received X11 connect request from %s:%d",
6689 addrstr, peerport);
6690
6691 if (!ssh->X11_fwd_enabled)
6692 error = "X11 forwarding is not enabled";
6693 else if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c,
6694 ssh->x11auth, addrstr, peerport,
6695 &ssh->cfg) != NULL) {
6696 error = "Unable to open an X11 connection";
6697 } else {
6698 logevent("Opening X11 forward connection succeeded");
6699 c->type = CHAN_X11;
6700 }
6701
6702 sfree(addrstr);
6703 } else if (typelen == 15 &&
6704 !memcmp(type, "forwarded-tcpip", 15)) {
6705 struct ssh_rportfwd pf, *realpf;
6706 char *dummy;
6707 int dummylen;
6708 ssh_pkt_getstring(pktin, &dummy, &dummylen);/* skip address */
6709 pf.sport = ssh_pkt_getuint32(pktin);
6710 ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
6711 peerport = ssh_pkt_getuint32(pktin);
6712 realpf = find234(ssh->rportfwds, &pf, NULL);
6713 logeventf(ssh, "Received remote port %d open request "
6714 "from %s:%d", pf.sport, peeraddr, peerport);
6715 if (realpf == NULL) {
6716 error = "Remote port is not recognised";
6717 } else {
6718 const char *e = pfd_newconnect(&c->u.pfd.s,
6719 realpf->dhost,
6720 realpf->dport, c,
05581745 6721 &ssh->cfg,
6722 realpf->pfrec->addressfamily);
51df0ab5 6723 logeventf(ssh, "Attempting to forward remote port to "
6724 "%s:%d", realpf->dhost, realpf->dport);
6725 if (e != NULL) {
6726 logeventf(ssh, "Port open failed: %s", e);
6727 error = "Port open failed";
6728 } else {
6729 logevent("Forwarded port opened successfully");
6730 c->type = CHAN_SOCKDATA;
6731 }
6732 }
6733 } else if (typelen == 22 &&
c49cf994 6734 !memcmp(type, "auth-agent@openssh.com", 22)) {
51df0ab5 6735 if (!ssh->agentfwd_enabled)
6736 error = "Agent forwarding is not enabled";
6737 else {
6738 c->type = CHAN_AGENT; /* identify channel type */
6739 c->u.a.lensofar = 0;
6740 }
6741 } else {
6742 error = "Unsupported channel type requested";
6743 }
6744
6745 c->remoteid = remid;
64d6ff88 6746 c->halfopen = FALSE;
51df0ab5 6747 if (error) {
6748 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_FAILURE);
6749 ssh2_pkt_adduint32(pktout, c->remoteid);
6750 ssh2_pkt_adduint32(pktout, SSH2_OPEN_CONNECT_FAILED);
6751 ssh2_pkt_addstring(pktout, error);
6752 ssh2_pkt_addstring(pktout, "en"); /* language tag */
6753 ssh2_pkt_send(ssh, pktout);
6754 logeventf(ssh, "Rejected channel open: %s", error);
6755 sfree(c);
6756 } else {
6757 c->localid = alloc_channel_id(ssh);
6758 c->closes = 0;
6759 c->v.v2.locwindow = OUR_V2_WINSIZE;
6760 c->v.v2.remwindow = winsize;
6761 c->v.v2.remmaxpkt = pktsize;
6762 bufchain_init(&c->v.v2.outbuffer);
6763 add234(ssh->channels, c);
6764 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
6765 ssh2_pkt_adduint32(pktout, c->remoteid);
6766 ssh2_pkt_adduint32(pktout, c->localid);
6767 ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);
954d5c5a 6768 ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
51df0ab5 6769 ssh2_pkt_send(ssh, pktout);
6770 }
6771}
6772
6bbce591 6773/*
6774 * Buffer banner messages for later display at some convenient point.
6775 */
6776static void ssh2_msg_userauth_banner(Ssh ssh, struct Packet *pktin)
6777{
6778 /* Arbitrary limit to prevent unbounded inflation of buffer */
6779 if (bufchain_size(&ssh->banner) <= 131072) {
6780 char *banner = NULL;
6781 int size = 0;
6782 ssh_pkt_getstring(pktin, &banner, &size);
6783 if (banner)
6784 bufchain_add(&ssh->banner, banner, size);
6785 }
6786}
6787
c6ccd5c2 6788/* Helper function to deal with sending tty modes for "pty-req" */
6789static void ssh2_send_ttymode(void *data, char *mode, char *val)
6790{
6791 struct Packet *pktout = (struct Packet *)data;
6792 int i = 0;
6793 unsigned int arg = 0;
6794 while (strcmp(mode, ssh_ttymodes[i].mode) != 0) i++;
6795 if (i == lenof(ssh_ttymodes)) return;
6796 switch (ssh_ttymodes[i].type) {
6797 case TTY_OP_CHAR:
6798 arg = ssh_tty_parse_specchar(val);
6799 break;
6800 case TTY_OP_BOOL:
6801 arg = ssh_tty_parse_boolean(val);
6802 break;
6803 }
6804 ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
6805 ssh2_pkt_adduint32(pktout, arg);
6806}
6807
783415f8 6808/*
2e85c969 6809 * Handle the SSH-2 userauth and connection layers.
7cca0d81 6810 */
ff3187f6 6811static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
6812 struct Packet *pktin)
7cca0d81 6813{
51470298 6814 struct do_ssh2_authconn_state {
6815 enum {
51470298 6816 AUTH_TYPE_NONE,
6817 AUTH_TYPE_PUBLICKEY,
6818 AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
6819 AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
6820 AUTH_TYPE_PASSWORD,
6821 AUTH_TYPE_KEYBOARD_INTERACTIVE,
6822 AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
6823 } type;
a1a1fae4 6824 int done_service_req;
51470298 6825 int gotit, need_pw, can_pubkey, can_passwd, can_keyb_inter;
94cd7c3a 6826 int tried_pubkey_config, done_agent;
edd0cb8a 6827 int kbd_inter_refused;
51470298 6828 int we_are_in;
edd0cb8a 6829 prompts_t *cur_prompt;
6830 int num_prompts;
51470298 6831 char username[100];
e955d348 6832 char *password;
51470298 6833 int got_username;
51470298 6834 void *publickey_blob;
6835 int publickey_bloblen;
edd0cb8a 6836 int publickey_encrypted;
6837 char *publickey_algorithm;
6838 char *publickey_comment;
94cd7c3a 6839 unsigned char agent_request[5], *agent_response, *agentp;
6840 int agent_responselen;
6841 unsigned char *pkblob_in_agent;
51470298 6842 int keyi, nkeys;
51470298 6843 char *pkblob, *alg, *commentp;
6844 int pklen, alglen, commentlen;
6845 int siglen, retlen, len;
6846 char *q, *agentreq, *ret;
6847 int try_send;
73feed4f 6848 int num_env, env_left, env_ok;
ff3187f6 6849 struct Packet *pktout;
51470298 6850 };
6851 crState(do_ssh2_authconn_state);
6852
6853 crBegin(ssh->do_ssh2_authconn_crstate);
e5574168 6854
a1a1fae4 6855 s->done_service_req = FALSE;
6856 s->we_are_in = FALSE;
6857 if (!ssh->cfg.ssh_no_userauth) {
6858 /*
6859 * Request userauth protocol, and await a response to it.
6860 */
6861 s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
6862 ssh2_pkt_addstring(s->pktout, "ssh-userauth");
6863 ssh2_pkt_send(ssh, s->pktout);
6864 crWaitUntilV(pktin);
6865 if (pktin->type == SSH2_MSG_SERVICE_ACCEPT)
6866 s->done_service_req = TRUE;
6867 }
6868 if (!s->done_service_req) {
6869 /*
6870 * Request connection protocol directly, without authentication.
6871 */
6872 s->pktout = ssh2_pkt_init(SSH2_MSG_SERVICE_REQUEST);
6873 ssh2_pkt_addstring(s->pktout, "ssh-connection");
6874 ssh2_pkt_send(ssh, s->pktout);
6875 crWaitUntilV(pktin);
6876 if (pktin->type == SSH2_MSG_SERVICE_ACCEPT) {
6877 s->we_are_in = TRUE; /* no auth required */
6878 } else {
6879 bombout(("Server refused service request"));
6880 crStopV;
6881 }
8d5de777 6882 }
7cca0d81 6883
94cd7c3a 6884 /* Arrange to be able to deal with any BANNERs that come in.
6885 * (We do this now as packets may come in during the next bit.) */
6886 bufchain_init(&ssh->banner);
6887 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] =
6888 ssh2_msg_userauth_banner;
6889
7cca0d81 6890 /*
edd0cb8a 6891 * Misc one-time setup for authentication.
6892 */
6893 s->publickey_blob = NULL;
6894 if (!s->we_are_in) {
6895
6896 /*
6897 * Load the public half of any configured public key file
6898 * for later use.
6899 */
6900 if (!filename_is_null(ssh->cfg.keyfile)) {
6901 int keytype;
6902 logeventf(ssh, "Reading private key file \"%.150s\"",
6903 filename_to_str(&ssh->cfg.keyfile));
6904 keytype = key_type(&ssh->cfg.keyfile);
6905 if (keytype == SSH_KEYTYPE_SSH2) {
6906 const char *error;
6907 s->publickey_blob =
6908 ssh2_userkey_loadpub(&ssh->cfg.keyfile,
6909 &s->publickey_algorithm,
6910 &s->publickey_bloblen,
6911 &s->publickey_comment, &error);
6912 if (s->publickey_blob) {
6913 s->publickey_encrypted =
6914 ssh2_userkey_encrypted(&ssh->cfg.keyfile, NULL);
6915 } else {
6916 char *msgbuf;
6917 logeventf(ssh, "Unable to load private key (%s)",
6918 error);
6919 msgbuf = dupprintf("Unable to load private key file "
6920 "\"%.150s\" (%s)\r\n",
6921 filename_to_str(&ssh->cfg.keyfile),
6922 error);
6923 c_write_str(ssh, msgbuf);
6924 sfree(msgbuf);
6925 }
6926 } else {
6927 char *msgbuf;
6928 logeventf(ssh, "Unable to use this key file (%s)",
6929 key_type_to_str(keytype));
6930 msgbuf = dupprintf("Unable to use key file \"%.150s\""
6931 " (%s)\r\n",
6932 filename_to_str(&ssh->cfg.keyfile),
6933 key_type_to_str(keytype));
6934 c_write_str(ssh, msgbuf);
6935 sfree(msgbuf);
6936 s->publickey_blob = NULL;
6937 }
6938 }
6939
94cd7c3a 6940 /*
6941 * Find out about any keys Pageant has (but if there's a
6942 * public key configured, filter out all others).
6943 */
6944 s->nkeys = 0;
6945 s->agent_response = NULL;
6946 s->pkblob_in_agent = NULL;
116f229d 6947 if (ssh->cfg.tryagent && agent_exists()) {
94cd7c3a 6948
6949 void *r;
6950
6951 logevent("Pageant is running. Requesting keys.");
6952
6953 /* Request the keys held by the agent. */
6954 PUT_32BIT(s->agent_request, 1);
6955 s->agent_request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
6956 if (!agent_query(s->agent_request, 5, &r, &s->agent_responselen,
6957 ssh_agent_callback, ssh)) {
6958 do {
6959 crReturnV;
6960 if (pktin) {
6961 bombout(("Unexpected data from server while"
6962 " waiting for agent response"));
6963 crStopV;
6964 }
6965 } while (pktin || inlen > 0);
6966 r = ssh->agent_response;
6967 s->agent_responselen = ssh->agent_response_len;
6968 }
6969 s->agent_response = (unsigned char *) r;
6970 if (s->agent_response && s->agent_responselen >= 5 &&
6971 s->agent_response[4] == SSH2_AGENT_IDENTITIES_ANSWER) {
6972 int keyi;
6973 unsigned char *p;
6974 p = s->agent_response + 5;
6975 s->nkeys = GET_32BIT(p);
6976 p += 4;
6977 logeventf(ssh, "Pageant has %d SSH-2 keys", s->nkeys);
6978 if (s->publickey_blob) {
6979 /* See if configured key is in agent. */
6980 for (keyi = 0; keyi < s->nkeys; keyi++) {
6981 s->pklen = GET_32BIT(p);
6982 if (s->pklen == s->publickey_bloblen &&
6983 !memcmp(p+4, s->publickey_blob,
6984 s->publickey_bloblen)) {
6985 logeventf(ssh, "Pageant key #%d matches "
6986 "configured key file", keyi);
6987 s->keyi = keyi;
6988 s->pkblob_in_agent = p;
6989 break;
6990 }
6991 p += 4 + s->pklen;
6992 p += GET_32BIT(p) + 4; /* comment */
6993 }
6994 if (!s->pkblob_in_agent) {
6995 logevent("Configured key file not in Pageant");
6996 s->nkeys = 0;
6997 }
6998 }
6999 }
7000 }
7001
edd0cb8a 7002 }
7003
7004 /*
1408a877 7005 * We repeat this whole loop, including the username prompt,
7006 * until we manage a successful authentication. If the user
51470298 7007 * types the wrong _password_, they can be sent back to the
7008 * beginning to try another username, if this is configured on.
7009 * (If they specify a username in the config, they are never
7010 * asked, even if they do give a wrong password.)
1408a877 7011 *
7012 * I think this best serves the needs of
7013 *
7014 * - the people who have no configuration, no keys, and just
7015 * want to try repeated (username,password) pairs until they
7016 * type both correctly
7017 *
7018 * - people who have keys and configuration but occasionally
7019 * need to fall back to passwords
7020 *
7021 * - people with a key held in Pageant, who might not have
7022 * logged in to a particular machine before; so they want to
7023 * type a username, and then _either_ their key will be
7024 * accepted, _or_ they will type a password. If they mistype
7025 * the username they will want to be able to get back and
7026 * retype it!
7cca0d81 7027 */
51470298 7028 s->username[0] = '\0';
7029 s->got_username = FALSE;
a1a1fae4 7030 while (!s->we_are_in) {
1408a877 7031 /*
7032 * Get a username.
7033 */
86916870 7034 if (s->got_username && !ssh->cfg.change_username) {
5bb641e1 7035 /*
7036 * We got a username last time round this loop, and
7037 * with change_username turned off we don't try to get
7038 * it again.
7039 */
aa09f7d0 7040 } else if (!*ssh->cfg.username) {
edd0cb8a 7041 int ret; /* need not be kept over crReturn */
7042 s->cur_prompt = new_prompts(ssh->frontend);
7043 s->cur_prompt->to_server = TRUE;
7044 s->cur_prompt->name = dupstr("SSH login name");
7045 add_prompt(s->cur_prompt, dupstr("login as: "), TRUE,
7046 lenof(s->username));
7047 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7048 while (ret < 0) {
51470298 7049 ssh->send_ok = 1;
edd0cb8a 7050 crWaitUntilV(!pktin);
7051 ret = get_userpass_input(s->cur_prompt, in, inlen);
7052 ssh->send_ok = 0;
32874aea 7053 }
edd0cb8a 7054 if (!ret) {
7055 /*
7056 * get_userpass_input() failed to get a username.
7057 * Terminate.
7058 */
7059 free_prompts(s->cur_prompt);
7060 ssh_disconnect(ssh, "No username provided", NULL, 0, TRUE);
7061 crStopV;
7062 }
7063 memcpy(s->username, s->cur_prompt->prompts[0]->result,
7064 lenof(s->username));
7065 free_prompts(s->cur_prompt);
7cca0d81 7066 } else {
57356d63 7067 char *stuff;
86916870 7068 strncpy(s->username, ssh->cfg.username, sizeof(s->username));
51470298 7069 s->username[sizeof(s->username)-1] = '\0';
65a22376 7070 if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
57356d63 7071 stuff = dupprintf("Using username \"%s\".\r\n", s->username);
51470298 7072 c_write_str(ssh, stuff);
57356d63 7073 sfree(stuff);
7cca0d81 7074 }
7075 }
51470298 7076 s->got_username = TRUE;
7cca0d81 7077
65a22376 7078 /*
1408a877 7079 * Send an authentication request using method "none": (a)
7080 * just in case it succeeds, and (b) so that we know what
7081 * authentication methods we can usefully try next.
65a22376 7082 */
acab36bc 7083 ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
51470298 7084
ff3187f6 7085 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7086 ssh2_pkt_addstring(s->pktout, s->username);
7087 ssh2_pkt_addstring(s->pktout, "ssh-connection");/* service requested */
7088 ssh2_pkt_addstring(s->pktout, "none"); /* method */
7089 ssh2_pkt_send(ssh, s->pktout);
51470298 7090 s->type = AUTH_TYPE_NONE;
7091 s->gotit = FALSE;
7092 s->we_are_in = FALSE;
7093
7094 s->tried_pubkey_config = FALSE;
6ac3a551 7095 s->kbd_inter_refused = FALSE;
65a22376 7096
94cd7c3a 7097 /* Reset agent request state. */
7098 s->done_agent = FALSE;
7099 if (s->agent_response) {
7100 if (s->pkblob_in_agent) {
7101 s->agentp = s->pkblob_in_agent;
7102 } else {
7103 s->agentp = s->agent_response + 5 + 4;
7104 s->keyi = 0;
7105 }
7106 }
7107
1408a877 7108 while (1) {
7109 /*
7110 * Wait for the result of the last authentication request.
7111 */
51470298 7112 if (!s->gotit)
ff3187f6 7113 crWaitUntilV(pktin);
6bbce591 7114 /*
7115 * Now is a convenient point to spew any banner material
7116 * that we've accumulated. (This should ensure that when
7117 * we exit the auth loop, we haven't any left to deal
7118 * with.)
7119 */
7120 {
7121 int size = bufchain_size(&ssh->banner);
32874aea 7122 /*
7123 * Don't show the banner if we're operating in
7124 * non-verbose non-interactive mode. (It's probably
7125 * a script, which means nobody will read the
7126 * banner _anyway_, and moreover the printing of
7127 * the banner will screw up processing on the
7128 * output of (say) plink.)
7129 */
6bbce591 7130 if (size && (flags & (FLAG_VERBOSE | FLAG_INTERACTIVE))) {
7131 char *banner = snewn(size, char);
7132 bufchain_fetch(&ssh->banner, banner, size);
7133 c_write_untrusted(ssh, banner, size);
7134 sfree(banner);
32874aea 7135 }
6bbce591 7136 bufchain_clear(&ssh->banner);
1408a877 7137 }
ff3187f6 7138 if (pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
1408a877 7139 logevent("Access granted");
51470298 7140 s->we_are_in = TRUE;
1408a877 7141 break;
7142 }
65a22376 7143
e955d348 7144 if (pktin->type != SSH2_MSG_USERAUTH_FAILURE) {
7145 bombout(("Strange packet received during authentication: "
7146 "type %d", pktin->type));
7ffdbc1a 7147 crStopV;
65a22376 7148 }
7149
51470298 7150 s->gotit = FALSE;
65a22376 7151
1408a877 7152 /*
7153 * OK, we're now sitting on a USERAUTH_FAILURE message, so
7154 * we can look at the string in it and know what we can
7155 * helpfully try next.
7156 */
ff3187f6 7157 if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
1408a877 7158 char *methods;
7159 int methlen;
ff3187f6 7160 ssh_pkt_getstring(pktin, &methods, &methlen);
ff3187f6 7161 if (!ssh2_pkt_getbool(pktin)) {
1408a877 7162 /*
7163 * We have received an unequivocal Access
7164 * Denied. This can translate to a variety of
7165 * messages:
7166 *
7167 * - if we'd just tried "none" authentication,
7168 * it's not worth printing anything at all
7169 *
7170 * - if we'd just tried a public key _offer_,
7171 * the message should be "Server refused our
7172 * key" (or no message at all if the key
7173 * came from Pageant)
7174 *
7175 * - if we'd just tried anything else, the
7176 * message really should be "Access denied".
7177 *
7178 * Additionally, if we'd just tried password
7179 * authentication, we should break out of this
7180 * whole loop so as to go back to the username
91f57d1f 7181 * prompt (iff we're configured to allow
7182 * username change attempts).
1408a877 7183 */
51470298 7184 if (s->type == AUTH_TYPE_NONE) {
1408a877 7185 /* do nothing */
51470298 7186 } else if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
7187 s->type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
7188 if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
7189 c_write_str(ssh, "Server refused our key\r\n");
1408a877 7190 logevent("Server refused public key");
51470298 7191 } else if (s->type==AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET) {
4bdf7c46 7192 /* server declined keyboard-interactive; ignore */
1408a877 7193 } else {
51470298 7194 c_write_str(ssh, "Access denied\r\n");
1408a877 7195 logevent("Access denied");
91f57d1f 7196 if (s->type == AUTH_TYPE_PASSWORD &&
7197 ssh->cfg.change_username) {
6c9dce7c 7198 /* XXX perhaps we should allow
7199 * keyboard-interactive to do this too? */
51470298 7200 s->we_are_in = FALSE;
1408a877 7201 break;
7202 }
7203 }
7204 } else {
51470298 7205 c_write_str(ssh, "Further authentication required\r\n");
1408a877 7206 logevent("Further authentication required");
7207 }
65a22376 7208
51470298 7209 s->can_pubkey =
32874aea 7210 in_commasep_string("publickey", methods, methlen);
51470298 7211 s->can_passwd =
32874aea 7212 in_commasep_string("password", methods, methlen);
86916870 7213 s->can_keyb_inter = ssh->cfg.try_ki_auth &&
761187b6 7214 in_commasep_string("keyboard-interactive", methods, methlen);
1408a877 7215 }
65a22376 7216
acab36bc 7217 ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
65a22376 7218
94cd7c3a 7219 if (s->can_pubkey && !s->done_agent && s->nkeys) {
0405e71f 7220
1983e559 7221 /*
94cd7c3a 7222 * Attempt public-key authentication using a key from Pageant.
1983e559 7223 */
1983e559 7224
acab36bc 7225 ssh->pkt_actx = SSH2_PKTCTX_PUBLICKEY;
00db133f 7226
94cd7c3a 7227 logeventf(ssh, "Trying Pageant key #%d", s->keyi);
7228
7229 /* Unpack key from agent response */
7230 s->pklen = GET_32BIT(s->agentp);
7231 s->agentp += 4;
7232 s->pkblob = (char *)s->agentp;
7233 s->agentp += s->pklen;
7234 s->alglen = GET_32BIT(s->pkblob);
7235 s->alg = s->pkblob + 4;
7236 s->commentlen = GET_32BIT(s->agentp);
7237 s->agentp += 4;
7238 s->commentp = (char *)s->agentp;
7239 s->agentp += s->commentlen;
7240 /* s->agentp now points at next key, if any */
7241
7242 /* See if server will accept it */
7243 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7244 ssh2_pkt_addstring(s->pktout, s->username);
7245 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7246 /* service requested */
7247 ssh2_pkt_addstring(s->pktout, "publickey");
7248 /* method */
7249 ssh2_pkt_addbool(s->pktout, FALSE); /* no signature included */
7250 ssh2_pkt_addstring_start(s->pktout);
7251 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
7252 ssh2_pkt_addstring_start(s->pktout);
7253 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
7254 ssh2_pkt_send(ssh, s->pktout);
7255 s->type = AUTH_TYPE_PUBLICKEY_OFFER_QUIET;
1983e559 7256
94cd7c3a 7257 crWaitUntilV(pktin);
7258 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
1983e559 7259
94cd7c3a 7260 /* Offer of key refused. */
7261 s->gotit = TRUE;
1983e559 7262
94cd7c3a 7263 } else {
7264
7265 void *vret;
1983e559 7266
94cd7c3a 7267 if (flags & FLAG_VERBOSE) {
7268 c_write_str(ssh, "Authenticating with "
7269 "public key \"");
7270 c_write(ssh, s->commentp, s->commentlen);
7271 c_write_str(ssh, "\" from agent\r\n");
7272 }
1983e559 7273
94cd7c3a 7274 /*
7275 * Server is willing to accept the key.
7276 * Construct a SIGN_REQUEST.
7277 */
7278 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7279 ssh2_pkt_addstring(s->pktout, s->username);
7280 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7281 /* service requested */
7282 ssh2_pkt_addstring(s->pktout, "publickey");
7283 /* method */
7284 ssh2_pkt_addbool(s->pktout, TRUE); /* signature included */
7285 ssh2_pkt_addstring_start(s->pktout);
7286 ssh2_pkt_addstring_data(s->pktout, s->alg, s->alglen);
7287 ssh2_pkt_addstring_start(s->pktout);
7288 ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen);
7289
7290 /* Ask agent for signature. */
7291 s->siglen = s->pktout->length - 5 + 4 +
7292 ssh->v2_session_id_len;
7293 if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7294 s->siglen -= 4;
7295 s->len = 1; /* message type */
7296 s->len += 4 + s->pklen; /* key blob */
7297 s->len += 4 + s->siglen; /* data to sign */
7298 s->len += 4; /* flags */
7299 s->agentreq = snewn(4 + s->len, char);
7300 PUT_32BIT(s->agentreq, s->len);
7301 s->q = s->agentreq + 4;
7302 *s->q++ = SSH2_AGENTC_SIGN_REQUEST;
7303 PUT_32BIT(s->q, s->pklen);
7304 s->q += 4;
7305 memcpy(s->q, s->pkblob, s->pklen);
7306 s->q += s->pklen;
7307 PUT_32BIT(s->q, s->siglen);
7308 s->q += 4;
7309 /* Now the data to be signed... */
7310 if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7311 PUT_32BIT(s->q, ssh->v2_session_id_len);
51470298 7312 s->q += 4;
94cd7c3a 7313 }
7314 memcpy(s->q, ssh->v2_session_id,
7315 ssh->v2_session_id_len);
7316 s->q += ssh->v2_session_id_len;
7317 memcpy(s->q, s->pktout->data + 5,
7318 s->pktout->length - 5);
7319 s->q += s->pktout->length - 5;
7320 /* And finally the (zero) flags word. */
7321 PUT_32BIT(s->q, 0);
7322 if (!agent_query(s->agentreq, s->len + 4,
7323 &vret, &s->retlen,
7324 ssh_agent_callback, ssh)) {
7325 do {
7326 crReturnV;
7327 if (pktin) {
7328 bombout(("Unexpected data from server"
7329 " while waiting for agent"
7330 " response"));
7331 crStopV;
1983e559 7332 }
94cd7c3a 7333 } while (pktin || inlen > 0);
7334 vret = ssh->agent_response;
7335 s->retlen = ssh->agent_response_len;
7336 }
7337 s->ret = vret;
7338 sfree(s->agentreq);
7339 if (s->ret) {
7340 if (s->ret[4] == SSH2_AGENT_SIGN_RESPONSE) {
7341 logevent("Sending Pageant's response");
7342 ssh2_add_sigblob(ssh, s->pktout,
7343 s->pkblob, s->pklen,
7344 s->ret + 9,
7345 GET_32BIT(s->ret + 5));
7346 ssh2_pkt_send(ssh, s->pktout);
7347 s->type = AUTH_TYPE_PUBLICKEY;
7348 } else {
7349 /* FIXME: less drastic response */
7350 bombout(("Pageant failed to answer challenge"));
7351 crStopV;
1983e559 7352 }
7353 }
1983e559 7354 }
94cd7c3a 7355
7356 /* Do we have any keys left to try? */
7357 if (s->pkblob_in_agent) {
7358 s->done_agent = TRUE;
7359 s->tried_pubkey_config = TRUE;
7360 } else {
7361 s->keyi++;
7362 if (s->keyi >= s->nkeys)
7363 s->done_agent = TRUE;
7364 }
1983e559 7365
edd0cb8a 7366 } else if (s->can_pubkey && s->publickey_blob &&
7367 !s->tried_pubkey_config) {
65a22376 7368
edd0cb8a 7369 struct ssh2_userkey *key; /* not live over crReturn */
7370 char *passphrase; /* not live over crReturn */
65a22376 7371
acab36bc 7372 ssh->pkt_actx = SSH2_PKTCTX_PUBLICKEY;
00db133f 7373
edd0cb8a 7374 s->tried_pubkey_config = TRUE;
7375
65a22376 7376 /*
1408a877 7377 * Try the public key supplied in the configuration.
7378 *
7379 * First, offer the public blob to see if the server is
7380 * willing to accept it.
65a22376 7381 */
ff3187f6 7382 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7383 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7384 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7385 /* service requested */
7386 ssh2_pkt_addstring(s->pktout, "publickey"); /* method */
7387 ssh2_pkt_addbool(s->pktout, FALSE);
7388 /* no signature included */
7389 ssh2_pkt_addstring(s->pktout, s->publickey_algorithm);
7390 ssh2_pkt_addstring_start(s->pktout);
7391 ssh2_pkt_addstring_data(s->pktout,
7392 (char *)s->publickey_blob,
7393 s->publickey_bloblen);
ff3187f6 7394 ssh2_pkt_send(ssh, s->pktout);
edd0cb8a 7395 logevent("Offered public key");
ff3187f6 7396
7397 crWaitUntilV(pktin);
edd0cb8a 7398 if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
7399 /* Key refused. Give up. */
7400 s->gotit = TRUE; /* reconsider message next loop */
7401 s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
7402 continue; /* process this new message */
45068b27 7403 }
edd0cb8a 7404 logevent("Offer of public key accepted");
af659722 7405
45068b27 7406 /*
edd0cb8a 7407 * Actually attempt a serious authentication using
7408 * the key.
45068b27 7409 */
edd0cb8a 7410 if (flags & FLAG_VERBOSE) {
7411 c_write_str(ssh, "Authenticating with public key \"");
7412 c_write_str(ssh, s->publickey_comment);
7413 c_write_str(ssh, "\"\r\n");
7414 }
7415 key = NULL;
7416 while (!key) {
7417 const char *error; /* not live over crReturn */
7418 if (s->publickey_encrypted) {
7419 /*
7420 * Get a passphrase from the user.
7421 */
7422 int ret; /* need not be kept over crReturn */
7423 s->cur_prompt = new_prompts(ssh->frontend);
7424 s->cur_prompt->to_server = FALSE;
7425 s->cur_prompt->name = dupstr("SSH key passphrase");
7426 add_prompt(s->cur_prompt,
7427 dupprintf("Passphrase for key \"%.100s\": ",
7428 s->publickey_comment),
7429 FALSE, SSH_MAX_PASSWORD_LEN);
7430 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7431 while (ret < 0) {
7432 ssh->send_ok = 1;
7433 crWaitUntilV(!pktin);
7434 ret = get_userpass_input(s->cur_prompt,
7435 in, inlen);
7436 ssh->send_ok = 0;
7437 }
7438 if (!ret) {
7439 /* Failed to get a passphrase. Terminate. */
7440 free_prompts(s->cur_prompt);
7441 ssh_disconnect(ssh, NULL,
7442 "Unable to authenticate",
7443 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7444 TRUE);
7445 crStopV;
85fdbe25 7446 }
edd0cb8a 7447 passphrase =
7448 dupstr(s->cur_prompt->prompts[0]->result);
7449 free_prompts(s->cur_prompt);
45068b27 7450 } else {
edd0cb8a 7451 passphrase = NULL; /* no passphrase needed */
45068b27 7452 }
1408a877 7453
edd0cb8a 7454 /*
7455 * Try decrypting the key.
7456 */
7457 key = ssh2_load_userkey(&ssh->cfg.keyfile, passphrase,
7458 &error);
7459 if (passphrase) {
7460 /* burn the evidence */
7461 memset(passphrase, 0, strlen(passphrase));
7462 sfree(passphrase);
7463 }
7464 if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
7465 if (passphrase &&
7466 (key == SSH2_WRONG_PASSPHRASE)) {
7467 c_write_str(ssh, "Wrong passphrase\r\n");
7468 key = NULL;
7469 /* and loop again */
7470 } else {
7471 c_write_str(ssh, "Unable to load private key (");
7472 c_write_str(ssh, error);
7473 c_write_str(ssh, ")\r\n");
7474 key = NULL;
7475 break; /* try something else */
7476 }
1408a877 7477 }
65a22376 7478 }
65a22376 7479
edd0cb8a 7480 if (key) {
1dd353b5 7481 unsigned char *pkblob, *sigblob, *sigdata;
7482 int pkblob_len, sigblob_len, sigdata_len;
edd0cb8a 7483 int p;
65a22376 7484
1408a877 7485 /*
7486 * We have loaded the private key and the server
7487 * has announced that it's willing to accept it.
7488 * Hallelujah. Generate a signature and send it.
7489 */
ff3187f6 7490 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7491 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7492 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7493 /* service requested */
7494 ssh2_pkt_addstring(s->pktout, "publickey");
7495 /* method */
ff3187f6 7496 ssh2_pkt_addbool(s->pktout, TRUE);
edd0cb8a 7497 /* signature follows */
ff3187f6 7498 ssh2_pkt_addstring(s->pktout, key->alg->name);
edd0cb8a 7499 pkblob = key->alg->public_blob(key->data,
7500 &pkblob_len);
ff3187f6 7501 ssh2_pkt_addstring_start(s->pktout);
edd0cb8a 7502 ssh2_pkt_addstring_data(s->pktout, (char *)pkblob,
7503 pkblob_len);
1408a877 7504
7505 /*
7506 * The data to be signed is:
7507 *
7508 * string session-id
7509 *
7510 * followed by everything so far placed in the
7511 * outgoing packet.
7512 */
b672f405 7513 sigdata_len = s->pktout->length - 5 + 4 +
7514 ssh->v2_session_id_len;
edd0cb8a 7515 if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)
7516 sigdata_len -= 4;
92d60585 7517 sigdata = snewn(sigdata_len, unsigned char);
edd0cb8a 7518 p = 0;
7519 if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) {
7520 PUT_32BIT(sigdata+p, ssh->v2_session_id_len);
7521 p += 4;
7522 }
b672f405 7523 memcpy(sigdata+p, ssh->v2_session_id,
7524 ssh->v2_session_id_len);
7525 p += ssh->v2_session_id_len;
ff3187f6 7526 memcpy(sigdata+p, s->pktout->data + 5,
7527 s->pktout->length - 5);
edd0cb8a 7528 p += s->pktout->length - 5;
7529 assert(p == sigdata_len);
d8baa528 7530 sigblob = key->alg->sign(key->data, (char *)sigdata,
1dd353b5 7531 sigdata_len, &sigblob_len);
ff3187f6 7532 ssh2_add_sigblob(ssh, s->pktout, pkblob, pkblob_len,
1dd353b5 7533 sigblob, sigblob_len);
7534 sfree(pkblob);
7535 sfree(sigblob);
1408a877 7536 sfree(sigdata);
7537
ff3187f6 7538 ssh2_pkt_send(ssh, s->pktout);
51470298 7539 s->type = AUTH_TYPE_PUBLICKEY;
75374b2f 7540 key->alg->freekey(key->data);
1408a877 7541 }
edd0cb8a 7542
7543 } else if (s->can_keyb_inter && !s->kbd_inter_refused) {
7544
7545 /*
7546 * Keyboard-interactive authentication.
7547 */
edd0cb8a 7548
edd0cb8a 7549 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
7550
acab36bc 7551 ssh->pkt_actx = SSH2_PKTCTX_KBDINTER;
edd0cb8a 7552
7553 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7554 ssh2_pkt_addstring(s->pktout, s->username);
7555 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7556 /* service requested */
7557 ssh2_pkt_addstring(s->pktout, "keyboard-interactive");
7558 /* method */
7559 ssh2_pkt_addstring(s->pktout, ""); /* lang */
7560 ssh2_pkt_addstring(s->pktout, ""); /* submethods */
7561 ssh2_pkt_send(ssh, s->pktout);
7562
7563 crWaitUntilV(pktin);
7564 if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
7565 /* Server is not willing to do keyboard-interactive
b8e3173d 7566 * at all (or, bizarrely but legally, accepts the
7567 * user without actually issuing any prompts).
7568 * Give up on it entirely. */
edd0cb8a 7569 s->gotit = TRUE;
7570 if (pktin->type == SSH2_MSG_USERAUTH_FAILURE)
7571 logevent("Keyboard-interactive authentication refused");
7572 s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
7573 s->kbd_inter_refused = TRUE; /* don't try it again */
7574 continue;
7575 }
7576
7577 /*
b8e3173d 7578 * Loop while the server continues to send INFO_REQUESTs.
edd0cb8a 7579 */
b8e3173d 7580 while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
edd0cb8a 7581
b8e3173d 7582 char *name, *inst, *lang;
7583 int name_len, inst_len, lang_len;
7584 int i;
7585
7586 /*
7587 * We've got a fresh USERAUTH_INFO_REQUEST.
7588 * Get the preamble and start building a prompt.
7589 */
7590 ssh_pkt_getstring(pktin, &name, &name_len);
7591 ssh_pkt_getstring(pktin, &inst, &inst_len);
7592 ssh_pkt_getstring(pktin, &lang, &lang_len);
7593 s->cur_prompt = new_prompts(ssh->frontend);
7594 s->cur_prompt->to_server = TRUE;
7595 if (name_len) {
7596 /* FIXME: better prefix to distinguish from
7597 * local prompts? */
7598 s->cur_prompt->name =
7599 dupprintf("SSH server: %.*s", name_len, name);
7600 s->cur_prompt->name_reqd = TRUE;
7601 } else {
7602 s->cur_prompt->name =
7603 dupstr("SSH server authentication");
7604 s->cur_prompt->name_reqd = FALSE;
edd0cb8a 7605 }
b8e3173d 7606 /* FIXME: ugly to print "Using..." in prompt _every_
7607 * time round. Can this be done more subtly? */
7608 s->cur_prompt->instruction =
7609 dupprintf("Using keyboard-interactive authentication.%s%.*s",
7610 inst_len ? "\n" : "", inst_len, inst);
7611 s->cur_prompt->instr_reqd = TRUE;
edd0cb8a 7612
b8e3173d 7613 /*
7614 * Get the prompts from the packet.
7615 */
7616 s->num_prompts = ssh_pkt_getuint32(pktin);
7617 for (i = 0; i < s->num_prompts; i++) {
7618 char *prompt;
7619 int prompt_len;
7620 int echo;
7621 static char noprompt[] =
7622 "<server failed to send prompt>: ";
7623
7624 ssh_pkt_getstring(pktin, &prompt, &prompt_len);
7625 echo = ssh2_pkt_getbool(pktin);
7626 if (!prompt_len) {
7627 prompt = noprompt;
7628 prompt_len = lenof(noprompt)-1;
7629 }
7630 add_prompt(s->cur_prompt,
7631 dupprintf("%.*s", prompt_len, prompt),
7632 echo, SSH_MAX_PASSWORD_LEN);
edd0cb8a 7633 }
b8e3173d 7634
7635 /*
7636 * Get the user's responses.
7637 */
7638 if (s->num_prompts) {
7639 int ret; /* not live over crReturn */
7640 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7641 while (ret < 0) {
7642 ssh->send_ok = 1;
7643 crWaitUntilV(!pktin);
7644 ret = get_userpass_input(s->cur_prompt, in, inlen);
7645 ssh->send_ok = 0;
7646 }
7647 if (!ret) {
7648 /*
7649 * Failed to get responses. Terminate.
7650 */
7651 free_prompts(s->cur_prompt);
7652 ssh_disconnect(ssh, NULL, "Unable to authenticate",
7653 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7654 TRUE);
7655 crStopV;
7656 }
edd0cb8a 7657 }
b8e3173d 7658
7659 /*
7660 * Send the responses to the server.
7661 */
7662 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_INFO_RESPONSE);
b8e3173d 7663 ssh2_pkt_adduint32(s->pktout, s->num_prompts);
7664 for (i=0; i < s->num_prompts; i++) {
7665 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
7666 ssh2_pkt_addstring(s->pktout,
7667 s->cur_prompt->prompts[i]->result);
7668 end_log_omission(ssh, s->pktout);
7669 }
18524056 7670 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
b8e3173d 7671
7672 /*
7673 * Get the next packet in case it's another
7674 * INFO_REQUEST.
7675 */
7676 crWaitUntilV(pktin);
7677
edd0cb8a 7678 }
7679
7680 /*
b8e3173d 7681 * We should have SUCCESS or FAILURE now.
edd0cb8a 7682 */
b8e3173d 7683 s->gotit = TRUE;
edd0cb8a 7684
7685 } else if (s->can_passwd) {
7686
7687 /*
7688 * Plain old password authentication.
7689 */
7690 int ret; /* not live over crReturn */
e955d348 7691 int changereq_first_time; /* not live over crReturn */
edd0cb8a 7692
acab36bc 7693 ssh->pkt_actx = SSH2_PKTCTX_PASSWORD;
edd0cb8a 7694
7695 s->cur_prompt = new_prompts(ssh->frontend);
7696 s->cur_prompt->to_server = TRUE;
7697 s->cur_prompt->name = dupstr("SSH password");
7698 add_prompt(s->cur_prompt, dupprintf("%.90s@%.90s's password: ",
7699 s->username,
7700 ssh->savedhost),
7701 FALSE, SSH_MAX_PASSWORD_LEN);
7702
7703 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7704 while (ret < 0) {
7705 ssh->send_ok = 1;
7706 crWaitUntilV(!pktin);
7707 ret = get_userpass_input(s->cur_prompt, in, inlen);
7708 ssh->send_ok = 0;
7709 }
7710 if (!ret) {
7711 /*
7712 * Failed to get responses. Terminate.
7713 */
7714 free_prompts(s->cur_prompt);
7715 ssh_disconnect(ssh, NULL, "Unable to authenticate",
7716 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7717 TRUE);
7718 crStopV;
7719 }
e955d348 7720 /*
7721 * Squirrel away the password. (We may need it later if
7722 * asked to change it.)
7723 */
7724 s->password = dupstr(s->cur_prompt->prompts[0]->result);
7725 free_prompts(s->cur_prompt);
edd0cb8a 7726
7727 /*
7728 * Send the password packet.
7729 *
95d2d262 7730 * We pad out the password packet to 256 bytes to make
7731 * it harder for an attacker to find the length of the
7732 * user's password.
1408a877 7733 *
95d2d262 7734 * Anyone using a password longer than 256 bytes
7735 * probably doesn't have much to worry about from
1408a877 7736 * people who find out how long their password is!
65a22376 7737 */
ff3187f6 7738 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
7739 ssh2_pkt_addstring(s->pktout, s->username);
edd0cb8a 7740 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7741 /* service requested */
ff3187f6 7742 ssh2_pkt_addstring(s->pktout, "password");
7743 ssh2_pkt_addbool(s->pktout, FALSE);
7744 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
e955d348 7745 ssh2_pkt_addstring(s->pktout, s->password);
ff3187f6 7746 end_log_omission(ssh, s->pktout);
18524056 7747 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
0d43337a 7748 logevent("Sent password");
28f4d4f0 7749 s->type = AUTH_TYPE_PASSWORD;
edd0cb8a 7750
e955d348 7751 /*
7752 * Wait for next packet, in case it's a password change
7753 * request.
7754 */
7755 crWaitUntilV(pktin);
7756 changereq_first_time = TRUE;
7757
7758 while (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
7759
7760 /*
7761 * We're being asked for a new password
7762 * (perhaps not for the first time).
7763 * Loop until the server accepts it.
7764 */
7765
7766 int got_new = FALSE; /* not live over crReturn */
7767 char *prompt; /* not live over crReturn */
7768 int prompt_len; /* not live over crReturn */
7769
7770 {
7771 char *msg;
7772 if (changereq_first_time)
7773 msg = "Server requested password change";
7774 else
7775 msg = "Server rejected new password";
7776 logevent(msg);
7777 c_write_str(ssh, msg);
7778 c_write_str(ssh, "\r\n");
7779 }
7780
7781 ssh_pkt_getstring(pktin, &prompt, &prompt_len);
7782
7783 s->cur_prompt = new_prompts(ssh->frontend);
7784 s->cur_prompt->to_server = TRUE;
7785 s->cur_prompt->name = dupstr("New SSH password");
7786 s->cur_prompt->instruction =
7787 dupprintf("%.*s", prompt_len, prompt);
7788 s->cur_prompt->instr_reqd = TRUE;
d9add7bc 7789 /*
7790 * There's no explicit requirement in the protocol
7791 * for the "old" passwords in the original and
7792 * password-change messages to be the same, and
7793 * apparently some Cisco kit supports password change
7794 * by the user entering a blank password originally
7795 * and the real password subsequently, so,
7796 * reluctantly, we prompt for the old password again.
7797 *
7798 * (On the other hand, some servers don't even bother
7799 * to check this field.)
7800 */
7801 add_prompt(s->cur_prompt,
7802 dupstr("Current password (blank for previously entered password): "),
7803 FALSE, SSH_MAX_PASSWORD_LEN);
e955d348 7804 add_prompt(s->cur_prompt, dupstr("Enter new password: "),
7805 FALSE, SSH_MAX_PASSWORD_LEN);
7806 add_prompt(s->cur_prompt, dupstr("Confirm new password: "),
7807 FALSE, SSH_MAX_PASSWORD_LEN);
7808
7809 /*
7810 * Loop until the user manages to enter the same
7811 * password twice.
7812 */
7813 while (!got_new) {
7814
7815 ret = get_userpass_input(s->cur_prompt, NULL, 0);
7816 while (ret < 0) {
7817 ssh->send_ok = 1;
7818 crWaitUntilV(!pktin);
7819 ret = get_userpass_input(s->cur_prompt, in, inlen);
7820 ssh->send_ok = 0;
7821 }
7822 if (!ret) {
7823 /*
7824 * Failed to get responses. Terminate.
7825 */
7826 /* burn the evidence */
7827 free_prompts(s->cur_prompt);
7828 memset(s->password, 0, strlen(s->password));
7829 sfree(s->password);
7830 ssh_disconnect(ssh, NULL, "Unable to authenticate",
7831 SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER,
7832 TRUE);
7833 crStopV;
7834 }
7835
7836 /*
d9add7bc 7837 * If the user specified a new original password
7838 * (IYSWIM), overwrite any previously specified
7839 * one.
7840 * (A side effect is that the user doesn't have to
7841 * re-enter it if they louse up the new password.)
7842 */
7843 if (s->cur_prompt->prompts[0]->result[0]) {
7844 memset(s->password, 0, strlen(s->password));
7845 /* burn the evidence */
7846 sfree(s->password);
7847 s->password =
7848 dupstr(s->cur_prompt->prompts[0]->result);
7849 }
7850
7851 /*
7852 * Check the two new passwords match.
e955d348 7853 */
d9add7bc 7854 got_new = (strcmp(s->cur_prompt->prompts[1]->result,
7855 s->cur_prompt->prompts[2]->result)
e955d348 7856 == 0);
7857 if (!got_new)
7858 /* They don't. Silly user. */
7859 c_write_str(ssh, "Passwords do not match\r\n");
7860
7861 }
7862
7863 /*
7864 * Send the new password (along with the old one).
7865 * (see above for padding rationale)
7866 */
7867 s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
e955d348 7868 ssh2_pkt_addstring(s->pktout, s->username);
7869 ssh2_pkt_addstring(s->pktout, "ssh-connection");
7870 /* service requested */
7871 ssh2_pkt_addstring(s->pktout, "password");
7872 ssh2_pkt_addbool(s->pktout, TRUE);
7873 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
7874 ssh2_pkt_addstring(s->pktout, s->password);
7875 ssh2_pkt_addstring(s->pktout,
d9add7bc 7876 s->cur_prompt->prompts[1]->result);
e955d348 7877 free_prompts(s->cur_prompt);
7878 end_log_omission(ssh, s->pktout);
18524056 7879 ssh2_pkt_send_with_padding(ssh, s->pktout, 256);
e955d348 7880 logevent("Sent new password");
7881
7882 /*
7883 * Now see what the server has to say about it.
7884 * (If it's CHANGEREQ again, it's not happy with the
7885 * new password.)
7886 */
7887 crWaitUntilV(pktin);
7888 changereq_first_time = FALSE;
7889
7890 }
7891
7892 /*
7893 * We need to reexamine the current pktin at the top
7894 * of the loop. Either:
7895 * - we weren't asked to change password at all, in
7896 * which case it's a SUCCESS or FAILURE with the
7897 * usual meaning
7898 * - we sent a new password, and the server was
7899 * either OK with it (SUCCESS or FAILURE w/partial
7900 * success) or unhappy with the _old_ password
7901 * (FAILURE w/o partial success)
7902 * In any of these cases, we go back to the top of
7903 * the loop and start again.
7904 */
7905 s->gotit = TRUE;
7906
7907 /*
7908 * We don't need the old password any more, in any
7909 * case. Burn the evidence.
7910 */
7911 memset(s->password, 0, strlen(s->password));
7912 sfree(s->password);
7913
1408a877 7914 } else {
edd0cb8a 7915
9e296bfa 7916 ssh_disconnect(ssh, NULL,
7917 "No supported authentication methods available",
7918 SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
7919 FALSE);
7ffdbc1a 7920 crStopV;
edd0cb8a 7921
65a22376 7922 }
edd0cb8a 7923
65a22376 7924 }
a1a1fae4 7925 }
6bbce591 7926 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
7cca0d81 7927
edd0cb8a 7928 /* Clear up various bits and pieces from authentication. */
7929 if (s->publickey_blob) {
7930 sfree(s->publickey_blob);
7931 sfree(s->publickey_comment);
7932 }
94cd7c3a 7933 if (s->agent_response)
7934 sfree(s->agent_response);
edd0cb8a 7935
7cca0d81 7936 /*
a1a1fae4 7937 * Now the connection protocol has started, one way or another.
7cca0d81 7938 */
7939
0ed48730 7940 ssh->channels = newtree234(ssh_channelcmp);
7941
7cca0d81 7942 /*
b09eaa88 7943 * Set up handlers for some connection protocol messages, so we
7944 * don't have to handle them repeatedly in this coroutine.
7945 */
7946 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] =
7947 ssh2_msg_channel_window_adjust;
51df0ab5 7948 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] =
7949 ssh2_msg_global_request;
b09eaa88 7950
7951 /*
0ed48730 7952 * Create the main session channel.
7cca0d81 7953 */
feb02b4e 7954 if (ssh->cfg.ssh_no_shell) {
7955 ssh->mainchan = NULL;
7956 } else if (*ssh->cfg.ssh_nc_host) {
7957 /*
7958 * Just start a direct-tcpip channel and use it as the main
7959 * channel.
7960 */
7961 ssh->mainchan = snew(struct ssh_channel);
7962 ssh->mainchan->ssh = ssh;
7963 ssh->mainchan->localid = alloc_channel_id(ssh);
23828b7e 7964 logeventf(ssh,
7965 "Opening direct-tcpip channel to %s:%d in place of session",
7966 ssh->cfg.ssh_nc_host, ssh->cfg.ssh_nc_port);
feb02b4e 7967 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
7968 ssh2_pkt_addstring(s->pktout, "direct-tcpip");
7969 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
7970 ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
7971 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
7972 ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT); /* our max pkt size */
7973 ssh2_pkt_addstring(s->pktout, ssh->cfg.ssh_nc_host);
7974 ssh2_pkt_adduint32(s->pktout, ssh->cfg.ssh_nc_port);
7975 /*
23828b7e 7976 * There's nothing meaningful to put in the originator
7977 * fields, but some servers insist on syntactically correct
7978 * information.
feb02b4e 7979 */
7980 ssh2_pkt_addstring(s->pktout, "0.0.0.0");
7981 ssh2_pkt_adduint32(s->pktout, 0);
7982 ssh2_pkt_send(ssh, s->pktout);
7983
7984 crWaitUntilV(pktin);
7985 if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
7986 bombout(("Server refused to open a direct-tcpip channel"));
7987 crStopV;
7988 /* FIXME: error data comes back in FAILURE packet */
7989 }
7990 if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
7991 bombout(("Server's channel confirmation cited wrong channel"));
7992 crStopV;
7993 }
7994 ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
7995 ssh->mainchan->halfopen = FALSE;
7996 ssh->mainchan->type = CHAN_MAINSESSION;
7997 ssh->mainchan->closes = 0;
7998 ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
7999 ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
8000 bufchain_init(&ssh->mainchan->v.v2.outbuffer);
8001 add234(ssh->channels, ssh->mainchan);
8002 update_specials_menu(ssh->frontend);
23828b7e 8003 logevent("Opened direct-tcpip channel");
feb02b4e 8004 ssh->ncmode = TRUE;
8005 } else {
0ed48730 8006 ssh->mainchan = snew(struct ssh_channel);
8007 ssh->mainchan->ssh = ssh;
8008 ssh->mainchan->localid = alloc_channel_id(ssh);
ff3187f6 8009 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
8010 ssh2_pkt_addstring(s->pktout, "session");
8011 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->localid);
0ed48730 8012 ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
ff3187f6 8013 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->v.v2.locwindow);/* our window size */
954d5c5a 8014 ssh2_pkt_adduint32(s->pktout, OUR_V2_MAXPKT); /* our max pkt size */
ff3187f6 8015 ssh2_pkt_send(ssh, s->pktout);
8016 crWaitUntilV(pktin);
8017 if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
0ed48730 8018 bombout(("Server refused to open a session"));
8019 crStopV;
8020 /* FIXME: error data comes back in FAILURE packet */
8021 }
ff3187f6 8022 if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
0ed48730 8023 bombout(("Server's channel confirmation cited wrong channel"));
8024 crStopV;
8025 }
ff3187f6 8026 ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
64d6ff88 8027 ssh->mainchan->halfopen = FALSE;
0ed48730 8028 ssh->mainchan->type = CHAN_MAINSESSION;
8029 ssh->mainchan->closes = 0;
ff3187f6 8030 ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(pktin);
8031 ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(pktin);
0ed48730 8032 bufchain_init(&ssh->mainchan->v.v2.outbuffer);
8033 add234(ssh->channels, ssh->mainchan);
62638676 8034 update_specials_menu(ssh->frontend);
0ed48730 8035 logevent("Opened channel for session");
feb02b4e 8036 ssh->ncmode = FALSE;
8037 }
7cca0d81 8038
8039 /*
51df0ab5 8040 * Now we have a channel, make dispatch table entries for
8041 * general channel-based messages.
8042 */
8043 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] =
8044 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] =
8045 ssh2_msg_channel_data;
8046 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_channel_eof;
8047 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_channel_close;
8048 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] =
8049 ssh2_msg_channel_open_confirmation;
8050 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] =
8051 ssh2_msg_channel_open_failure;
8052 ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] =
8053 ssh2_msg_channel_request;
8054 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] =
8055 ssh2_msg_channel_open;
8056
8057 /*
783415f8 8058 * Potentially enable X11 forwarding.
8059 */
feb02b4e 8060 if (ssh->mainchan && !ssh->ncmode && ssh->cfg.x11_forward) {
32874aea 8061 char proto[20], data[64];
8062 logevent("Requesting X11 forwarding");
302121de 8063 ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
86916870 8064 data, sizeof(data), ssh->cfg.x11_auth);
8065 x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
ff3187f6 8066 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8067 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
8068 ssh2_pkt_addstring(s->pktout, "x11-req");
8069 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8070 ssh2_pkt_addbool(s->pktout, 0); /* many connections */
8071 ssh2_pkt_addstring(s->pktout, proto);
f68353be 8072 /*
8073 * Note that while we blank the X authentication data here, we don't
8074 * take any special action to blank the start of an X11 channel,
8075 * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
8076 * without having session blanking enabled is likely to leak your
8077 * cookie into the log.
8078 */
178c3872 8079 dont_log_password(ssh, s->pktout, PKTLOG_BLANK);
ff3187f6 8080 ssh2_pkt_addstring(s->pktout, data);
178c3872 8081 end_log_omission(ssh, s->pktout);
ff3187f6 8082 ssh2_pkt_adduint32(s->pktout, x11_get_screen_number(ssh->cfg.x11_display));
8083 ssh2_pkt_send(ssh, s->pktout);
32874aea 8084
b09eaa88 8085 crWaitUntilV(pktin);
32874aea 8086
ff3187f6 8087 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8088 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8089 bombout(("Unexpected response to X11 forwarding request:"
ff3187f6 8090 " packet type %d", pktin->type));
7ffdbc1a 8091 crStopV;
32874aea 8092 }
8093 logevent("X11 forwarding refused");
8094 } else {
8095 logevent("X11 forwarding enabled");
51470298 8096 ssh->X11_fwd_enabled = TRUE;
32874aea 8097 }
783415f8 8098 }
8099
8100 /*
bc240b21 8101 * Enable port forwardings.
8102 */
06fadff5 8103 ssh_setup_portfwd(ssh, &ssh->cfg);
bc240b21 8104
8105 /*
36c2a3e9 8106 * Potentially enable agent forwarding.
8107 */
feb02b4e 8108 if (ssh->mainchan && !ssh->ncmode && ssh->cfg.agentfwd && agent_exists()) {
32874aea 8109 logevent("Requesting OpenSSH-style agent forwarding");
ff3187f6 8110 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8111 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
8112 ssh2_pkt_addstring(s->pktout, "auth-agent-req@openssh.com");
8113 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8114 ssh2_pkt_send(ssh, s->pktout);
32874aea 8115
b09eaa88 8116 crWaitUntilV(pktin);
32874aea 8117
ff3187f6 8118 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8119 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8120 bombout(("Unexpected response to agent forwarding request:"
ff3187f6 8121 " packet type %d", pktin->type));
7ffdbc1a 8122 crStopV;
32874aea 8123 }
8124 logevent("Agent forwarding refused");
8125 } else {
8126 logevent("Agent forwarding enabled");
51470298 8127 ssh->agentfwd_enabled = TRUE;
32874aea 8128 }
36c2a3e9 8129 }
8130
8131 /*
7cca0d81 8132 * Now allocate a pty for the session.
8133 */
feb02b4e 8134 if (ssh->mainchan && !ssh->ncmode && !ssh->cfg.nopty) {
a5dd8467 8135 /* Unpick the terminal-speed string. */
8136 /* XXX perhaps we should allow no speeds to be sent. */
db219738 8137 ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
8138 sscanf(ssh->cfg.termspeed, "%d,%d", &ssh->ospeed, &ssh->ispeed);
a5dd8467 8139 /* Build the pty request. */
ff3187f6 8140 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8141 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); /* recipient channel */
8142 ssh2_pkt_addstring(s->pktout, "pty-req");
8143 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8144 ssh2_pkt_addstring(s->pktout, ssh->cfg.termtype);
8145 ssh2_pkt_adduint32(s->pktout, ssh->term_width);
8146 ssh2_pkt_adduint32(s->pktout, ssh->term_height);
8147 ssh2_pkt_adduint32(s->pktout, 0); /* pixel width */
8148 ssh2_pkt_adduint32(s->pktout, 0); /* pixel height */
8149 ssh2_pkt_addstring_start(s->pktout);
c6ccd5c2 8150 parse_ttymodes(ssh, ssh->cfg.ttymodes,
8151 ssh2_send_ttymode, (void *)s->pktout);
8152 ssh2_pkt_addbyte(s->pktout, SSH2_TTY_OP_ISPEED);
ff3187f6 8153 ssh2_pkt_adduint32(s->pktout, ssh->ispeed);
c6ccd5c2 8154 ssh2_pkt_addbyte(s->pktout, SSH2_TTY_OP_OSPEED);
ff3187f6 8155 ssh2_pkt_adduint32(s->pktout, ssh->ospeed);
8156 ssh2_pkt_addstring_data(s->pktout, "\0", 1); /* TTY_OP_END */
8157 ssh2_pkt_send(ssh, s->pktout);
51470298 8158 ssh->state = SSH_STATE_INTERMED;
32874aea 8159
b09eaa88 8160 crWaitUntilV(pktin);
32874aea 8161
ff3187f6 8162 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8163 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8164 bombout(("Unexpected response to pty request:"
ff3187f6 8165 " packet type %d", pktin->type));
7ffdbc1a 8166 crStopV;
32874aea 8167 }
51470298 8168 c_write_str(ssh, "Server refused to allocate pty\r\n");
8169 ssh->editing = ssh->echoing = 1;
32874aea 8170 } else {
a5dd8467 8171 logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
db219738 8172 ssh->ospeed, ssh->ispeed);
32874aea 8173 }
0965bee0 8174 } else {
51470298 8175 ssh->editing = ssh->echoing = 1;
7cca0d81 8176 }
8177
8178 /*
73feed4f 8179 * Send environment variables.
8180 *
8181 * Simplest thing here is to send all the requests at once, and
8182 * then wait for a whole bunch of successes or failures.
8183 */
feb02b4e 8184 if (ssh->mainchan && !ssh->ncmode && *ssh->cfg.environmt) {
73feed4f 8185 char *e = ssh->cfg.environmt;
8186 char *var, *varend, *val;
8187
8188 s->num_env = 0;
8189
8190 while (*e) {
8191 var = e;
8192 while (*e && *e != '\t') e++;
8193 varend = e;
8194 if (*e == '\t') e++;
8195 val = e;
8196 while (*e) e++;
8197 e++;
8198
ff3187f6 8199 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8200 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid);
8201 ssh2_pkt_addstring(s->pktout, "env");
8202 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8203 ssh2_pkt_addstring_start(s->pktout);
8204 ssh2_pkt_addstring_data(s->pktout, var, varend-var);
8205 ssh2_pkt_addstring(s->pktout, val);
8206 ssh2_pkt_send(ssh, s->pktout);
73feed4f 8207
8208 s->num_env++;
8209 }
8210
8211 logeventf(ssh, "Sent %d environment variables", s->num_env);
8212
8213 s->env_ok = 0;
8214 s->env_left = s->num_env;
8215
8216 while (s->env_left > 0) {
b09eaa88 8217 crWaitUntilV(pktin);
73feed4f 8218
ff3187f6 8219 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8220 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
73feed4f 8221 bombout(("Unexpected response to environment request:"
ff3187f6 8222 " packet type %d", pktin->type));
73feed4f 8223 crStopV;
8224 }
8225 } else {
8226 s->env_ok++;
8227 }
8228
8229 s->env_left--;
8230 }
8231
8232 if (s->env_ok == s->num_env) {
8233 logevent("All environment variables successfully set");
8234 } else if (s->env_ok == 0) {
8235 logevent("All environment variables refused");
8236 c_write_str(ssh, "Server refused to set environment variables\r\n");
8237 } else {
8238 logeventf(ssh, "%d environment variables refused",
8239 s->num_env - s->env_ok);
8240 c_write_str(ssh, "Server refused to set all environment variables\r\n");
8241 }
8242 }
8243
8244 /*
fd5e5847 8245 * Start a shell or a remote command. We may have to attempt
8246 * this twice if the config data has provided a second choice
8247 * of command.
7cca0d81 8248 */
feb02b4e 8249 if (ssh->mainchan && !ssh->ncmode) while (1) {
fd5e5847 8250 int subsys;
8251 char *cmd;
8252
51470298 8253 if (ssh->fallback_cmd) {
86916870 8254 subsys = ssh->cfg.ssh_subsys2;
8255 cmd = ssh->cfg.remote_cmd_ptr2;
fd5e5847 8256 } else {
86916870 8257 subsys = ssh->cfg.ssh_subsys;
8258 cmd = ssh->cfg.remote_cmd_ptr;
04c52f10 8259 if (!cmd) cmd = ssh->cfg.remote_cmd;
fd5e5847 8260 }
8261
ff3187f6 8262 s->pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8263 ssh2_pkt_adduint32(s->pktout, ssh->mainchan->remoteid); /* recipient channel */
fd5e5847 8264 if (subsys) {
ff3187f6 8265 ssh2_pkt_addstring(s->pktout, "subsystem");
8266 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8267 ssh2_pkt_addstring(s->pktout, cmd);
fd5e5847 8268 } else if (*cmd) {
ff3187f6 8269 ssh2_pkt_addstring(s->pktout, "exec");
8270 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
8271 ssh2_pkt_addstring(s->pktout, cmd);
fd5e5847 8272 } else {
ff3187f6 8273 ssh2_pkt_addstring(s->pktout, "shell");
8274 ssh2_pkt_addbool(s->pktout, 1); /* want reply */
32874aea 8275 }
ff3187f6 8276 ssh2_pkt_send(ssh, s->pktout);
b09eaa88 8277
8278 crWaitUntilV(pktin);
8279
ff3187f6 8280 if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
8281 if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
6b5cf8b4 8282 bombout(("Unexpected response to shell/command request:"
ff3187f6 8283 " packet type %d", pktin->type));
7ffdbc1a 8284 crStopV;
fd5e5847 8285 }
8286 /*
8287 * We failed to start the command. If this is the
8288 * fallback command, we really are finished; if it's
8289 * not, and if the fallback command exists, try falling
8290 * back to it before complaining.
8291 */
86916870 8292 if (!ssh->fallback_cmd && ssh->cfg.remote_cmd_ptr2 != NULL) {
fd5e5847 8293 logevent("Primary command failed; attempting fallback");
51470298 8294 ssh->fallback_cmd = TRUE;
fd5e5847 8295 continue;
8296 }
6b5cf8b4 8297 bombout(("Server refused to start a shell/command"));
7ffdbc1a 8298 crStopV;
fd5e5847 8299 } else {
8300 logevent("Started a shell/command");
32874aea 8301 }
fd5e5847 8302 break;
7cca0d81 8303 }
8304
51470298 8305 ssh->state = SSH_STATE_SESSION;
8306 if (ssh->size_needed)
8307 ssh_size(ssh, ssh->term_width, ssh->term_height);
8308 if (ssh->eof_needed)
8309 ssh_special(ssh, TS_EOF);
6e48c3fe 8310
7cca0d81 8311 /*
8312 * Transfer data!
8313 */
b9d7bcad 8314 if (ssh->ldisc)
8315 ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
0ed48730 8316 if (ssh->mainchan)
8317 ssh->send_ok = 1;
7cca0d81 8318 while (1) {
e5574168 8319 crReturnV;
51470298 8320 s->try_send = FALSE;
ff3187f6 8321 if (pktin) {
2b7540a7 8322
51df0ab5 8323 /*
8324 * _All_ the connection-layer packets we expect to
8325 * receive are now handled by the dispatch table.
8326 * Anything that reaches here must be bogus.
8327 */
32874aea 8328
51df0ab5 8329 bombout(("Strange packet received: type %d", pktin->type));
8330 crStopV;
0ed48730 8331 } else if (ssh->mainchan) {
32874aea 8332 /*
8333 * We have spare data. Add it to the channel buffer.
8334 */
d8baa528 8335 ssh2_add_channel_data(ssh->mainchan, (char *)in, inlen);
51470298 8336 s->try_send = TRUE;
32874aea 8337 }
51470298 8338 if (s->try_send) {
32874aea 8339 int i;
8340 struct ssh_channel *c;
8341 /*
8342 * Try to send data on all channels if we can.
8343 */
1bfc7e93 8344 for (i = 0; NULL != (c = index234(ssh->channels, i)); i++)
8345 ssh2_try_send_and_unthrottle(c);
7cca0d81 8346 }
e5574168 8347 }
8348
8349 crFinishV;
8350}
8351
8352/*
2e85c969 8353 * Handlers for SSH-2 messages that might arrive at any moment.
b09eaa88 8354 */
409bfa77 8355static void ssh2_msg_disconnect(Ssh ssh, struct Packet *pktin)
b09eaa88 8356{
8357 /* log reason code in disconnect message */
8358 char *buf, *msg;
8359 int nowlen, reason, msglen;
8360
8361 reason = ssh_pkt_getuint32(pktin);
8362 ssh_pkt_getstring(pktin, &msg, &msglen);
8363
8364 if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {
8365 buf = dupprintf("Received disconnect message (%s)",
8366 ssh2_disconnect_reasons[reason]);
8367 } else {
8368 buf = dupprintf("Received disconnect message (unknown"
8369 " type %d)", reason);
8370 }
8371 logevent(buf);
8372 sfree(buf);
8373 buf = dupprintf("Disconnection message text: %n%.*s",
8374 &nowlen, msglen, msg);
8375 logevent(buf);
8376 bombout(("Server sent disconnect message\ntype %d (%s):\n\"%s\"",
8377 reason,
8378 (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?
8379 ssh2_disconnect_reasons[reason] : "unknown",
8380 buf+nowlen));
8381 sfree(buf);
8382}
8383
409bfa77 8384static void ssh2_msg_debug(Ssh ssh, struct Packet *pktin)
b09eaa88 8385{
8386 /* log the debug message */
fb983202 8387 char *msg;
b09eaa88 8388 int msglen;
8389 int always_display;
8390
8391 /* XXX maybe we should actually take notice of this */
8392 always_display = ssh2_pkt_getbool(pktin);
8393 ssh_pkt_getstring(pktin, &msg, &msglen);
8394
fb983202 8395 logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
b09eaa88 8396}
8397
409bfa77 8398static void ssh2_msg_something_unimplemented(Ssh ssh, struct Packet *pktin)
b09eaa88 8399{
8400 struct Packet *pktout;
8401 pktout = ssh2_pkt_init(SSH2_MSG_UNIMPLEMENTED);
8402 ssh2_pkt_adduint32(pktout, pktin->sequence);
8403 /*
8404 * UNIMPLEMENTED messages MUST appear in the same order as the
8405 * messages they respond to. Hence, never queue them.
8406 */
8407 ssh2_pkt_send_noqueue(ssh, pktout);
8408}
8409
8410/*
2e85c969 8411 * Handle the top-level SSH-2 protocol.
7cca0d81 8412 */
b09eaa88 8413static void ssh2_protocol_setup(Ssh ssh)
8414{
8415 int i;
8416
8417 /*
8418 * Most messages cause SSH2_MSG_UNIMPLEMENTED.
8419 */
8420 for (i = 0; i < 256; i++)
8421 ssh->packet_dispatch[i] = ssh2_msg_something_unimplemented;
8422
8423 /*
8424 * Any message we actually understand, we set to NULL so that
8425 * the coroutines will get it.
8426 */
8427 ssh->packet_dispatch[SSH2_MSG_UNIMPLEMENTED] = NULL;
8428 ssh->packet_dispatch[SSH2_MSG_SERVICE_REQUEST] = NULL;
8429 ssh->packet_dispatch[SSH2_MSG_SERVICE_ACCEPT] = NULL;
8430 ssh->packet_dispatch[SSH2_MSG_KEXINIT] = NULL;
8431 ssh->packet_dispatch[SSH2_MSG_NEWKEYS] = NULL;
8432 ssh->packet_dispatch[SSH2_MSG_KEXDH_INIT] = NULL;
8433 ssh->packet_dispatch[SSH2_MSG_KEXDH_REPLY] = NULL;
8434 /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REQUEST] = NULL; duplicate case value */
8435 /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_GROUP] = NULL; duplicate case value */
8436 ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_INIT] = NULL;
8437 ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REPLY] = NULL;
8438 ssh->packet_dispatch[SSH2_MSG_USERAUTH_REQUEST] = NULL;
8439 ssh->packet_dispatch[SSH2_MSG_USERAUTH_FAILURE] = NULL;
8440 ssh->packet_dispatch[SSH2_MSG_USERAUTH_SUCCESS] = NULL;
8441 ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
8442 ssh->packet_dispatch[SSH2_MSG_USERAUTH_PK_OK] = NULL;
8443 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ] = NULL; duplicate case value */
8444 /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_REQUEST] = NULL; duplicate case value */
8445 ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_RESPONSE] = NULL;
8446 ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] = NULL;
8447 ssh->packet_dispatch[SSH2_MSG_REQUEST_SUCCESS] = NULL;
8448 ssh->packet_dispatch[SSH2_MSG_REQUEST_FAILURE] = NULL;
8449 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = NULL;
8450 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] = NULL;
8451 ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] = NULL;
8452 ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] = NULL;
8453 ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] = NULL;
8454 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] = NULL;
8455 ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = NULL;
8456 ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = NULL;
8457 ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] = NULL;
8458 ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = NULL;
8459 ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = NULL;
8460
8461 /*
8462 * These special message types we install handlers for.
8463 */
8464 ssh->packet_dispatch[SSH2_MSG_DISCONNECT] = ssh2_msg_disconnect;
2e85c969 8465 ssh->packet_dispatch[SSH2_MSG_IGNORE] = ssh_msg_ignore; /* shared with SSH-1 */
b09eaa88 8466 ssh->packet_dispatch[SSH2_MSG_DEBUG] = ssh2_msg_debug;
8467}
8468
9442dd57 8469static void ssh2_timer(void *ctx, long now)
8470{
8471 Ssh ssh = (Ssh)ctx;
8472
ecbb0000 8473 if (ssh->state == SSH_STATE_CLOSED)
8474 return;
8475
e6c1536e 8476 if (!ssh->kex_in_progress && ssh->cfg.ssh_rekey_time != 0 &&
9442dd57 8477 now - ssh->next_rekey >= 0) {
f382c87d 8478 do_ssh2_transport(ssh, "timeout", -1, NULL);
9442dd57 8479 }
8480}
8481
1c1a7262 8482static void ssh2_protocol(Ssh ssh, void *vin, int inlen,
ff3187f6 8483 struct Packet *pktin)
7cca0d81 8484{
1c1a7262 8485 unsigned char *in = (unsigned char *)vin;
b09eaa88 8486 if (ssh->state == SSH_STATE_CLOSED)
8487 return;
8488
9442dd57 8489 if (pktin) {
8490 ssh->incoming_data_size += pktin->encrypted_len;
8491 if (!ssh->kex_in_progress &&
d57f70af 8492 ssh->max_data_size != 0 &&
8493 ssh->incoming_data_size > ssh->max_data_size)
f382c87d 8494 do_ssh2_transport(ssh, "too much data received", -1, NULL);
9442dd57 8495 }
8496
b09eaa88 8497 if (pktin && ssh->packet_dispatch[pktin->type]) {
8498 ssh->packet_dispatch[pktin->type](ssh, pktin);
32874aea 8499 return;
b09eaa88 8500 }
8501
8502 if (!ssh->protocol_initial_phase_done ||
8503 (pktin && pktin->type >= 20 && pktin->type < 50)) {
8504 if (do_ssh2_transport(ssh, in, inlen, pktin) &&
8505 !ssh->protocol_initial_phase_done) {
8506 ssh->protocol_initial_phase_done = TRUE;
8507 /*
8508 * Allow authconn to initialise itself.
8509 */
8510 do_ssh2_authconn(ssh, NULL, 0, NULL);
8511 }
8512 } else {
8513 do_ssh2_authconn(ssh, in, inlen, pktin);
8514 }
7cca0d81 8515}
8516
8517/*
8df7a775 8518 * Called to set up the connection.
374330e2 8519 *
8520 * Returns an error message, or NULL on success.
374330e2 8521 */
cbe2d68f 8522static const char *ssh_init(void *frontend_handle, void **backend_handle,
8523 Config *cfg,
79bf227b 8524 char *host, int port, char **realhost, int nodelay,
8525 int keepalive)
32874aea 8526{
cbe2d68f 8527 const char *p;
51470298 8528 Ssh ssh;
8529
3d88e64d 8530 ssh = snew(struct ssh_tag);
86916870 8531 ssh->cfg = *cfg; /* STRUCTURE COPY */
125105d1 8532 ssh->version = 0; /* when not ready yet */
51470298 8533 ssh->s = NULL;
8534 ssh->cipher = NULL;
371e569c 8535 ssh->v1_cipher_ctx = NULL;
0183b242 8536 ssh->crcda_ctx = NULL;
51470298 8537 ssh->cscipher = NULL;
371e569c 8538 ssh->cs_cipher_ctx = NULL;
51470298 8539 ssh->sccipher = NULL;
371e569c 8540 ssh->sc_cipher_ctx = NULL;
51470298 8541 ssh->csmac = NULL;
a8327734 8542 ssh->cs_mac_ctx = NULL;
51470298 8543 ssh->scmac = NULL;
e0e1a00d 8544 ssh->sc_mac_ctx = NULL;
51470298 8545 ssh->cscomp = NULL;
5366aed8 8546 ssh->cs_comp_ctx = NULL;
51470298 8547 ssh->sccomp = NULL;
5366aed8 8548 ssh->sc_comp_ctx = NULL;
51470298 8549 ssh->kex = NULL;
389aa499 8550 ssh->kex_ctx = NULL;
51470298 8551 ssh->hostkey = NULL;
8552 ssh->exitcode = -1;
ac934965 8553 ssh->close_expected = FALSE;
9e296bfa 8554 ssh->clean_exit = FALSE;
51470298 8555 ssh->state = SSH_STATE_PREPACKET;
8556 ssh->size_needed = FALSE;
8557 ssh->eof_needed = FALSE;
b9d7bcad 8558 ssh->ldisc = NULL;
a8327734 8559 ssh->logctx = NULL;
51470298 8560 ssh->deferred_send_data = NULL;
8561 ssh->deferred_len = 0;
8562 ssh->deferred_size = 0;
8563 ssh->fallback_cmd = 0;
acab36bc 8564 ssh->pkt_kctx = SSH2_PKTCTX_NOKEX;
8565 ssh->pkt_actx = SSH2_PKTCTX_NOAUTH;
302121de 8566 ssh->x11auth = NULL;
be738459 8567 ssh->v1_compressing = FALSE;
51470298 8568 ssh->v2_outgoing_sequence = 0;
8569 ssh->ssh1_rdpkt_crstate = 0;
8570 ssh->ssh2_rdpkt_crstate = 0;
8571 ssh->do_ssh_init_crstate = 0;
8572 ssh->ssh_gotdata_crstate = 0;
b09eaa88 8573 ssh->do_ssh1_connection_crstate = 0;
51470298 8574 ssh->do_ssh1_login_crstate = 0;
8575 ssh->do_ssh2_transport_crstate = 0;
8576 ssh->do_ssh2_authconn_crstate = 0;
8577 ssh->do_ssh_init_state = NULL;
8578 ssh->do_ssh1_login_state = NULL;
8579 ssh->do_ssh2_transport_state = NULL;
8580 ssh->do_ssh2_authconn_state = NULL;
4320baf7 8581 ssh->v_c = NULL;
8582 ssh->v_s = NULL;
6571dbfd 8583 ssh->mainchan = NULL;
968d2d92 8584 ssh->throttled_all = 0;
8585 ssh->v1_stdout_throttling = 0;
590f6a5f 8586 ssh->queue = NULL;
8587 ssh->queuelen = ssh->queuesize = 0;
8588 ssh->queueing = FALSE;
06fadff5 8589 ssh->qhead = ssh->qtail = NULL;
e13bba36 8590 ssh->deferred_rekey_reason = NULL;
3d9449a1 8591 bufchain_init(&ssh->queued_incoming_data);
8592 ssh->frozen = FALSE;
51470298 8593
8594 *backend_handle = ssh;
32874aea 8595
8f203108 8596#ifdef MSCRYPTOAPI
32874aea 8597 if (crypto_startup() == 0)
8f203108 8598 return "Microsoft high encryption pack not installed!";
8599#endif
374330e2 8600
51470298 8601 ssh->frontend = frontend_handle;
86916870 8602 ssh->term_width = ssh->cfg.width;
8603 ssh->term_height = ssh->cfg.height;
887035a5 8604
fabd1805 8605 ssh->channels = NULL;
8606 ssh->rportfwds = NULL;
f47a5ffb 8607 ssh->portfwds = NULL;
fabd1805 8608
51470298 8609 ssh->send_ok = 0;
8610 ssh->editing = 0;
8611 ssh->echoing = 0;
8612 ssh->v1_throttle_count = 0;
8613 ssh->overall_bufsize = 0;
8614 ssh->fallback_cmd = 0;
8df7a775 8615
3648d4c5 8616 ssh->protocol = NULL;
8617
b09eaa88 8618 ssh->protocol_initial_phase_done = FALSE;
8619
39934deb 8620 ssh->pinger = NULL;
8621
9442dd57 8622 ssh->incoming_data_size = ssh->outgoing_data_size =
8623 ssh->deferred_data_size = 0L;
d57f70af 8624 ssh->max_data_size = parse_blocksize(ssh->cfg.ssh_rekey_data);
9442dd57 8625 ssh->kex_in_progress = FALSE;
8626
79bf227b 8627 p = connect_to_host(ssh, host, port, realhost, nodelay, keepalive);
fb09bf1c 8628 if (p != NULL)
8629 return p;
374330e2 8630
5d17ccfc 8631 random_ref();
8632
374330e2 8633 return NULL;
8634}
8635
fabd1805 8636static void ssh_free(void *handle)
8637{
8638 Ssh ssh = (Ssh) handle;
8639 struct ssh_channel *c;
8640 struct ssh_rportfwd *pf;
8641
8642 if (ssh->v1_cipher_ctx)
8643 ssh->cipher->free_context(ssh->v1_cipher_ctx);
8644 if (ssh->cs_cipher_ctx)
8645 ssh->cscipher->free_context(ssh->cs_cipher_ctx);
8646 if (ssh->sc_cipher_ctx)
8647 ssh->sccipher->free_context(ssh->sc_cipher_ctx);
8648 if (ssh->cs_mac_ctx)
8649 ssh->csmac->free_context(ssh->cs_mac_ctx);
8650 if (ssh->sc_mac_ctx)
8651 ssh->scmac->free_context(ssh->sc_mac_ctx);
29b1d0b3 8652 if (ssh->cs_comp_ctx) {
8653 if (ssh->cscomp)
8654 ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx);
8655 else
8656 zlib_compress_cleanup(ssh->cs_comp_ctx);
8657 }
8658 if (ssh->sc_comp_ctx) {
8659 if (ssh->sccomp)
8660 ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx);
8661 else
8662 zlib_decompress_cleanup(ssh->sc_comp_ctx);
8663 }
fabd1805 8664 if (ssh->kex_ctx)
8665 dh_cleanup(ssh->kex_ctx);
8666 sfree(ssh->savedhost);
8667
590f6a5f 8668 while (ssh->queuelen-- > 0)
8669 ssh_free_packet(ssh->queue[ssh->queuelen]);
8670 sfree(ssh->queue);
8671
06fadff5 8672 while (ssh->qhead) {
8673 struct queued_handler *qh = ssh->qhead;
8674 ssh->qhead = qh->next;
8675 sfree(ssh->qhead);
8676 }
8677 ssh->qhead = ssh->qtail = NULL;
8678
fabd1805 8679 if (ssh->channels) {
8680 while ((c = delpos234(ssh->channels, 0)) != NULL) {
8681 switch (c->type) {
8682 case CHAN_X11:
8683 if (c->u.x11.s != NULL)
8684 x11_close(c->u.x11.s);
8685 break;
8686 case CHAN_SOCKDATA:
8687 if (c->u.pfd.s != NULL)
8688 pfd_close(c->u.pfd.s);
8689 break;
8690 }
8691 sfree(c);
8692 }
8693 freetree234(ssh->channels);
cdb52705 8694 ssh->channels = NULL;
fabd1805 8695 }
8696
8697 if (ssh->rportfwds) {
8698 while ((pf = delpos234(ssh->rportfwds, 0)) != NULL)
8699 sfree(pf);
8700 freetree234(ssh->rportfwds);
cdb52705 8701 ssh->rportfwds = NULL;
fabd1805 8702 }
8703 sfree(ssh->deferred_send_data);
8704 if (ssh->x11auth)
8705 x11_free_auth(ssh->x11auth);
8706 sfree(ssh->do_ssh_init_state);
8707 sfree(ssh->do_ssh1_login_state);
8708 sfree(ssh->do_ssh2_transport_state);
8709 sfree(ssh->do_ssh2_authconn_state);
4320baf7 8710 sfree(ssh->v_c);
8711 sfree(ssh->v_s);
679539d7 8712 if (ssh->crcda_ctx) {
8713 crcda_free_context(ssh->crcda_ctx);
8714 ssh->crcda_ctx = NULL;
8715 }
fabd1805 8716 if (ssh->s)
ac934965 8717 ssh_do_close(ssh, TRUE);
9442dd57 8718 expire_timer_context(ssh);
39934deb 8719 if (ssh->pinger)
8720 pinger_free(ssh->pinger);
3d9449a1 8721 bufchain_clear(&ssh->queued_incoming_data);
ee50e8b6 8722 sfree(ssh);
5d17ccfc 8723
8724 random_unref();
fabd1805 8725}
8726
374330e2 8727/*
86916870 8728 * Reconfigure the SSH backend.
86916870 8729 */
8730static void ssh_reconfig(void *handle, Config *cfg)
8731{
8732 Ssh ssh = (Ssh) handle;
e13bba36 8733 char *rekeying = NULL, rekey_mandatory = FALSE;
e6c1536e 8734 unsigned long old_max_data_size;
8735
39934deb 8736 pinger_reconfig(ssh->pinger, &ssh->cfg, cfg);
3b6606c7 8737 if (ssh->portfwds)
8738 ssh_setup_portfwd(ssh, cfg);
e6c1536e 8739
8740 if (ssh->cfg.ssh_rekey_time != cfg->ssh_rekey_time &&
8741 cfg->ssh_rekey_time != 0) {
8742 long new_next = ssh->last_rekey + cfg->ssh_rekey_time*60*TICKSPERSEC;
8743 long now = GETTICKCOUNT();
8744
8745 if (new_next - now < 0) {
f382c87d 8746 rekeying = "timeout shortened";
e6c1536e 8747 } else {
8748 ssh->next_rekey = schedule_timer(new_next - now, ssh2_timer, ssh);
8749 }
8750 }
8751
8752 old_max_data_size = ssh->max_data_size;
8753 ssh->max_data_size = parse_blocksize(cfg->ssh_rekey_data);
8754 if (old_max_data_size != ssh->max_data_size &&
8755 ssh->max_data_size != 0) {
8756 if (ssh->outgoing_data_size > ssh->max_data_size ||
8757 ssh->incoming_data_size > ssh->max_data_size)
f382c87d 8758 rekeying = "data limit lowered";
e6c1536e 8759 }
8760
e13bba36 8761 if (ssh->cfg.compression != cfg->compression) {
f382c87d 8762 rekeying = "compression setting changed";
e13bba36 8763 rekey_mandatory = TRUE;
8764 }
8765
8766 if (ssh->cfg.ssh2_des_cbc != cfg->ssh2_des_cbc ||
8767 memcmp(ssh->cfg.ssh_cipherlist, cfg->ssh_cipherlist,
8768 sizeof(ssh->cfg.ssh_cipherlist))) {
f382c87d 8769 rekeying = "cipher settings changed";
e13bba36 8770 rekey_mandatory = TRUE;
e6c1536e 8771 }
8772
86916870 8773 ssh->cfg = *cfg; /* STRUCTURE COPY */
e13bba36 8774
8775 if (rekeying) {
8776 if (!ssh->kex_in_progress) {
8777 do_ssh2_transport(ssh, rekeying, -1, NULL);
8778 } else if (rekey_mandatory) {
8779 ssh->deferred_rekey_reason = rekeying;
8780 }
8781 }
86916870 8782}
8783
8784/*
86dc445a 8785 * Called to send data down the SSH connection.
374330e2 8786 */
51470298 8787static int ssh_send(void *handle, char *buf, int len)
32874aea 8788{
51470298 8789 Ssh ssh = (Ssh) handle;
8790
8791 if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
5471d09a 8792 return 0;
374330e2 8793
d8baa528 8794 ssh->protocol(ssh, (unsigned char *)buf, len, 0);
5471d09a 8795
51470298 8796 return ssh_sendbuffer(ssh);
5471d09a 8797}
8798
8799/*
8800 * Called to query the current amount of buffered stdin data.
8801 */
51470298 8802static int ssh_sendbuffer(void *handle)
5471d09a 8803{
51470298 8804 Ssh ssh = (Ssh) handle;
5471d09a 8805 int override_value;
8806
51470298 8807 if (ssh == NULL || ssh->s == NULL || ssh->protocol == NULL)
5471d09a 8808 return 0;
8809
8810 /*
8811 * If the SSH socket itself has backed up, add the total backup
8812 * size on that to any individual buffer on the stdin channel.
8813 */
8814 override_value = 0;
51470298 8815 if (ssh->throttled_all)
8816 override_value = ssh->overall_bufsize;
5471d09a 8817
51470298 8818 if (ssh->version == 1) {
5471d09a 8819 return override_value;
51470298 8820 } else if (ssh->version == 2) {
8821 if (!ssh->mainchan || ssh->mainchan->closes > 0)
5471d09a 8822 return override_value;
8823 else
51470298 8824 return (override_value +
8825 bufchain_size(&ssh->mainchan->v.v2.outbuffer));
5471d09a 8826 }
8827
8828 return 0;
374330e2 8829}
8830
8831/*
6e48c3fe 8832 * Called to set the size of the window from SSH's POV.
374330e2 8833 */
51470298 8834static void ssh_size(void *handle, int width, int height)
32874aea 8835{
51470298 8836 Ssh ssh = (Ssh) handle;
ff3187f6 8837 struct Packet *pktout;
51470298 8838
8839 ssh->term_width = width;
8840 ssh->term_height = height;
f278d6f8 8841
51470298 8842 switch (ssh->state) {
374330e2 8843 case SSH_STATE_BEFORE_SIZE:
3687d221 8844 case SSH_STATE_PREPACKET:
21248260 8845 case SSH_STATE_CLOSED:
374330e2 8846 break; /* do nothing */
8847 case SSH_STATE_INTERMED:
51470298 8848 ssh->size_needed = TRUE; /* buffer for later */
374330e2 8849 break;
8850 case SSH_STATE_SESSION:
86916870 8851 if (!ssh->cfg.nopty) {
51470298 8852 if (ssh->version == 1) {
8853 send_packet(ssh, SSH1_CMSG_WINDOW_SIZE,
8854 PKT_INT, ssh->term_height,
8855 PKT_INT, ssh->term_width,
32874aea 8856 PKT_INT, 0, PKT_INT, 0, PKT_END);
0ed48730 8857 } else if (ssh->mainchan) {
ff3187f6 8858 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8859 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8860 ssh2_pkt_addstring(pktout, "window-change");
8861 ssh2_pkt_addbool(pktout, 0);
8862 ssh2_pkt_adduint32(pktout, ssh->term_width);
8863 ssh2_pkt_adduint32(pktout, ssh->term_height);
8864 ssh2_pkt_adduint32(pktout, 0);
8865 ssh2_pkt_adduint32(pktout, 0);
8866 ssh2_pkt_send(ssh, pktout);
32874aea 8867 }
8868 }
8869 break;
374330e2 8870 }
8871}
8872
8873/*
125105d1 8874 * Return a list of the special codes that make sense in this
8875 * protocol.
8876 */
8877static const struct telnet_special *ssh_get_specials(void *handle)
8878{
786ba75e 8879 static const struct telnet_special ssh1_ignore_special[] = {
8880 {"IGNORE message", TS_NOP}
8881 };
8882 static const struct telnet_special ssh2_transport_specials[] = {
62638676 8883 {"IGNORE message", TS_NOP},
9442dd57 8884 {"Repeat key exchange", TS_REKEY},
62638676 8885 };
8886 static const struct telnet_special ssh2_session_specials[] = {
6f2d0cde 8887 {NULL, TS_SEP},
8888 {"Break", TS_BRK},
786ba75e 8889 /* These are the signal names defined by draft-ietf-secsh-connect-23.
6f2d0cde 8890 * They include all the ISO C signals, but are a subset of the POSIX
8891 * required signals. */
8892 {"SIGINT (Interrupt)", TS_SIGINT},
8893 {"SIGTERM (Terminate)", TS_SIGTERM},
8894 {"SIGKILL (Kill)", TS_SIGKILL},
8895 {"SIGQUIT (Quit)", TS_SIGQUIT},
8896 {"SIGHUP (Hangup)", TS_SIGHUP},
8897 {"More signals", TS_SUBMENU},
8898 {"SIGABRT", TS_SIGABRT}, {"SIGALRM", TS_SIGALRM},
8899 {"SIGFPE", TS_SIGFPE}, {"SIGILL", TS_SIGILL},
8900 {"SIGPIPE", TS_SIGPIPE}, {"SIGSEGV", TS_SIGSEGV},
8901 {"SIGUSR1", TS_SIGUSR1}, {"SIGUSR2", TS_SIGUSR2},
8902 {NULL, TS_EXITMENU}
62638676 8903 };
8904 static const struct telnet_special specials_end[] = {
6f2d0cde 8905 {NULL, TS_EXITMENU}
62638676 8906 };
786ba75e 8907 /* XXX review this length for any changes: */
8908 static struct telnet_special ssh_specials[lenof(ssh2_transport_specials) +
62638676 8909 lenof(ssh2_session_specials) +
8910 lenof(specials_end)];
125105d1 8911 Ssh ssh = (Ssh) handle;
62638676 8912 int i = 0;
8913#define ADD_SPECIALS(name) \
8914 do { \
8915 assert((i + lenof(name)) <= lenof(ssh_specials)); \
8916 memcpy(&ssh_specials[i], name, sizeof name); \
8917 i += lenof(name); \
8918 } while(0)
125105d1 8919
8920 if (ssh->version == 1) {
62638676 8921 /* Don't bother offering IGNORE if we've decided the remote
8922 * won't cope with it, since we wouldn't bother sending it if
8923 * asked anyway. */
8924 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
786ba75e 8925 ADD_SPECIALS(ssh1_ignore_special);
125105d1 8926 } else if (ssh->version == 2) {
786ba75e 8927 ADD_SPECIALS(ssh2_transport_specials);
62638676 8928 if (ssh->mainchan)
8929 ADD_SPECIALS(ssh2_session_specials);
8930 } /* else we're not ready yet */
8931
8932 if (i) {
8933 ADD_SPECIALS(specials_end);
8934 return ssh_specials;
8935 } else {
125105d1 8936 return NULL;
62638676 8937 }
8938#undef ADD_SPECIALS
125105d1 8939}
8940
8941/*
86dc445a 8942 * Send special codes. TS_EOF is useful for `plink', so you
6abbf9e3 8943 * can send an EOF and collect resulting output (e.g. `plink
8944 * hostname sort').
374330e2 8945 */
51470298 8946static void ssh_special(void *handle, Telnet_Special code)
32874aea 8947{
51470298 8948 Ssh ssh = (Ssh) handle;
ff3187f6 8949 struct Packet *pktout;
51470298 8950
6abbf9e3 8951 if (code == TS_EOF) {
51470298 8952 if (ssh->state != SSH_STATE_SESSION) {
32874aea 8953 /*
8954 * Buffer the EOF in case we are pre-SESSION, so we can
8955 * send it as soon as we reach SESSION.
8956 */
8957 if (code == TS_EOF)
51470298 8958 ssh->eof_needed = TRUE;
32874aea 8959 return;
8960 }
51470298 8961 if (ssh->version == 1) {
8962 send_packet(ssh, SSH1_CMSG_EOF, PKT_END);
0ed48730 8963 } else if (ssh->mainchan) {
ff3187f6 8964 struct Packet *pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
8965 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8966 ssh2_pkt_send(ssh, pktout);
00a0b113 8967 ssh->send_ok = 0; /* now stop trying to read from stdin */
32874aea 8968 }
8969 logevent("Sent EOF message");
125105d1 8970 } else if (code == TS_PING || code == TS_NOP) {
51470298 8971 if (ssh->state == SSH_STATE_CLOSED
8972 || ssh->state == SSH_STATE_PREPACKET) return;
8973 if (ssh->version == 1) {
8974 if (!(ssh->remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE))
8975 send_packet(ssh, SSH1_MSG_IGNORE, PKT_STR, "", PKT_END);
32874aea 8976 } else {
ff3187f6 8977 pktout = ssh2_pkt_init(SSH2_MSG_IGNORE);
8978 ssh2_pkt_addstring_start(pktout);
590f6a5f 8979 ssh2_pkt_send_noqueue(ssh, pktout);
32874aea 8980 }
9442dd57 8981 } else if (code == TS_REKEY) {
8982 if (!ssh->kex_in_progress && ssh->version == 2) {
f382c87d 8983 do_ssh2_transport(ssh, "at user request", -1, NULL);
9442dd57 8984 }
125105d1 8985 } else if (code == TS_BRK) {
8986 if (ssh->state == SSH_STATE_CLOSED
8987 || ssh->state == SSH_STATE_PREPACKET) return;
8988 if (ssh->version == 1) {
2e85c969 8989 logevent("Unable to send BREAK signal in SSH-1");
0ed48730 8990 } else if (ssh->mainchan) {
ff3187f6 8991 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
8992 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
8993 ssh2_pkt_addstring(pktout, "break");
8994 ssh2_pkt_addbool(pktout, 0);
8995 ssh2_pkt_adduint32(pktout, 0); /* default break length */
8996 ssh2_pkt_send(ssh, pktout);
125105d1 8997 }
6abbf9e3 8998 } else {
6f2d0cde 8999 /* Is is a POSIX signal? */
9000 char *signame = NULL;
9001 if (code == TS_SIGABRT) signame = "ABRT";
9002 if (code == TS_SIGALRM) signame = "ALRM";
9003 if (code == TS_SIGFPE) signame = "FPE";
9004 if (code == TS_SIGHUP) signame = "HUP";
9005 if (code == TS_SIGILL) signame = "ILL";
9006 if (code == TS_SIGINT) signame = "INT";
9007 if (code == TS_SIGKILL) signame = "KILL";
9008 if (code == TS_SIGPIPE) signame = "PIPE";
9009 if (code == TS_SIGQUIT) signame = "QUIT";
9010 if (code == TS_SIGSEGV) signame = "SEGV";
9011 if (code == TS_SIGTERM) signame = "TERM";
9012 if (code == TS_SIGUSR1) signame = "USR1";
9013 if (code == TS_SIGUSR2) signame = "USR2";
9014 /* The SSH-2 protocol does in principle support arbitrary named
9015 * signals, including signame@domain, but we don't support those. */
9016 if (signame) {
9017 /* It's a signal. */
9018 if (ssh->version == 2 && ssh->mainchan) {
ff3187f6 9019 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
9020 ssh2_pkt_adduint32(pktout, ssh->mainchan->remoteid);
9021 ssh2_pkt_addstring(pktout, "signal");
9022 ssh2_pkt_addbool(pktout, 0);
9023 ssh2_pkt_addstring(pktout, signame);
9024 ssh2_pkt_send(ssh, pktout);
6f2d0cde 9025 logeventf(ssh, "Sent signal SIG%s", signame);
9026 }
9027 } else {
9028 /* Never heard of it. Do nothing */
9029 }
6abbf9e3 9030 }
374330e2 9031}
9032
51470298 9033void *new_sock_channel(void *handle, Socket s)
d74d141c 9034{
51470298 9035 Ssh ssh = (Ssh) handle;
d74d141c 9036 struct ssh_channel *c;
3d88e64d 9037 c = snew(struct ssh_channel);
51470298 9038 c->ssh = ssh;
d74d141c 9039
9040 if (c) {
64d6ff88 9041 c->halfopen = TRUE;
51470298 9042 c->localid = alloc_channel_id(ssh);
d74d141c 9043 c->closes = 0;
bc240b21 9044 c->type = CHAN_SOCKDATA_DORMANT;/* identify channel type */
d74d141c 9045 c->u.pfd.s = s;
013dd8c0 9046 bufchain_init(&c->v.v2.outbuffer);
51470298 9047 add234(ssh->channels, c);
d74d141c 9048 }
9049 return c;
9050}
9051
5471d09a 9052/*
9053 * This is called when stdout/stderr (the entity to which
9054 * from_backend sends data) manages to clear some backlog.
9055 */
ae9ae89f 9056static void ssh_unthrottle(void *handle, int bufsize)
5471d09a 9057{
51470298 9058 Ssh ssh = (Ssh) handle;
9059 if (ssh->version == 1) {
9060 if (ssh->v1_stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
9061 ssh->v1_stdout_throttling = 0;
9062 ssh1_throttle(ssh, -1);
5471d09a 9063 }
9064 } else {
f5c578b0 9065 ssh2_set_window(ssh->mainchan, OUR_V2_WINSIZE - bufsize);
5471d09a 9066 }
9067}
9068
6b78788a 9069void ssh_send_port_open(void *channel, char *hostname, int port, char *org)
d74d141c 9070{
9071 struct ssh_channel *c = (struct ssh_channel *)channel;
6b78788a 9072 Ssh ssh = c->ssh;
ff3187f6 9073 struct Packet *pktout;
d74d141c 9074
57356d63 9075 logeventf(ssh, "Opening forwarded connection to %s:%d", hostname, port);
d74d141c 9076
51470298 9077 if (ssh->version == 1) {
9078 send_packet(ssh, SSH1_MSG_PORT_OPEN,
bc240b21 9079 PKT_INT, c->localid,
9080 PKT_STR, hostname,
9081 PKT_INT, port,
31fb1866 9082 /* PKT_STR, <org:orgport>, */
bc240b21 9083 PKT_END);
9084 } else {
ff3187f6 9085 pktout = ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
9086 ssh2_pkt_addstring(pktout, "direct-tcpip");
9087 ssh2_pkt_adduint32(pktout, c->localid);
5471d09a 9088 c->v.v2.locwindow = OUR_V2_WINSIZE;
ff3187f6 9089 ssh2_pkt_adduint32(pktout, c->v.v2.locwindow);/* our window size */
954d5c5a 9090 ssh2_pkt_adduint32(pktout, OUR_V2_MAXPKT); /* our max pkt size */
ff3187f6 9091 ssh2_pkt_addstring(pktout, hostname);
9092 ssh2_pkt_adduint32(pktout, port);
bc240b21 9093 /*
9094 * We make up values for the originator data; partly it's
9095 * too much hassle to keep track, and partly I'm not
9096 * convinced the server should be told details like that
9097 * about my local network configuration.
1f182589 9098 * The "originator IP address" is syntactically a numeric
9099 * IP address, and some servers (e.g., Tectia) get upset
9100 * if it doesn't match this syntax.
bc240b21 9101 */
1f182589 9102 ssh2_pkt_addstring(pktout, "0.0.0.0");
ff3187f6 9103 ssh2_pkt_adduint32(pktout, 0);
9104 ssh2_pkt_send(ssh, pktout);
bc240b21 9105 }
d74d141c 9106}
9107
6226c939 9108static int ssh_connected(void *handle)
32874aea 9109{
51470298 9110 Ssh ssh = (Ssh) handle;
6226c939 9111 return ssh->s != NULL;
32874aea 9112}
8ccc75b0 9113
51470298 9114static int ssh_sendok(void *handle)
32874aea 9115{
51470298 9116 Ssh ssh = (Ssh) handle;
9117 return ssh->send_ok;
32874aea 9118}
fb09bf1c 9119
51470298 9120static int ssh_ldisc(void *handle, int option)
32874aea 9121{
51470298 9122 Ssh ssh = (Ssh) handle;
32874aea 9123 if (option == LD_ECHO)
51470298 9124 return ssh->echoing;
32874aea 9125 if (option == LD_EDIT)
51470298 9126 return ssh->editing;
0965bee0 9127 return FALSE;
9128}
9129
b9d7bcad 9130static void ssh_provide_ldisc(void *handle, void *ldisc)
9131{
9132 Ssh ssh = (Ssh) handle;
9133 ssh->ldisc = ldisc;
9134}
9135
a8327734 9136static void ssh_provide_logctx(void *handle, void *logctx)
9137{
9138 Ssh ssh = (Ssh) handle;
9139 ssh->logctx = logctx;
9140}
9141
51470298 9142static int ssh_return_exitcode(void *handle)
9143{
9144 Ssh ssh = (Ssh) handle;
3bb2f322 9145 if (ssh->s != NULL)
9146 return -1;
9147 else
3c112d53 9148 return (ssh->exitcode >= 0 ? ssh->exitcode : INT_MAX);
51470298 9149}
9150
9151/*
f89c3294 9152 * cfg_info for SSH is the currently running version of the
9153 * protocol. (1 for 1; 2 for 2; 0 for not-decided-yet.)
9154 */
9155static int ssh_cfg_info(void *handle)
9156{
9157 Ssh ssh = (Ssh) handle;
9158 return ssh->version;
9159}
9160
9161/*
51470298 9162 * Gross hack: pscp will try to start SFTP but fall back to scp1 if
9163 * that fails. This variable is the means by which scp.c can reach
9164 * into the SSH code and find out which one it got.
9165 */
9166extern int ssh_fallback_cmd(void *handle)
d8d6c7e5 9167{
51470298 9168 Ssh ssh = (Ssh) handle;
9169 return ssh->fallback_cmd;
d8d6c7e5 9170}
9171
374330e2 9172Backend ssh_backend = {
9173 ssh_init,
fabd1805 9174 ssh_free,
86916870 9175 ssh_reconfig,
374330e2 9176 ssh_send,
5471d09a 9177 ssh_sendbuffer,
374330e2 9178 ssh_size,
4017be6d 9179 ssh_special,
125105d1 9180 ssh_get_specials,
6226c939 9181 ssh_connected,
d8d6c7e5 9182 ssh_return_exitcode,
97db3be4 9183 ssh_sendok,
0965bee0 9184 ssh_ldisc,
b9d7bcad 9185 ssh_provide_ldisc,
a8327734 9186 ssh_provide_logctx,
5471d09a 9187 ssh_unthrottle,
f89c3294 9188 ssh_cfg_info,
9e164d82 9189 "ssh",
9190 PROT_SSH,
97db3be4 9191 22
bc240b21 9192};