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