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