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