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