sfsasl.c revision 157001
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> 12SM_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 */ 26struct sasl_obj 27{ 28 SM_FILE_T *fp; 29 sasl_conn_t *conn; 30}; 31 32struct 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 52static int sasl_getinfo __P((SM_FILE_T *, int, void *)); 53 54static int 55sasl_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 96static int sasl_open __P((SM_FILE_T *, const void *, int, const void *)); 97 98/* ARGSUSED2 */ 99static int 100sasl_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 144static int sasl_close __P((SM_FILE_T *)); 145 146static int 147sasl_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 */ 166extern 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 182static ssize_t sasl_read __P((SM_FILE_T *, char *, size_t)); 183 184static ssize_t 185sasl_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 277static ssize_t sasl_write __P((SM_FILE_T *, const char *, size_t)); 278 279static ssize_t 280sasl_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 362int 363sfdcsasl(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 */ 414struct tls_obj 415{ 416 SM_FILE_T *fp; 417 SSL *con; 418}; 419 420struct 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 440static int tls_getinfo __P((SM_FILE_T *, int, void *)); 441 442/* ARGSUSED2 */ 443static int 444tls_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 481static int tls_open __P((SM_FILE_T *, const void *, int, const void *)); 482 483/* ARGSUSED2 */ 484static int 485tls_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 527static int tls_close __P((SM_FILE_T *)); 528 529static int 530tls_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 569int 570tls_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 683static ssize_t tls_read __P((SM_FILE_T *, char *, size_t)); 684 685static ssize_t 686tls_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 793static ssize_t tls_write __P((SM_FILE_T *, const char *, size_t)); 794 795static ssize_t 796tls_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 907int 908sfdctls(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