1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
5  * Authors: Doug Rabson <dfr@rabson.org>
6  * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 /*
31  * Extensively modified from /usr/src/usr.sbin/gssd.c r344402 for
32  * the server side of kernel RPC-over-TLS by Rick Macklem.
33  */
34 
35 #include <sys/cdefs.h>
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/linker.h>
39 #include <sys/module.h>
40 #include <sys/queue.h>
41 #include <sys/stat.h>
42 #include <sys/sysctl.h>
43 #include <sys/syslog.h>
44 #include <sys/time.h>
45 #include <sys/wait.h>
46 #include <err.h>
47 #include <getopt.h>
48 #include <libutil.h>
49 #include <netdb.h>
50 #include <pwd.h>
51 #include <signal.h>
52 #include <stdarg.h>
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <stdbool.h>
56 #include <string.h>
57 #include <unistd.h>
58 
59 #include <rpc/rpc.h>
60 #include <rpc/rpc_com.h>
61 #include <rpc/rpcsec_tls.h>
62 
63 #include <openssl/opensslconf.h>
64 #include <openssl/bio.h>
65 #include <openssl/ssl.h>
66 #include <openssl/err.h>
67 #include <openssl/x509v3.h>
68 
69 #include "rpctlssd.h"
70 #include "rpc.tlscommon.h"
71 
72 #ifndef _PATH_RPCTLSSDSOCK
73 #define _PATH_RPCTLSSDSOCK	"/var/run/rpc.tlsservd.sock"
74 #endif
75 #ifndef	_PATH_CERTANDKEY
76 #define	_PATH_CERTANDKEY	"/etc/rpc.tlsservd/"
77 #endif
78 #ifndef	_PATH_RPCTLSSDPID
79 #define	_PATH_RPCTLSSDPID	"/var/run/rpc.tlsservd.pid"
80 #endif
81 #ifndef	_PREFERRED_CIPHERS
82 #define	_PREFERRED_CIPHERS	"AES128-GCM-SHA256"
83 #endif
84 
85 /* Global variables also used by rpc.tlscommon.c. */
86 int			rpctls_debug_level;
87 bool			rpctls_verbose;
88 SSL_CTX			*rpctls_ctx = NULL;
89 const char		*rpctls_verify_cafile = NULL;
90 const char		*rpctls_verify_capath = NULL;
91 char			*rpctls_crlfile = NULL;
92 bool			rpctls_gothup = false;
93 struct ssl_list		rpctls_ssllist;
94 
95 static struct pidfh	*rpctls_pfh = NULL;
96 static bool		rpctls_do_mutual = false;
97 static const char	*rpctls_certdir = _PATH_CERTANDKEY;
98 static bool		rpctls_comparehost = false;
99 static unsigned int	rpctls_wildcard = X509_CHECK_FLAG_NO_WILDCARDS;
100 static uint64_t		rpctls_ssl_refno = 0;
101 static uint64_t		rpctls_ssl_sec = 0;
102 static uint64_t		rpctls_ssl_usec = 0;
103 static bool		rpctls_cnuser = false;
104 static char		*rpctls_dnsname;
105 static const char	*rpctls_cnuseroid = "1.3.6.1.4.1.2238.1.1.1";
106 static const char	*rpctls_ciphers = NULL;
107 static int		rpctls_mintls = TLS1_3_VERSION;
108 static int		rpctls_procs = 1;
109 static char		*rpctls_sockname[RPCTLS_SRV_MAXNPROCS];
110 static pid_t		rpctls_workers[RPCTLS_SRV_MAXNPROCS - 1];
111 static bool		rpctls_im_a_worker = false;
112 
113 static void		rpctls_cleanup_term(int sig);
114 static SSL_CTX		*rpctls_setup_ssl(const char *certdir);
115 static SSL		*rpctls_server(SSL_CTX *ctx, int s,
116 			    uint32_t *flags, uint32_t *uidp,
117 			    int *ngrps, uint32_t *gidp, X509 **certp);
118 static int		rpctls_cnname(X509 *cert, uint32_t *uidp,
119 			    int *ngrps, uint32_t *gidp);
120 static char		*rpctls_getdnsname(char *dnsname);
121 static void		rpctls_huphandler(int sig __unused);
122 
123 extern void		rpctlssd_1(struct svc_req *rqstp, SVCXPRT *transp);
124 
125 static struct option longopts[] = {
126 	{ "allowtls1_2",	no_argument,		NULL,	'2' },
127 	{ "ciphers",		required_argument,	NULL,	'C' },
128 	{ "certdir",		required_argument,	NULL,	'D' },
129 	{ "debuglevel",		no_argument,		NULL,	'd' },
130 	{ "checkhost",		no_argument,		NULL,	'h' },
131 	{ "verifylocs",		required_argument,	NULL,	'l' },
132 	{ "mutualverf",		no_argument,		NULL,	'm' },
133 	{ "numdaemons",		required_argument,	NULL,	'N' },
134 	{ "domain",		required_argument,	NULL,	'n' },
135 	{ "verifydir",		required_argument,	NULL,	'p' },
136 	{ "crl",		required_argument,	NULL,	'r' },
137 	{ "certuser",		no_argument,		NULL,	'u' },
138 	{ "verbose",		no_argument,		NULL,	'v' },
139 	{ "multiwild",		no_argument,		NULL,	'W' },
140 	{ "singlewild",		no_argument,		NULL,	'w' },
141 	{ NULL,			0,			NULL,	0  }
142 };
143 
144 int
145 main(int argc, char **argv)
146 {
147 	/*
148 	 * We provide an RPC service on a local-domain socket. The
149 	 * kernel rpctls code will upcall to this daemon to do the initial
150 	 * TLS handshake.
151 	 */
152 	struct sockaddr_un sun;
153 	int ch, fd, i, mypos, oldmask;
154 	SVCXPRT *xprt;
155 	struct timeval tm;
156 	struct timezone tz;
157 	char hostname[MAXHOSTNAMELEN + 2];
158 	pid_t otherpid;
159 	bool tls_enable;
160 	size_t tls_enable_len;
161 	sigset_t signew;
162 
163 	/* Check that another rpctlssd isn't already running. */
164 	rpctls_pfh = pidfile_open(_PATH_RPCTLSSDPID, 0600, &otherpid);
165 	if (rpctls_pfh == NULL) {
166 		if (errno == EEXIST)
167 			errx(1, "rpctlssd already running, pid: %d.", otherpid);
168 		warn("cannot open or create pidfile");
169 	}
170 
171 	/* Check to see that the ktls is enabled. */
172 	tls_enable_len = sizeof(tls_enable);
173 	if (sysctlbyname("kern.ipc.tls.enable", &tls_enable, &tls_enable_len,
174 	    NULL, 0) != 0 || !tls_enable)
175 		errx(1, "Kernel TLS not enabled");
176 
177 	/* Get the time when this daemon is started. */
178 	gettimeofday(&tm, &tz);
179 	rpctls_ssl_sec = tm.tv_sec;
180 	rpctls_ssl_usec = tm.tv_usec;
181 
182 	/* Set the dns name for the server. */
183 	rpctls_dnsname = rpctls_getdnsname(hostname);
184 	if (rpctls_dnsname == NULL) {
185 		strcpy(hostname, "@default.domain");
186 		rpctls_dnsname = hostname;
187 	}
188 
189 	/* Initialize socket names. */
190 	for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++) {
191 		asprintf(&rpctls_sockname[i], "%s.%d", _PATH_RPCTLSSDSOCK, i);
192 		if (rpctls_sockname[i] == NULL)
193 			errx(1, "Cannot malloc socknames");
194 	}
195 
196 	rpctls_verbose = false;
197 	while ((ch = getopt_long(argc, argv, "2C:D:dhl:N:n:mp:r:uvWw", longopts,
198 	    NULL)) != -1) {
199 		switch (ch) {
200 		case '2':
201 			rpctls_mintls = TLS1_2_VERSION;
202 			break;
203 		case 'C':
204 			rpctls_ciphers = optarg;
205 			break;
206 		case 'D':
207 			rpctls_certdir = optarg;
208 			break;
209 		case 'd':
210 			rpctls_debug_level++;
211 			break;
212 		case 'h':
213 			rpctls_comparehost = true;
214 			break;
215 		case 'l':
216 			rpctls_verify_cafile = optarg;
217 			break;
218 		case 'm':
219 			rpctls_do_mutual = true;
220 			break;
221 		case 'N':
222 			rpctls_procs = atoi(optarg);
223 			if (rpctls_procs < 1 ||
224 			    rpctls_procs > RPCTLS_SRV_MAXNPROCS)
225 				errx(1, "numdaemons/-N must be between 1 and "
226 				    "%d", RPCTLS_SRV_MAXNPROCS);
227 			break;
228 		case 'n':
229 			hostname[0] = '@';
230 			strlcpy(&hostname[1], optarg, MAXHOSTNAMELEN + 1);
231 			rpctls_dnsname = hostname;
232 			break;
233 		case 'p':
234 			rpctls_verify_capath = optarg;
235 			break;
236 		case 'r':
237 			rpctls_crlfile = optarg;
238 			break;
239 		case 'u':
240 			rpctls_cnuser = true;
241 			break;
242 		case 'v':
243 			rpctls_verbose = true;
244 			break;
245 		case 'W':
246 			if (rpctls_wildcard != X509_CHECK_FLAG_NO_WILDCARDS)
247 				errx(1, "options -w and -W are mutually "
248 				    "exclusive");
249 			rpctls_wildcard = X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS;
250 			break;
251 		case 'w':
252 			if (rpctls_wildcard != X509_CHECK_FLAG_NO_WILDCARDS)
253 				errx(1, "options -w and -W are mutually "
254 				    "exclusive");
255 			rpctls_wildcard = 0;
256 			break;
257 		default:
258 			fprintf(stderr, "usage: %s "
259 			    "[-2/--allowtls1_2] "
260 			    "[-C/--ciphers available_ciphers] "
261 			    "[-D/--certdir certdir] [-d/--debuglevel] "
262 			    "[-h/--checkhost] "
263 			    "[-l/--verifylocs CAfile] [-m/--mutualverf] "
264 			    "[-N/--numdaemons num] "
265 			    "[-n/--domain domain_name] "
266 			    "[-p/--verifydir CApath] [-r/--crl CRLfile] "
267 			    "[-u/--certuser] [-v/--verbose] [-W/--multiwild] "
268 			    "[-w/--singlewild]\n", argv[0]);
269 			exit(1);
270 		}
271 	}
272 	if (rpctls_do_mutual && rpctls_verify_cafile == NULL &&
273 	    rpctls_verify_capath == NULL)
274 		errx(1, "-m requires the -l <CAfile> and/or "
275 		    "-p <CApath> options");
276 	if (rpctls_comparehost && (!rpctls_do_mutual ||
277 	    (rpctls_verify_cafile == NULL && rpctls_verify_capath == NULL)))
278 		errx(1, "-h requires the -m plus the "
279 		    "-l <CAfile> and/or -p <CApath> options");
280 	if (!rpctls_comparehost && rpctls_wildcard !=
281 	    X509_CHECK_FLAG_NO_WILDCARDS)
282 		errx(1, "The -w or -W options require the -h option");
283 	if (rpctls_cnuser && (!rpctls_do_mutual ||
284 	    (rpctls_verify_cafile == NULL && rpctls_verify_capath == NULL)))
285 		errx(1, "-u requires the -m plus the "
286 		    "-l <CAfile> and/or -p <CApath> options");
287 
288 	if (modfind("krpc") < 0) {
289 		/* Not present in kernel, try loading it */
290 		if (kldload("krpc") < 0 || modfind("krpc") < 0)
291 			errx(1, "Kernel RPC is not available");
292 	}
293 
294 	for (i = 0; i < rpctls_procs - 1; i++)
295 		rpctls_workers[i] = -1;
296 	mypos = 0;
297 
298 	if (rpctls_debug_level == 0) {
299 		/*
300 		 * Temporarily block SIGTERM and SIGCHLD, so workers[] can't
301 		 * end up bogus.
302 		 */
303 		sigemptyset(&signew);
304 		sigaddset(&signew, SIGTERM);
305 		sigaddset(&signew, SIGCHLD);
306 		sigprocmask(SIG_BLOCK, &signew, NULL);
307 
308 		if (daemon(0, 0) != 0)
309 			err(1, "Can't daemonize");
310 		signal(SIGINT, SIG_IGN);
311 		signal(SIGQUIT, SIG_IGN);
312 	}
313 	signal(SIGPIPE, SIG_IGN);
314 	signal(SIGHUP, rpctls_huphandler);
315 	signal(SIGTERM, rpctls_cleanup_term);
316 	signal(SIGCHLD, rpctls_cleanup_term);
317 
318 	pidfile_write(rpctls_pfh);
319 
320 	rpctls_syscall(RPCTLS_SYSC_SRVSTARTUP, "");
321 
322 	if (rpctls_debug_level == 0) {
323 		/* Fork off the worker daemons. */
324 		for (i = 0; i < rpctls_procs - 1; i++) {
325 			rpctls_workers[i] = fork();
326 			if (rpctls_workers[i] == 0) {
327 				rpctls_im_a_worker = true;
328 				mypos = i + 1;
329 				setproctitle("server");
330 				break;
331 			} else if (rpctls_workers[i] < 0) {
332 				syslog(LOG_ERR, "fork: %m");
333 			}
334 		}
335 
336 		if (!rpctls_im_a_worker && rpctls_procs > 1)
337 			setproctitle("master");
338 	}
339 	sigemptyset(&signew);
340 	sigaddset(&signew, SIGTERM);
341 	sigaddset(&signew, SIGCHLD);
342 	sigprocmask(SIG_UNBLOCK, &signew, NULL);
343 
344 	memset(&sun, 0, sizeof sun);
345 	sun.sun_family = AF_LOCAL;
346 	unlink(rpctls_sockname[mypos]);
347 	strcpy(sun.sun_path, rpctls_sockname[mypos]);
348 	sun.sun_len = SUN_LEN(&sun);
349 	fd = socket(AF_LOCAL, SOCK_STREAM, 0);
350 	if (fd < 0) {
351 		if (rpctls_debug_level == 0) {
352 			syslog(LOG_ERR, "Can't create local rpctlssd socket");
353 			exit(1);
354 		}
355 		err(1, "Can't create local rpctlssd socket");
356 	}
357 	oldmask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
358 	if (bind(fd, (struct sockaddr *)&sun, sun.sun_len) < 0) {
359 		if (rpctls_debug_level == 0) {
360 			syslog(LOG_ERR, "Can't bind local rpctlssd socket");
361 			exit(1);
362 		}
363 		err(1, "Can't bind local rpctlssd socket");
364 	}
365 	umask(oldmask);
366 	if (listen(fd, SOMAXCONN) < 0) {
367 		if (rpctls_debug_level == 0) {
368 			syslog(LOG_ERR,
369 			    "Can't listen on local rpctlssd socket");
370 			exit(1);
371 		}
372 		err(1, "Can't listen on local rpctlssd socket");
373 	}
374 	xprt = svc_vc_create(fd, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
375 	if (!xprt) {
376 		if (rpctls_debug_level == 0) {
377 			syslog(LOG_ERR,
378 			    "Can't create transport for local rpctlssd socket");
379 			exit(1);
380 		}
381 		err(1, "Can't create transport for local rpctlssd socket");
382 	}
383 	if (!svc_reg(xprt, RPCTLSSD, RPCTLSSDVERS, rpctlssd_1, NULL)) {
384 		if (rpctls_debug_level == 0) {
385 			syslog(LOG_ERR,
386 			    "Can't register service for local rpctlssd socket");
387 			exit(1);
388 		}
389 		err(1, "Can't register service for local rpctlssd socket");
390 	}
391 
392 	rpctls_ctx = rpctls_setup_ssl(rpctls_certdir);
393 	if (rpctls_ctx == NULL) {
394 		if (rpctls_debug_level == 0) {
395 			syslog(LOG_ERR, "Can't create SSL context");
396 			exit(1);
397 		}
398 		err(1, "Can't create SSL context");
399 	}
400 	rpctls_gothup = false;
401 	LIST_INIT(&rpctls_ssllist);
402 
403 	if (rpctls_syscall(RPCTLS_SYSC_SRVSETPATH, rpctls_sockname[mypos]) < 0){
404 		if (rpctls_debug_level == 0) {
405 			syslog(LOG_ERR,
406 			    "Can't set upcall socket path=%s errno=%d",
407 			    rpctls_sockname[mypos], errno);
408 			exit(1);
409 		}
410 		err(1, "Can't set upcall socket path=%s",
411 		    rpctls_sockname[mypos]);
412 	}
413 
414 	rpctls_svc_run();
415 
416 	SSL_CTX_free(rpctls_ctx);
417 	return (0);
418 }
419 
420 bool_t
421 rpctlssd_null_1_svc(__unused void *argp, __unused void *result,
422     __unused struct svc_req *rqstp)
423 {
424 
425 	rpctls_verbose_out("rpctlssd_null_svc: done\n");
426 	return (TRUE);
427 }
428 
429 bool_t
430 rpctlssd_connect_1_svc(__unused void *argp,
431     struct rpctlssd_connect_res *result, __unused struct svc_req *rqstp)
432 {
433 	int ngrps, s;
434 	SSL *ssl;
435 	uint32_t flags;
436 	struct ssl_entry *newslp;
437 	uint32_t uid;
438 	uint32_t *gidp;
439 	X509 *cert;
440 
441 	rpctls_verbose_out("rpctlsd_connect_svc: started\n");
442 	memset(result, 0, sizeof(*result));
443 	/* Get the socket fd from the kernel. */
444 	s = rpctls_syscall(RPCTLS_SYSC_SRVSOCKET, "");
445 	if (s < 0)
446 		return (FALSE);
447 
448 	/* Do the server side of a TLS handshake. */
449 	gidp = calloc(NGROUPS, sizeof(*gidp));
450 	ssl = rpctls_server(rpctls_ctx, s, &flags, &uid, &ngrps, gidp, &cert);
451 	if (ssl == NULL) {
452 		free(gidp);
453 		rpctls_verbose_out("rpctlssd_connect_svc: ssl "
454 		    "accept failed\n");
455 		/*
456 		 * For RPC-over-TLS, this upcall is expected
457 		 * to close off the socket upon handshake failure.
458 		 */
459 		close(s);
460 		return (FALSE);
461 	} else {
462 		rpctls_verbose_out("rpctlssd_connect_svc: "
463 		    "succeeded flags=0x%x\n", flags);
464 		result->flags = flags;
465 		result->sec = rpctls_ssl_sec;
466 		result->usec = rpctls_ssl_usec;
467 		result->ssl = ++rpctls_ssl_refno;
468 		/* Hard to believe this could ever wrap around.. */
469 		if (rpctls_ssl_refno == 0)
470 			result->ssl = ++rpctls_ssl_refno;
471 		if ((flags & RPCTLS_FLAGS_CERTUSER) != 0) {
472 			result->uid = uid;
473 			result->gid.gid_len = ngrps;
474 			result->gid.gid_val = gidp;
475 		} else {
476 			result->uid = 0;
477 			result->gid.gid_len = 0;
478 			result->gid.gid_val = gidp;
479 		}
480 	}
481 
482 	/* Maintain list of all current SSL *'s */
483 	newslp = malloc(sizeof(*newslp));
484 	newslp->ssl = ssl;
485 	newslp->s = s;
486 	newslp->shutoff = false;
487 	newslp->refno = rpctls_ssl_refno;
488 	newslp->cert = cert;
489 	LIST_INSERT_HEAD(&rpctls_ssllist, newslp, next);
490 	return (TRUE);
491 }
492 
493 bool_t
494 rpctlssd_handlerecord_1_svc(struct rpctlssd_handlerecord_arg *argp,
495     struct rpctlssd_handlerecord_res *result, __unused struct svc_req *rqstp)
496 {
497 	struct ssl_entry *slp;
498 	int ret;
499 	char junk;
500 
501 	slp = NULL;
502 	if (argp->sec == rpctls_ssl_sec && argp->usec ==
503 	    rpctls_ssl_usec) {
504 		LIST_FOREACH(slp, &rpctls_ssllist, next) {
505 			if (slp->refno == argp->ssl)
506 				break;
507 		}
508 	}
509 
510 	if (slp != NULL) {
511 		rpctls_verbose_out("rpctlssd_handlerecord fd=%d\n",
512 		    slp->s);
513 		/*
514 		 * An SSL_read() of 0 bytes should fail, but it should
515 		 * handle the non-application data record before doing so.
516 		 */
517 		ret = SSL_read(slp->ssl, &junk, 0);
518 		if (ret <= 0) {
519 			/* Check to see if this was a close alert. */
520 			ret = SSL_get_shutdown(slp->ssl);
521 			if ((ret & (SSL_SENT_SHUTDOWN |
522 			    SSL_RECEIVED_SHUTDOWN)) == SSL_RECEIVED_SHUTDOWN)
523 				SSL_shutdown(slp->ssl);
524 		} else {
525 			if (rpctls_debug_level == 0)
526 				syslog(LOG_ERR, "SSL_read returned %d", ret);
527 			else
528 				fprintf(stderr, "SSL_read returned %d\n", ret);
529 		}
530 		result->reterr = RPCTLSERR_OK;
531 	} else
532 		result->reterr = RPCTLSERR_NOSSL;
533 	return (TRUE);
534 }
535 
536 bool_t
537 rpctlssd_disconnect_1_svc(struct rpctlssd_disconnect_arg *argp,
538     struct rpctlssd_disconnect_res *result, __unused struct svc_req *rqstp)
539 {
540 	struct ssl_entry *slp;
541 	int ret;
542 
543 	slp = NULL;
544 	if (argp->sec == rpctls_ssl_sec && argp->usec ==
545 	    rpctls_ssl_usec) {
546 		LIST_FOREACH(slp, &rpctls_ssllist, next) {
547 			if (slp->refno == argp->ssl)
548 				break;
549 		}
550 	}
551 
552 	if (slp != NULL) {
553 		rpctls_verbose_out("rpctlssd_disconnect fd=%d closed\n",
554 		    slp->s);
555 		LIST_REMOVE(slp, next);
556 		if (!slp->shutoff) {
557 			ret = SSL_get_shutdown(slp->ssl);
558 			/*
559 			 * Do an SSL_shutdown() unless a close alert has
560 			 * already been sent.
561 			 */
562 			if ((ret & SSL_SENT_SHUTDOWN) == 0)
563 				SSL_shutdown(slp->ssl);
564 		}
565 		SSL_free(slp->ssl);
566 		if (slp->cert != NULL)
567 			X509_free(slp->cert);
568 		/*
569 		 * For RPC-over-TLS, this upcall is expected
570 		 * to close off the socket.
571 		 */
572 		if (!slp->shutoff)
573 			shutdown(slp->s, SHUT_WR);
574 		close(slp->s);
575 		free(slp);
576 		result->reterr = RPCTLSERR_OK;
577 	} else
578 		result->reterr = RPCTLSERR_NOCLOSE;
579 	return (TRUE);
580 }
581 
582 int
583 rpctlssd_1_freeresult(__unused SVCXPRT *transp, xdrproc_t xdr_result,
584     caddr_t result)
585 {
586 	rpctlssd_connect_res *res;
587 
588 	if (xdr_result == (xdrproc_t)xdr_rpctlssd_connect_res) {
589 		res = (rpctlssd_connect_res *)(void *)result;
590 		free(res->gid.gid_val);
591 	}
592 	return (TRUE);
593 }
594 
595 /*
596  * cleanup_term() called via SIGTERM (or SIGCHLD if a child dies).
597  */
598 static void
599 rpctls_cleanup_term(int sig)
600 {
601 	struct ssl_entry *slp;
602 	int i, cnt;
603 
604 	if (rpctls_im_a_worker && sig == SIGCHLD)
605 		return;
606 	LIST_FOREACH(slp, &rpctls_ssllist, next)
607 		shutdown(slp->s, SHUT_RD);
608 	SSL_CTX_free(rpctls_ctx);
609 	EVP_cleanup();
610 
611 	if (rpctls_im_a_worker)
612 		exit(0);
613 
614 	/* I'm the server, so terminate the workers. */
615 	cnt = 0;
616 	for (i = 0; i < rpctls_procs - 1; i++) {
617 		if (rpctls_workers[i] != -1) {
618 			cnt++;
619 			kill(rpctls_workers[i], SIGTERM);
620 		}
621 	}
622 
623 	/*
624 	 * Wait for them to die.
625 	 */
626 	for (i = 0; i < cnt; i++)
627 		wait3(NULL, 0, NULL);
628 
629 	rpctls_syscall(RPCTLS_SYSC_SRVSHUTDOWN, "");
630 	pidfile_remove(rpctls_pfh);
631 
632 	exit(0);
633 }
634 
635 /* Allow the handshake to proceed. */
636 static int
637 rpctls_verify_callback(__unused int preverify_ok,
638     __unused X509_STORE_CTX *x509_ctx)
639 {
640 
641 	return (1);
642 }
643 
644 static SSL_CTX *
645 rpctls_setup_ssl(const char *certdir)
646 {
647 	SSL_CTX *ctx;
648 	char path[PATH_MAX];
649 	size_t len, rlen;
650 	int ret;
651 
652 	ctx = SSL_CTX_new(TLS_server_method());
653 	if (ctx == NULL) {
654 		rpctls_verbose_out("rpctls_setup_ssl: SSL_CTX_new failed\n");
655 		return (NULL);
656 	}
657 
658 	if (rpctls_ciphers != NULL) {
659 		/*
660 		 * Set available ciphers, since KERN_TLS only supports a
661 		 * few of them.  Normally, not doing this should be ok,
662 		 * since the library defaults will work.
663 		 */
664 		ret = SSL_CTX_set_ciphersuites(ctx, rpctls_ciphers);
665 		if (ret == 0) {
666 			rpctls_verbose_out("rpctls_setup_ssl: "
667 			    "SSL_CTX_set_ciphersuites failed: %s\n",
668 			    rpctls_ciphers);
669 			SSL_CTX_free(ctx);
670 			return (NULL);
671 		}
672 	}
673 
674 	ret = SSL_CTX_set_min_proto_version(ctx, rpctls_mintls);
675 	if (ret == 0) {
676 		rpctls_verbose_out("rpctls_setup_ssl: "
677 		    "SSL_CTX_set_min_proto_version failed\n");
678 		SSL_CTX_free(ctx);
679 		return (NULL);
680 	}
681 	ret = SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
682 	if (ret == 0) {
683 		rpctls_verbose_out("rpctls_setup_ssl: "
684 		    "SSL_CTX_set_max_proto_version failed\n");
685 		SSL_CTX_free(ctx);
686 		return (NULL);
687 	}
688 
689 	/* Get the cert.pem and certkey.pem files from the directory certdir. */
690 	len = strlcpy(path, certdir, sizeof(path));
691 	rlen = sizeof(path) - len;
692 	if (strlcpy(&path[len], "cert.pem", rlen) != 8) {
693 		SSL_CTX_free(ctx);
694 		return (NULL);
695 	}
696 	ret = SSL_CTX_use_certificate_file(ctx, path, SSL_FILETYPE_PEM);
697 	if (ret != 1) {
698 		rpctls_verbose_out("rpctls_setup_ssl: can't use certificate "
699 		    "file path=%s ret=%d\n", path, ret);
700 		SSL_CTX_free(ctx);
701 		return (NULL);
702 	}
703 	if (strlcpy(&path[len], "certkey.pem", rlen) != 11) {
704 		SSL_CTX_free(ctx);
705 		return (NULL);
706 	}
707 	ret = SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM);
708 	if (ret != 1) {
709 		rpctls_verbose_out("rpctls_setup_ssl: Can't use private "
710 		    "key path=%s ret=%d\n", path, ret);
711 		SSL_CTX_free(ctx);
712 		return (NULL);
713 	}
714 
715 	/* Set Mutual authentication, as required. */
716 	if (rpctls_do_mutual) {
717 		if (rpctls_verify_cafile != NULL ||
718 		    rpctls_verify_capath != NULL) {
719 			if (rpctls_crlfile != NULL) {
720 				ret = rpctls_loadcrlfile(ctx);
721 				if (ret == 0) {
722 					rpctls_verbose_out("rpctls_setup_ssl:"
723 					    " Load CRLfile failed\n");
724 					SSL_CTX_free(ctx);
725 					return (NULL);
726 				}
727 			}
728 #if OPENSSL_VERSION_NUMBER >= 0x30000000
729 			ret = 1;
730 			if (rpctls_verify_cafile != NULL)
731 				ret = SSL_CTX_load_verify_file(ctx,
732 				    rpctls_verify_cafile);
733 			if (ret != 0 && rpctls_verify_capath != NULL)
734 				ret = SSL_CTX_load_verify_dir(ctx,
735 				    rpctls_verify_capath);
736 #else
737 			ret = SSL_CTX_load_verify_locations(ctx,
738 			    rpctls_verify_cafile, rpctls_verify_capath);
739 #endif
740 			if (ret == 0) {
741 				rpctls_verbose_out("rpctls_setup_ssl: "
742 				    "Can't load verify locations\n");
743 				SSL_CTX_free(ctx);
744 				return (NULL);
745 			}
746 			if (rpctls_verify_cafile != NULL)
747 				SSL_CTX_set_client_CA_list(ctx,
748 				    SSL_load_client_CA_file(
749 			    rpctls_verify_cafile));
750 		}
751 		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER,
752 		    rpctls_verify_callback);
753 	}
754 #ifdef SSL_OP_ENABLE_KTLS
755 	SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS);
756 #endif
757 #ifdef SSL_MODE_NO_KTLS_TX
758 	SSL_CTX_clear_mode(ctx, SSL_MODE_NO_KTLS_TX | SSL_MODE_NO_KTLS_RX);
759 #endif
760 	return (ctx);
761 }
762 
763 static SSL *
764 rpctls_server(SSL_CTX *ctx, int s, uint32_t *flags, uint32_t *uidp,
765     int *ngrps, uint32_t *gidp, X509 **certp)
766 {
767 	SSL *ssl;
768 	X509 *cert;
769 	struct sockaddr *sad;
770 	struct sockaddr_storage ad;
771 	char hostnam[NI_MAXHOST];
772 	int gethostret, ret;
773 	char *cp, *cp2;
774 	long verfret;
775 
776 	*flags = 0;
777 	*certp = NULL;
778 	sad = (struct sockaddr *)&ad;
779 	ssl = SSL_new(ctx);
780 	if (ssl == NULL) {
781 		rpctls_verbose_out("rpctls_server: SSL_new failed\n");
782 		return (NULL);
783 	}
784 	if (SSL_set_fd(ssl, s) != 1) {
785 		rpctls_verbose_out("rpctls_server: SSL_set_fd failed\n");
786 		SSL_free(ssl);
787 		return (NULL);
788 	}
789 	ret = SSL_accept(ssl);
790 	if (ret != 1) {
791 		rpctls_verbose_out("rpctls_server: SSL_accept "
792 		    "failed ret=%d\n", ret);
793 		SSL_free(ssl);
794 		return (NULL);
795 	}
796 	*flags |= RPCTLS_FLAGS_HANDSHAKE;
797 	if (rpctls_verbose) {
798 		gethostret = rpctls_gethost(s, sad, hostnam, sizeof(hostnam));
799 		if (gethostret == 0)
800 			hostnam[0] = '\0';
801 		rpctls_verbose_out("rpctls_server: SSL handshake ok for host %s"
802 		    " <%s %s>\n", hostnam, SSL_get_version(ssl),
803 		    SSL_get_cipher(ssl));
804 	}
805 	if (rpctls_do_mutual) {
806 #if OPENSSL_VERSION_NUMBER >= 0x30000000
807 		cert = SSL_get1_peer_certificate(ssl);
808 #else
809 		cert = SSL_get_peer_certificate(ssl);
810 #endif
811 		if (cert != NULL) {
812 			if (!rpctls_verbose) {
813 				gethostret = rpctls_gethost(s, sad, hostnam,
814 				    sizeof(hostnam));
815 				if (gethostret == 0)
816 					hostnam[0] = '\0';
817 			}
818 			cp2 = X509_NAME_oneline(
819 			    X509_get_subject_name(cert), NULL, 0);
820 			*flags |= RPCTLS_FLAGS_GOTCERT;
821 			verfret = SSL_get_verify_result(ssl);
822 			if (verfret != X509_V_OK) {
823 				cp = X509_NAME_oneline(
824 				    X509_get_issuer_name(cert), NULL, 0);
825 				if (rpctls_debug_level == 0)
826 					syslog(LOG_INFO | LOG_DAEMON,
827 					    "rpctls_server: client IP %s "
828 					    "issuerName=%s subjectName=%s"
829 					    " verify failed %s\n", hostnam,
830 					    cp, cp2,
831 					    X509_verify_cert_error_string(
832 					    verfret));
833 				else
834 					fprintf(stderr,
835 					    "rpctls_server: client IP %s "
836 					    "issuerName=%s subjectName=%s"
837 					    " verify failed %s\n", hostnam,
838 					    cp, cp2,
839 					    X509_verify_cert_error_string(
840 					    verfret));
841 			}
842 			if (verfret ==
843 			    X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
844 			    verfret == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)
845 				*flags |= RPCTLS_FLAGS_SELFSIGNED;
846 			else if (verfret == X509_V_OK) {
847 				if (rpctls_comparehost) {
848 					ret = 0;
849 					if (gethostret != 0)
850 						ret = rpctls_checkhost(sad,
851 						    cert, rpctls_wildcard);
852 					if (ret != 1) {
853 						*flags |=
854 						    RPCTLS_FLAGS_DISABLED;
855 						rpctls_verbose_out(
856 						    "rpctls_server: "
857 						    "checkhost "
858 						    "failed\n");
859 					}
860 				}
861 				if (rpctls_cnuser) {
862 					ret = rpctls_cnname(cert, uidp,
863 					    ngrps, gidp);
864 					if (ret != 0)
865 						*flags |= RPCTLS_FLAGS_CERTUSER;
866 				}
867 				*flags |= RPCTLS_FLAGS_VERIFIED;
868 				*certp = cert;
869 				cert = NULL;
870 			}
871 			if (cert != NULL)
872 				X509_free(cert);
873 		} else
874 			rpctls_verbose_out("rpctls_server: "
875 			    "No peer certificate\n");
876 	}
877 
878 	/* Check to see that ktls is working for the connection. */
879 	ret = BIO_get_ktls_send(SSL_get_wbio(ssl));
880 	rpctls_verbose_out("rpctls_server: BIO_get_ktls_send=%d\n", ret);
881 	if (ret != 0) {
882 		ret = BIO_get_ktls_recv(SSL_get_rbio(ssl));
883 		rpctls_verbose_out("rpctls_server: BIO_get_ktls_recv=%d\n",
884 		    ret);
885 	}
886 	if (ret == 0) {
887 		if (rpctls_debug_level == 0)
888 			syslog(LOG_ERR, "ktls not working");
889 		else
890 			fprintf(stderr, "ktls not working\n");
891 		/*
892 		 * The handshake has completed, so all that can be
893 		 * done is disable the connection.
894 		 */
895 		*flags |= RPCTLS_FLAGS_DISABLED;
896 	}
897 
898 	return (ssl);
899 }
900 
901 /*
902  * Acquire the dnsname for this server.
903  */
904 static char *
905 rpctls_getdnsname(char *hostname)
906 {
907 	char *cp, *dnsname;
908 	struct addrinfo *aip, hints;
909 	int error;
910 
911 	dnsname = NULL;
912 	if (gethostname(hostname, MAXHOSTNAMELEN) == 0) {
913 		if ((cp = strchr(hostname, '.')) != NULL &&
914 		    *(cp + 1) != '\0') {
915 			*cp = '@';
916 			dnsname = cp;
917 		} else {
918 			memset((void *)&hints, 0, sizeof (hints));
919 			hints.ai_flags = AI_CANONNAME;
920 			error = getaddrinfo(hostname, NULL, &hints, &aip);
921 			if (error == 0) {
922 				if (aip->ai_canonname != NULL &&
923 				    (cp = strchr(aip->ai_canonname, '.')) !=
924 				    NULL && *(cp + 1) != '\0') {
925 					hostname[0] = '@';
926 					strlcpy(&hostname[1], cp + 1,
927 					    MAXHOSTNAMELEN + 1);
928 					dnsname = hostname;
929 				}
930 				freeaddrinfo(aip);
931 			}
932 		}
933 	}
934 	return (dnsname);
935 }
936 
937 /*
938  * Check for an otherName component of subjectAltName where the OID
939  * matches and the "domain" matches that of this server.
940  * If found, map "user" to a <uid, gidlist> for it.
941  */
942 static int
943 rpctls_cnname(X509 *cert, uint32_t *uidp, int *ngrps, uint32_t *gidp)
944 {
945 	char *cp, usern[1024 + 1];
946 	struct passwd *pwd;
947 	gid_t gids[NGROUPS];
948 	int i, j;
949 	GENERAL_NAMES *genlist;
950 	GENERAL_NAME *genname;
951 	OTHERNAME *val;
952 	size_t slen;
953 
954 	/* First, find the otherName in the subjectAltName. */
955 	genlist = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
956 	if (genlist == NULL)
957 		return (0);
958 	cp = NULL;
959 	for (i = 0; i < sk_GENERAL_NAME_num(genlist); i++) {
960 		genname = sk_GENERAL_NAME_value(genlist, i);
961 		if (genname->type != GEN_OTHERNAME)
962 			continue;
963 		val = genname->d.otherName;
964 
965 		/* Check to see that it is the correct OID. */
966 		slen = i2t_ASN1_OBJECT(usern, sizeof(usern), val->type_id);
967 		if (slen != strlen(rpctls_cnuseroid) || memcmp(usern,
968 		    rpctls_cnuseroid, slen) != 0)
969 			continue;
970 
971 		/* Sanity check the otherName. */
972 		if (val->value->type != V_ASN1_UTF8STRING ||
973 		    val->value->value.utf8string->length < 3 ||
974 		    (size_t)val->value->value.utf8string->length > sizeof(usern)
975 		    - 1) {
976 			rpctls_verbose_out("rpctls_cnname: invalid cnuser "
977 			    "type=%d\n", val->value->type);
978 			continue;
979 		}
980 
981 		/* Look for a "user" in the otherName */
982 		memcpy(usern, val->value->value.utf8string->data,
983 		    val->value->value.utf8string->length);
984 		usern[val->value->value.utf8string->length] = '\0';
985 
986 		/* Now, look for the @dnsname suffix in the commonName. */
987 		cp = strcasestr(usern, rpctls_dnsname);
988 		if (cp == NULL)
989 			continue;
990 		if (*(cp + strlen(rpctls_dnsname)) != '\0') {
991 			cp = NULL;
992 			continue;
993 		}
994 		*cp = '\0';
995 		break;
996 	}
997 	if (cp == NULL)
998 		return (0);
999 
1000 	/* See if the "user" is in the passwd database. */
1001 	pwd = getpwnam(usern);
1002 	if (pwd == NULL)
1003 		return (0);
1004 	*uidp = pwd->pw_uid;
1005 	*ngrps = NGROUPS;
1006 	if (getgrouplist(pwd->pw_name, pwd->pw_gid, gids, ngrps) < 0)
1007 		return (0);
1008 	rpctls_verbose_out("mapped user=%s ngrps=%d uid=%d\n", pwd->pw_name,
1009 	    *ngrps, pwd->pw_uid);
1010 	for (j = 0; j < *ngrps; j++)
1011 		gidp[j] = gids[j];
1012 	return (1);
1013 }
1014 
1015 static void
1016 rpctls_huphandler(int sig __unused)
1017 {
1018 
1019 	rpctls_gothup = true;
1020 }
1021