1 /* $NetBSD: ssl.c,v 1.13 2023/02/25 12:07:25 mlelstv Exp $ */ 2 3 /*- 4 * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav 5 * Copyright (c) 2008, 2010 Joerg Sonnenberger <joerg@NetBSD.org> 6 * Copyright (c) 2015 Thomas Klausner <wiz@NetBSD.org> 7 * Copyright (c) 2023 Michael van Elst <mlelstv@NetBSD.org> 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer 15 * in this position and unchanged. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $FreeBSD: common.c,v 1.53 2007/12/19 00:26:36 des Exp $ 34 */ 35 36 #include <sys/cdefs.h> 37 #ifndef lint 38 __RCSID("$NetBSD: ssl.c,v 1.13 2023/02/25 12:07:25 mlelstv Exp $"); 39 #endif 40 41 #include <errno.h> 42 #include <fcntl.h> 43 #include <stdarg.h> 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <string.h> 47 #include <time.h> 48 #include <unistd.h> 49 50 #include <sys/param.h> 51 #include <sys/select.h> 52 #include <sys/uio.h> 53 54 #include <netinet/tcp.h> 55 #include <netinet/in.h> 56 57 #ifdef WITH_SSL 58 #include <openssl/crypto.h> 59 #include <openssl/x509.h> 60 #include <openssl/pem.h> 61 #include <openssl/ssl.h> 62 #include <openssl/err.h> 63 #endif 64 65 #include "ssl.h" 66 67 #include <stringlist.h> 68 #include <histedit.h> 69 #include <sys/poll.h> 70 #include "extern.h" 71 72 extern int quit_time, verbose, ftp_debug; 73 extern FILE *ttyout; 74 75 struct fetch_connect { 76 int sd; /* file/socket descriptor */ 77 char *buf; /* buffer */ 78 size_t bufsize; /* buffer size */ 79 size_t bufpos; /* position of buffer */ 80 size_t buflen; /* length of buffer contents */ 81 struct { /* data cached after an 82 interrupted read */ 83 char *buf; 84 size_t size; 85 size_t pos; 86 size_t len; 87 } cache; 88 int issock; 89 int iserr; 90 int iseof; 91 #ifdef WITH_SSL 92 SSL *ssl; /* SSL handle */ 93 #endif 94 }; 95 96 /* 97 * Write a vector to a connection w/ timeout 98 * Note: can modify the iovec. 99 */ 100 static ssize_t 101 fetch_writev(struct fetch_connect *conn, struct iovec *iov, int iovcnt) 102 { 103 struct timeval now, timeout, delta; 104 fd_set writefds; 105 ssize_t len, total; 106 int fd = conn->sd; 107 int r; 108 109 if (quit_time > 0) { 110 FD_ZERO(&writefds); 111 gettimeofday(&timeout, NULL); 112 timeout.tv_sec += quit_time; 113 } 114 115 total = 0; 116 while (iovcnt > 0) { 117 while (quit_time > 0 && !FD_ISSET(fd, &writefds)) { 118 FD_SET(fd, &writefds); 119 gettimeofday(&now, NULL); 120 delta.tv_sec = timeout.tv_sec - now.tv_sec; 121 delta.tv_usec = timeout.tv_usec - now.tv_usec; 122 if (delta.tv_usec < 0) { 123 delta.tv_usec += 1000000; 124 delta.tv_sec--; 125 } 126 if (delta.tv_sec < 0) { 127 errno = ETIMEDOUT; 128 return -1; 129 } 130 errno = 0; 131 r = select(fd + 1, NULL, &writefds, NULL, &delta); 132 if (r == -1) { 133 if (errno == EINTR) 134 continue; 135 return -1; 136 } 137 } 138 errno = 0; 139 #ifdef WITH_SSL 140 if (conn->ssl != NULL) 141 len = SSL_write(conn->ssl, iov->iov_base, iov->iov_len); 142 else 143 #endif 144 len = writev(fd, iov, iovcnt); 145 if (len == 0) { 146 /* we consider a short write a failure */ 147 /* XXX perhaps we shouldn't in the SSL case */ 148 errno = EPIPE; 149 return -1; 150 } 151 if (len < 0) { 152 if (errno == EINTR || errno == EAGAIN) 153 continue; 154 return -1; 155 } 156 total += len; 157 while (iovcnt > 0 && len >= (ssize_t)iov->iov_len) { 158 len -= iov->iov_len; 159 iov++; 160 iovcnt--; 161 } 162 if (iovcnt > 0) { 163 iov->iov_len -= len; 164 iov->iov_base = (char *)iov->iov_base + len; 165 } 166 } 167 return total; 168 } 169 170 static ssize_t 171 fetch_write(const void *str, size_t len, struct fetch_connect *conn) 172 { 173 struct iovec iov[1]; 174 175 iov[0].iov_base = (char *)__UNCONST(str); 176 iov[0].iov_len = len; 177 return fetch_writev(conn, iov, 1); 178 } 179 180 /* 181 * Send a formatted line; optionally echo to terminal 182 */ 183 int 184 fetch_printf(struct fetch_connect *conn, const char *fmt, ...) 185 { 186 va_list ap; 187 size_t len; 188 char *msg; 189 int r; 190 191 va_start(ap, fmt); 192 len = vasprintf(&msg, fmt, ap); 193 va_end(ap); 194 195 if (msg == NULL) { 196 errno = ENOMEM; 197 return -1; 198 } 199 200 r = fetch_write(msg, len, conn); 201 free(msg); 202 return r; 203 } 204 205 int 206 fetch_fileno(struct fetch_connect *conn) 207 { 208 209 return conn->sd; 210 } 211 212 int 213 fetch_error(struct fetch_connect *conn) 214 { 215 216 return conn->iserr; 217 } 218 219 static void 220 fetch_clearerr(struct fetch_connect *conn) 221 { 222 223 conn->iserr = 0; 224 } 225 226 int 227 fetch_flush(struct fetch_connect *conn) 228 { 229 230 if (conn->issock) { 231 int fd = conn->sd; 232 int v; 233 #ifdef TCP_NOPUSH 234 v = 0; 235 setsockopt(fd, IPPROTO_TCP, TCP_NOPUSH, &v, sizeof(v)); 236 #endif 237 v = 1; 238 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)); 239 } 240 return 0; 241 } 242 243 /*ARGSUSED*/ 244 struct fetch_connect * 245 fetch_open(const char *fname, const char *fmode) 246 { 247 struct fetch_connect *conn; 248 int fd; 249 250 fd = open(fname, O_RDONLY); /* XXX: fmode */ 251 if (fd < 0) 252 return NULL; 253 254 if ((conn = calloc(1, sizeof(*conn))) == NULL) { 255 close(fd); 256 return NULL; 257 } 258 259 conn->sd = fd; 260 conn->issock = 0; 261 return conn; 262 } 263 264 /*ARGSUSED*/ 265 struct fetch_connect * 266 fetch_fdopen(int sd, const char *fmode) 267 { 268 struct fetch_connect *conn; 269 #if defined(SO_NOSIGPIPE) || defined(TCP_NOPUSH) 270 int opt = 1; 271 #endif 272 273 if ((conn = calloc(1, sizeof(*conn))) == NULL) 274 return NULL; 275 276 conn->sd = sd; 277 conn->issock = 1; 278 fcntl(sd, F_SETFD, FD_CLOEXEC); 279 #ifdef SO_NOSIGPIPE 280 setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); 281 #endif 282 #ifdef TCP_NOPUSH 283 setsockopt(sd, IPPROTO_TCP, TCP_NOPUSH, &opt, sizeof(opt)); 284 #endif 285 return conn; 286 } 287 288 int 289 fetch_close(struct fetch_connect *conn) 290 { 291 if (conn == NULL) 292 return 0; 293 294 fetch_flush(conn); 295 #ifdef WITH_SSL 296 SSL_free(conn->ssl); 297 #endif 298 close(conn->sd); 299 free(conn->cache.buf); 300 free(conn->buf); 301 free(conn); 302 return 0; 303 } 304 305 #define FETCH_WRITE_WAIT -3 306 #define FETCH_READ_WAIT -2 307 #define FETCH_READ_ERROR -1 308 309 #ifdef WITH_SSL 310 static ssize_t 311 fetch_ssl_read(SSL *ssl, void *buf, size_t len) 312 { 313 ssize_t rlen; 314 rlen = SSL_read(ssl, buf, len); 315 if (rlen >= 0) 316 return rlen; 317 318 switch (SSL_get_error(ssl, rlen)) { 319 case SSL_ERROR_WANT_READ: 320 return FETCH_READ_WAIT; 321 case SSL_ERROR_WANT_WRITE: 322 return FETCH_WRITE_WAIT; 323 default: 324 ERR_print_errors_fp(ttyout); 325 return FETCH_READ_ERROR; 326 } 327 } 328 #endif /* WITH_SSL */ 329 330 static ssize_t 331 fetch_nonssl_read(int sd, void *buf, size_t len) 332 { 333 ssize_t rlen; 334 335 rlen = read(sd, buf, len); 336 if (rlen == -1) { 337 if (errno == EAGAIN || errno == EINTR) 338 return FETCH_READ_WAIT; 339 return FETCH_READ_ERROR; 340 } 341 return rlen; 342 } 343 344 /* 345 * Cache some data that was read from a socket but cannot be immediately 346 * returned because of an interrupted system call. 347 */ 348 static int 349 fetch_cache_data(struct fetch_connect *conn, char *src, size_t nbytes) 350 { 351 352 if (conn->cache.size < nbytes) { 353 char *tmp = realloc(conn->cache.buf, nbytes); 354 if (tmp == NULL) 355 return -1; 356 357 conn->cache.buf = tmp; 358 conn->cache.size = nbytes; 359 } 360 361 memcpy(conn->cache.buf, src, nbytes); 362 conn->cache.len = nbytes; 363 conn->cache.pos = 0; 364 return 0; 365 } 366 367 static int 368 fetch_wait(struct fetch_connect *conn, ssize_t rlen, struct timeval *timeout) 369 { 370 struct timeval now, delta; 371 int fd = conn->sd; 372 fd_set fds; 373 374 FD_ZERO(&fds); 375 while (!FD_ISSET(fd, &fds)) { 376 FD_SET(fd, &fds); 377 if (quit_time > 0) { 378 gettimeofday(&now, NULL); 379 if (!timercmp(timeout, &now, >)) { 380 fprintf(ttyout, "\r\n%s: transfer aborted" 381 " because stalled for %lu sec.\r\n", 382 getprogname(), (unsigned long)quit_time); 383 errno = ETIMEDOUT; 384 conn->iserr = ETIMEDOUT; 385 return -1; 386 } 387 timersub(timeout, &now, &delta); 388 } 389 errno = 0; 390 if (select(fd + 1, 391 rlen == FETCH_READ_WAIT ? &fds : NULL, 392 rlen == FETCH_WRITE_WAIT ? &fds : NULL, 393 NULL, quit_time > 0 ? &delta : NULL) < 0) { 394 if (errno == EINTR) 395 continue; 396 conn->iserr = errno; 397 return -1; 398 } 399 } 400 return 0; 401 } 402 403 size_t 404 fetch_read(void *ptr, size_t size, size_t nmemb, struct fetch_connect *conn) 405 { 406 ssize_t rlen, total; 407 size_t len; 408 char *start, *buf; 409 struct timeval timeout; 410 411 if (quit_time > 0) { 412 gettimeofday(&timeout, NULL); 413 timeout.tv_sec += quit_time; 414 } 415 416 total = 0; 417 start = buf = ptr; 418 len = size * nmemb; 419 420 if (conn->cache.len > 0) { 421 /* 422 * The last invocation of fetch_read was interrupted by a 423 * signal after some data had been read from the socket. Copy 424 * the cached data into the supplied buffer before trying to 425 * read from the socket again. 426 */ 427 total = (conn->cache.len < len) ? conn->cache.len : len; 428 memcpy(buf, conn->cache.buf, total); 429 430 conn->cache.len -= total; 431 conn->cache.pos += total; 432 len -= total; 433 buf += total; 434 } 435 436 while (len > 0) { 437 /* 438 * The socket is non-blocking. Instead of the canonical 439 * select() -> read(), we do the following: 440 * 441 * 1) call read() or SSL_read(). 442 * 2) if an error occurred, return -1. 443 * 3) if we received data but we still expect more, 444 * update our counters and loop. 445 * 4) if read() or SSL_read() signaled EOF, return. 446 * 5) if we did not receive any data but we're not at EOF, 447 * call select(). 448 * 449 * In the SSL case, this is necessary because if we 450 * receive a close notification, we have to call 451 * SSL_read() one additional time after we've read 452 * everything we received. 453 * 454 * In the non-SSL case, it may improve performance (very 455 * slightly) when reading small amounts of data. 456 */ 457 #ifdef WITH_SSL 458 if (conn->ssl != NULL) 459 rlen = fetch_ssl_read(conn->ssl, buf, len); 460 else 461 #endif 462 rlen = fetch_nonssl_read(conn->sd, buf, len); 463 switch (rlen) { 464 case 0: 465 conn->iseof = 1; 466 return total; 467 case FETCH_READ_ERROR: 468 conn->iserr = errno; 469 if (errno == EINTR) 470 fetch_cache_data(conn, start, total); 471 return 0; 472 case FETCH_READ_WAIT: 473 case FETCH_WRITE_WAIT: 474 if (fetch_wait(conn, rlen, &timeout) == -1) 475 return 0; 476 break; 477 default: 478 len -= rlen; 479 buf += rlen; 480 total += rlen; 481 break; 482 } 483 } 484 return total; 485 } 486 487 #define MIN_BUF_SIZE 1024 488 489 /* 490 * Read a line of text from a connection w/ timeout 491 */ 492 char * 493 fetch_getln(char *str, int size, struct fetch_connect *conn) 494 { 495 size_t tmpsize; 496 size_t len; 497 char c; 498 499 if (conn->buf == NULL) { 500 if ((conn->buf = malloc(MIN_BUF_SIZE)) == NULL) { 501 errno = ENOMEM; 502 conn->iserr = 1; 503 return NULL; 504 } 505 conn->bufsize = MIN_BUF_SIZE; 506 } 507 508 if (conn->iserr || conn->iseof) 509 return NULL; 510 511 if (conn->buflen - conn->bufpos > 0) 512 goto done; 513 514 conn->buf[0] = '\0'; 515 conn->bufpos = 0; 516 conn->buflen = 0; 517 do { 518 len = fetch_read(&c, sizeof(c), 1, conn); 519 if (len == 0) { 520 if (conn->iserr) 521 return NULL; 522 if (conn->iseof) 523 break; 524 abort(); 525 } 526 conn->buf[conn->buflen++] = c; 527 if (conn->buflen == conn->bufsize) { 528 char *tmp = conn->buf; 529 tmpsize = conn->bufsize * 2 + 1; 530 if ((tmp = realloc(tmp, tmpsize)) == NULL) { 531 errno = ENOMEM; 532 conn->iserr = 1; 533 return NULL; 534 } 535 conn->buf = tmp; 536 conn->bufsize = tmpsize; 537 } 538 } while (c != '\n'); 539 540 if (conn->buflen == 0) 541 return NULL; 542 done: 543 tmpsize = MIN(size - 1, (int)(conn->buflen - conn->bufpos)); 544 memcpy(str, conn->buf + conn->bufpos, tmpsize); 545 str[tmpsize] = '\0'; 546 conn->bufpos += tmpsize; 547 return str; 548 } 549 550 int 551 fetch_getline(struct fetch_connect *conn, char *buf, size_t buflen, 552 const char **errormsg) 553 { 554 size_t len; 555 int rv; 556 557 if (fetch_getln(buf, buflen, conn) == NULL) { 558 if (conn->iseof) { /* EOF */ 559 rv = -2; 560 if (errormsg) 561 *errormsg = "\nEOF received"; 562 } else { /* error */ 563 rv = -1; 564 if (errormsg) 565 *errormsg = "Error encountered"; 566 } 567 fetch_clearerr(conn); 568 return rv; 569 } 570 len = strlen(buf); 571 if (buf[len - 1] == '\n') { /* clear any trailing newline */ 572 buf[--len] = '\0'; 573 } else if (len == buflen - 1) { /* line too long */ 574 while (1) { 575 char c; 576 size_t rlen = fetch_read(&c, sizeof(c), 1, conn); 577 if (rlen == 0 || c == '\n') 578 break; 579 } 580 if (errormsg) 581 *errormsg = "Input line is too long"; 582 fetch_clearerr(conn); 583 return -3; 584 } 585 if (errormsg) 586 *errormsg = NULL; 587 return len; 588 } 589 590 #ifdef WITH_SSL 591 void * 592 fetch_start_ssl(int sock, const char *servername) 593 { 594 SSL *ssl; 595 SSL_CTX *ctx; 596 X509_VERIFY_PARAM *param; 597 int ret, ssl_err; 598 int verify = !ftp_truthy("sslnoverify", getoptionvalue("sslnoverify"), 0); 599 600 /* Init the SSL library and context */ 601 if (!SSL_library_init()){ 602 fprintf(ttyout, "SSL library init failed\n"); 603 return NULL; 604 } 605 606 SSL_load_error_strings(); 607 608 ctx = SSL_CTX_new(SSLv23_client_method()); 609 SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); 610 if (verify) { 611 SSL_CTX_set_default_verify_paths(ctx); 612 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 613 } 614 615 ssl = SSL_new(ctx); 616 if (ssl == NULL){ 617 fprintf(ttyout, "SSL context creation failed\n"); 618 SSL_CTX_free(ctx); 619 return NULL; 620 } 621 622 if (verify) { 623 param = SSL_get0_param(ssl); 624 if (!X509_VERIFY_PARAM_set1_host(param, servername, 625 strlen(servername))) { 626 fprintf(ttyout, "SSL verification setup failed\n"); 627 SSL_free(ssl); 628 SSL_CTX_free(ctx); 629 return NULL; 630 } 631 632 /* Enable peer verification, (using the default callback) */ 633 SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); 634 } 635 636 SSL_set_fd(ssl, sock); 637 if (!SSL_set_tlsext_host_name(ssl, __UNCONST(servername))) { 638 fprintf(ttyout, "SSL hostname setting failed\n"); 639 SSL_free(ssl); 640 SSL_CTX_free(ctx); 641 return NULL; 642 } 643 while ((ret = SSL_connect(ssl)) == -1) { 644 ssl_err = SSL_get_error(ssl, ret); 645 if (ssl_err != SSL_ERROR_WANT_READ && 646 ssl_err != SSL_ERROR_WANT_WRITE) { 647 ERR_print_errors_fp(ttyout); 648 SSL_free(ssl); 649 SSL_CTX_free(ctx); 650 return NULL; 651 } 652 } 653 654 if (ftp_debug && verbose) { 655 X509 *cert; 656 X509_NAME *name; 657 char *str; 658 659 fprintf(ttyout, "SSL connection established using %s\n", 660 SSL_get_cipher(ssl)); 661 cert = SSL_get_peer_certificate(ssl); 662 name = X509_get_subject_name(cert); 663 str = X509_NAME_oneline(name, 0, 0); 664 fprintf(ttyout, "Certificate subject: %s\n", str); 665 free(str); 666 name = X509_get_issuer_name(cert); 667 str = X509_NAME_oneline(name, 0, 0); 668 fprintf(ttyout, "Certificate issuer: %s\n", str); 669 free(str); 670 } 671 672 return ssl; 673 } 674 #endif /* WITH_SSL */ 675 676 677 void 678 fetch_set_ssl(struct fetch_connect *conn, void *ssl) 679 { 680 #ifdef WITH_SSL 681 conn->ssl = ssl; 682 #endif 683 } 684