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