jcs's openbsd hax
openbsd
1/* $OpenBSD: monitor_wrap.c,v 1.145 2026/02/08 19:54:31 dtucker 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 <sys/types.h>
29#include <sys/uio.h>
30#include <sys/queue.h>
31#include <sys/wait.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#ifdef WITH_OPENSSL
42#include <openssl/bn.h>
43#include <openssl/dh.h>
44#include <openssl/evp.h>
45#endif
46
47#include "xmalloc.h"
48#include "ssh.h"
49#ifdef WITH_OPENSSL
50#include "dh.h"
51#endif
52#include "sshbuf.h"
53#include "sshkey.h"
54#include "cipher.h"
55#include "kex.h"
56#include "hostfile.h"
57#include "auth.h"
58#include "auth-options.h"
59#include "packet.h"
60#include "mac.h"
61#include "log.h"
62#include "monitor.h"
63#ifdef GSSAPI
64#include "ssh-gss.h"
65#endif
66#include "atomicio.h"
67#include "monitor_fdpass.h"
68#include "misc.h"
69
70#include "channels.h"
71#include "session.h"
72#include "servconf.h"
73#include "monitor_wrap.h"
74#include "srclimit.h"
75
76#include "ssherr.h"
77
78/* Imports */
79extern struct monitor *pmonitor;
80extern struct sshbuf *loginmsg;
81extern ServerOptions options;
82
83void
84mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx)
85{
86 struct sshbuf *log_msg;
87 struct monitor *mon = (struct monitor *)ctx;
88 int r;
89 size_t len;
90
91 if (mon->m_log_sendfd == -1)
92 fatal_f("no log channel");
93
94 if ((log_msg = sshbuf_new()) == NULL)
95 fatal_f("sshbuf_new failed");
96
97 if ((r = sshbuf_put_u32(log_msg, 0)) != 0 || /* length; filled below */
98 (r = sshbuf_put_u32(log_msg, level)) != 0 ||
99 (r = sshbuf_put_u32(log_msg, forced)) != 0 ||
100 (r = sshbuf_put_cstring(log_msg, msg)) != 0)
101 fatal_fr(r, "assemble");
102 if ((len = sshbuf_len(log_msg)) < 4 || len > 0xffffffff)
103 fatal_f("bad length %zu", len);
104 POKE_U32(sshbuf_mutable_ptr(log_msg), len - 4);
105 if (atomicio(vwrite, mon->m_log_sendfd,
106 sshbuf_mutable_ptr(log_msg), len) != len) {
107 if (errno == EPIPE) {
108 debug_f("write: %s", strerror(errno));
109 cleanup_exit(255);
110 }
111 fatal_f("write: %s", strerror(errno));
112 }
113 sshbuf_free(log_msg);
114}
115
116static void
117mm_reap(void)
118{
119 int status = -1;
120
121 if (!mm_is_monitor())
122 return;
123 while (waitpid(pmonitor->m_pid, &status, 0) == -1) {
124 if (errno == EINTR)
125 continue;
126 pmonitor->m_pid = -1;
127 fatal_f("waitpid: %s", strerror(errno));
128 }
129 if (WIFEXITED(status)) {
130 if (WEXITSTATUS(status) != 0) {
131 debug_f("child exited with status %d",
132 WEXITSTATUS(status));
133 cleanup_exit(255);
134 }
135 } else if (WIFSIGNALED(status)) {
136 error_f("child terminated by signal %d",
137 WTERMSIG(status));
138 cleanup_exit(signal_is_crash(WTERMSIG(status)) ?
139 EXIT_CHILD_CRASH : 255);
140 } else {
141 error_f("child terminated abnormally (status=0x%x)",
142 status);
143 cleanup_exit(EXIT_CHILD_CRASH);
144 }
145}
146
147void
148mm_request_send(int sock, enum monitor_reqtype type, struct sshbuf *m)
149{
150 size_t mlen = sshbuf_len(m);
151 u_char buf[5];
152
153 debug3_f("entering, type %d", type);
154
155 if (mlen >= MONITOR_MAX_MSGLEN)
156 fatal_f("bad length %zu", mlen);
157 POKE_U32(buf, mlen + 1);
158 buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */
159 if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf) ||
160 atomicio(vwrite, sock, sshbuf_mutable_ptr(m), mlen) != mlen) {
161 if (errno == EPIPE) {
162 debug3_f("monitor fd closed");
163 mm_reap();
164 cleanup_exit(255);
165 }
166 fatal_f("write: %s", strerror(errno));
167 }
168}
169
170void
171mm_request_receive(int sock, struct sshbuf *m)
172{
173 u_char buf[4], *p = NULL;
174 u_int msg_len;
175 int oerrno, r;
176
177 debug3_f("entering");
178
179 if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
180 if (errno == EPIPE) {
181 debug3_f("monitor fd closed");
182 mm_reap();
183 cleanup_exit(255);
184 }
185 fatal_f("read: %s", strerror(errno));
186 }
187 msg_len = PEEK_U32(buf);
188 if (msg_len > MONITOR_MAX_MSGLEN)
189 fatal_f("read: bad msg_len %d", msg_len);
190 sshbuf_reset(m);
191 if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
192 fatal_fr(r, "reserve");
193 if (atomicio(read, sock, p, msg_len) != msg_len) {
194 oerrno = errno;
195 error_f("read: %s", strerror(errno));
196 if (oerrno == EPIPE)
197 mm_reap();
198 cleanup_exit(255);
199 }
200}
201
202void
203mm_request_receive_expect(int sock, enum monitor_reqtype type, struct sshbuf *m)
204{
205 u_char rtype;
206 int r;
207
208 debug3_f("entering, type %d", type);
209
210 mm_request_receive(sock, m);
211 if ((r = sshbuf_get_u8(m, &rtype)) != 0)
212 fatal_fr(r, "parse");
213 if (rtype != type)
214 fatal_f("read: rtype %d != type %d", rtype, type);
215}
216
217#ifdef WITH_OPENSSL
218DH *
219mm_choose_dh(int min, int nbits, int max)
220{
221 BIGNUM *p, *g;
222 int r;
223 u_char success = 0;
224 struct sshbuf *m;
225
226 if ((m = sshbuf_new()) == NULL)
227 fatal_f("sshbuf_new failed");
228 if ((r = sshbuf_put_u32(m, min)) != 0 ||
229 (r = sshbuf_put_u32(m, nbits)) != 0 ||
230 (r = sshbuf_put_u32(m, max)) != 0)
231 fatal_fr(r, "assemble");
232
233 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, m);
234
235 debug3_f("waiting for MONITOR_ANS_MODULI");
236 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, m);
237
238 if ((r = sshbuf_get_u8(m, &success)) != 0)
239 fatal_fr(r, "parse success");
240 if (success == 0)
241 fatal_f("MONITOR_ANS_MODULI failed");
242
243 if ((r = sshbuf_get_bignum2(m, &p)) != 0 ||
244 (r = sshbuf_get_bignum2(m, &g)) != 0)
245 fatal_fr(r, "parse group");
246
247 debug3_f("remaining %zu", sshbuf_len(m));
248 sshbuf_free(m);
249
250 return (dh_new_group(g, p));
251}
252#endif
253
254int
255mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
256 const u_char *data, size_t datalen, const char *hostkey_alg,
257 const char *sk_provider, const char *sk_pin, u_int compat)
258{
259 struct sshbuf *m;
260 int r;
261
262 debug3_f("entering");
263 if ((m = sshbuf_new()) == NULL)
264 fatal_f("sshbuf_new failed");
265 if ((r = sshkey_puts(key, m)) != 0 ||
266 (r = sshbuf_put_string(m, data, datalen)) != 0 ||
267 (r = sshbuf_put_cstring(m, hostkey_alg)) != 0 ||
268 (r = sshbuf_put_u32(m, compat)) != 0)
269 fatal_fr(r, "assemble");
270
271 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, m);
272
273 debug3_f("waiting for MONITOR_ANS_SIGN");
274 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, m);
275 if ((r = sshbuf_get_string(m, sigp, lenp)) != 0)
276 fatal_fr(r, "parse");
277 sshbuf_free(m);
278 debug3_f("%s signature len=%zu", hostkey_alg ? hostkey_alg : "(null)",
279 *lenp);
280
281 return (0);
282}
283
284void
285mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m)
286{
287 const u_char *p;
288 size_t len;
289 u_int i;
290 ServerOptions *newopts;
291 int r;
292
293 if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0)
294 fatal_fr(r, "parse opts");
295 if (len != sizeof(*newopts))
296 fatal_f("option block size mismatch");
297 newopts = xcalloc(sizeof(*newopts), 1);
298 memcpy(newopts, p, sizeof(*newopts));
299
300#define M_CP_STROPT(x) do { \
301 if (newopts->x != NULL && \
302 (r = sshbuf_get_cstring(m, &newopts->x, NULL)) != 0) \
303 fatal_fr(r, "parse %s", #x); \
304 } while (0)
305#define M_CP_STRARRAYOPT(x, nx, clobber) do { \
306 newopts->x = newopts->nx == 0 ? \
307 NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
308 for (i = 0; i < newopts->nx; i++) { \
309 if ((r = sshbuf_get_cstring(m, \
310 &newopts->x[i], NULL)) != 0) \
311 fatal_fr(r, "parse %s", #x); \
312 } \
313 } while (0)
314 /* See comment in servconf.h */
315 COPY_MATCH_STRING_OPTS();
316#undef M_CP_STROPT
317#undef M_CP_STRARRAYOPT
318
319 copy_set_server_options(&options, newopts, 1);
320 log_change_level(options.log_level);
321 log_verbose_reset();
322 for (i = 0; i < options.num_log_verbose; i++)
323 log_verbose_add(options.log_verbose[i]);
324
325 /* use the macro hell to clean up too */
326#define M_CP_STROPT(x) free(newopts->x)
327#define M_CP_STRARRAYOPT(x, nx, clobber) do { \
328 for (i = 0; i < newopts->nx; i++) \
329 free(newopts->x[i]); \
330 free(newopts->x); \
331 } while (0)
332 COPY_MATCH_STRING_OPTS();
333#undef M_CP_STROPT
334#undef M_CP_STRARRAYOPT
335 free(newopts);
336}
337
338#define GETPW(b, id) \
339 do { \
340 if ((r = sshbuf_get_string_direct(b, &p, &len)) != 0) \
341 fatal_fr(r, "parse pw %s", #id); \
342 if (len != sizeof(pw->id)) \
343 fatal_fr(r, "bad length for %s", #id); \
344 memcpy(&pw->id, p, len); \
345 } while (0)
346
347struct passwd *
348mm_getpwnamallow(struct ssh *ssh, const char *username)
349{
350 struct sshbuf *m;
351 struct passwd *pw;
352 size_t len;
353 int r;
354 u_char ok;
355 const u_char *p;
356
357 debug3_f("entering");
358
359 if ((m = sshbuf_new()) == NULL)
360 fatal_f("sshbuf_new failed");
361 if ((r = sshbuf_put_cstring(m, username)) != 0)
362 fatal_fr(r, "assemble");
363
364 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, m);
365
366 debug3_f("waiting for MONITOR_ANS_PWNAM");
367 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, m);
368
369 if ((r = sshbuf_get_u8(m, &ok)) != 0)
370 fatal_fr(r, "parse success");
371 if (ok == 0) {
372 pw = NULL;
373 goto out;
374 }
375
376 pw = xcalloc(sizeof(*pw), 1);
377 GETPW(m, pw_uid);
378 GETPW(m, pw_gid);
379 GETPW(m, pw_change);
380 GETPW(m, pw_expire);
381 if ((r = sshbuf_get_cstring(m, &pw->pw_name, NULL)) != 0 ||
382 (r = sshbuf_get_cstring(m, &pw->pw_passwd, NULL)) != 0 ||
383 (r = sshbuf_get_cstring(m, &pw->pw_gecos, NULL)) != 0 ||
384 (r = sshbuf_get_cstring(m, &pw->pw_class, NULL)) != 0 ||
385 (r = sshbuf_get_cstring(m, &pw->pw_dir, NULL)) != 0 ||
386 (r = sshbuf_get_cstring(m, &pw->pw_shell, NULL)) != 0)
387 fatal_fr(r, "parse pw");
388
389out:
390 /* copy options block as a Match directive may have changed some */
391 mm_decode_activate_server_options(ssh, m);
392 server_process_permitopen(ssh);
393 server_process_channel_timeouts(ssh);
394 kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos);
395 sshbuf_free(m);
396
397 return (pw);
398}
399
400char *
401mm_auth2_read_banner(void)
402{
403 struct sshbuf *m;
404 char *banner;
405 int r;
406
407 debug3_f("entering");
408
409 if ((m = sshbuf_new()) == NULL)
410 fatal_f("sshbuf_new failed");
411 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, m);
412 sshbuf_reset(m);
413
414 mm_request_receive_expect(pmonitor->m_recvfd,
415 MONITOR_ANS_AUTH2_READ_BANNER, m);
416 if ((r = sshbuf_get_cstring(m, &banner, NULL)) != 0)
417 fatal_fr(r, "parse");
418 sshbuf_free(m);
419
420 /* treat empty banner as missing banner */
421 if (strlen(banner) == 0) {
422 free(banner);
423 banner = NULL;
424 }
425 return (banner);
426}
427
428/* Inform the privileged process about service and style */
429
430void
431mm_inform_authserv(char *service, char *style)
432{
433 struct sshbuf *m;
434 int r;
435
436 debug3_f("entering");
437
438 if ((m = sshbuf_new()) == NULL)
439 fatal_f("sshbuf_new failed");
440 if ((r = sshbuf_put_cstring(m, service)) != 0 ||
441 (r = sshbuf_put_cstring(m, style ? style : "")) != 0)
442 fatal_fr(r, "assemble");
443
444 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m);
445
446 sshbuf_free(m);
447}
448
449/* Do the password authentication */
450int
451mm_auth_password(struct ssh *ssh, char *password)
452{
453 struct sshbuf *m;
454 int r, authenticated = 0;
455
456 debug3_f("entering");
457
458 if ((m = sshbuf_new()) == NULL)
459 fatal_f("sshbuf_new failed");
460 if ((r = sshbuf_put_cstring(m, password)) != 0)
461 fatal_fr(r, "assemble");
462 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, m);
463
464 debug3_f("waiting for MONITOR_ANS_AUTHPASSWORD");
465 mm_request_receive_expect(pmonitor->m_recvfd,
466 MONITOR_ANS_AUTHPASSWORD, m);
467
468 if ((r = sshbuf_get_u32(m, &authenticated)) != 0)
469 fatal_fr(r, "parse");
470
471 sshbuf_free(m);
472
473 debug3_f("user %sauthenticated", authenticated ? "" : "not ");
474 return (authenticated);
475}
476
477int
478mm_user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
479 int pubkey_auth_attempt, struct sshauthopt **authoptp)
480{
481 return (mm_key_allowed(MM_USERKEY, NULL, NULL, key,
482 pubkey_auth_attempt, authoptp));
483}
484
485int
486mm_hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
487 const char *user, const char *host, struct sshkey *key)
488{
489 return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0, NULL));
490}
491
492int
493mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
494 struct sshkey *key, int pubkey_auth_attempt, struct sshauthopt **authoptp)
495{
496 struct sshbuf *m;
497 int r, allowed = 0;
498 struct sshauthopt *opts = NULL;
499
500 debug3_f("entering");
501
502 if (authoptp != NULL)
503 *authoptp = NULL;
504
505 if ((m = sshbuf_new()) == NULL)
506 fatal_f("sshbuf_new failed");
507 if ((r = sshbuf_put_u32(m, type)) != 0 ||
508 (r = sshbuf_put_cstring(m, user ? user : "")) != 0 ||
509 (r = sshbuf_put_cstring(m, host ? host : "")) != 0 ||
510 (r = sshkey_puts(key, m)) != 0 ||
511 (r = sshbuf_put_u32(m, pubkey_auth_attempt)) != 0)
512 fatal_fr(r, "assemble");
513
514 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, m);
515
516 debug3_f("waiting for MONITOR_ANS_KEYALLOWED");
517 mm_request_receive_expect(pmonitor->m_recvfd,
518 MONITOR_ANS_KEYALLOWED, m);
519
520 if ((r = sshbuf_get_u32(m, &allowed)) != 0)
521 fatal_fr(r, "parse");
522 if (allowed && type == MM_USERKEY &&
523 (r = sshauthopt_deserialise(m, &opts)) != 0)
524 fatal_fr(r, "sshauthopt_deserialise");
525 sshbuf_free(m);
526
527 if (authoptp != NULL) {
528 *authoptp = opts;
529 opts = NULL;
530 }
531 sshauthopt_free(opts);
532
533 return allowed;
534}
535
536/*
537 * This key verify needs to send the key type along, because the
538 * privileged parent makes the decision if the key is allowed
539 * for authentication.
540 */
541
542int
543mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
544 const u_char *data, size_t datalen, const char *sigalg, u_int compat,
545 struct sshkey_sig_details **sig_detailsp)
546{
547 struct sshbuf *m;
548 u_int encoded_ret = 0;
549 int r;
550 u_char sig_details_present, flags;
551 u_int counter;
552
553 debug3_f("entering");
554
555 if (sig_detailsp != NULL)
556 *sig_detailsp = NULL;
557 if ((m = sshbuf_new()) == NULL)
558 fatal_f("sshbuf_new failed");
559 if ((r = sshkey_puts(key, m)) != 0 ||
560 (r = sshbuf_put_string(m, sig, siglen)) != 0 ||
561 (r = sshbuf_put_string(m, data, datalen)) != 0 ||
562 (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0)
563 fatal_fr(r, "assemble");
564
565 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, m);
566
567 debug3_f("waiting for MONITOR_ANS_KEYVERIFY");
568 mm_request_receive_expect(pmonitor->m_recvfd,
569 MONITOR_ANS_KEYVERIFY, m);
570
571 if ((r = sshbuf_get_u32(m, &encoded_ret)) != 0 ||
572 (r = sshbuf_get_u8(m, &sig_details_present)) != 0)
573 fatal_fr(r, "parse");
574 if (sig_details_present && encoded_ret == 0) {
575 if ((r = sshbuf_get_u32(m, &counter)) != 0 ||
576 (r = sshbuf_get_u8(m, &flags)) != 0)
577 fatal_fr(r, "parse sig_details");
578 if (sig_detailsp != NULL) {
579 *sig_detailsp = xcalloc(1, sizeof(**sig_detailsp));
580 (*sig_detailsp)->sk_counter = counter;
581 (*sig_detailsp)->sk_flags = flags;
582 }
583 }
584
585 sshbuf_free(m);
586
587 if (encoded_ret != 0)
588 return SSH_ERR_SIGNATURE_INVALID;
589 return 0;
590}
591
592void
593mm_send_keystate(struct ssh *ssh, struct monitor *monitor)
594{
595 struct sshbuf *m;
596 int r;
597
598 if ((m = sshbuf_new()) == NULL)
599 fatal_f("sshbuf_new failed");
600 if ((r = ssh_packet_get_state(ssh, m)) != 0)
601 fatal_fr(r, "ssh_packet_get_state");
602 mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m);
603 debug3_f("Finished sending state");
604 sshbuf_free(m);
605}
606
607int
608mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
609{
610 struct sshbuf *m;
611 char *p, *msg;
612 int success = 0, tmp1 = -1, tmp2 = -1, r;
613
614 /* Kludge: ensure there are fds free to receive the pty/tty */
615 if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 ||
616 (tmp2 = dup(pmonitor->m_recvfd)) == -1) {
617 error_f("cannot allocate fds for pty");
618 if (tmp1 >= 0)
619 close(tmp1);
620 return 0;
621 }
622 close(tmp1);
623 close(tmp2);
624
625 if ((m = sshbuf_new()) == NULL)
626 fatal_f("sshbuf_new failed");
627 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, m);
628
629 debug3_f("waiting for MONITOR_ANS_PTY");
630 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, m);
631
632 if ((r = sshbuf_get_u32(m, &success)) != 0)
633 fatal_fr(r, "parse success");
634 if (success == 0) {
635 debug3_f("pty alloc failed");
636 sshbuf_free(m);
637 return (0);
638 }
639 if ((r = sshbuf_get_cstring(m, &p, NULL)) != 0 ||
640 (r = sshbuf_get_cstring(m, &msg, NULL)) != 0)
641 fatal_fr(r, "parse");
642 sshbuf_free(m);
643
644 strlcpy(namebuf, p, namebuflen); /* Possible truncation */
645 free(p);
646
647 if ((r = sshbuf_put(loginmsg, msg, strlen(msg))) != 0)
648 fatal_fr(r, "put loginmsg");
649 free(msg);
650
651 if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
652 (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
653 fatal_f("receive fds failed");
654
655 /* Success */
656 return (1);
657}
658
659void
660mm_session_pty_cleanup2(Session *s)
661{
662 struct sshbuf *m;
663 int r;
664
665 if (s->ttyfd == -1)
666 return;
667 if ((m = sshbuf_new()) == NULL)
668 fatal_f("sshbuf_new failed");
669 if ((r = sshbuf_put_cstring(m, s->tty)) != 0)
670 fatal_fr(r, "assmble");
671 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, m);
672 sshbuf_free(m);
673
674 /* closed dup'ed master */
675 if (s->ptymaster != -1 && close(s->ptymaster) == -1)
676 error("close(s->ptymaster/%d): %s",
677 s->ptymaster, strerror(errno));
678
679 /* unlink pty from session */
680 s->ttyfd = -1;
681}
682
683/* Request process termination */
684
685void
686mm_terminate(void)
687{
688 struct sshbuf *m;
689
690 if ((m = sshbuf_new()) == NULL)
691 fatal_f("sshbuf_new failed");
692 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, m);
693 sshbuf_free(m);
694}
695
696/* Request state information */
697
698void
699mm_get_state(struct ssh *ssh, struct include_list *includes,
700 struct sshbuf *conf, struct sshbuf **confdatap,
701 uint64_t *timing_secretp,
702 struct sshbuf **hostkeysp, struct sshbuf **keystatep,
703 u_char **pw_namep,
704 struct sshbuf **authinfop, struct sshbuf **auth_optsp)
705{
706 struct sshbuf *m, *inc;
707 u_char *cp;
708 size_t len;
709 int r;
710 struct include_item *item;
711
712 debug3_f("entering");
713
714 if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
715 fatal_f("sshbuf_new failed");
716
717 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_STATE, m);
718
719 debug3_f("waiting for MONITOR_ANS_STATE");
720 mm_request_receive_expect(pmonitor->m_recvfd,
721 MONITOR_ANS_STATE, m);
722
723 if ((r = sshbuf_get_string(m, &cp, &len)) != 0 ||
724 (r = sshbuf_get_u64(m, timing_secretp)) != 0 ||
725 (r = sshbuf_froms(m, hostkeysp)) != 0 ||
726 (r = sshbuf_get_stringb(m, ssh->kex->server_version)) != 0 ||
727 (r = sshbuf_get_stringb(m, ssh->kex->client_version)) != 0 ||
728 (r = sshbuf_get_stringb(m, inc)) != 0)
729 fatal_fr(r, "parse config");
730
731 /* postauth */
732 if (confdatap) {
733 if ((r = sshbuf_froms(m, confdatap)) != 0 ||
734 (r = sshbuf_froms(m, keystatep)) != 0 ||
735 (r = sshbuf_get_string(m, pw_namep, NULL)) != 0 ||
736 (r = sshbuf_froms(m, authinfop)) != 0 ||
737 (r = sshbuf_froms(m, auth_optsp)) != 0)
738 fatal_fr(r, "parse config postauth");
739 }
740
741 if (conf != NULL && (r = sshbuf_put(conf, cp, len)))
742 fatal_fr(r, "sshbuf_put");
743
744 while (sshbuf_len(inc) != 0) {
745 item = xcalloc(1, sizeof(*item));
746 if ((item->contents = sshbuf_new()) == NULL)
747 fatal_f("sshbuf_new failed");
748 if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 ||
749 (r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 ||
750 (r = sshbuf_get_stringb(inc, item->contents)) != 0)
751 fatal_fr(r, "parse includes");
752 TAILQ_INSERT_TAIL(includes, item, entry);
753 }
754
755 free(cp);
756 sshbuf_free(m);
757 sshbuf_free(inc);
758
759 debug3_f("done");
760}
761
762static void
763mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
764 char ***prompts, u_int **echo_on)
765{
766 *name = xstrdup("");
767 *infotxt = xstrdup("");
768 *numprompts = 1;
769 *prompts = xcalloc(*numprompts, sizeof(char *));
770 *echo_on = xcalloc(*numprompts, sizeof(u_int));
771 (*echo_on)[0] = 0;
772}
773
774int
775mm_bsdauth_query(void *ctx, char **name, char **infotxt,
776 u_int *numprompts, char ***prompts, u_int **echo_on)
777{
778 struct sshbuf *m;
779 u_int success;
780 char *challenge;
781 int r;
782
783 debug3_f("entering");
784
785 if ((m = sshbuf_new()) == NULL)
786 fatal_f("sshbuf_new failed");
787 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, m);
788
789 mm_request_receive_expect(pmonitor->m_recvfd,
790 MONITOR_ANS_BSDAUTHQUERY, m);
791 if ((r = sshbuf_get_u32(m, &success)) != 0)
792 fatal_fr(r, "parse success");
793 if (success == 0) {
794 debug3_f("no challenge");
795 sshbuf_free(m);
796 return (-1);
797 }
798
799 /* Get the challenge, and format the response */
800 if ((r = sshbuf_get_cstring(m, &challenge, NULL)) != 0)
801 fatal_fr(r, "parse challenge");
802 sshbuf_free(m);
803
804 mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
805 (*prompts)[0] = challenge;
806
807 debug3_f("received challenge: %s", challenge);
808
809 return (0);
810}
811
812int
813mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
814{
815 struct sshbuf *m;
816 int r, authok;
817
818 debug3_f("entering");
819 if (numresponses != 1)
820 return (-1);
821
822 if ((m = sshbuf_new()) == NULL)
823 fatal_f("sshbuf_new failed");
824 if ((r = sshbuf_put_cstring(m, responses[0])) != 0)
825 fatal_fr(r, "assemble");
826 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, m);
827
828 mm_request_receive_expect(pmonitor->m_recvfd,
829 MONITOR_ANS_BSDAUTHRESPOND, m);
830
831 if ((r = sshbuf_get_u32(m, &authok)) != 0)
832 fatal_fr(r, "parse");
833 sshbuf_free(m);
834
835 return ((authok == 0) ? -1 : 0);
836}
837
838#ifdef GSSAPI
839OM_uint32
840mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
841{
842 struct sshbuf *m;
843 OM_uint32 major;
844 int r;
845
846 /* Client doesn't get to see the context */
847 *ctx = NULL;
848
849 if ((m = sshbuf_new()) == NULL)
850 fatal_f("sshbuf_new failed");
851 if ((r = sshbuf_put_string(m, goid->elements, goid->length)) != 0)
852 fatal_fr(r, "assemble");
853
854 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, m);
855 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, m);
856
857 if ((r = sshbuf_get_u32(m, &major)) != 0)
858 fatal_fr(r, "parse");
859
860 sshbuf_free(m);
861 return (major);
862}
863
864OM_uint32
865mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
866 gss_buffer_desc *out, OM_uint32 *flagsp)
867{
868 struct sshbuf *m;
869 OM_uint32 major;
870 u_int flags;
871 int r;
872
873 if ((m = sshbuf_new()) == NULL)
874 fatal_f("sshbuf_new failed");
875 if ((r = sshbuf_put_string(m, in->value, in->length)) != 0)
876 fatal_fr(r, "assemble");
877
878 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, m);
879 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, m);
880
881 if ((r = sshbuf_get_u32(m, &major)) != 0 ||
882 (r = ssh_gssapi_get_buffer_desc(m, out)) != 0)
883 fatal_fr(r, "parse");
884 if (flagsp != NULL) {
885 if ((r = sshbuf_get_u32(m, &flags)) != 0)
886 fatal_fr(r, "parse flags");
887 *flagsp = flags;
888 }
889
890 sshbuf_free(m);
891
892 return (major);
893}
894
895OM_uint32
896mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
897{
898 struct sshbuf *m;
899 OM_uint32 major;
900 int r;
901
902 if ((m = sshbuf_new()) == NULL)
903 fatal_f("sshbuf_new failed");
904 if ((r = sshbuf_put_string(m, gssbuf->value, gssbuf->length)) != 0 ||
905 (r = sshbuf_put_string(m, gssmic->value, gssmic->length)) != 0)
906 fatal_fr(r, "assemble");
907
908 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, m);
909 mm_request_receive_expect(pmonitor->m_recvfd,
910 MONITOR_ANS_GSSCHECKMIC, m);
911
912 if ((r = sshbuf_get_u32(m, &major)) != 0)
913 fatal_fr(r, "parse");
914 sshbuf_free(m);
915 return(major);
916}
917
918int
919mm_ssh_gssapi_userok(char *user)
920{
921 struct sshbuf *m;
922 int r, authenticated = 0;
923
924 if ((m = sshbuf_new()) == NULL)
925 fatal_f("sshbuf_new failed");
926
927 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m);
928 mm_request_receive_expect(pmonitor->m_recvfd,
929 MONITOR_ANS_GSSUSEROK, m);
930
931 if ((r = sshbuf_get_u32(m, &authenticated)) != 0)
932 fatal_fr(r, "parse");
933
934 sshbuf_free(m);
935 debug3_f("user %sauthenticated", authenticated ? "" : "not ");
936 return (authenticated);
937}
938#endif /* GSSAPI */
939
940/*
941 * Inform channels layer of permitopen options for a single forwarding
942 * direction (local/remote).
943 */
944static void
945server_process_permitopen_list(struct ssh *ssh, int listen,
946 char **opens, u_int num_opens)
947{
948 u_int i;
949 int port;
950 char *host, *arg, *oarg;
951 int where = listen ? FORWARD_REMOTE : FORWARD_LOCAL;
952 const char *what = listen ? "permitlisten" : "permitopen";
953
954 channel_clear_permission(ssh, FORWARD_ADM, where);
955 if (num_opens == 0)
956 return; /* permit any */
957
958 /* handle keywords: "any" / "none" */
959 if (num_opens == 1 && strcmp(opens[0], "any") == 0)
960 return;
961 if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
962 channel_disable_admin(ssh, where);
963 return;
964 }
965 /* Otherwise treat it as a list of permitted host:port */
966 for (i = 0; i < num_opens; i++) {
967 oarg = arg = xstrdup(opens[i]);
968 host = hpdelim(&arg);
969 if (host == NULL)
970 fatal_f("missing host in %s", what);
971 host = cleanhostname(host);
972 if (arg == NULL || ((port = permitopen_port(arg)) < 0))
973 fatal_f("bad port number in %s", what);
974 /* Send it to channels layer */
975 channel_add_permission(ssh, FORWARD_ADM,
976 where, host, port);
977 free(oarg);
978 }
979}
980
981/*
982 * Inform channels layer of permitopen options from configuration.
983 */
984void
985server_process_permitopen(struct ssh *ssh)
986{
987 server_process_permitopen_list(ssh, 0,
988 options.permitted_opens, options.num_permitted_opens);
989 server_process_permitopen_list(ssh, 1,
990 options.permitted_listens, options.num_permitted_listens);
991}
992
993void
994server_process_channel_timeouts(struct ssh *ssh)
995{
996 u_int i, secs;
997 char *type;
998
999 debug3_f("setting %u timeouts", options.num_channel_timeouts);
1000 channel_clear_timeouts(ssh);
1001 for (i = 0; i < options.num_channel_timeouts; i++) {
1002 if (parse_pattern_interval(options.channel_timeouts[i],
1003 &type, &secs) != 0) {
1004 fatal_f("internal error: bad timeout %s",
1005 options.channel_timeouts[i]);
1006 }
1007 channel_add_timeout(ssh, type, secs);
1008 free(type);
1009 }
1010}
1011
1012struct connection_info *
1013server_get_connection_info(struct ssh *ssh, int populate, int use_dns)
1014{
1015 static struct connection_info ci;
1016
1017 if (ssh == NULL || !populate)
1018 return &ci;
1019 ci.host = use_dns ? ssh_remote_hostname(ssh) : ssh_remote_ipaddr(ssh);
1020 ci.address = ssh_remote_ipaddr(ssh);
1021 ci.laddress = ssh_local_ipaddr(ssh);
1022 ci.lport = ssh_local_port(ssh);
1023 ci.rdomain = ssh_packet_rdomain_in(ssh);
1024 return &ci;
1025}
1026