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