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