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