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