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