1 /* 2 * Copyright (c) 1999-2006, 2008 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 */ 10 11 #pragma ident "%Z%%M% %I% %E% SMI" 12 13 #include <sm/gen.h> 14 SM_RCSID("@(#)$Id: sfsasl.c,v 8.117 2008/01/31 18:48:29 ca Exp $") 15 #include <stdlib.h> 16 #include <sendmail.h> 17 #include <sm/time.h> 18 #include <errno.h> 19 20 /* allow to disable error handling code just in case... */ 21 #ifndef DEAL_WITH_ERROR_SSL 22 # define DEAL_WITH_ERROR_SSL 1 23 #endif /* ! DEAL_WITH_ERROR_SSL */ 24 25 #if SASL 26 # include "sfsasl.h" 27 28 /* Structure used by the "sasl" file type */ 29 struct sasl_obj 30 { 31 SM_FILE_T *fp; 32 sasl_conn_t *conn; 33 }; 34 35 struct sasl_info 36 { 37 SM_FILE_T *fp; 38 sasl_conn_t *conn; 39 }; 40 41 /* 42 ** SASL_GETINFO - returns requested information about a "sasl" file 43 ** descriptor. 44 ** 45 ** Parameters: 46 ** fp -- the file descriptor 47 ** what -- the type of information requested 48 ** valp -- the thang to return the information in 49 ** 50 ** Returns: 51 ** -1 for unknown requests 52 ** >=0 on success with valp filled in (if possible). 53 */ 54 55 static int sasl_getinfo __P((SM_FILE_T *, int, void *)); 56 57 static int 58 sasl_getinfo(fp, what, valp) 59 SM_FILE_T *fp; 60 int what; 61 void *valp; 62 { 63 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie; 64 65 switch (what) 66 { 67 case SM_IO_WHAT_FD: 68 if (so->fp == NULL) 69 return -1; 70 return so->fp->f_file; /* for stdio fileno() compatability */ 71 72 case SM_IO_IS_READABLE: 73 if (so->fp == NULL) 74 return 0; 75 76 /* get info from underlying file */ 77 return sm_io_getinfo(so->fp, what, valp); 78 79 default: 80 return -1; 81 } 82 } 83 84 /* 85 ** SASL_OPEN -- creates the sasl specific information for opening a 86 ** file of the sasl type. 87 ** 88 ** Parameters: 89 ** fp -- the file pointer associated with the new open 90 ** info -- contains the sasl connection information pointer and 91 ** the original SM_FILE_T that holds the open 92 ** flags -- ignored 93 ** rpool -- ignored 94 ** 95 ** Returns: 96 ** 0 on success 97 */ 98 99 static int sasl_open __P((SM_FILE_T *, const void *, int, const void *)); 100 101 /* ARGSUSED2 */ 102 static int 103 sasl_open(fp, info, flags, rpool) 104 SM_FILE_T *fp; 105 const void *info; 106 int flags; 107 const void *rpool; 108 { 109 struct sasl_obj *so; 110 struct sasl_info *si = (struct sasl_info *) info; 111 112 so = (struct sasl_obj *) sm_malloc(sizeof(struct sasl_obj)); 113 if (so == NULL) 114 { 115 errno = ENOMEM; 116 return -1; 117 } 118 so->fp = si->fp; 119 so->conn = si->conn; 120 121 /* 122 ** The underlying 'fp' is set to SM_IO_NOW so that the entire 123 ** encoded string is written in one chunk. Otherwise there is 124 ** the possibility that it may appear illegal, bogus or 125 ** mangled to the other side of the connection. 126 ** We will read or write through 'fp' since it is the opaque 127 ** connection for the communications. We need to treat it this 128 ** way in case the encoded string is to be sent down a TLS 129 ** connection rather than, say, sm_io's stdio. 130 */ 131 132 (void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0); 133 fp->f_cookie = so; 134 return 0; 135 } 136 137 /* 138 ** SASL_CLOSE -- close the sasl specific parts of the sasl file pointer 139 ** 140 ** Parameters: 141 ** fp -- the file pointer to close 142 ** 143 ** Returns: 144 ** 0 on success 145 */ 146 147 static int sasl_close __P((SM_FILE_T *)); 148 149 static int 150 sasl_close(fp) 151 SM_FILE_T *fp; 152 { 153 struct sasl_obj *so; 154 155 so = (struct sasl_obj *) fp->f_cookie; 156 if (so == NULL) 157 return 0; 158 if (so->fp != NULL) 159 { 160 sm_io_close(so->fp, SM_TIME_DEFAULT); 161 so->fp = NULL; 162 } 163 sm_free(so); 164 so = NULL; 165 return 0; 166 } 167 168 /* how to deallocate a buffer allocated by SASL */ 169 extern void sm_sasl_free __P((void *)); 170 # define SASL_DEALLOC(b) sm_sasl_free(b) 171 172 /* 173 ** SASL_READ -- read encrypted information and decrypt it for the caller 174 ** 175 ** Parameters: 176 ** fp -- the file pointer 177 ** buf -- the location to place the decrypted information 178 ** size -- the number of bytes to read after decryption 179 ** 180 ** Results: 181 ** -1 on error 182 ** otherwise the number of bytes read 183 */ 184 185 static ssize_t sasl_read __P((SM_FILE_T *, char *, size_t)); 186 187 static ssize_t 188 sasl_read(fp, buf, size) 189 SM_FILE_T *fp; 190 char *buf; 191 size_t size; 192 { 193 int result; 194 ssize_t len; 195 # if SASL >= 20000 196 static const char *outbuf = NULL; 197 # else /* SASL >= 20000 */ 198 static char *outbuf = NULL; 199 # endif /* SASL >= 20000 */ 200 static unsigned int outlen = 0; 201 static unsigned int offset = 0; 202 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie; 203 204 /* 205 ** sasl_decode() may require more data than a single read() returns. 206 ** Hence we have to put a loop around the decoding. 207 ** This also requires that we may have to split up the returned 208 ** data since it might be larger than the allowed size. 209 ** Therefore we use a static pointer and return portions of it 210 ** if necessary. 211 ** XXX Note: This function is not thread-safe nor can it be used 212 ** on more than one file. A correct implementation would store 213 ** this data in fp->f_cookie. 214 */ 215 216 # if SASL >= 20000 217 while (outlen == 0) 218 # else /* SASL >= 20000 */ 219 while (outbuf == NULL && outlen == 0) 220 # endif /* SASL >= 20000 */ 221 { 222 len = sm_io_read(so->fp, SM_TIME_DEFAULT, buf, size); 223 if (len <= 0) 224 return len; 225 result = sasl_decode(so->conn, buf, 226 (unsigned int) len, &outbuf, &outlen); 227 if (result != SASL_OK) 228 { 229 if (LogLevel > 7) 230 sm_syslog(LOG_WARNING, NOQID, 231 "AUTH: sasl_decode error=%d", result); 232 outbuf = NULL; 233 offset = 0; 234 outlen = 0; 235 return -1; 236 } 237 } 238 239 if (outbuf == NULL) 240 { 241 /* be paranoid: outbuf == NULL but outlen != 0 */ 242 syserr("@sasl_read failure: outbuf == NULL but outlen != 0"); 243 /* NOTREACHED */ 244 } 245 if (outlen - offset > size) 246 { 247 /* return another part of the buffer */ 248 (void) memcpy(buf, outbuf + offset, size); 249 offset += size; 250 len = size; 251 } 252 else 253 { 254 /* return the rest of the buffer */ 255 len = outlen - offset; 256 (void) memcpy(buf, outbuf + offset, (size_t) len); 257 # if SASL < 20000 258 SASL_DEALLOC(outbuf); 259 # endif /* SASL < 20000 */ 260 outbuf = NULL; 261 offset = 0; 262 outlen = 0; 263 } 264 return len; 265 } 266 267 /* 268 ** SASL_WRITE -- write information out after encrypting it 269 ** 270 ** Parameters: 271 ** fp -- the file pointer 272 ** buf -- holds the data to be encrypted and written 273 ** size -- the number of bytes to have encrypted and written 274 ** 275 ** Returns: 276 ** -1 on error 277 ** otherwise number of bytes written 278 */ 279 280 static ssize_t sasl_write __P((SM_FILE_T *, const char *, size_t)); 281 282 static ssize_t 283 sasl_write(fp, buf, size) 284 SM_FILE_T *fp; 285 const char *buf; 286 size_t size; 287 { 288 int result; 289 # if SASL >= 20000 290 const char *outbuf; 291 # else /* SASL >= 20000 */ 292 char *outbuf; 293 # endif /* SASL >= 20000 */ 294 unsigned int outlen, *maxencode; 295 size_t ret = 0, total = 0; 296 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie; 297 298 /* 299 ** Fetch the maximum input buffer size for sasl_encode(). 300 ** This can be less than the size set in attemptauth() 301 ** due to a negotation with the other side, e.g., 302 ** Cyrus IMAP lmtp program sets maxbuf=4096, 303 ** digestmd5 substracts 25 and hence we'll get 4071 304 ** instead of 8192 (MAXOUTLEN). 305 ** Hack (for now): simply reduce the size, callers are (must be) 306 ** able to deal with that and invoke sasl_write() again with 307 ** the rest of the data. 308 ** Note: it would be better to store this value in the context 309 ** after the negotiation. 310 */ 311 312 result = sasl_getprop(so->conn, SASL_MAXOUTBUF, 313 (const void **) &maxencode); 314 if (result == SASL_OK && size > *maxencode && *maxencode > 0) 315 size = *maxencode; 316 317 result = sasl_encode(so->conn, buf, 318 (unsigned int) size, &outbuf, &outlen); 319 320 if (result != SASL_OK) 321 { 322 if (LogLevel > 7) 323 sm_syslog(LOG_WARNING, NOQID, 324 "AUTH: sasl_encode error=%d", result); 325 return -1; 326 } 327 328 if (outbuf != NULL) 329 { 330 while (outlen > 0) 331 { 332 errno = 0; 333 /* XXX result == 0? */ 334 ret = sm_io_write(so->fp, SM_TIME_DEFAULT, 335 &outbuf[total], outlen); 336 if (ret <= 0) 337 return ret; 338 outlen -= ret; 339 total += ret; 340 } 341 # if SASL < 20000 342 SASL_DEALLOC(outbuf); 343 # endif /* SASL < 20000 */ 344 } 345 return size; 346 } 347 348 /* 349 ** SFDCSASL -- create sasl file type and open in and out file pointers 350 ** for sendmail to read from and write to. 351 ** 352 ** Parameters: 353 ** fin -- the sm_io file encrypted data to be read from 354 ** fout -- the sm_io file encrypted data to be written to 355 ** conn -- the sasl connection pointer 356 ** tmo -- timeout 357 ** 358 ** Returns: 359 ** -1 on error 360 ** 0 on success 361 ** 362 ** Side effects: 363 ** The arguments "fin" and "fout" are replaced with the new 364 ** SM_FILE_T pointers. 365 */ 366 367 int 368 sfdcsasl(fin, fout, conn, tmo) 369 SM_FILE_T **fin; 370 SM_FILE_T **fout; 371 sasl_conn_t *conn; 372 int tmo; 373 { 374 SM_FILE_T *newin, *newout; 375 SM_FILE_T SM_IO_SET_TYPE(sasl_vector, "sasl", sasl_open, sasl_close, 376 sasl_read, sasl_write, NULL, sasl_getinfo, NULL, 377 SM_TIME_DEFAULT); 378 struct sasl_info info; 379 380 if (conn == NULL) 381 { 382 /* no need to do anything */ 383 return 0; 384 } 385 386 SM_IO_INIT_TYPE(sasl_vector, "sasl", sasl_open, sasl_close, 387 sasl_read, sasl_write, NULL, sasl_getinfo, NULL, 388 SM_TIME_DEFAULT); 389 info.fp = *fin; 390 info.conn = conn; 391 newin = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info, 392 SM_IO_RDONLY_B, NULL); 393 394 if (newin == NULL) 395 return -1; 396 397 info.fp = *fout; 398 info.conn = conn; 399 newout = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info, 400 SM_IO_WRONLY_B, NULL); 401 402 if (newout == NULL) 403 { 404 (void) sm_io_close(newin, SM_TIME_DEFAULT); 405 return -1; 406 } 407 sm_io_automode(newin, newout); 408 409 sm_io_setinfo(*fin, SM_IO_WHAT_TIMEOUT, &tmo); 410 sm_io_setinfo(*fout, SM_IO_WHAT_TIMEOUT, &tmo); 411 412 *fin = newin; 413 *fout = newout; 414 return 0; 415 } 416 #endif /* SASL */ 417 418 #if STARTTLS 419 # include "sfsasl.h" 420 # include <openssl/err.h> 421 422 /* Structure used by the "tls" file type */ 423 struct tls_obj 424 { 425 SM_FILE_T *fp; 426 SSL *con; 427 }; 428 429 struct tls_info 430 { 431 SM_FILE_T *fp; 432 SSL *con; 433 }; 434 435 /* 436 ** TLS_GETINFO - returns requested information about a "tls" file 437 ** descriptor. 438 ** 439 ** Parameters: 440 ** fp -- the file descriptor 441 ** what -- the type of information requested 442 ** valp -- the thang to return the information in (unused) 443 ** 444 ** Returns: 445 ** -1 for unknown requests 446 ** >=0 on success with valp filled in (if possible). 447 */ 448 449 static int tls_getinfo __P((SM_FILE_T *, int, void *)); 450 451 /* ARGSUSED2 */ 452 static int 453 tls_getinfo(fp, what, valp) 454 SM_FILE_T *fp; 455 int what; 456 void *valp; 457 { 458 struct tls_obj *so = (struct tls_obj *) fp->f_cookie; 459 460 switch (what) 461 { 462 case SM_IO_WHAT_FD: 463 if (so->fp == NULL) 464 return -1; 465 return so->fp->f_file; /* for stdio fileno() compatability */ 466 467 case SM_IO_IS_READABLE: 468 return SSL_pending(so->con) > 0; 469 470 default: 471 return -1; 472 } 473 } 474 475 /* 476 ** TLS_OPEN -- creates the tls specific information for opening a 477 ** file of the tls type. 478 ** 479 ** Parameters: 480 ** fp -- the file pointer associated with the new open 481 ** info -- the sm_io file pointer holding the open and the 482 ** TLS encryption connection to be read from or written to 483 ** flags -- ignored 484 ** rpool -- ignored 485 ** 486 ** Returns: 487 ** 0 on success 488 */ 489 490 static int tls_open __P((SM_FILE_T *, const void *, int, const void *)); 491 492 /* ARGSUSED2 */ 493 static int 494 tls_open(fp, info, flags, rpool) 495 SM_FILE_T *fp; 496 const void *info; 497 int flags; 498 const void *rpool; 499 { 500 struct tls_obj *so; 501 struct tls_info *ti = (struct tls_info *) info; 502 503 so = (struct tls_obj *) sm_malloc(sizeof(struct tls_obj)); 504 if (so == NULL) 505 { 506 errno = ENOMEM; 507 return -1; 508 } 509 so->fp = ti->fp; 510 so->con = ti->con; 511 512 /* 513 ** We try to get the "raw" file descriptor that TLS uses to 514 ** do the actual read/write with. This is to allow us control 515 ** over the file descriptor being a blocking or non-blocking type. 516 ** Under the covers TLS handles the change and this allows us 517 ** to do timeouts with sm_io. 518 */ 519 520 fp->f_file = sm_io_getinfo(so->fp, SM_IO_WHAT_FD, NULL); 521 (void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0); 522 fp->f_cookie = so; 523 return 0; 524 } 525 526 /* 527 ** TLS_CLOSE -- close the tls specific parts of the tls file pointer 528 ** 529 ** Parameters: 530 ** fp -- the file pointer to close 531 ** 532 ** Returns: 533 ** 0 on success 534 */ 535 536 static int tls_close __P((SM_FILE_T *)); 537 538 static int 539 tls_close(fp) 540 SM_FILE_T *fp; 541 { 542 struct tls_obj *so; 543 544 so = (struct tls_obj *) fp->f_cookie; 545 if (so == NULL) 546 return 0; 547 if (so->fp != NULL) 548 { 549 sm_io_close(so->fp, SM_TIME_DEFAULT); 550 so->fp = NULL; 551 } 552 sm_free(so); 553 so = NULL; 554 return 0; 555 } 556 557 /* maximum number of retries for TLS related I/O due to handshakes */ 558 # define MAX_TLS_IOS 4 559 560 /* 561 ** TLS_RETRY -- check whether a failed SSL operation can be retried 562 ** 563 ** Parameters: 564 ** ssl -- TLS structure 565 ** rfd -- read fd 566 ** wfd -- write fd 567 ** tlsstart -- start time of TLS operation 568 ** timeout -- timeout for TLS operation 569 ** err -- SSL error 570 ** where -- description of operation 571 ** 572 ** Results: 573 ** >0 on success 574 ** 0 on timeout 575 ** <0 on error 576 */ 577 578 int 579 tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where) 580 SSL *ssl; 581 int rfd; 582 int wfd; 583 time_t tlsstart; 584 int timeout; 585 int err; 586 const char *where; 587 { 588 int ret; 589 time_t left; 590 time_t now = curtime(); 591 struct timeval tv; 592 593 ret = -1; 594 595 /* 596 ** For SSL_ERROR_WANT_{READ,WRITE}: 597 ** There is not a complete SSL record available yet 598 ** or there is only a partial SSL record removed from 599 ** the network (socket) buffer into the SSL buffer. 600 ** The SSL_connect will only succeed when a full 601 ** SSL record is available (assuming a "real" error 602 ** doesn't happen). To handle when a "real" error 603 ** does happen the select is set for exceptions too. 604 ** The connection may be re-negotiated during this time 605 ** so both read and write "want errors" need to be handled. 606 ** A select() exception loops back so that a proper SSL 607 ** error message can be gotten. 608 */ 609 610 left = timeout - (now - tlsstart); 611 if (left <= 0) 612 return 0; /* timeout */ 613 tv.tv_sec = left; 614 tv.tv_usec = 0; 615 616 if (LogLevel > 14) 617 { 618 sm_syslog(LOG_INFO, NOQID, 619 "STARTTLS=%s, info: fds=%d/%d, err=%d", 620 where, rfd, wfd, err); 621 } 622 623 if (FD_SETSIZE > 0 && 624 ((err == SSL_ERROR_WANT_READ && rfd >= FD_SETSIZE) || 625 (err == SSL_ERROR_WANT_WRITE && wfd >= FD_SETSIZE))) 626 { 627 if (LogLevel > 5) 628 { 629 sm_syslog(LOG_ERR, NOQID, 630 "STARTTLS=%s, error: fd %d/%d too large", 631 where, rfd, wfd); 632 if (LogLevel > 8) 633 tlslogerr(where); 634 } 635 errno = EINVAL; 636 } 637 else if (err == SSL_ERROR_WANT_READ) 638 { 639 fd_set ssl_maskr, ssl_maskx; 640 641 FD_ZERO(&ssl_maskr); 642 FD_SET(rfd, &ssl_maskr); 643 FD_ZERO(&ssl_maskx); 644 FD_SET(rfd, &ssl_maskx); 645 do 646 { 647 ret = select(rfd + 1, &ssl_maskr, NULL, &ssl_maskx, 648 &tv); 649 } while (ret < 0 && errno == EINTR); 650 if (ret < 0 && errno > 0) 651 ret = -errno; 652 } 653 else if (err == SSL_ERROR_WANT_WRITE) 654 { 655 fd_set ssl_maskw, ssl_maskx; 656 657 FD_ZERO(&ssl_maskw); 658 FD_SET(wfd, &ssl_maskw); 659 FD_ZERO(&ssl_maskx); 660 FD_SET(rfd, &ssl_maskx); 661 do 662 { 663 ret = select(wfd + 1, NULL, &ssl_maskw, &ssl_maskx, 664 &tv); 665 } while (ret < 0 && errno == EINTR); 666 if (ret < 0 && errno > 0) 667 ret = -errno; 668 } 669 return ret; 670 } 671 672 /* errno to force refill() etc to stop (see IS_IO_ERROR()) */ 673 #ifdef ETIMEDOUT 674 # define SM_ERR_TIMEOUT ETIMEDOUT 675 #else /* ETIMEDOUT */ 676 # define SM_ERR_TIMEOUT EIO 677 #endif /* ETIMEDOUT */ 678 679 /* 680 ** SET_TLS_RD_TMO -- read secured information for the caller 681 ** 682 ** Parameters: 683 ** rd_tmo -- read timeout 684 ** 685 ** Results: 686 ** none 687 ** This is a hack: there is no way to pass it in 688 */ 689 690 static int tls_rd_tmo = -1; 691 692 void 693 set_tls_rd_tmo(rd_tmo) 694 int rd_tmo; 695 { 696 tls_rd_tmo = rd_tmo; 697 } 698 699 /* 700 ** TLS_READ -- read secured information for the caller 701 ** 702 ** Parameters: 703 ** fp -- the file pointer 704 ** buf -- the location to place the data 705 ** size -- the number of bytes to read from connection 706 ** 707 ** Results: 708 ** -1 on error 709 ** otherwise the number of bytes read 710 */ 711 712 static ssize_t tls_read __P((SM_FILE_T *, char *, size_t)); 713 714 static ssize_t 715 tls_read(fp, buf, size) 716 SM_FILE_T *fp; 717 char *buf; 718 size_t size; 719 { 720 int r, rfd, wfd, try, ssl_err; 721 struct tls_obj *so = (struct tls_obj *) fp->f_cookie; 722 time_t tlsstart; 723 char *err; 724 725 try = 99; 726 err = NULL; 727 tlsstart = curtime(); 728 729 retry: 730 r = SSL_read(so->con, (char *) buf, size); 731 732 if (r > 0) 733 return r; 734 735 err = NULL; 736 switch (ssl_err = SSL_get_error(so->con, r)) 737 { 738 case SSL_ERROR_NONE: 739 case SSL_ERROR_ZERO_RETURN: 740 break; 741 case SSL_ERROR_WANT_WRITE: 742 err = "read W BLOCK"; 743 /* FALLTHROUGH */ 744 case SSL_ERROR_WANT_READ: 745 if (err == NULL) 746 err = "read R BLOCK"; 747 rfd = SSL_get_rfd(so->con); 748 wfd = SSL_get_wfd(so->con); 749 try = tls_retry(so->con, rfd, wfd, tlsstart, 750 (tls_rd_tmo < 0) ? TimeOuts.to_datablock 751 : tls_rd_tmo, 752 ssl_err, "read"); 753 if (try > 0) 754 goto retry; 755 errno = SM_ERR_TIMEOUT; 756 break; 757 758 case SSL_ERROR_WANT_X509_LOOKUP: 759 err = "write X BLOCK"; 760 break; 761 case SSL_ERROR_SYSCALL: 762 if (r == 0 && errno == 0) /* out of protocol EOF found */ 763 break; 764 err = "syscall error"; 765 /* 766 get_last_socket_error()); 767 */ 768 break; 769 case SSL_ERROR_SSL: 770 #if DEAL_WITH_ERROR_SSL 771 if (r == 0 && errno == 0) /* out of protocol EOF found */ 772 break; 773 #endif /* DEAL_WITH_ERROR_SSL */ 774 err = "generic SSL error"; 775 if (LogLevel > 9) 776 tlslogerr("read"); 777 778 #if DEAL_WITH_ERROR_SSL 779 /* avoid repeated calls? */ 780 if (r == 0) 781 r = -1; 782 #endif /* DEAL_WITH_ERROR_SSL */ 783 break; 784 } 785 if (err != NULL) 786 { 787 int save_errno; 788 789 save_errno = (errno == 0) ? EIO : errno; 790 if (try == 0 && save_errno == SM_ERR_TIMEOUT) 791 { 792 if (LogLevel > 7) 793 sm_syslog(LOG_WARNING, NOQID, 794 "STARTTLS: read error=timeout"); 795 } 796 else if (LogLevel > 8) 797 sm_syslog(LOG_WARNING, NOQID, 798 "STARTTLS: read error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d", 799 err, r, errno, 800 ERR_error_string(ERR_get_error(), NULL), try, 801 ssl_err); 802 else if (LogLevel > 7) 803 sm_syslog(LOG_WARNING, NOQID, 804 "STARTTLS: read error=%s (%d), retry=%d, ssl_err=%d", 805 err, r, errno, try, ssl_err); 806 errno = save_errno; 807 } 808 return r; 809 } 810 811 /* 812 ** TLS_WRITE -- write information out through secure connection 813 ** 814 ** Parameters: 815 ** fp -- the file pointer 816 ** buf -- holds the data to be securely written 817 ** size -- the number of bytes to write 818 ** 819 ** Returns: 820 ** -1 on error 821 ** otherwise number of bytes written 822 */ 823 824 static ssize_t tls_write __P((SM_FILE_T *, const char *, size_t)); 825 826 static ssize_t 827 tls_write(fp, buf, size) 828 SM_FILE_T *fp; 829 const char *buf; 830 size_t size; 831 { 832 int r, rfd, wfd, try, ssl_err; 833 struct tls_obj *so = (struct tls_obj *) fp->f_cookie; 834 time_t tlsstart; 835 char *err; 836 837 try = 99; 838 err = NULL; 839 tlsstart = curtime(); 840 841 retry: 842 r = SSL_write(so->con, (char *) buf, size); 843 844 if (r > 0) 845 return r; 846 err = NULL; 847 switch (ssl_err = SSL_get_error(so->con, r)) 848 { 849 case SSL_ERROR_NONE: 850 case SSL_ERROR_ZERO_RETURN: 851 break; 852 case SSL_ERROR_WANT_WRITE: 853 err = "read W BLOCK"; 854 /* FALLTHROUGH */ 855 case SSL_ERROR_WANT_READ: 856 if (err == NULL) 857 err = "read R BLOCK"; 858 rfd = SSL_get_rfd(so->con); 859 wfd = SSL_get_wfd(so->con); 860 try = tls_retry(so->con, rfd, wfd, tlsstart, 861 DATA_PROGRESS_TIMEOUT, ssl_err, "write"); 862 if (try > 0) 863 goto retry; 864 errno = SM_ERR_TIMEOUT; 865 break; 866 case SSL_ERROR_WANT_X509_LOOKUP: 867 err = "write X BLOCK"; 868 break; 869 case SSL_ERROR_SYSCALL: 870 if (r == 0 && errno == 0) /* out of protocol EOF found */ 871 break; 872 err = "syscall error"; 873 /* 874 get_last_socket_error()); 875 */ 876 break; 877 case SSL_ERROR_SSL: 878 err = "generic SSL error"; 879 /* 880 ERR_GET_REASON(ERR_peek_error())); 881 */ 882 if (LogLevel > 9) 883 tlslogerr("write"); 884 885 #if DEAL_WITH_ERROR_SSL 886 /* avoid repeated calls? */ 887 if (r == 0) 888 r = -1; 889 #endif /* DEAL_WITH_ERROR_SSL */ 890 break; 891 } 892 if (err != NULL) 893 { 894 int save_errno; 895 896 save_errno = (errno == 0) ? EIO : errno; 897 if (try == 0 && save_errno == SM_ERR_TIMEOUT) 898 { 899 if (LogLevel > 7) 900 sm_syslog(LOG_WARNING, NOQID, 901 "STARTTLS: write error=timeout"); 902 } 903 else if (LogLevel > 8) 904 sm_syslog(LOG_WARNING, NOQID, 905 "STARTTLS: write error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d", 906 err, r, errno, 907 ERR_error_string(ERR_get_error(), NULL), try, 908 ssl_err); 909 else if (LogLevel > 7) 910 sm_syslog(LOG_WARNING, NOQID, 911 "STARTTLS: write error=%s (%d), errno=%d, retry=%d, ssl_err=%d", 912 err, r, errno, try, ssl_err); 913 errno = save_errno; 914 } 915 return r; 916 } 917 918 /* 919 ** SFDCTLS -- create tls file type and open in and out file pointers 920 ** for sendmail to read from and write to. 921 ** 922 ** Parameters: 923 ** fin -- data input source being replaced 924 ** fout -- data output source being replaced 925 ** con -- the tls connection pointer 926 ** 927 ** Returns: 928 ** -1 on error 929 ** 0 on success 930 ** 931 ** Side effects: 932 ** The arguments "fin" and "fout" are replaced with the new 933 ** SM_FILE_T pointers. 934 ** The original "fin" and "fout" are preserved in the tls file 935 ** type but are not actually used because of the design of TLS. 936 */ 937 938 int 939 sfdctls(fin, fout, con) 940 SM_FILE_T **fin; 941 SM_FILE_T **fout; 942 SSL *con; 943 { 944 SM_FILE_T *tlsin, *tlsout; 945 SM_FILE_T SM_IO_SET_TYPE(tls_vector, "tls", tls_open, tls_close, 946 tls_read, tls_write, NULL, tls_getinfo, NULL, 947 SM_TIME_FOREVER); 948 struct tls_info info; 949 950 SM_ASSERT(con != NULL); 951 952 SM_IO_INIT_TYPE(tls_vector, "tls", tls_open, tls_close, 953 tls_read, tls_write, NULL, tls_getinfo, NULL, 954 SM_TIME_FOREVER); 955 info.fp = *fin; 956 info.con = con; 957 tlsin = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY_B, 958 NULL); 959 if (tlsin == NULL) 960 return -1; 961 962 info.fp = *fout; 963 tlsout = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY_B, 964 NULL); 965 if (tlsout == NULL) 966 { 967 (void) sm_io_close(tlsin, SM_TIME_DEFAULT); 968 return -1; 969 } 970 sm_io_automode(tlsin, tlsout); 971 972 *fin = tlsin; 973 *fout = tlsout; 974 return 0; 975 } 976 #endif /* STARTTLS */ 977