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