Branch data Line data Source code
1 : : /* $OpenBSD: monitor_wrap.c,v 1.79 2014/02/02 03:44:31 djm Exp $ */
2 : : /*
3 : : * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 : : * Copyright 2002 Markus Friedl <markus@openbsd.org>
5 : : * All rights reserved.
6 : : *
7 : : * Redistribution and use in source and binary forms, with or without
8 : : * modification, are permitted provided that the following conditions
9 : : * are met:
10 : : * 1. Redistributions of source code must retain the above copyright
11 : : * notice, this list of conditions and the following disclaimer.
12 : : * 2. Redistributions in binary form must reproduce the above copyright
13 : : * notice, this list of conditions and the following disclaimer in the
14 : : * documentation and/or other materials provided with the distribution.
15 : : *
16 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 : : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : : */
27 : :
28 : : #include "includes.h"
29 : :
30 : : #include <sys/types.h>
31 : : #include <sys/uio.h>
32 : :
33 : : #include <errno.h>
34 : : #include <pwd.h>
35 : : #include <signal.h>
36 : : #include <stdarg.h>
37 : : #include <stdio.h>
38 : : #include <string.h>
39 : : #include <unistd.h>
40 : :
41 : : #include <openssl/bn.h>
42 : : #include <openssl/dh.h>
43 : : #include <openssl/evp.h>
44 : :
45 : : #include "openbsd-compat/sys-queue.h"
46 : : #include "xmalloc.h"
47 : : #include "ssh.h"
48 : : #include "dh.h"
49 : : #include "buffer.h"
50 : : #include "key.h"
51 : : #include "cipher.h"
52 : : #include "kex.h"
53 : : #include "hostfile.h"
54 : : #include "auth.h"
55 : : #include "auth-options.h"
56 : : #include "packet.h"
57 : : #include "mac.h"
58 : : #include "log.h"
59 : : #ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */
60 : : #undef TARGET_OS_MAC
61 : : #include "zlib.h"
62 : : #define TARGET_OS_MAC 1
63 : : #else
64 : : #include "zlib.h"
65 : : #endif
66 : : #include "monitor.h"
67 : : #ifdef GSSAPI
68 : : #include "ssh-gss.h"
69 : : #endif
70 : : #include "monitor_wrap.h"
71 : : #include "atomicio.h"
72 : : #include "monitor_fdpass.h"
73 : : #include "misc.h"
74 : : #include "uuencode.h"
75 : :
76 : : #include "channels.h"
77 : : #include "session.h"
78 : : #include "servconf.h"
79 : : #include "roaming.h"
80 : :
81 : : /* Imports */
82 : : extern int compat20;
83 : : extern z_stream incoming_stream;
84 : : extern z_stream outgoing_stream;
85 : : extern struct monitor *pmonitor;
86 : : extern Buffer loginmsg;
87 : : extern ServerOptions options;
88 : :
89 : : void
90 : 62807 : mm_log_handler(LogLevel level, const char *msg, void *ctx)
91 : : {
92 : : Buffer log_msg;
93 : 62807 : struct monitor *mon = (struct monitor *)ctx;
94 : :
95 [ - + ]: 62807 : if (mon->m_log_sendfd == -1)
96 : 0 : fatal("%s: no log channel", __func__);
97 : :
98 : 62807 : buffer_init(&log_msg);
99 : : /*
100 : : * Placeholder for packet length. Will be filled in with the actual
101 : : * packet length once the packet has been constucted. This saves
102 : : * fragile math.
103 : : */
104 : 62807 : buffer_put_int(&log_msg, 0);
105 : :
106 : 62807 : buffer_put_int(&log_msg, level);
107 : 62807 : buffer_put_cstring(&log_msg, msg);
108 : 62807 : put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4);
109 [ - + ]: 125614 : if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg),
110 : 125614 : buffer_len(&log_msg)) != buffer_len(&log_msg))
111 : 0 : fatal("%s: write: %s", __func__, strerror(errno));
112 : 62807 : buffer_free(&log_msg);
113 : 62807 : }
114 : :
115 : : int
116 : 3130 : mm_is_monitor(void)
117 : : {
118 : : /*
119 : : * m_pid is only set in the privileged part, and
120 : : * points to the unprivileged child.
121 : : */
122 [ + - ][ + + ]: 3130 : return (pmonitor && pmonitor->m_pid > 0);
123 : : }
124 : :
125 : : void
126 : 9371 : mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
127 : : {
128 : 9371 : u_int mlen = buffer_len(m);
129 : : u_char buf[5];
130 : :
131 : 9371 : debug3("%s entering: type %d", __func__, type);
132 : :
133 : 9371 : put_u32(buf, mlen + 1);
134 : 9371 : buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */
135 [ - + ]: 9371 : if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
136 : 0 : fatal("%s: write: %s", __func__, strerror(errno));
137 [ - + ]: 9371 : if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen)
138 : 0 : fatal("%s: write: %s", __func__, strerror(errno));
139 : 9371 : }
140 : :
141 : : void
142 : 9371 : mm_request_receive(int sock, Buffer *m)
143 : : {
144 : : u_char buf[4];
145 : : u_int msg_len;
146 : :
147 : 9371 : debug3("%s entering", __func__);
148 : :
149 [ - + ]: 9371 : if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
150 [ # # ]: 0 : if (errno == EPIPE)
151 : 0 : cleanup_exit(255);
152 : 0 : fatal("%s: read: %s", __func__, strerror(errno));
153 : : }
154 : 9371 : msg_len = get_u32(buf);
155 [ - + ]: 9371 : if (msg_len > 256 * 1024)
156 : 0 : fatal("%s: read: bad msg_len %d", __func__, msg_len);
157 : 9371 : buffer_clear(m);
158 : 9371 : buffer_append_space(m, msg_len);
159 [ - + ]: 9371 : if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len)
160 : 0 : fatal("%s: read: %s", __func__, strerror(errno));
161 : 9371 : }
162 : :
163 : : void
164 : 4674 : mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m)
165 : : {
166 : : u_char rtype;
167 : :
168 : 4674 : debug3("%s entering: type %d", __func__, type);
169 : :
170 : 4674 : mm_request_receive(sock, m);
171 : 4674 : rtype = buffer_get_char(m);
172 [ - + ]: 4674 : if (rtype != type)
173 : 0 : fatal("%s: read: rtype %d != type %d", __func__,
174 : : rtype, type);
175 : 4674 : }
176 : :
177 : : DH *
178 : 16 : mm_choose_dh(int min, int nbits, int max)
179 : : {
180 : : BIGNUM *p, *g;
181 : 16 : int success = 0;
182 : : Buffer m;
183 : :
184 : 16 : buffer_init(&m);
185 : 16 : buffer_put_int(&m, min);
186 : 16 : buffer_put_int(&m, nbits);
187 : 16 : buffer_put_int(&m, max);
188 : :
189 : 16 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m);
190 : :
191 : 16 : debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
192 : 16 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m);
193 : :
194 : 16 : success = buffer_get_char(&m);
195 [ - + ]: 16 : if (success == 0)
196 : 0 : fatal("%s: MONITOR_ANS_MODULI failed", __func__);
197 : :
198 [ - + ]: 16 : if ((p = BN_new()) == NULL)
199 : 0 : fatal("%s: BN_new failed", __func__);
200 [ - + ]: 16 : if ((g = BN_new()) == NULL)
201 : 0 : fatal("%s: BN_new failed", __func__);
202 : 16 : buffer_get_bignum2(&m, p);
203 : 16 : buffer_get_bignum2(&m, g);
204 : :
205 : 16 : debug3("%s: remaining %d", __func__, buffer_len(&m));
206 : 16 : buffer_free(&m);
207 : :
208 : 16 : return (dh_new_group(g, p));
209 : : }
210 : :
211 : : int
212 : 660 : mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen)
213 : : {
214 : 660 : Kex *kex = *pmonitor->m_pkex;
215 : : Buffer m;
216 : :
217 : 660 : debug3("%s entering", __func__);
218 : :
219 : 660 : buffer_init(&m);
220 : 660 : buffer_put_int(&m, kex->host_key_index(key));
221 : 660 : buffer_put_string(&m, data, datalen);
222 : :
223 : 660 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
224 : :
225 : 660 : debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
226 : 660 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
227 : 660 : *sigp = buffer_get_string(&m, lenp);
228 : 660 : buffer_free(&m);
229 : :
230 : 660 : return (0);
231 : : }
232 : :
233 : : struct passwd *
234 : 761 : mm_getpwnamallow(const char *username)
235 : : {
236 : : Buffer m;
237 : : struct passwd *pw;
238 : : u_int len, i;
239 : : ServerOptions *newopts;
240 : :
241 : 761 : debug3("%s entering", __func__);
242 : :
243 : 761 : buffer_init(&m);
244 : 761 : buffer_put_cstring(&m, username);
245 : :
246 : 761 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
247 : :
248 : 761 : debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
249 : 761 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
250 : :
251 [ + - ]: 761 : if (buffer_get_char(&m) == 0) {
252 : : pw = NULL;
253 : : goto out;
254 : : }
255 : 761 : pw = buffer_get_string(&m, &len);
256 [ - + ]: 761 : if (len != sizeof(struct passwd))
257 : 0 : fatal("%s: struct passwd size mismatch", __func__);
258 : 761 : pw->pw_name = buffer_get_string(&m, NULL);
259 : 761 : pw->pw_passwd = buffer_get_string(&m, NULL);
260 : : #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
261 : 761 : pw->pw_gecos = buffer_get_string(&m, NULL);
262 : : #endif
263 : : #ifdef HAVE_STRUCT_PASSWD_PW_CLASS
264 : : pw->pw_class = buffer_get_string(&m, NULL);
265 : : #endif
266 : 761 : pw->pw_dir = buffer_get_string(&m, NULL);
267 : 761 : pw->pw_shell = buffer_get_string(&m, NULL);
268 : :
269 : : out:
270 : : /* copy options block as a Match directive may have changed some */
271 : 761 : newopts = buffer_get_string(&m, &len);
272 [ - + ]: 761 : if (len != sizeof(*newopts))
273 : 0 : fatal("%s: option block size mismatch", __func__);
274 : :
275 : : #define M_CP_STROPT(x) do { \
276 : : if (newopts->x != NULL) \
277 : : newopts->x = buffer_get_string(&m, NULL); \
278 : : } while (0)
279 : : #define M_CP_STRARRAYOPT(x, nx) do { \
280 : : for (i = 0; i < newopts->nx; i++) \
281 : : newopts->x[i] = buffer_get_string(&m, NULL); \
282 : : } while (0)
283 : : /* See comment in servconf.h */
284 [ + + ][ + + ]: 3048 : COPY_MATCH_STRING_OPTS();
[ + + ][ + + ]
[ - + ][ - + ]
[ + + ][ - + ]
[ - + ][ - + ]
[ - + ][ + + ]
[ - + ]
285 : : #undef M_CP_STROPT
286 : : #undef M_CP_STRARRAYOPT
287 : :
288 : 761 : copy_set_server_options(&options, newopts, 1);
289 : 761 : free(newopts);
290 : :
291 : 761 : buffer_free(&m);
292 : :
293 : 761 : return (pw);
294 : : }
295 : :
296 : : char *
297 : 8 : mm_auth2_read_banner(void)
298 : : {
299 : : Buffer m;
300 : : char *banner;
301 : :
302 : 8 : debug3("%s entering", __func__);
303 : :
304 : 8 : buffer_init(&m);
305 : 8 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
306 : 8 : buffer_clear(&m);
307 : :
308 : 8 : mm_request_receive_expect(pmonitor->m_recvfd,
309 : : MONITOR_ANS_AUTH2_READ_BANNER, &m);
310 : 8 : banner = buffer_get_string(&m, NULL);
311 : 8 : buffer_free(&m);
312 : :
313 : : /* treat empty banner as missing banner */
314 [ + + ]: 8 : if (strlen(banner) == 0) {
315 : 2 : free(banner);
316 : 2 : banner = NULL;
317 : : }
318 : 8 : return (banner);
319 : : }
320 : :
321 : : /* Inform the privileged process about service and style */
322 : :
323 : : void
324 : 658 : mm_inform_authserv(char *service, char *style)
325 : : {
326 : : Buffer m;
327 : :
328 : 658 : debug3("%s entering", __func__);
329 : :
330 : 658 : buffer_init(&m);
331 : 658 : buffer_put_cstring(&m, service);
332 [ + + ]: 658 : buffer_put_cstring(&m, style ? style : "");
333 : :
334 : 658 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
335 : :
336 : 658 : buffer_free(&m);
337 : 658 : }
338 : :
339 : : /* Do the password authentication */
340 : : int
341 : 0 : mm_auth_password(Authctxt *authctxt, char *password)
342 : : {
343 : : Buffer m;
344 : 0 : int authenticated = 0;
345 : :
346 : 0 : debug3("%s entering", __func__);
347 : :
348 : 0 : buffer_init(&m);
349 : 0 : buffer_put_cstring(&m, password);
350 : 0 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
351 : :
352 : 0 : debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
353 : 0 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
354 : :
355 : 0 : authenticated = buffer_get_int(&m);
356 : :
357 : 0 : buffer_free(&m);
358 : :
359 [ # # ]: 0 : debug3("%s: user %sauthenticated",
360 : : __func__, authenticated ? "" : "not ");
361 : 0 : return (authenticated);
362 : : }
363 : :
364 : : int
365 : 1398 : mm_user_key_allowed(struct passwd *pw, Key *key)
366 : : {
367 : 1398 : return (mm_key_allowed(MM_USERKEY, NULL, NULL, key));
368 : : }
369 : :
370 : : int
371 : 0 : mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host,
372 : : Key *key)
373 : : {
374 : 0 : return (mm_key_allowed(MM_HOSTKEY, user, host, key));
375 : : }
376 : :
377 : : int
378 : 0 : mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
379 : : char *host, Key *key)
380 : : {
381 : : int ret;
382 : :
383 : 0 : key->type = KEY_RSA; /* XXX hack for key_to_blob */
384 : 0 : ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key);
385 : 0 : key->type = KEY_RSA1;
386 : 0 : return (ret);
387 : : }
388 : :
389 : : int
390 : 1398 : mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
391 : : {
392 : : Buffer m;
393 : : u_char *blob;
394 : : u_int len;
395 : 1398 : int allowed = 0, have_forced = 0;
396 : :
397 : 1398 : debug3("%s entering", __func__);
398 : :
399 : : /* Convert the key to a blob and the pass it over */
400 [ + - ]: 1398 : if (!key_to_blob(key, &blob, &len))
401 : : return (0);
402 : :
403 : 1398 : buffer_init(&m);
404 : 1398 : buffer_put_int(&m, type);
405 [ - + ]: 1398 : buffer_put_cstring(&m, user ? user : "");
406 [ - + ]: 1398 : buffer_put_cstring(&m, host ? host : "");
407 : 1398 : buffer_put_string(&m, blob, len);
408 : 1398 : free(blob);
409 : :
410 : 1398 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
411 : :
412 : 1398 : debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
413 : 1398 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
414 : :
415 : 1398 : allowed = buffer_get_int(&m);
416 : :
417 : : /* fake forced command */
418 : 1398 : auth_clear_options();
419 : 1398 : have_forced = buffer_get_int(&m);
420 [ + + ]: 1398 : forced_command = have_forced ? xstrdup("true") : NULL;
421 : :
422 : 1398 : buffer_free(&m);
423 : :
424 : 1398 : return (allowed);
425 : : }
426 : :
427 : : /*
428 : : * This key verify needs to send the key type along, because the
429 : : * privileged parent makes the decision if the key is allowed
430 : : * for authentication.
431 : : */
432 : :
433 : : int
434 : 658 : mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
435 : : {
436 : : Buffer m;
437 : : u_char *blob;
438 : : u_int len;
439 : 658 : int verified = 0;
440 : :
441 : 658 : debug3("%s entering", __func__);
442 : :
443 : : /* Convert the key to a blob and the pass it over */
444 [ + - ]: 658 : if (!key_to_blob(key, &blob, &len))
445 : : return (0);
446 : :
447 : 658 : buffer_init(&m);
448 : 658 : buffer_put_string(&m, blob, len);
449 : 658 : buffer_put_string(&m, sig, siglen);
450 : 658 : buffer_put_string(&m, data, datalen);
451 : 658 : free(blob);
452 : :
453 : 658 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
454 : :
455 : 658 : debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
456 : 658 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
457 : :
458 : 658 : verified = buffer_get_int(&m);
459 : :
460 : 658 : buffer_free(&m);
461 : :
462 : 658 : return (verified);
463 : : }
464 : :
465 : : /* Export key state after authentication */
466 : : Newkeys *
467 : 1316 : mm_newkeys_from_blob(u_char *blob, int blen)
468 : : {
469 : : Buffer b;
470 : : u_int len;
471 : 1316 : Newkeys *newkey = NULL;
472 : : Enc *enc;
473 : : Mac *mac;
474 : : Comp *comp;
475 : :
476 : 1316 : debug3("%s: %p(%d)", __func__, blob, blen);
477 : : #ifdef DEBUG_PK
478 : : dump_base64(stderr, blob, blen);
479 : : #endif
480 : 1316 : buffer_init(&b);
481 : 1316 : buffer_append(&b, blob, blen);
482 : :
483 : 1316 : newkey = xcalloc(1, sizeof(*newkey));
484 : 1316 : enc = &newkey->enc;
485 : 1316 : mac = &newkey->mac;
486 : 1316 : comp = &newkey->comp;
487 : :
488 : : /* Enc structure */
489 : 1316 : enc->name = buffer_get_string(&b, NULL);
490 : 1316 : buffer_get(&b, &enc->cipher, sizeof(enc->cipher));
491 : 1316 : enc->enabled = buffer_get_int(&b);
492 : 1316 : enc->block_size = buffer_get_int(&b);
493 : 1316 : enc->key = buffer_get_string(&b, &enc->key_len);
494 : 1316 : enc->iv = buffer_get_string(&b, &enc->iv_len);
495 : :
496 [ + - ][ - + ]: 1316 : if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher)
497 : 0 : fatal("%s: bad cipher name %s or pointer %p", __func__,
498 : : enc->name, enc->cipher);
499 : :
500 : : /* Mac structure */
501 [ + + ]: 1316 : if (cipher_authlen(enc->cipher) == 0) {
502 : 1250 : mac->name = buffer_get_string(&b, NULL);
503 [ + - ][ - + ]: 1250 : if (mac->name == NULL || mac_setup(mac, mac->name) == -1)
504 : 0 : fatal("%s: can not setup mac %s", __func__, mac->name);
505 : 1250 : mac->enabled = buffer_get_int(&b);
506 : 1250 : mac->key = buffer_get_string(&b, &len);
507 [ - + ]: 1250 : if (len > mac->key_len)
508 : 0 : fatal("%s: bad mac key length: %u > %d", __func__, len,
509 : : mac->key_len);
510 : 1250 : mac->key_len = len;
511 : : }
512 : :
513 : : /* Comp structure */
514 : 1316 : comp->type = buffer_get_int(&b);
515 : 1316 : comp->enabled = buffer_get_int(&b);
516 : 1316 : comp->name = buffer_get_string(&b, NULL);
517 : :
518 : 1316 : len = buffer_len(&b);
519 [ - + ]: 1316 : if (len != 0)
520 : 0 : error("newkeys_from_blob: remaining bytes in blob %u", len);
521 : 1316 : buffer_free(&b);
522 : 1316 : return (newkey);
523 : : }
524 : :
525 : : int
526 : 1316 : mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
527 : : {
528 : : Buffer b;
529 : : int len;
530 : : Enc *enc;
531 : : Mac *mac;
532 : : Comp *comp;
533 : 1316 : Newkeys *newkey = (Newkeys *)packet_get_newkeys(mode);
534 : :
535 : 1316 : debug3("%s: converting %p", __func__, newkey);
536 : :
537 [ - + ]: 1316 : if (newkey == NULL) {
538 : 0 : error("%s: newkey == NULL", __func__);
539 : 0 : return 0;
540 : : }
541 : 1316 : enc = &newkey->enc;
542 : 1316 : mac = &newkey->mac;
543 : 1316 : comp = &newkey->comp;
544 : :
545 : 1316 : buffer_init(&b);
546 : : /* Enc structure */
547 : 1316 : buffer_put_cstring(&b, enc->name);
548 : : /* The cipher struct is constant and shared, you export pointer */
549 : 1316 : buffer_append(&b, &enc->cipher, sizeof(enc->cipher));
550 : 1316 : buffer_put_int(&b, enc->enabled);
551 : 1316 : buffer_put_int(&b, enc->block_size);
552 : 1316 : buffer_put_string(&b, enc->key, enc->key_len);
553 : 1316 : packet_get_keyiv(mode, enc->iv, enc->iv_len);
554 : 1316 : buffer_put_string(&b, enc->iv, enc->iv_len);
555 : :
556 : : /* Mac structure */
557 [ + + ]: 1316 : if (cipher_authlen(enc->cipher) == 0) {
558 : 1250 : buffer_put_cstring(&b, mac->name);
559 : 1250 : buffer_put_int(&b, mac->enabled);
560 : 1250 : buffer_put_string(&b, mac->key, mac->key_len);
561 : : }
562 : :
563 : : /* Comp structure */
564 : 1316 : buffer_put_int(&b, comp->type);
565 : 1316 : buffer_put_int(&b, comp->enabled);
566 : 1316 : buffer_put_cstring(&b, comp->name);
567 : :
568 : 1316 : len = buffer_len(&b);
569 [ + - ]: 1316 : if (lenp != NULL)
570 : 1316 : *lenp = len;
571 [ + - ]: 1316 : if (blobp != NULL) {
572 : 1316 : *blobp = xmalloc(len);
573 : 1316 : memcpy(*blobp, buffer_ptr(&b), len);
574 : : }
575 : 1316 : explicit_bzero(buffer_ptr(&b), len);
576 : 1316 : buffer_free(&b);
577 : 1316 : return len;
578 : : }
579 : :
580 : : static void
581 : 658 : mm_send_kex(Buffer *m, Kex *kex)
582 : : {
583 : 658 : buffer_put_string(m, kex->session_id, kex->session_id_len);
584 : 658 : buffer_put_int(m, kex->we_need);
585 : 658 : buffer_put_int(m, kex->hostkey_type);
586 : 658 : buffer_put_int(m, kex->kex_type);
587 : 658 : buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my));
588 : 658 : buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer));
589 : 658 : buffer_put_int(m, kex->flags);
590 : 658 : buffer_put_cstring(m, kex->client_version_string);
591 : 658 : buffer_put_cstring(m, kex->server_version_string);
592 : 658 : }
593 : :
594 : : void
595 : 761 : mm_send_keystate(struct monitor *monitor)
596 : : {
597 : : Buffer m, *input, *output;
598 : : u_char *blob, *p;
599 : : u_int bloblen, plen;
600 : : u_int32_t seqnr, packets;
601 : : u_int64_t blocks, bytes;
602 : :
603 : 761 : buffer_init(&m);
604 : :
605 [ + + ]: 761 : if (!compat20) {
606 : : u_char iv[24];
607 : : u_char *key;
608 : : u_int ivlen, keylen;
609 : :
610 : 103 : buffer_put_int(&m, packet_get_protocol_flags());
611 : :
612 : 103 : buffer_put_int(&m, packet_get_ssh1_cipher());
613 : :
614 : 103 : debug3("%s: Sending ssh1 KEY+IV", __func__);
615 : 103 : keylen = packet_get_encryption_key(NULL);
616 : 103 : key = xmalloc(keylen+1); /* add 1 if keylen == 0 */
617 : 103 : keylen = packet_get_encryption_key(key);
618 : 103 : buffer_put_string(&m, key, keylen);
619 : 103 : explicit_bzero(key, keylen);
620 : 103 : free(key);
621 : :
622 : 103 : ivlen = packet_get_keyiv_len(MODE_OUT);
623 : 103 : packet_get_keyiv(MODE_OUT, iv, ivlen);
624 : 103 : buffer_put_string(&m, iv, ivlen);
625 : 103 : ivlen = packet_get_keyiv_len(MODE_IN);
626 : 103 : packet_get_keyiv(MODE_IN, iv, ivlen);
627 : 103 : buffer_put_string(&m, iv, ivlen);
628 : : goto skip;
629 : : } else {
630 : : /* Kex for rekeying */
631 : 658 : mm_send_kex(&m, *monitor->m_pkex);
632 : : }
633 : :
634 : 658 : debug3("%s: Sending new keys: %p %p",
635 : : __func__, packet_get_newkeys(MODE_OUT),
636 : : packet_get_newkeys(MODE_IN));
637 : :
638 : : /* Keys from Kex */
639 [ - + ]: 658 : if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
640 : 0 : fatal("%s: conversion of newkeys failed", __func__);
641 : :
642 : 658 : buffer_put_string(&m, blob, bloblen);
643 : 658 : free(blob);
644 : :
645 [ - + ]: 658 : if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))
646 : 0 : fatal("%s: conversion of newkeys failed", __func__);
647 : :
648 : 658 : buffer_put_string(&m, blob, bloblen);
649 : 658 : free(blob);
650 : :
651 : 658 : packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes);
652 : 658 : buffer_put_int(&m, seqnr);
653 : 658 : buffer_put_int64(&m, blocks);
654 : 658 : buffer_put_int(&m, packets);
655 : 658 : buffer_put_int64(&m, bytes);
656 : 658 : packet_get_state(MODE_IN, &seqnr, &blocks, &packets, &bytes);
657 : 658 : buffer_put_int(&m, seqnr);
658 : 658 : buffer_put_int64(&m, blocks);
659 : 658 : buffer_put_int(&m, packets);
660 : 658 : buffer_put_int64(&m, bytes);
661 : :
662 : 658 : debug3("%s: New keys have been sent", __func__);
663 : : skip:
664 : : /* More key context */
665 : 761 : plen = packet_get_keycontext(MODE_OUT, NULL);
666 : 761 : p = xmalloc(plen+1);
667 : 761 : packet_get_keycontext(MODE_OUT, p);
668 : 761 : buffer_put_string(&m, p, plen);
669 : 761 : free(p);
670 : :
671 : 761 : plen = packet_get_keycontext(MODE_IN, NULL);
672 : 761 : p = xmalloc(plen+1);
673 : 761 : packet_get_keycontext(MODE_IN, p);
674 : 761 : buffer_put_string(&m, p, plen);
675 : 761 : free(p);
676 : :
677 : : /* Compression state */
678 : 761 : debug3("%s: Sending compression state", __func__);
679 : 761 : buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream));
680 : 761 : buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
681 : :
682 : : /* Network I/O buffers */
683 : 761 : input = (Buffer *)packet_get_input();
684 : 761 : output = (Buffer *)packet_get_output();
685 : 761 : buffer_put_string(&m, buffer_ptr(input), buffer_len(input));
686 : 761 : buffer_put_string(&m, buffer_ptr(output), buffer_len(output));
687 : :
688 : : /* Roaming */
689 [ + + ]: 761 : if (compat20) {
690 : 658 : buffer_put_int64(&m, get_sent_bytes());
691 : 658 : buffer_put_int64(&m, get_recv_bytes());
692 : : }
693 : :
694 : 761 : mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
695 : 761 : debug3("%s: Finished sending state", __func__);
696 : :
697 : 761 : buffer_free(&m);
698 : 761 : }
699 : :
700 : : int
701 : 0 : mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
702 : : {
703 : : Buffer m;
704 : : char *p, *msg;
705 : 0 : int success = 0, tmp1 = -1, tmp2 = -1;
706 : :
707 : : /* Kludge: ensure there are fds free to receive the pty/tty */
708 [ # # ][ # # ]: 0 : if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
709 : 0 : (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
710 : 0 : error("%s: cannot allocate fds for pty", __func__);
711 [ # # ]: 0 : if (tmp1 > 0)
712 : 0 : close(tmp1);
713 [ # # ]: 0 : if (tmp2 > 0)
714 : 0 : close(tmp2);
715 : : return 0;
716 : : }
717 : 0 : close(tmp1);
718 : 0 : close(tmp2);
719 : :
720 : 0 : buffer_init(&m);
721 : 0 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
722 : :
723 : 0 : debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
724 : 0 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m);
725 : :
726 : 0 : success = buffer_get_int(&m);
727 [ # # ]: 0 : if (success == 0) {
728 : 0 : debug3("%s: pty alloc failed", __func__);
729 : 0 : buffer_free(&m);
730 : 0 : return (0);
731 : : }
732 : 0 : p = buffer_get_string(&m, NULL);
733 : 0 : msg = buffer_get_string(&m, NULL);
734 : 0 : buffer_free(&m);
735 : :
736 : 0 : strlcpy(namebuf, p, namebuflen); /* Possible truncation */
737 : 0 : free(p);
738 : :
739 : 0 : buffer_append(&loginmsg, msg, strlen(msg));
740 : 0 : free(msg);
741 : :
742 [ # # # # ]: 0 : if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
743 : 0 : (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
744 : 0 : fatal("%s: receive fds failed", __func__);
745 : :
746 : : /* Success */
747 : : return (1);
748 : : }
749 : :
750 : : void
751 : 0 : mm_session_pty_cleanup2(Session *s)
752 : : {
753 : : Buffer m;
754 : :
755 [ # # ]: 0 : if (s->ttyfd == -1)
756 : 0 : return;
757 : 0 : buffer_init(&m);
758 : 0 : buffer_put_cstring(&m, s->tty);
759 : 0 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
760 : 0 : buffer_free(&m);
761 : :
762 : : /* closed dup'ed master */
763 [ # # ][ # # ]: 0 : if (s->ptymaster != -1 && close(s->ptymaster) < 0)
764 : 0 : error("close(s->ptymaster/%d): %s",
765 : 0 : s->ptymaster, strerror(errno));
766 : :
767 : : /* unlink pty from session */
768 : 0 : s->ttyfd = -1;
769 : : }
770 : :
771 : : #ifdef USE_PAM
772 : : void
773 : : mm_start_pam(Authctxt *authctxt)
774 : : {
775 : : Buffer m;
776 : :
777 : : debug3("%s entering", __func__);
778 : : if (!options.use_pam)
779 : : fatal("UsePAM=no, but ended up in %s anyway", __func__);
780 : :
781 : : buffer_init(&m);
782 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m);
783 : :
784 : : buffer_free(&m);
785 : : }
786 : :
787 : : u_int
788 : : mm_do_pam_account(void)
789 : : {
790 : : Buffer m;
791 : : u_int ret;
792 : : char *msg;
793 : :
794 : : debug3("%s entering", __func__);
795 : : if (!options.use_pam)
796 : : fatal("UsePAM=no, but ended up in %s anyway", __func__);
797 : :
798 : : buffer_init(&m);
799 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
800 : :
801 : : mm_request_receive_expect(pmonitor->m_recvfd,
802 : : MONITOR_ANS_PAM_ACCOUNT, &m);
803 : : ret = buffer_get_int(&m);
804 : : msg = buffer_get_string(&m, NULL);
805 : : buffer_append(&loginmsg, msg, strlen(msg));
806 : : free(msg);
807 : :
808 : : buffer_free(&m);
809 : :
810 : : debug3("%s returning %d", __func__, ret);
811 : :
812 : : return (ret);
813 : : }
814 : :
815 : : void *
816 : : mm_sshpam_init_ctx(Authctxt *authctxt)
817 : : {
818 : : Buffer m;
819 : : int success;
820 : :
821 : : debug3("%s", __func__);
822 : : buffer_init(&m);
823 : : buffer_put_cstring(&m, authctxt->user);
824 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m);
825 : : debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
826 : : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m);
827 : : success = buffer_get_int(&m);
828 : : if (success == 0) {
829 : : debug3("%s: pam_init_ctx failed", __func__);
830 : : buffer_free(&m);
831 : : return (NULL);
832 : : }
833 : : buffer_free(&m);
834 : : return (authctxt);
835 : : }
836 : :
837 : : int
838 : : mm_sshpam_query(void *ctx, char **name, char **info,
839 : : u_int *num, char ***prompts, u_int **echo_on)
840 : : {
841 : : Buffer m;
842 : : u_int i;
843 : : int ret;
844 : :
845 : : debug3("%s", __func__);
846 : : buffer_init(&m);
847 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m);
848 : : debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
849 : : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m);
850 : : ret = buffer_get_int(&m);
851 : : debug3("%s: pam_query returned %d", __func__, ret);
852 : : *name = buffer_get_string(&m, NULL);
853 : : *info = buffer_get_string(&m, NULL);
854 : : *num = buffer_get_int(&m);
855 : : if (*num > PAM_MAX_NUM_MSG)
856 : : fatal("%s: recieved %u PAM messages, expected <= %u",
857 : : __func__, *num, PAM_MAX_NUM_MSG);
858 : : *prompts = xcalloc((*num + 1), sizeof(char *));
859 : : *echo_on = xcalloc((*num + 1), sizeof(u_int));
860 : : for (i = 0; i < *num; ++i) {
861 : : (*prompts)[i] = buffer_get_string(&m, NULL);
862 : : (*echo_on)[i] = buffer_get_int(&m);
863 : : }
864 : : buffer_free(&m);
865 : : return (ret);
866 : : }
867 : :
868 : : int
869 : : mm_sshpam_respond(void *ctx, u_int num, char **resp)
870 : : {
871 : : Buffer m;
872 : : u_int i;
873 : : int ret;
874 : :
875 : : debug3("%s", __func__);
876 : : buffer_init(&m);
877 : : buffer_put_int(&m, num);
878 : : for (i = 0; i < num; ++i)
879 : : buffer_put_cstring(&m, resp[i]);
880 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m);
881 : : debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
882 : : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m);
883 : : ret = buffer_get_int(&m);
884 : : debug3("%s: pam_respond returned %d", __func__, ret);
885 : : buffer_free(&m);
886 : : return (ret);
887 : : }
888 : :
889 : : void
890 : : mm_sshpam_free_ctx(void *ctxtp)
891 : : {
892 : : Buffer m;
893 : :
894 : : debug3("%s", __func__);
895 : : buffer_init(&m);
896 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m);
897 : : debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
898 : : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m);
899 : : buffer_free(&m);
900 : : }
901 : : #endif /* USE_PAM */
902 : :
903 : : /* Request process termination */
904 : :
905 : : void
906 : 25 : mm_terminate(void)
907 : : {
908 : : Buffer m;
909 : :
910 : 25 : buffer_init(&m);
911 : 25 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m);
912 : 25 : buffer_free(&m);
913 : 25 : }
914 : :
915 : : int
916 : 103 : mm_ssh1_session_key(BIGNUM *num)
917 : : {
918 : : int rsafail;
919 : : Buffer m;
920 : :
921 : 103 : buffer_init(&m);
922 : 103 : buffer_put_bignum2(&m, num);
923 : 103 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m);
924 : :
925 : 103 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m);
926 : :
927 : 103 : rsafail = buffer_get_int(&m);
928 : 103 : buffer_get_bignum2(&m, num);
929 : :
930 : 103 : buffer_free(&m);
931 : :
932 : 103 : return (rsafail);
933 : : }
934 : :
935 : : static void
936 : 0 : mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
937 : : char ***prompts, u_int **echo_on)
938 : : {
939 : 0 : *name = xstrdup("");
940 : 0 : *infotxt = xstrdup("");
941 : 0 : *numprompts = 1;
942 : 0 : *prompts = xcalloc(*numprompts, sizeof(char *));
943 : 0 : *echo_on = xcalloc(*numprompts, sizeof(u_int));
944 : 0 : (*echo_on)[0] = 0;
945 : 0 : }
946 : :
947 : : int
948 : 0 : mm_bsdauth_query(void *ctx, char **name, char **infotxt,
949 : : u_int *numprompts, char ***prompts, u_int **echo_on)
950 : : {
951 : : Buffer m;
952 : : u_int success;
953 : : char *challenge;
954 : :
955 : 0 : debug3("%s: entering", __func__);
956 : :
957 : 0 : buffer_init(&m);
958 : 0 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
959 : :
960 : 0 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
961 : : &m);
962 : 0 : success = buffer_get_int(&m);
963 [ # # ]: 0 : if (success == 0) {
964 : 0 : debug3("%s: no challenge", __func__);
965 : 0 : buffer_free(&m);
966 : 0 : return (-1);
967 : : }
968 : :
969 : : /* Get the challenge, and format the response */
970 : 0 : challenge = buffer_get_string(&m, NULL);
971 : 0 : buffer_free(&m);
972 : :
973 : 0 : mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
974 : 0 : (*prompts)[0] = challenge;
975 : :
976 : 0 : debug3("%s: received challenge: %s", __func__, challenge);
977 : :
978 : 0 : return (0);
979 : : }
980 : :
981 : : int
982 : 0 : mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
983 : : {
984 : : Buffer m;
985 : : int authok;
986 : :
987 : 0 : debug3("%s: entering", __func__);
988 [ # # ]: 0 : if (numresponses != 1)
989 : : return (-1);
990 : :
991 : 0 : buffer_init(&m);
992 : 0 : buffer_put_cstring(&m, responses[0]);
993 : 0 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
994 : :
995 : 0 : mm_request_receive_expect(pmonitor->m_recvfd,
996 : : MONITOR_ANS_BSDAUTHRESPOND, &m);
997 : :
998 : 0 : authok = buffer_get_int(&m);
999 : 0 : buffer_free(&m);
1000 : :
1001 [ # # ]: 0 : return ((authok == 0) ? -1 : 0);
1002 : : }
1003 : :
1004 : : #ifdef SKEY
1005 : : int
1006 : : mm_skey_query(void *ctx, char **name, char **infotxt,
1007 : : u_int *numprompts, char ***prompts, u_int **echo_on)
1008 : : {
1009 : : Buffer m;
1010 : : u_int success;
1011 : : char *challenge;
1012 : :
1013 : : debug3("%s: entering", __func__);
1014 : :
1015 : : buffer_init(&m);
1016 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
1017 : :
1018 : : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
1019 : : &m);
1020 : : success = buffer_get_int(&m);
1021 : : if (success == 0) {
1022 : : debug3("%s: no challenge", __func__);
1023 : : buffer_free(&m);
1024 : : return (-1);
1025 : : }
1026 : :
1027 : : /* Get the challenge, and format the response */
1028 : : challenge = buffer_get_string(&m, NULL);
1029 : : buffer_free(&m);
1030 : :
1031 : : debug3("%s: received challenge: %s", __func__, challenge);
1032 : :
1033 : : mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
1034 : :
1035 : : xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
1036 : : free(challenge);
1037 : :
1038 : : return (0);
1039 : : }
1040 : :
1041 : : int
1042 : : mm_skey_respond(void *ctx, u_int numresponses, char **responses)
1043 : : {
1044 : : Buffer m;
1045 : : int authok;
1046 : :
1047 : : debug3("%s: entering", __func__);
1048 : : if (numresponses != 1)
1049 : : return (-1);
1050 : :
1051 : : buffer_init(&m);
1052 : : buffer_put_cstring(&m, responses[0]);
1053 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
1054 : :
1055 : : mm_request_receive_expect(pmonitor->m_recvfd,
1056 : : MONITOR_ANS_SKEYRESPOND, &m);
1057 : :
1058 : : authok = buffer_get_int(&m);
1059 : : buffer_free(&m);
1060 : :
1061 : : return ((authok == 0) ? -1 : 0);
1062 : : }
1063 : : #endif /* SKEY */
1064 : :
1065 : : void
1066 : 103 : mm_ssh1_session_id(u_char session_id[16])
1067 : : {
1068 : : Buffer m;
1069 : : int i;
1070 : :
1071 : 103 : debug3("%s entering", __func__);
1072 : :
1073 : 103 : buffer_init(&m);
1074 [ + + ]: 1751 : for (i = 0; i < 16; i++)
1075 : 1648 : buffer_put_char(&m, session_id[i]);
1076 : :
1077 : 103 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m);
1078 : 103 : buffer_free(&m);
1079 : 103 : }
1080 : :
1081 : : int
1082 : 103 : mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
1083 : : {
1084 : : Buffer m;
1085 : : Key *key;
1086 : : u_char *blob;
1087 : : u_int blen;
1088 : 103 : int allowed = 0, have_forced = 0;
1089 : :
1090 : 103 : debug3("%s entering", __func__);
1091 : :
1092 : 103 : buffer_init(&m);
1093 : 103 : buffer_put_bignum2(&m, client_n);
1094 : :
1095 : 103 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
1096 : 103 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);
1097 : :
1098 : 103 : allowed = buffer_get_int(&m);
1099 : :
1100 : : /* fake forced command */
1101 : 103 : auth_clear_options();
1102 : 103 : have_forced = buffer_get_int(&m);
1103 [ + + ]: 103 : forced_command = have_forced ? xstrdup("true") : NULL;
1104 : :
1105 [ + - ]: 103 : if (allowed && rkey != NULL) {
1106 : 103 : blob = buffer_get_string(&m, &blen);
1107 [ - + ]: 103 : if ((key = key_from_blob(blob, blen)) == NULL)
1108 : 0 : fatal("%s: key_from_blob failed", __func__);
1109 : 103 : *rkey = key;
1110 : 103 : free(blob);
1111 : : }
1112 : 103 : buffer_free(&m);
1113 : :
1114 : 103 : return (allowed);
1115 : : }
1116 : :
1117 : : BIGNUM *
1118 : 103 : mm_auth_rsa_generate_challenge(Key *key)
1119 : : {
1120 : : Buffer m;
1121 : : BIGNUM *challenge;
1122 : : u_char *blob;
1123 : : u_int blen;
1124 : :
1125 : 103 : debug3("%s entering", __func__);
1126 : :
1127 [ - + ]: 103 : if ((challenge = BN_new()) == NULL)
1128 : 0 : fatal("%s: BN_new failed", __func__);
1129 : :
1130 : 103 : key->type = KEY_RSA; /* XXX cheat for key_to_blob */
1131 [ - + ]: 103 : if (key_to_blob(key, &blob, &blen) == 0)
1132 : 0 : fatal("%s: key_to_blob failed", __func__);
1133 : 103 : key->type = KEY_RSA1;
1134 : :
1135 : 103 : buffer_init(&m);
1136 : 103 : buffer_put_string(&m, blob, blen);
1137 : 103 : free(blob);
1138 : :
1139 : 103 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
1140 : 103 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
1141 : :
1142 : 103 : buffer_get_bignum2(&m, challenge);
1143 : 103 : buffer_free(&m);
1144 : :
1145 : 103 : return (challenge);
1146 : : }
1147 : :
1148 : : int
1149 : 103 : mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
1150 : : {
1151 : : Buffer m;
1152 : : u_char *blob;
1153 : : u_int blen;
1154 : 103 : int success = 0;
1155 : :
1156 : 103 : debug3("%s entering", __func__);
1157 : :
1158 : 103 : key->type = KEY_RSA; /* XXX cheat for key_to_blob */
1159 [ - + ]: 103 : if (key_to_blob(key, &blob, &blen) == 0)
1160 : 0 : fatal("%s: key_to_blob failed", __func__);
1161 : 103 : key->type = KEY_RSA1;
1162 : :
1163 : 103 : buffer_init(&m);
1164 : 103 : buffer_put_string(&m, blob, blen);
1165 : 103 : buffer_put_string(&m, response, 16);
1166 : 103 : free(blob);
1167 : :
1168 : 103 : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
1169 : 103 : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
1170 : :
1171 : 103 : success = buffer_get_int(&m);
1172 : 103 : buffer_free(&m);
1173 : :
1174 : 103 : return (success);
1175 : : }
1176 : :
1177 : : #ifdef SSH_AUDIT_EVENTS
1178 : : void
1179 : : mm_audit_event(ssh_audit_event_t event)
1180 : : {
1181 : : Buffer m;
1182 : :
1183 : : debug3("%s entering", __func__);
1184 : :
1185 : : buffer_init(&m);
1186 : : buffer_put_int(&m, event);
1187 : :
1188 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
1189 : : buffer_free(&m);
1190 : : }
1191 : :
1192 : : void
1193 : : mm_audit_run_command(const char *command)
1194 : : {
1195 : : Buffer m;
1196 : :
1197 : : debug3("%s entering command %s", __func__, command);
1198 : :
1199 : : buffer_init(&m);
1200 : : buffer_put_cstring(&m, command);
1201 : :
1202 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
1203 : : buffer_free(&m);
1204 : : }
1205 : : #endif /* SSH_AUDIT_EVENTS */
1206 : :
1207 : : #ifdef GSSAPI
1208 : : OM_uint32
1209 : : mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
1210 : : {
1211 : : Buffer m;
1212 : : OM_uint32 major;
1213 : :
1214 : : /* Client doesn't get to see the context */
1215 : : *ctx = NULL;
1216 : :
1217 : : buffer_init(&m);
1218 : : buffer_put_string(&m, goid->elements, goid->length);
1219 : :
1220 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
1221 : : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
1222 : :
1223 : : major = buffer_get_int(&m);
1224 : :
1225 : : buffer_free(&m);
1226 : : return (major);
1227 : : }
1228 : :
1229 : : OM_uint32
1230 : : mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
1231 : : gss_buffer_desc *out, OM_uint32 *flags)
1232 : : {
1233 : : Buffer m;
1234 : : OM_uint32 major;
1235 : : u_int len;
1236 : :
1237 : : buffer_init(&m);
1238 : : buffer_put_string(&m, in->value, in->length);
1239 : :
1240 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
1241 : : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
1242 : :
1243 : : major = buffer_get_int(&m);
1244 : : out->value = buffer_get_string(&m, &len);
1245 : : out->length = len;
1246 : : if (flags)
1247 : : *flags = buffer_get_int(&m);
1248 : :
1249 : : buffer_free(&m);
1250 : :
1251 : : return (major);
1252 : : }
1253 : :
1254 : : OM_uint32
1255 : : mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
1256 : : {
1257 : : Buffer m;
1258 : : OM_uint32 major;
1259 : :
1260 : : buffer_init(&m);
1261 : : buffer_put_string(&m, gssbuf->value, gssbuf->length);
1262 : : buffer_put_string(&m, gssmic->value, gssmic->length);
1263 : :
1264 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
1265 : : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
1266 : : &m);
1267 : :
1268 : : major = buffer_get_int(&m);
1269 : : buffer_free(&m);
1270 : : return(major);
1271 : : }
1272 : :
1273 : : int
1274 : : mm_ssh_gssapi_userok(char *user)
1275 : : {
1276 : : Buffer m;
1277 : : int authenticated = 0;
1278 : :
1279 : : buffer_init(&m);
1280 : :
1281 : : mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
1282 : : mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
1283 : : &m);
1284 : :
1285 : : authenticated = buffer_get_int(&m);
1286 : :
1287 : : buffer_free(&m);
1288 : : debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
1289 : : return (authenticated);
1290 : : }
1291 : : #endif /* GSSAPI */
1292 : :
|