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