1*b9cbc85dSRick Macklem /*- 2*b9cbc85dSRick Macklem * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*b9cbc85dSRick Macklem * 4*b9cbc85dSRick Macklem * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ 5*b9cbc85dSRick Macklem * Authors: Doug Rabson <dfr@rabson.org> 6*b9cbc85dSRick Macklem * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org> 7*b9cbc85dSRick Macklem * 8*b9cbc85dSRick Macklem * Redistribution and use in source and binary forms, with or without 9*b9cbc85dSRick Macklem * modification, are permitted provided that the following conditions 10*b9cbc85dSRick Macklem * are met: 11*b9cbc85dSRick Macklem * 1. Redistributions of source code must retain the above copyright 12*b9cbc85dSRick Macklem * notice, this list of conditions and the following disclaimer. 13*b9cbc85dSRick Macklem * 2. Redistributions in binary form must reproduce the above copyright 14*b9cbc85dSRick Macklem * notice, this list of conditions and the following disclaimer in the 15*b9cbc85dSRick Macklem * documentation and/or other materials provided with the distribution. 16*b9cbc85dSRick Macklem * 17*b9cbc85dSRick Macklem * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18*b9cbc85dSRick Macklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*b9cbc85dSRick Macklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*b9cbc85dSRick Macklem * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21*b9cbc85dSRick Macklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*b9cbc85dSRick Macklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*b9cbc85dSRick Macklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*b9cbc85dSRick Macklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*b9cbc85dSRick Macklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*b9cbc85dSRick Macklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*b9cbc85dSRick Macklem * SUCH DAMAGE. 28*b9cbc85dSRick Macklem */ 29*b9cbc85dSRick Macklem 30*b9cbc85dSRick Macklem /* 31*b9cbc85dSRick Macklem * Extensively modified from /usr/src/usr.sbin/gssd.c r344402 for 32*b9cbc85dSRick Macklem * the client side of kernel RPC-over-TLS by Rick Macklem. 33*b9cbc85dSRick Macklem */ 34*b9cbc85dSRick Macklem 35*b9cbc85dSRick Macklem #include <sys/cdefs.h> 36*b9cbc85dSRick Macklem __FBSDID("$FreeBSD$"); 37*b9cbc85dSRick Macklem 38*b9cbc85dSRick Macklem #include <sys/param.h> 39*b9cbc85dSRick Macklem #include <sys/types.h> 40*b9cbc85dSRick Macklem #include <sys/queue.h> 41*b9cbc85dSRick Macklem #include <sys/linker.h> 42*b9cbc85dSRick Macklem #include <sys/module.h> 43*b9cbc85dSRick Macklem #include <sys/stat.h> 44*b9cbc85dSRick Macklem #include <sys/sysctl.h> 45*b9cbc85dSRick Macklem #include <sys/syslog.h> 46*b9cbc85dSRick Macklem #include <sys/time.h> 47*b9cbc85dSRick Macklem #include <err.h> 48*b9cbc85dSRick Macklem #include <getopt.h> 49*b9cbc85dSRick Macklem #include <libutil.h> 50*b9cbc85dSRick Macklem #include <netdb.h> 51*b9cbc85dSRick Macklem #include <signal.h> 52*b9cbc85dSRick Macklem #include <stdarg.h> 53*b9cbc85dSRick Macklem #include <stdbool.h> 54*b9cbc85dSRick Macklem #include <stdio.h> 55*b9cbc85dSRick Macklem #include <stdlib.h> 56*b9cbc85dSRick Macklem #include <string.h> 57*b9cbc85dSRick Macklem #include <unistd.h> 58*b9cbc85dSRick Macklem 59*b9cbc85dSRick Macklem #include <rpc/rpc.h> 60*b9cbc85dSRick Macklem #include <rpc/rpc_com.h> 61*b9cbc85dSRick Macklem #include <rpc/rpcsec_tls.h> 62*b9cbc85dSRick Macklem 63*b9cbc85dSRick Macklem #include <openssl/opensslconf.h> 64*b9cbc85dSRick Macklem #include <openssl/bio.h> 65*b9cbc85dSRick Macklem #include <openssl/ssl.h> 66*b9cbc85dSRick Macklem #include <openssl/err.h> 67*b9cbc85dSRick Macklem #include <openssl/x509v3.h> 68*b9cbc85dSRick Macklem 69*b9cbc85dSRick Macklem #include "rpctlscd.h" 70*b9cbc85dSRick Macklem #include "rpc.tlscommon.h" 71*b9cbc85dSRick Macklem 72*b9cbc85dSRick Macklem #ifndef _PATH_RPCTLSCDSOCK 73*b9cbc85dSRick Macklem #define _PATH_RPCTLSCDSOCK "/var/run/rpc.tlsclntd.sock" 74*b9cbc85dSRick Macklem #endif 75*b9cbc85dSRick Macklem #ifndef _PATH_CERTANDKEY 76*b9cbc85dSRick Macklem #define _PATH_CERTANDKEY "/etc/rpc.tlsclntd/" 77*b9cbc85dSRick Macklem #endif 78*b9cbc85dSRick Macklem #ifndef _PATH_RPCTLSCDPID 79*b9cbc85dSRick Macklem #define _PATH_RPCTLSCDPID "/var/run/rpc.tlsclntd.pid" 80*b9cbc85dSRick Macklem #endif 81*b9cbc85dSRick Macklem 82*b9cbc85dSRick Macklem /* Global variables also used by rpc.tlscommon.c. */ 83*b9cbc85dSRick Macklem int rpctls_debug_level; 84*b9cbc85dSRick Macklem bool rpctls_verbose; 85*b9cbc85dSRick Macklem SSL_CTX *rpctls_ctx = NULL; 86*b9cbc85dSRick Macklem const char *rpctls_verify_cafile = NULL; 87*b9cbc85dSRick Macklem const char *rpctls_verify_capath = NULL; 88*b9cbc85dSRick Macklem char *rpctls_crlfile = NULL; 89*b9cbc85dSRick Macklem bool rpctls_cert = false; 90*b9cbc85dSRick Macklem bool rpctls_gothup = false; 91*b9cbc85dSRick Macklem struct ssl_list rpctls_ssllist; 92*b9cbc85dSRick Macklem 93*b9cbc85dSRick Macklem static struct pidfh *rpctls_pfh = NULL; 94*b9cbc85dSRick Macklem static const char *rpctls_certdir = _PATH_CERTANDKEY; 95*b9cbc85dSRick Macklem static const char *rpctls_ciphers = NULL; 96*b9cbc85dSRick Macklem static uint64_t rpctls_ssl_refno = 0; 97*b9cbc85dSRick Macklem static uint64_t rpctls_ssl_sec = 0; 98*b9cbc85dSRick Macklem static uint64_t rpctls_ssl_usec = 0; 99*b9cbc85dSRick Macklem 100*b9cbc85dSRick Macklem static void rpctlscd_terminate(int); 101*b9cbc85dSRick Macklem static SSL_CTX *rpctls_setupcl_ssl(void); 102*b9cbc85dSRick Macklem static SSL *rpctls_connect(SSL_CTX *ctx, int s, char *certname, 103*b9cbc85dSRick Macklem u_int certlen, X509 **certp); 104*b9cbc85dSRick Macklem static void rpctls_huphandler(int sig __unused); 105*b9cbc85dSRick Macklem 106*b9cbc85dSRick Macklem extern void rpctlscd_1(struct svc_req *rqstp, SVCXPRT *transp); 107*b9cbc85dSRick Macklem 108*b9cbc85dSRick Macklem static struct option longopts[] = { 109*b9cbc85dSRick Macklem { "certdir", required_argument, NULL, 'D' }, 110*b9cbc85dSRick Macklem { "ciphers", required_argument, NULL, 'C' }, 111*b9cbc85dSRick Macklem { "debuglevel", no_argument, NULL, 'd' }, 112*b9cbc85dSRick Macklem { "verifylocs", required_argument, NULL, 'l' }, 113*b9cbc85dSRick Macklem { "mutualverf", no_argument, NULL, 'm' }, 114*b9cbc85dSRick Macklem { "verifydir", required_argument, NULL, 'p' }, 115*b9cbc85dSRick Macklem { "crl", required_argument, NULL, 'r' }, 116*b9cbc85dSRick Macklem { "verbose", no_argument, NULL, 'v' }, 117*b9cbc85dSRick Macklem { NULL, 0, NULL, 0 } 118*b9cbc85dSRick Macklem }; 119*b9cbc85dSRick Macklem 120*b9cbc85dSRick Macklem int 121*b9cbc85dSRick Macklem main(int argc, char **argv) 122*b9cbc85dSRick Macklem { 123*b9cbc85dSRick Macklem /* 124*b9cbc85dSRick Macklem * We provide an RPC service on a local-domain socket. The 125*b9cbc85dSRick Macklem * kernel rpctls code will upcall to this daemon to do the initial 126*b9cbc85dSRick Macklem * TLS handshake. 127*b9cbc85dSRick Macklem */ 128*b9cbc85dSRick Macklem struct sockaddr_un sun; 129*b9cbc85dSRick Macklem int ch, fd, oldmask; 130*b9cbc85dSRick Macklem SVCXPRT *xprt; 131*b9cbc85dSRick Macklem bool tls_enable; 132*b9cbc85dSRick Macklem struct timeval tm; 133*b9cbc85dSRick Macklem struct timezone tz; 134*b9cbc85dSRick Macklem pid_t otherpid; 135*b9cbc85dSRick Macklem size_t tls_enable_len; 136*b9cbc85dSRick Macklem 137*b9cbc85dSRick Macklem /* Check that another rpctlscd isn't already running. */ 138*b9cbc85dSRick Macklem rpctls_pfh = pidfile_open(_PATH_RPCTLSCDPID, 0600, &otherpid); 139*b9cbc85dSRick Macklem if (rpctls_pfh == NULL) { 140*b9cbc85dSRick Macklem if (errno == EEXIST) 141*b9cbc85dSRick Macklem errx(1, "rpctlscd already running, pid: %d.", otherpid); 142*b9cbc85dSRick Macklem warn("cannot open or create pidfile"); 143*b9cbc85dSRick Macklem } 144*b9cbc85dSRick Macklem 145*b9cbc85dSRick Macklem /* Check to see that the ktls is enabled. */ 146*b9cbc85dSRick Macklem tls_enable_len = sizeof(tls_enable); 147*b9cbc85dSRick Macklem if (sysctlbyname("kern.ipc.tls.enable", &tls_enable, &tls_enable_len, 148*b9cbc85dSRick Macklem NULL, 0) != 0 || !tls_enable) 149*b9cbc85dSRick Macklem errx(1, "Kernel TLS not enabled"); 150*b9cbc85dSRick Macklem 151*b9cbc85dSRick Macklem /* Get the time when this daemon is started. */ 152*b9cbc85dSRick Macklem gettimeofday(&tm, &tz); 153*b9cbc85dSRick Macklem rpctls_ssl_sec = tm.tv_sec; 154*b9cbc85dSRick Macklem rpctls_ssl_usec = tm.tv_usec; 155*b9cbc85dSRick Macklem 156*b9cbc85dSRick Macklem rpctls_verbose = false; 157*b9cbc85dSRick Macklem while ((ch = getopt_long(argc, argv, "CD:dl:mp:r:v", longopts, NULL)) != 158*b9cbc85dSRick Macklem -1) { 159*b9cbc85dSRick Macklem switch (ch) { 160*b9cbc85dSRick Macklem case 'C': 161*b9cbc85dSRick Macklem rpctls_ciphers = optarg; 162*b9cbc85dSRick Macklem break; 163*b9cbc85dSRick Macklem case 'D': 164*b9cbc85dSRick Macklem rpctls_certdir = optarg; 165*b9cbc85dSRick Macklem break; 166*b9cbc85dSRick Macklem case 'd': 167*b9cbc85dSRick Macklem rpctls_debug_level++; 168*b9cbc85dSRick Macklem break; 169*b9cbc85dSRick Macklem case 'l': 170*b9cbc85dSRick Macklem rpctls_verify_cafile = optarg; 171*b9cbc85dSRick Macklem break; 172*b9cbc85dSRick Macklem case 'm': 173*b9cbc85dSRick Macklem rpctls_cert = true; 174*b9cbc85dSRick Macklem break; 175*b9cbc85dSRick Macklem case 'p': 176*b9cbc85dSRick Macklem rpctls_verify_capath = optarg; 177*b9cbc85dSRick Macklem break; 178*b9cbc85dSRick Macklem case 'r': 179*b9cbc85dSRick Macklem rpctls_crlfile = optarg; 180*b9cbc85dSRick Macklem break; 181*b9cbc85dSRick Macklem case 'v': 182*b9cbc85dSRick Macklem rpctls_verbose = true; 183*b9cbc85dSRick Macklem break; 184*b9cbc85dSRick Macklem default: 185*b9cbc85dSRick Macklem fprintf(stderr, "usage: %s " 186*b9cbc85dSRick Macklem "[-C/--ciphers preferred_ciphers] " 187*b9cbc85dSRick Macklem "[-D/--certdir certdir] [-d/--debuglevel] " 188*b9cbc85dSRick Macklem "[-l/--verifylocs CAfile] [-m/--mutualverf] " 189*b9cbc85dSRick Macklem "[-p/--verifydir CApath] [-r/--crl CRLfile] " 190*b9cbc85dSRick Macklem "[-v/--verbose]\n", argv[0]); 191*b9cbc85dSRick Macklem exit(1); 192*b9cbc85dSRick Macklem break; 193*b9cbc85dSRick Macklem } 194*b9cbc85dSRick Macklem } 195*b9cbc85dSRick Macklem if (rpctls_crlfile != NULL && rpctls_verify_cafile == NULL && 196*b9cbc85dSRick Macklem rpctls_verify_capath == NULL) 197*b9cbc85dSRick Macklem errx(1, "-r requires the -l <CAfile> and/or " 198*b9cbc85dSRick Macklem "-p <CApath> options"); 199*b9cbc85dSRick Macklem 200*b9cbc85dSRick Macklem if (modfind("krpc") < 0) { 201*b9cbc85dSRick Macklem /* Not present in kernel, try loading it */ 202*b9cbc85dSRick Macklem if (kldload("krpc") < 0 || modfind("krpc") < 0) 203*b9cbc85dSRick Macklem errx(1, "Kernel RPC is not available"); 204*b9cbc85dSRick Macklem } 205*b9cbc85dSRick Macklem 206*b9cbc85dSRick Macklem /* 207*b9cbc85dSRick Macklem * Set up the SSL_CTX *. 208*b9cbc85dSRick Macklem * Do it now, before daemonizing, in case the private key 209*b9cbc85dSRick Macklem * is encrypted and requires a passphrase to be entered. 210*b9cbc85dSRick Macklem */ 211*b9cbc85dSRick Macklem rpctls_ctx = rpctls_setupcl_ssl(); 212*b9cbc85dSRick Macklem if (rpctls_ctx == NULL) { 213*b9cbc85dSRick Macklem if (rpctls_debug_level == 0) { 214*b9cbc85dSRick Macklem syslog(LOG_ERR, "Can't set up TLS context"); 215*b9cbc85dSRick Macklem exit(1); 216*b9cbc85dSRick Macklem } 217*b9cbc85dSRick Macklem err(1, "Can't set up TLS context"); 218*b9cbc85dSRick Macklem } 219*b9cbc85dSRick Macklem LIST_INIT(&rpctls_ssllist); 220*b9cbc85dSRick Macklem 221*b9cbc85dSRick Macklem if (!rpctls_debug_level) { 222*b9cbc85dSRick Macklem if (daemon(0, 0) != 0) 223*b9cbc85dSRick Macklem err(1, "Can't daemonize"); 224*b9cbc85dSRick Macklem signal(SIGINT, SIG_IGN); 225*b9cbc85dSRick Macklem signal(SIGQUIT, SIG_IGN); 226*b9cbc85dSRick Macklem signal(SIGHUP, SIG_IGN); 227*b9cbc85dSRick Macklem } 228*b9cbc85dSRick Macklem signal(SIGTERM, rpctlscd_terminate); 229*b9cbc85dSRick Macklem signal(SIGPIPE, SIG_IGN); 230*b9cbc85dSRick Macklem signal(SIGHUP, rpctls_huphandler); 231*b9cbc85dSRick Macklem 232*b9cbc85dSRick Macklem pidfile_write(rpctls_pfh); 233*b9cbc85dSRick Macklem 234*b9cbc85dSRick Macklem memset(&sun, 0, sizeof sun); 235*b9cbc85dSRick Macklem sun.sun_family = AF_LOCAL; 236*b9cbc85dSRick Macklem unlink(_PATH_RPCTLSCDSOCK); 237*b9cbc85dSRick Macklem strcpy(sun.sun_path, _PATH_RPCTLSCDSOCK); 238*b9cbc85dSRick Macklem sun.sun_len = SUN_LEN(&sun); 239*b9cbc85dSRick Macklem fd = socket(AF_LOCAL, SOCK_STREAM, 0); 240*b9cbc85dSRick Macklem if (fd < 0) { 241*b9cbc85dSRick Macklem if (rpctls_debug_level == 0) { 242*b9cbc85dSRick Macklem syslog(LOG_ERR, "Can't create local rpctlscd socket"); 243*b9cbc85dSRick Macklem exit(1); 244*b9cbc85dSRick Macklem } 245*b9cbc85dSRick Macklem err(1, "Can't create local rpctlscd socket"); 246*b9cbc85dSRick Macklem } 247*b9cbc85dSRick Macklem oldmask = umask(S_IXUSR|S_IRWXG|S_IRWXO); 248*b9cbc85dSRick Macklem if (bind(fd, (struct sockaddr *)&sun, sun.sun_len) < 0) { 249*b9cbc85dSRick Macklem if (rpctls_debug_level == 0) { 250*b9cbc85dSRick Macklem syslog(LOG_ERR, "Can't bind local rpctlscd socket"); 251*b9cbc85dSRick Macklem exit(1); 252*b9cbc85dSRick Macklem } 253*b9cbc85dSRick Macklem err(1, "Can't bind local rpctlscd socket"); 254*b9cbc85dSRick Macklem } 255*b9cbc85dSRick Macklem umask(oldmask); 256*b9cbc85dSRick Macklem if (listen(fd, SOMAXCONN) < 0) { 257*b9cbc85dSRick Macklem if (rpctls_debug_level == 0) { 258*b9cbc85dSRick Macklem syslog(LOG_ERR, 259*b9cbc85dSRick Macklem "Can't listen on local rpctlscd socket"); 260*b9cbc85dSRick Macklem exit(1); 261*b9cbc85dSRick Macklem } 262*b9cbc85dSRick Macklem err(1, "Can't listen on local rpctlscd socket"); 263*b9cbc85dSRick Macklem } 264*b9cbc85dSRick Macklem xprt = svc_vc_create(fd, RPC_MAXDATASIZE, RPC_MAXDATASIZE); 265*b9cbc85dSRick Macklem if (!xprt) { 266*b9cbc85dSRick Macklem if (rpctls_debug_level == 0) { 267*b9cbc85dSRick Macklem syslog(LOG_ERR, 268*b9cbc85dSRick Macklem "Can't create transport for local rpctlscd socket"); 269*b9cbc85dSRick Macklem exit(1); 270*b9cbc85dSRick Macklem } 271*b9cbc85dSRick Macklem err(1, "Can't create transport for local rpctlscd socket"); 272*b9cbc85dSRick Macklem } 273*b9cbc85dSRick Macklem if (!svc_reg(xprt, RPCTLSCD, RPCTLSCDVERS, rpctlscd_1, NULL)) { 274*b9cbc85dSRick Macklem if (rpctls_debug_level == 0) { 275*b9cbc85dSRick Macklem syslog(LOG_ERR, 276*b9cbc85dSRick Macklem "Can't register service for local rpctlscd socket"); 277*b9cbc85dSRick Macklem exit(1); 278*b9cbc85dSRick Macklem } 279*b9cbc85dSRick Macklem err(1, "Can't register service for local rpctlscd socket"); 280*b9cbc85dSRick Macklem } 281*b9cbc85dSRick Macklem 282*b9cbc85dSRick Macklem rpctls_syscall(RPCTLS_SYSC_CLSETPATH, _PATH_RPCTLSCDSOCK); 283*b9cbc85dSRick Macklem 284*b9cbc85dSRick Macklem rpctls_svc_run(); 285*b9cbc85dSRick Macklem 286*b9cbc85dSRick Macklem rpctls_syscall(RPCTLS_SYSC_CLSHUTDOWN, ""); 287*b9cbc85dSRick Macklem 288*b9cbc85dSRick Macklem SSL_CTX_free(rpctls_ctx); 289*b9cbc85dSRick Macklem EVP_cleanup(); 290*b9cbc85dSRick Macklem return (0); 291*b9cbc85dSRick Macklem } 292*b9cbc85dSRick Macklem 293*b9cbc85dSRick Macklem bool_t 294*b9cbc85dSRick Macklem rpctlscd_null_1_svc(__unused void *argp, __unused void *result, 295*b9cbc85dSRick Macklem __unused struct svc_req *rqstp) 296*b9cbc85dSRick Macklem { 297*b9cbc85dSRick Macklem 298*b9cbc85dSRick Macklem rpctls_verbose_out("rpctlscd_null: done\n"); 299*b9cbc85dSRick Macklem return (TRUE); 300*b9cbc85dSRick Macklem } 301*b9cbc85dSRick Macklem 302*b9cbc85dSRick Macklem bool_t 303*b9cbc85dSRick Macklem rpctlscd_connect_1_svc(struct rpctlscd_connect_arg *argp, 304*b9cbc85dSRick Macklem struct rpctlscd_connect_res *result, __unused struct svc_req *rqstp) 305*b9cbc85dSRick Macklem { 306*b9cbc85dSRick Macklem int s; 307*b9cbc85dSRick Macklem SSL *ssl; 308*b9cbc85dSRick Macklem struct ssl_entry *newslp; 309*b9cbc85dSRick Macklem X509 *cert; 310*b9cbc85dSRick Macklem 311*b9cbc85dSRick Macklem rpctls_verbose_out("rpctlsd_connect: started\n"); 312*b9cbc85dSRick Macklem /* Get the socket fd from the kernel. */ 313*b9cbc85dSRick Macklem s = rpctls_syscall(RPCTLS_SYSC_CLSOCKET, ""); 314*b9cbc85dSRick Macklem if (s < 0) { 315*b9cbc85dSRick Macklem result->reterr = RPCTLSERR_NOSOCKET; 316*b9cbc85dSRick Macklem return (TRUE); 317*b9cbc85dSRick Macklem } 318*b9cbc85dSRick Macklem 319*b9cbc85dSRick Macklem /* Do a TLS connect handshake. */ 320*b9cbc85dSRick Macklem ssl = rpctls_connect(rpctls_ctx, s, argp->certname.certname_val, 321*b9cbc85dSRick Macklem argp->certname.certname_len, &cert); 322*b9cbc85dSRick Macklem if (ssl == NULL) { 323*b9cbc85dSRick Macklem rpctls_verbose_out("rpctlsd_connect: can't do TLS " 324*b9cbc85dSRick Macklem "handshake\n"); 325*b9cbc85dSRick Macklem result->reterr = RPCTLSERR_NOSSL; 326*b9cbc85dSRick Macklem } else { 327*b9cbc85dSRick Macklem result->reterr = RPCTLSERR_OK; 328*b9cbc85dSRick Macklem result->sec = rpctls_ssl_sec; 329*b9cbc85dSRick Macklem result->usec = rpctls_ssl_usec; 330*b9cbc85dSRick Macklem result->ssl = ++rpctls_ssl_refno; 331*b9cbc85dSRick Macklem /* Hard to believe this will ever wrap around.. */ 332*b9cbc85dSRick Macklem if (rpctls_ssl_refno == 0) 333*b9cbc85dSRick Macklem result->ssl = ++rpctls_ssl_refno; 334*b9cbc85dSRick Macklem } 335*b9cbc85dSRick Macklem 336*b9cbc85dSRick Macklem if (ssl == NULL) { 337*b9cbc85dSRick Macklem /* 338*b9cbc85dSRick Macklem * For RPC-over-TLS, this upcall is expected 339*b9cbc85dSRick Macklem * to close off the socket. 340*b9cbc85dSRick Macklem */ 341*b9cbc85dSRick Macklem close(s); 342*b9cbc85dSRick Macklem return (TRUE); 343*b9cbc85dSRick Macklem } 344*b9cbc85dSRick Macklem 345*b9cbc85dSRick Macklem /* Maintain list of all current SSL *'s */ 346*b9cbc85dSRick Macklem newslp = malloc(sizeof(*newslp)); 347*b9cbc85dSRick Macklem newslp->refno = rpctls_ssl_refno; 348*b9cbc85dSRick Macklem newslp->s = s; 349*b9cbc85dSRick Macklem newslp->shutoff = false; 350*b9cbc85dSRick Macklem newslp->ssl = ssl; 351*b9cbc85dSRick Macklem newslp->cert = cert; 352*b9cbc85dSRick Macklem LIST_INSERT_HEAD(&rpctls_ssllist, newslp, next); 353*b9cbc85dSRick Macklem return (TRUE); 354*b9cbc85dSRick Macklem } 355*b9cbc85dSRick Macklem 356*b9cbc85dSRick Macklem bool_t 357*b9cbc85dSRick Macklem rpctlscd_handlerecord_1_svc(struct rpctlscd_handlerecord_arg *argp, 358*b9cbc85dSRick Macklem struct rpctlscd_handlerecord_res *result, __unused struct svc_req *rqstp) 359*b9cbc85dSRick Macklem { 360*b9cbc85dSRick Macklem struct ssl_entry *slp; 361*b9cbc85dSRick Macklem int ret; 362*b9cbc85dSRick Macklem char junk; 363*b9cbc85dSRick Macklem 364*b9cbc85dSRick Macklem slp = NULL; 365*b9cbc85dSRick Macklem if (argp->sec == rpctls_ssl_sec && argp->usec == 366*b9cbc85dSRick Macklem rpctls_ssl_usec) { 367*b9cbc85dSRick Macklem LIST_FOREACH(slp, &rpctls_ssllist, next) { 368*b9cbc85dSRick Macklem if (slp->refno == argp->ssl) 369*b9cbc85dSRick Macklem break; 370*b9cbc85dSRick Macklem } 371*b9cbc85dSRick Macklem } 372*b9cbc85dSRick Macklem 373*b9cbc85dSRick Macklem if (slp != NULL) { 374*b9cbc85dSRick Macklem rpctls_verbose_out("rpctlscd_handlerecord fd=%d\n", 375*b9cbc85dSRick Macklem slp->s); 376*b9cbc85dSRick Macklem /* 377*b9cbc85dSRick Macklem * An SSL_read() of 0 bytes should fail, but it should 378*b9cbc85dSRick Macklem * handle the non-application data record before doing so. 379*b9cbc85dSRick Macklem */ 380*b9cbc85dSRick Macklem ret = SSL_read(slp->ssl, &junk, 0); 381*b9cbc85dSRick Macklem if (ret <= 0) { 382*b9cbc85dSRick Macklem /* Check to see if this was a close alert. */ 383*b9cbc85dSRick Macklem ret = SSL_get_shutdown(slp->ssl); 384*b9cbc85dSRick Macklem if ((ret & (SSL_SENT_SHUTDOWN | 385*b9cbc85dSRick Macklem SSL_RECEIVED_SHUTDOWN)) == SSL_RECEIVED_SHUTDOWN) 386*b9cbc85dSRick Macklem SSL_shutdown(slp->ssl); 387*b9cbc85dSRick Macklem } else { 388*b9cbc85dSRick Macklem if (rpctls_debug_level == 0) 389*b9cbc85dSRick Macklem syslog(LOG_ERR, "SSL_read returned %d", ret); 390*b9cbc85dSRick Macklem else 391*b9cbc85dSRick Macklem fprintf(stderr, "SSL_read returned %d\n", ret); 392*b9cbc85dSRick Macklem } 393*b9cbc85dSRick Macklem result->reterr = RPCTLSERR_OK; 394*b9cbc85dSRick Macklem } else 395*b9cbc85dSRick Macklem result->reterr = RPCTLSERR_NOSSL; 396*b9cbc85dSRick Macklem return (TRUE); 397*b9cbc85dSRick Macklem } 398*b9cbc85dSRick Macklem 399*b9cbc85dSRick Macklem bool_t 400*b9cbc85dSRick Macklem rpctlscd_disconnect_1_svc(struct rpctlscd_disconnect_arg *argp, 401*b9cbc85dSRick Macklem struct rpctlscd_disconnect_res *result, __unused struct svc_req *rqstp) 402*b9cbc85dSRick Macklem { 403*b9cbc85dSRick Macklem struct ssl_entry *slp; 404*b9cbc85dSRick Macklem int ret; 405*b9cbc85dSRick Macklem 406*b9cbc85dSRick Macklem slp = NULL; 407*b9cbc85dSRick Macklem if (argp->sec == rpctls_ssl_sec && argp->usec == 408*b9cbc85dSRick Macklem rpctls_ssl_usec) { 409*b9cbc85dSRick Macklem LIST_FOREACH(slp, &rpctls_ssllist, next) { 410*b9cbc85dSRick Macklem if (slp->refno == argp->ssl) 411*b9cbc85dSRick Macklem break; 412*b9cbc85dSRick Macklem } 413*b9cbc85dSRick Macklem } 414*b9cbc85dSRick Macklem 415*b9cbc85dSRick Macklem if (slp != NULL) { 416*b9cbc85dSRick Macklem rpctls_verbose_out("rpctlscd_disconnect: fd=%d closed\n", 417*b9cbc85dSRick Macklem slp->s); 418*b9cbc85dSRick Macklem LIST_REMOVE(slp, next); 419*b9cbc85dSRick Macklem if (!slp->shutoff) { 420*b9cbc85dSRick Macklem ret = SSL_get_shutdown(slp->ssl); 421*b9cbc85dSRick Macklem /* 422*b9cbc85dSRick Macklem * Do an SSL_shutdown() unless a close alert has 423*b9cbc85dSRick Macklem * already been sent. 424*b9cbc85dSRick Macklem */ 425*b9cbc85dSRick Macklem if ((ret & SSL_SENT_SHUTDOWN) == 0) 426*b9cbc85dSRick Macklem SSL_shutdown(slp->ssl); 427*b9cbc85dSRick Macklem } 428*b9cbc85dSRick Macklem SSL_free(slp->ssl); 429*b9cbc85dSRick Macklem if (slp->cert != NULL) 430*b9cbc85dSRick Macklem X509_free(slp->cert); 431*b9cbc85dSRick Macklem /* 432*b9cbc85dSRick Macklem * For RPC-over-TLS, this upcall is expected 433*b9cbc85dSRick Macklem * to close off the socket. 434*b9cbc85dSRick Macklem */ 435*b9cbc85dSRick Macklem if (!slp->shutoff) 436*b9cbc85dSRick Macklem shutdown(slp->s, SHUT_WR); 437*b9cbc85dSRick Macklem close(slp->s); 438*b9cbc85dSRick Macklem free(slp); 439*b9cbc85dSRick Macklem result->reterr = RPCTLSERR_OK; 440*b9cbc85dSRick Macklem } else 441*b9cbc85dSRick Macklem result->reterr = RPCTLSERR_NOCLOSE; 442*b9cbc85dSRick Macklem return (TRUE); 443*b9cbc85dSRick Macklem } 444*b9cbc85dSRick Macklem 445*b9cbc85dSRick Macklem int 446*b9cbc85dSRick Macklem rpctlscd_1_freeresult(__unused SVCXPRT *transp, __unused xdrproc_t xdr_result, 447*b9cbc85dSRick Macklem __unused caddr_t result) 448*b9cbc85dSRick Macklem { 449*b9cbc85dSRick Macklem 450*b9cbc85dSRick Macklem return (TRUE); 451*b9cbc85dSRick Macklem } 452*b9cbc85dSRick Macklem 453*b9cbc85dSRick Macklem static void 454*b9cbc85dSRick Macklem rpctlscd_terminate(int sig __unused) 455*b9cbc85dSRick Macklem { 456*b9cbc85dSRick Macklem 457*b9cbc85dSRick Macklem rpctls_syscall(RPCTLS_SYSC_CLSHUTDOWN, ""); 458*b9cbc85dSRick Macklem pidfile_remove(rpctls_pfh); 459*b9cbc85dSRick Macklem exit(0); 460*b9cbc85dSRick Macklem } 461*b9cbc85dSRick Macklem 462*b9cbc85dSRick Macklem static SSL_CTX * 463*b9cbc85dSRick Macklem rpctls_setupcl_ssl(void) 464*b9cbc85dSRick Macklem { 465*b9cbc85dSRick Macklem SSL_CTX *ctx; 466*b9cbc85dSRick Macklem long flags; 467*b9cbc85dSRick Macklem char path[PATH_MAX]; 468*b9cbc85dSRick Macklem size_t len, rlen; 469*b9cbc85dSRick Macklem int ret; 470*b9cbc85dSRick Macklem 471*b9cbc85dSRick Macklem SSL_library_init(); 472*b9cbc85dSRick Macklem SSL_load_error_strings(); 473*b9cbc85dSRick Macklem OpenSSL_add_all_algorithms(); 474*b9cbc85dSRick Macklem 475*b9cbc85dSRick Macklem ctx = SSL_CTX_new(TLS_client_method()); 476*b9cbc85dSRick Macklem if (ctx == NULL) { 477*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_setupcl_ssl: SSL_CTX_new " 478*b9cbc85dSRick Macklem "failed\n"); 479*b9cbc85dSRick Macklem return (NULL); 480*b9cbc85dSRick Macklem } 481*b9cbc85dSRick Macklem SSL_CTX_set_ecdh_auto(ctx, 1); 482*b9cbc85dSRick Macklem 483*b9cbc85dSRick Macklem if (rpctls_ciphers != NULL) { 484*b9cbc85dSRick Macklem /* 485*b9cbc85dSRick Macklem * Set preferred ciphers, since KERN_TLS only supports a 486*b9cbc85dSRick Macklem * few of them. 487*b9cbc85dSRick Macklem */ 488*b9cbc85dSRick Macklem ret = SSL_CTX_set_cipher_list(ctx, rpctls_ciphers); 489*b9cbc85dSRick Macklem if (ret == 0) { 490*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_setupcl_ssl: " 491*b9cbc85dSRick Macklem "SSL_CTX_set_cipher_list failed: %s\n", 492*b9cbc85dSRick Macklem rpctls_ciphers); 493*b9cbc85dSRick Macklem SSL_CTX_free(ctx); 494*b9cbc85dSRick Macklem return (NULL); 495*b9cbc85dSRick Macklem } 496*b9cbc85dSRick Macklem } 497*b9cbc85dSRick Macklem 498*b9cbc85dSRick Macklem /* 499*b9cbc85dSRick Macklem * If rpctls_cert is true, a certificate and key exists in 500*b9cbc85dSRick Macklem * rpctls_certdir, so that it can do mutual authentication. 501*b9cbc85dSRick Macklem */ 502*b9cbc85dSRick Macklem if (rpctls_cert) { 503*b9cbc85dSRick Macklem /* Get the cert.pem and certkey.pem files. */ 504*b9cbc85dSRick Macklem len = strlcpy(path, rpctls_certdir, sizeof(path)); 505*b9cbc85dSRick Macklem rlen = sizeof(path) - len; 506*b9cbc85dSRick Macklem if (strlcpy(&path[len], "cert.pem", rlen) != 8) { 507*b9cbc85dSRick Macklem SSL_CTX_free(ctx); 508*b9cbc85dSRick Macklem return (NULL); 509*b9cbc85dSRick Macklem } 510*b9cbc85dSRick Macklem ret = SSL_CTX_use_certificate_file(ctx, path, 511*b9cbc85dSRick Macklem SSL_FILETYPE_PEM); 512*b9cbc85dSRick Macklem if (ret != 1) { 513*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_setupcl_ssl: can't use " 514*b9cbc85dSRick Macklem "certificate file path=%s ret=%d\n", path, ret); 515*b9cbc85dSRick Macklem SSL_CTX_free(ctx); 516*b9cbc85dSRick Macklem return (NULL); 517*b9cbc85dSRick Macklem } 518*b9cbc85dSRick Macklem if (strlcpy(&path[len], "certkey.pem", rlen) != 11) { 519*b9cbc85dSRick Macklem SSL_CTX_free(ctx); 520*b9cbc85dSRick Macklem return (NULL); 521*b9cbc85dSRick Macklem } 522*b9cbc85dSRick Macklem ret = SSL_CTX_use_PrivateKey_file(ctx, path, 523*b9cbc85dSRick Macklem SSL_FILETYPE_PEM); 524*b9cbc85dSRick Macklem if (ret != 1) { 525*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_setupcl_ssl: Can't use " 526*b9cbc85dSRick Macklem "private key path=%s ret=%d\n", path, ret); 527*b9cbc85dSRick Macklem SSL_CTX_free(ctx); 528*b9cbc85dSRick Macklem return (NULL); 529*b9cbc85dSRick Macklem } 530*b9cbc85dSRick Macklem } 531*b9cbc85dSRick Macklem 532*b9cbc85dSRick Macklem if (rpctls_verify_cafile != NULL || rpctls_verify_capath != NULL) { 533*b9cbc85dSRick Macklem if (rpctls_crlfile != NULL) { 534*b9cbc85dSRick Macklem ret = rpctls_loadcrlfile(ctx); 535*b9cbc85dSRick Macklem if (ret == 0) { 536*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_setupcl_ssl: " 537*b9cbc85dSRick Macklem "Load CRLfile failed\n"); 538*b9cbc85dSRick Macklem SSL_CTX_free(ctx); 539*b9cbc85dSRick Macklem return (NULL); 540*b9cbc85dSRick Macklem } 541*b9cbc85dSRick Macklem } 542*b9cbc85dSRick Macklem #if OPENSSL_VERSION_NUMBER >= 0x30000000 543*b9cbc85dSRick Macklem ret = 1; 544*b9cbc85dSRick Macklem if (rpctls_verify_cafile != NULL) 545*b9cbc85dSRick Macklem ret = SSL_CTX_load_verify_file(ctx, 546*b9cbc85dSRick Macklem rpctls_verify_cafile); 547*b9cbc85dSRick Macklem if (ret != 0 && rpctls_verify_capath != NULL) 548*b9cbc85dSRick Macklem ret = SSL_CTX_load_verify_dir(ctx, 549*b9cbc85dSRick Macklem rpctls_verify_capath); 550*b9cbc85dSRick Macklem #else 551*b9cbc85dSRick Macklem ret = SSL_CTX_load_verify_locations(ctx, 552*b9cbc85dSRick Macklem rpctls_verify_cafile, rpctls_verify_capath); 553*b9cbc85dSRick Macklem #endif 554*b9cbc85dSRick Macklem if (ret == 0) { 555*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_setupcl_ssl: " 556*b9cbc85dSRick Macklem "Can't load verify locations\n"); 557*b9cbc85dSRick Macklem SSL_CTX_free(ctx); 558*b9cbc85dSRick Macklem return (NULL); 559*b9cbc85dSRick Macklem } 560*b9cbc85dSRick Macklem /* 561*b9cbc85dSRick Macklem * The man page says that the 562*b9cbc85dSRick Macklem * SSL_CTX_set0_CA_list() call is not normally 563*b9cbc85dSRick Macklem * needed, but I believe it is harmless. 564*b9cbc85dSRick Macklem */ 565*b9cbc85dSRick Macklem if (rpctls_verify_cafile != NULL) 566*b9cbc85dSRick Macklem SSL_CTX_set0_CA_list(ctx, 567*b9cbc85dSRick Macklem SSL_load_client_CA_file(rpctls_verify_cafile)); 568*b9cbc85dSRick Macklem } 569*b9cbc85dSRick Macklem 570*b9cbc85dSRick Macklem /* RPC-over-TLS must use TLSv1.3, according to the IETF draft.*/ 571*b9cbc85dSRick Macklem #ifdef notyet 572*b9cbc85dSRick Macklem flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | 573*b9cbc85dSRick Macklem SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2; 574*b9cbc85dSRick Macklem #else 575*b9cbc85dSRick Macklem flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_3; 576*b9cbc85dSRick Macklem #endif 577*b9cbc85dSRick Macklem SSL_CTX_set_options(ctx, flags); 578*b9cbc85dSRick Macklem SSL_CTX_clear_mode(ctx, SSL_MODE_NO_KTLS_TX | SSL_MODE_NO_KTLS_RX); 579*b9cbc85dSRick Macklem return (ctx); 580*b9cbc85dSRick Macklem } 581*b9cbc85dSRick Macklem 582*b9cbc85dSRick Macklem static SSL * 583*b9cbc85dSRick Macklem rpctls_connect(SSL_CTX *ctx, int s, char *certname, u_int certlen, X509 **certp) 584*b9cbc85dSRick Macklem { 585*b9cbc85dSRick Macklem SSL *ssl; 586*b9cbc85dSRick Macklem X509 *cert; 587*b9cbc85dSRick Macklem struct sockaddr_storage ad; 588*b9cbc85dSRick Macklem struct sockaddr *sad; 589*b9cbc85dSRick Macklem char hostnam[NI_MAXHOST], path[PATH_MAX]; 590*b9cbc85dSRick Macklem int gethostret, ret; 591*b9cbc85dSRick Macklem char *cp, *cp2; 592*b9cbc85dSRick Macklem size_t len, rlen; 593*b9cbc85dSRick Macklem long verfret; 594*b9cbc85dSRick Macklem 595*b9cbc85dSRick Macklem *certp = NULL; 596*b9cbc85dSRick Macklem sad = (struct sockaddr *)&ad; 597*b9cbc85dSRick Macklem ssl = SSL_new(ctx); 598*b9cbc85dSRick Macklem if (ssl == NULL) { 599*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_connect: " 600*b9cbc85dSRick Macklem "SSL_new failed\n"); 601*b9cbc85dSRick Macklem return (NULL); 602*b9cbc85dSRick Macklem } 603*b9cbc85dSRick Macklem if (SSL_set_fd(ssl, s) != 1) { 604*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_connect: " 605*b9cbc85dSRick Macklem "SSL_set_fd failed\n"); 606*b9cbc85dSRick Macklem SSL_free(ssl); 607*b9cbc85dSRick Macklem return (NULL); 608*b9cbc85dSRick Macklem } 609*b9cbc85dSRick Macklem 610*b9cbc85dSRick Macklem /* 611*b9cbc85dSRick Macklem * If rpctls_cert is true and certname is set, a alternate certificate 612*b9cbc85dSRick Macklem * and key exists in files named <certname>.pem and <certname>key.pem 613*b9cbc85dSRick Macklem * in rpctls_certdir that is to be used for mutual authentication. 614*b9cbc85dSRick Macklem */ 615*b9cbc85dSRick Macklem if (rpctls_cert && certlen > 0) { 616*b9cbc85dSRick Macklem len = strlcpy(path, rpctls_certdir, sizeof(path)); 617*b9cbc85dSRick Macklem rlen = sizeof(path) - len; 618*b9cbc85dSRick Macklem if (rlen <= certlen) { 619*b9cbc85dSRick Macklem SSL_free(ssl); 620*b9cbc85dSRick Macklem return (NULL); 621*b9cbc85dSRick Macklem } 622*b9cbc85dSRick Macklem memcpy(&path[len], certname, certlen); 623*b9cbc85dSRick Macklem rlen -= certlen; 624*b9cbc85dSRick Macklem len += certlen; 625*b9cbc85dSRick Macklem path[len] = '\0'; 626*b9cbc85dSRick Macklem if (strlcpy(&path[len], ".pem", rlen) != 4) { 627*b9cbc85dSRick Macklem SSL_free(ssl); 628*b9cbc85dSRick Macklem return (NULL); 629*b9cbc85dSRick Macklem } 630*b9cbc85dSRick Macklem ret = SSL_use_certificate_file(ssl, path, SSL_FILETYPE_PEM); 631*b9cbc85dSRick Macklem if (ret != 1) { 632*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_connect: can't use " 633*b9cbc85dSRick Macklem "certificate file path=%s ret=%d\n", path, ret); 634*b9cbc85dSRick Macklem SSL_free(ssl); 635*b9cbc85dSRick Macklem return (NULL); 636*b9cbc85dSRick Macklem } 637*b9cbc85dSRick Macklem if (strlcpy(&path[len], "key.pem", rlen) != 7) { 638*b9cbc85dSRick Macklem SSL_free(ssl); 639*b9cbc85dSRick Macklem return (NULL); 640*b9cbc85dSRick Macklem } 641*b9cbc85dSRick Macklem ret = SSL_use_PrivateKey_file(ssl, path, SSL_FILETYPE_PEM); 642*b9cbc85dSRick Macklem if (ret != 1) { 643*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_connect: Can't use " 644*b9cbc85dSRick Macklem "private key path=%s ret=%d\n", path, ret); 645*b9cbc85dSRick Macklem SSL_free(ssl); 646*b9cbc85dSRick Macklem return (NULL); 647*b9cbc85dSRick Macklem } 648*b9cbc85dSRick Macklem } 649*b9cbc85dSRick Macklem 650*b9cbc85dSRick Macklem ret = SSL_connect(ssl); 651*b9cbc85dSRick Macklem if (ret != 1) { 652*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_connect: " 653*b9cbc85dSRick Macklem "SSL_connect failed %d\n", 654*b9cbc85dSRick Macklem ret); 655*b9cbc85dSRick Macklem SSL_free(ssl); 656*b9cbc85dSRick Macklem return (NULL); 657*b9cbc85dSRick Macklem } 658*b9cbc85dSRick Macklem 659*b9cbc85dSRick Macklem cert = SSL_get_peer_certificate(ssl); 660*b9cbc85dSRick Macklem if (cert == NULL) { 661*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_connect: get peer" 662*b9cbc85dSRick Macklem " certificate failed\n"); 663*b9cbc85dSRick Macklem SSL_free(ssl); 664*b9cbc85dSRick Macklem return (NULL); 665*b9cbc85dSRick Macklem } 666*b9cbc85dSRick Macklem gethostret = rpctls_gethost(s, sad, hostnam, sizeof(hostnam)); 667*b9cbc85dSRick Macklem if (gethostret == 0) 668*b9cbc85dSRick Macklem hostnam[0] = '\0'; 669*b9cbc85dSRick Macklem verfret = SSL_get_verify_result(ssl); 670*b9cbc85dSRick Macklem if (verfret == X509_V_OK && (rpctls_verify_cafile != NULL || 671*b9cbc85dSRick Macklem rpctls_verify_capath != NULL) && (gethostret == 0 || 672*b9cbc85dSRick Macklem rpctls_checkhost(sad, cert, X509_CHECK_FLAG_NO_WILDCARDS) != 1)) 673*b9cbc85dSRick Macklem verfret = X509_V_ERR_HOSTNAME_MISMATCH; 674*b9cbc85dSRick Macklem if (verfret != X509_V_OK && (rpctls_verify_cafile != NULL || 675*b9cbc85dSRick Macklem rpctls_verify_capath != NULL)) { 676*b9cbc85dSRick Macklem if (verfret != X509_V_OK) { 677*b9cbc85dSRick Macklem cp = X509_NAME_oneline(X509_get_issuer_name(cert), 678*b9cbc85dSRick Macklem NULL, 0); 679*b9cbc85dSRick Macklem cp2 = X509_NAME_oneline(X509_get_subject_name(cert), 680*b9cbc85dSRick Macklem NULL, 0); 681*b9cbc85dSRick Macklem if (rpctls_debug_level == 0) 682*b9cbc85dSRick Macklem syslog(LOG_INFO | LOG_DAEMON, 683*b9cbc85dSRick Macklem "rpctls_connect: client IP %s " 684*b9cbc85dSRick Macklem "issuerName=%s subjectName=%s verify " 685*b9cbc85dSRick Macklem "failed %s\n", hostnam, cp, cp2, 686*b9cbc85dSRick Macklem X509_verify_cert_error_string(verfret)); 687*b9cbc85dSRick Macklem else 688*b9cbc85dSRick Macklem fprintf(stderr, 689*b9cbc85dSRick Macklem "rpctls_connect: client IP %s " 690*b9cbc85dSRick Macklem "issuerName=%s subjectName=%s verify " 691*b9cbc85dSRick Macklem "failed %s\n", hostnam, cp, cp2, 692*b9cbc85dSRick Macklem X509_verify_cert_error_string(verfret)); 693*b9cbc85dSRick Macklem } 694*b9cbc85dSRick Macklem X509_free(cert); 695*b9cbc85dSRick Macklem SSL_free(ssl); 696*b9cbc85dSRick Macklem return (NULL); 697*b9cbc85dSRick Macklem } 698*b9cbc85dSRick Macklem 699*b9cbc85dSRick Macklem /* Check to see if ktls is enabled on the connection. */ 700*b9cbc85dSRick Macklem ret = BIO_get_ktls_send(SSL_get_wbio(ssl)); 701*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_connect: BIO_get_ktls_send=%d\n", ret); 702*b9cbc85dSRick Macklem if (ret != 0) { 703*b9cbc85dSRick Macklem ret = BIO_get_ktls_recv(SSL_get_rbio(ssl)); 704*b9cbc85dSRick Macklem rpctls_verbose_out("rpctls_connect: BIO_get_ktls_recv=%d\n", 705*b9cbc85dSRick Macklem ret); 706*b9cbc85dSRick Macklem } 707*b9cbc85dSRick Macklem if (ret == 0) { 708*b9cbc85dSRick Macklem if (rpctls_debug_level == 0) 709*b9cbc85dSRick Macklem syslog(LOG_ERR, "ktls not working\n"); 710*b9cbc85dSRick Macklem else 711*b9cbc85dSRick Macklem fprintf(stderr, "ktls not working\n"); 712*b9cbc85dSRick Macklem X509_free(cert); 713*b9cbc85dSRick Macklem SSL_free(ssl); 714*b9cbc85dSRick Macklem return (NULL); 715*b9cbc85dSRick Macklem } 716*b9cbc85dSRick Macklem if (ret == X509_V_OK && (rpctls_verify_cafile != NULL || 717*b9cbc85dSRick Macklem rpctls_verify_capath != NULL) && rpctls_crlfile != NULL) 718*b9cbc85dSRick Macklem *certp = cert; 719*b9cbc85dSRick Macklem else 720*b9cbc85dSRick Macklem X509_free(cert); 721*b9cbc85dSRick Macklem 722*b9cbc85dSRick Macklem return (ssl); 723*b9cbc85dSRick Macklem } 724*b9cbc85dSRick Macklem 725*b9cbc85dSRick Macklem static void 726*b9cbc85dSRick Macklem rpctls_huphandler(int sig __unused) 727*b9cbc85dSRick Macklem { 728*b9cbc85dSRick Macklem 729*b9cbc85dSRick Macklem rpctls_gothup = true; 730*b9cbc85dSRick Macklem } 731