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.90 2002/05/09 20:44:11 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 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 while (outbuf == NULL && outlen == 0) 198 { 199 len = sm_io_read(so->fp, SM_TIME_DEFAULT, buf, size); 200 if (len <= 0) 201 return len; 202 result = sasl_decode(so->conn, buf, 203 (unsigned int) len, &outbuf, &outlen); 204 if (result != SASL_OK) 205 { 206 outbuf = NULL; 207 offset = 0; 208 outlen = 0; 209 return -1; 210 } 211 } 212 213 if (outbuf == NULL) 214 { 215 /* be paranoid: outbuf == NULL but outlen != 0 */ 216 syserr("@sasl_read failure: outbuf == NULL but outlen != 0"); 217 /* NOTREACHED */ 218 } 219 if (outlen - offset > size) 220 { 221 /* return another part of the buffer */ 222 (void) memcpy(buf, outbuf + offset, size); 223 offset += size; 224 len = size; 225 } 226 else 227 { 228 /* return the rest of the buffer */ 229 len = outlen - offset; 230 (void) memcpy(buf, outbuf + offset, (size_t) len); 231 # if SASL < 20000 232 SASL_DEALLOC(outbuf); 233 # endif /* SASL < 20000 */ 234 outbuf = NULL; 235 offset = 0; 236 outlen = 0; 237 } 238 return len; 239 } 240 241 /* 242 ** SASL_WRITE -- write information out after encrypting it 243 ** 244 ** Parameters: 245 ** fp -- the file pointer 246 ** buf -- holds the data to be encrypted and written 247 ** size -- the number of bytes to have encrypted and written 248 ** 249 ** Returns: 250 ** -1 on error 251 ** otherwise number of bytes written 252 */ 253 254 static ssize_t sasl_write __P((SM_FILE_T *, const char *, size_t)); 255 256 static ssize_t 257 sasl_write(fp, buf, size) 258 SM_FILE_T *fp; 259 const char *buf; 260 size_t size; 261 { 262 int result; 263 # if SASL >= 20000 264 const char *outbuf; 265 # else /* SASL >= 20000 */ 266 char *outbuf; 267 # endif /* SASL >= 20000 */ 268 unsigned int outlen; 269 size_t ret = 0, total = 0; 270 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie; 271 272 result = sasl_encode(so->conn, buf, 273 (unsigned int) size, &outbuf, &outlen); 274 275 if (result != SASL_OK) 276 return -1; 277 278 if (outbuf != NULL) 279 { 280 while (outlen > 0) 281 { 282 /* XXX result == 0? */ 283 ret = sm_io_write(so->fp, SM_TIME_DEFAULT, 284 &outbuf[total], outlen); 285 outlen -= ret; 286 total += ret; 287 } 288 # if SASL < 20000 289 SASL_DEALLOC(outbuf); 290 # endif /* SASL < 20000 */ 291 } 292 return size; 293 } 294 295 /* 296 ** SFDCSASL -- create sasl file type and open in and out file pointers 297 ** for sendmail to read from and write to. 298 ** 299 ** Parameters: 300 ** fin -- the sm_io file encrypted data to be read from 301 ** fout -- the sm_io file encrypted data to be writen to 302 ** conn -- the sasl connection pointer 303 ** 304 ** Returns: 305 ** -1 on error 306 ** 0 on success 307 ** 308 ** Side effects: 309 ** The arguments "fin" and "fout" are replaced with the new 310 ** SM_FILE_T pointers. 311 */ 312 313 int 314 sfdcsasl(fin, fout, conn) 315 SM_FILE_T **fin; 316 SM_FILE_T **fout; 317 sasl_conn_t *conn; 318 { 319 SM_FILE_T *newin, *newout; 320 SM_FILE_T SM_IO_SET_TYPE(sasl_vector, "sasl", sasl_open, sasl_close, 321 sasl_read, sasl_write, NULL, sasl_getinfo, NULL, 322 SM_TIME_FOREVER); 323 struct sasl_info info; 324 325 if (conn == NULL) 326 { 327 /* no need to do anything */ 328 return 0; 329 } 330 331 SM_IO_INIT_TYPE(sasl_vector, "sasl", sasl_open, sasl_close, 332 sasl_read, sasl_write, NULL, sasl_getinfo, NULL, 333 SM_TIME_FOREVER); 334 info.fp = *fin; 335 info.conn = conn; 336 newin = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY, 337 NULL); 338 339 if (newin == NULL) 340 return -1; 341 342 info.fp = *fout; 343 info.conn = conn; 344 newout = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY, 345 NULL); 346 347 if (newout == NULL) 348 { 349 (void) sm_io_close(newin, SM_TIME_DEFAULT); 350 return -1; 351 } 352 sm_io_automode(newin, newout); 353 354 *fin = newin; 355 *fout = newout; 356 return 0; 357 } 358 #endif /* SASL */ 359 360 #if STARTTLS 361 # include "sfsasl.h" 362 # include <openssl/err.h> 363 364 /* Structure used by the "tls" file type */ 365 struct tls_obj 366 { 367 SM_FILE_T *fp; 368 SSL *con; 369 }; 370 371 struct tls_info 372 { 373 SM_FILE_T *fp; 374 SSL *con; 375 }; 376 377 /* 378 ** TLS_GETINFO - returns requested information about a "tls" file 379 ** descriptor. 380 ** 381 ** Parameters: 382 ** fp -- the file descriptor 383 ** what -- the type of information requested 384 ** valp -- the thang to return the information in (unused) 385 ** 386 ** Returns: 387 ** -1 for unknown requests 388 ** >=0 on success with valp filled in (if possible). 389 */ 390 391 static int tls_getinfo __P((SM_FILE_T *, int, void *)); 392 393 /* ARGSUSED2 */ 394 static int 395 tls_getinfo(fp, what, valp) 396 SM_FILE_T *fp; 397 int what; 398 void *valp; 399 { 400 struct tls_obj *so = (struct tls_obj *) fp->f_cookie; 401 402 switch (what) 403 { 404 case SM_IO_WHAT_FD: 405 if (so->fp == NULL) 406 return -1; 407 return so->fp->f_file; /* for stdio fileno() compatability */ 408 409 case SM_IO_IS_READABLE: 410 return SSL_pending(so->con) > 0; 411 412 default: 413 return -1; 414 } 415 } 416 417 /* 418 ** TLS_OPEN -- creates the tls specific information for opening a 419 ** file of the tls type. 420 ** 421 ** Parameters: 422 ** fp -- the file pointer associated with the new open 423 ** info -- the sm_io file pointer holding the open and the 424 ** TLS encryption connection to be read from or written to 425 ** flags -- ignored 426 ** rpool -- ignored 427 ** 428 ** Returns: 429 ** 0 on success 430 */ 431 432 static int tls_open __P((SM_FILE_T *, const void *, int, const void *)); 433 434 /* ARGSUSED2 */ 435 static int 436 tls_open(fp, info, flags, rpool) 437 SM_FILE_T *fp; 438 const void *info; 439 int flags; 440 const void *rpool; 441 { 442 struct tls_obj *so; 443 struct tls_info *ti = (struct tls_info *) info; 444 445 so = (struct tls_obj *) sm_malloc(sizeof(struct tls_obj)); 446 so->fp = ti->fp; 447 so->con = ti->con; 448 449 /* 450 ** We try to get the "raw" file descriptor that TLS uses to 451 ** do the actual read/write with. This is to allow us control 452 ** over the file descriptor being a blocking or non-blocking type. 453 ** Under the covers TLS handles the change and this allows us 454 ** to do timeouts with sm_io. 455 */ 456 457 fp->f_file = sm_io_getinfo(so->fp, SM_IO_WHAT_FD, NULL); 458 (void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0); 459 fp->f_cookie = so; 460 return 0; 461 } 462 463 /* 464 ** TLS_CLOSE -- close the tls specific parts of the tls file pointer 465 ** 466 ** Parameters: 467 ** fp -- the file pointer to close 468 ** 469 ** Returns: 470 ** 0 on success 471 */ 472 473 static int tls_close __P((SM_FILE_T *)); 474 475 static int 476 tls_close(fp) 477 SM_FILE_T *fp; 478 { 479 struct tls_obj *so; 480 481 so = (struct tls_obj *) fp->f_cookie; 482 if (so->fp != NULL) 483 { 484 sm_io_close(so->fp, SM_TIME_DEFAULT); 485 so->fp = NULL; 486 } 487 sm_free(so); 488 so = NULL; 489 return 0; 490 } 491 492 /* maximum number of retries for TLS related I/O due to handshakes */ 493 # define MAX_TLS_IOS 4 494 495 /* 496 ** TLS_READ -- read secured information for the caller 497 ** 498 ** Parameters: 499 ** fp -- the file pointer 500 ** buf -- the location to place the data 501 ** size -- the number of bytes to read from connection 502 ** 503 ** Results: 504 ** -1 on error 505 ** otherwise the number of bytes read 506 */ 507 508 static ssize_t tls_read __P((SM_FILE_T *, char *, size_t)); 509 510 static ssize_t 511 tls_read(fp, buf, size) 512 SM_FILE_T *fp; 513 char *buf; 514 size_t size; 515 { 516 int r; 517 static int again = MAX_TLS_IOS; 518 struct tls_obj *so = (struct tls_obj *) fp->f_cookie; 519 char *err; 520 521 r = SSL_read(so->con, (char *) buf, size); 522 523 if (r > 0) 524 { 525 again = MAX_TLS_IOS; 526 return r; 527 } 528 529 err = NULL; 530 switch (SSL_get_error(so->con, r)) 531 { 532 case SSL_ERROR_NONE: 533 case SSL_ERROR_ZERO_RETURN: 534 again = MAX_TLS_IOS; 535 break; 536 case SSL_ERROR_WANT_WRITE: 537 if (--again <= 0) 538 err = "read W BLOCK"; 539 else 540 errno = EAGAIN; 541 break; 542 case SSL_ERROR_WANT_READ: 543 if (--again <= 0) 544 err = "read R BLOCK"; 545 else 546 errno = EAGAIN; 547 break; 548 case SSL_ERROR_WANT_X509_LOOKUP: 549 err = "write X BLOCK"; 550 break; 551 case SSL_ERROR_SYSCALL: 552 if (r == 0 && errno == 0) /* out of protocol EOF found */ 553 break; 554 err = "syscall error"; 555 /* 556 get_last_socket_error()); 557 */ 558 break; 559 case SSL_ERROR_SSL: 560 err = "generic SSL error"; 561 if (LogLevel > 9) 562 tlslogerr("read"); 563 break; 564 } 565 if (err != NULL) 566 { 567 int save_errno; 568 569 save_errno = (errno == 0) ? EIO : errno; 570 again = MAX_TLS_IOS; 571 if (LogLevel > 7) 572 sm_syslog(LOG_WARNING, NOQID, 573 "STARTTLS: read error=%s (%d)", err, r); 574 errno = save_errno; 575 } 576 return r; 577 } 578 579 /* 580 ** TLS_WRITE -- write information out through secure connection 581 ** 582 ** Parameters: 583 ** fp -- the file pointer 584 ** buf -- holds the data to be securely written 585 ** size -- the number of bytes to write 586 ** 587 ** Returns: 588 ** -1 on error 589 ** otherwise number of bytes written 590 */ 591 592 static ssize_t tls_write __P((SM_FILE_T *, const char *, size_t)); 593 594 static ssize_t 595 tls_write(fp, buf, size) 596 SM_FILE_T *fp; 597 const char *buf; 598 size_t size; 599 { 600 int r; 601 static int again = MAX_TLS_IOS; 602 struct tls_obj *so = (struct tls_obj *) fp->f_cookie; 603 char *err; 604 605 r = SSL_write(so->con, (char *) buf, size); 606 607 if (r > 0) 608 { 609 again = MAX_TLS_IOS; 610 return r; 611 } 612 err = NULL; 613 switch (SSL_get_error(so->con, r)) 614 { 615 case SSL_ERROR_NONE: 616 case SSL_ERROR_ZERO_RETURN: 617 again = MAX_TLS_IOS; 618 break; 619 case SSL_ERROR_WANT_WRITE: 620 if (--again <= 0) 621 err = "write W BLOCK"; 622 else 623 errno = EAGAIN; 624 break; 625 case SSL_ERROR_WANT_READ: 626 if (--again <= 0) 627 err = "write R BLOCK"; 628 else 629 errno = EAGAIN; 630 break; 631 case SSL_ERROR_WANT_X509_LOOKUP: 632 err = "write X BLOCK"; 633 break; 634 case SSL_ERROR_SYSCALL: 635 if (r == 0 && errno == 0) /* out of protocol EOF found */ 636 break; 637 err = "syscall error"; 638 /* 639 get_last_socket_error()); 640 */ 641 break; 642 case SSL_ERROR_SSL: 643 err = "generic SSL error"; 644 /* 645 ERR_GET_REASON(ERR_peek_error())); 646 */ 647 if (LogLevel > 9) 648 tlslogerr("write"); 649 break; 650 } 651 if (err != NULL) 652 { 653 int save_errno; 654 655 save_errno = (errno == 0) ? EIO : errno; 656 again = MAX_TLS_IOS; 657 if (LogLevel > 7) 658 sm_syslog(LOG_WARNING, NOQID, 659 "STARTTLS: write error=%s (%d)", err, r); 660 errno = save_errno; 661 } 662 return r; 663 } 664 665 /* 666 ** SFDCTLS -- create tls file type and open in and out file pointers 667 ** for sendmail to read from and write to. 668 ** 669 ** Parameters: 670 ** fin -- data input source being replaced 671 ** fout -- data output source being replaced 672 ** conn -- the tls connection pointer 673 ** 674 ** Returns: 675 ** -1 on error 676 ** 0 on success 677 ** 678 ** Side effects: 679 ** The arguments "fin" and "fout" are replaced with the new 680 ** SM_FILE_T pointers. 681 ** The original "fin" and "fout" are preserved in the tls file 682 ** type but are not actually used because of the design of TLS. 683 */ 684 685 int 686 sfdctls(fin, fout, con) 687 SM_FILE_T **fin; 688 SM_FILE_T **fout; 689 SSL *con; 690 { 691 SM_FILE_T *tlsin, *tlsout; 692 SM_FILE_T SM_IO_SET_TYPE(tls_vector, "tls", tls_open, tls_close, 693 tls_read, tls_write, NULL, tls_getinfo, NULL, 694 SM_TIME_FOREVER); 695 struct tls_info info; 696 697 SM_ASSERT(con != NULL); 698 699 SM_IO_INIT_TYPE(tls_vector, "tls", tls_open, tls_close, 700 tls_read, tls_write, NULL, tls_getinfo, NULL, 701 SM_TIME_FOREVER); 702 info.fp = *fin; 703 info.con = con; 704 tlsin = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY, 705 NULL); 706 if (tlsin == NULL) 707 return -1; 708 709 info.fp = *fout; 710 tlsout = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY, 711 NULL); 712 if (tlsout == NULL) 713 { 714 (void) sm_io_close(tlsin, SM_TIME_DEFAULT); 715 return -1; 716 } 717 sm_io_automode(tlsin, tlsout); 718 719 *fin = tlsin; 720 *fout = tlsout; 721 return 0; 722 } 723 #endif /* STARTTLS */ 724