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