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