1N/A * Copyright (c) 1999-2006, 2008 Sendmail, Inc. and its suppliers. 1N/A * All rights reserved. 1N/A * By using this file, you agree to the terms and conditions set 1N/A * forth in the LICENSE file which can be found at the top level of 1N/A * the sendmail distribution. 1N/A/* allow to disable error handling code just in case... */ 1N/A#
endif /* ! DEAL_WITH_ERROR_SSL */ 1N/A/* Structure used by the "sasl" file type */ 1N/A** SASL_GETINFO - returns requested information about a "sasl" file 1N/A** fp -- the file descriptor 1N/A** what -- the type of information requested 1N/A** valp -- the thang to return the information in 1N/A** -1 for unknown requests 1N/A** >=0 on success with valp filled in (if possible). 1N/A /* get info from underlying file */ 1N/A** SASL_OPEN -- creates the sasl specific information for opening a 1N/A** file of the sasl type. 1N/A** fp -- the file pointer associated with the new open 1N/A** info -- contains the sasl connection information pointer and 1N/A** the original SM_FILE_T that holds the open 1N/A ** The underlying 'fp' is set to SM_IO_NOW so that the entire 1N/A ** encoded string is written in one chunk. Otherwise there is 1N/A ** the possibility that it may appear illegal, bogus or 1N/A ** mangled to the other side of the connection. 1N/A ** We will read or write through 'fp' since it is the opaque 1N/A ** connection for the communications. We need to treat it this 1N/A ** way in case the encoded string is to be sent down a TLS 1N/A ** connection rather than, say, sm_io's stdio. 1N/A** SASL_CLOSE -- close the sasl specific parts of the sasl file pointer 1N/A** fp -- the file pointer to close 1N/A/* how to deallocate a buffer allocated by SASL */ 1N/A** SASL_READ -- read encrypted information and decrypt it for the caller 1N/A** fp -- the file pointer 1N/A** buf -- the location to place the decrypted information 1N/A** size -- the number of bytes to read after decryption 1N/A** otherwise the number of bytes read 1N/A#
else /* SASL >= 20000 */ 1N/A#
endif /* SASL >= 20000 */ 1N/A ** sasl_decode() may require more data than a single read() returns. 1N/A ** Hence we have to put a loop around the decoding. 1N/A ** This also requires that we may have to split up the returned 1N/A ** data since it might be larger than the allowed size. 1N/A ** Therefore we use a static pointer and return portions of it 1N/A ** XXX Note: This function is not thread-safe nor can it be used 1N/A ** on more than one file. A correct implementation would store 1N/A ** this data in fp->f_cookie. 1N/A#
else /* SASL >= 20000 */ 1N/A#
endif /* SASL >= 20000 */ 1N/A /* be paranoid: outbuf == NULL but outlen != 0 */ 1N/A syserr(
"@sasl_read failure: outbuf == NULL but outlen != 0");
1N/A /* return another part of the buffer */ 1N/A /* return the rest of the buffer */ 1N/A#
endif /* SASL < 20000 */ 1N/A** SASL_WRITE -- write information out after encrypting it 1N/A** fp -- the file pointer 1N/A** buf -- holds the data to be encrypted and written 1N/A** size -- the number of bytes to have encrypted and written 1N/A** otherwise number of bytes written 1N/A#
else /* SASL >= 20000 */ 1N/A#
endif /* SASL >= 20000 */ 1N/A ** Fetch the maximum input buffer size for sasl_encode(). 1N/A ** This can be less than the size set in attemptauth() 1N/A ** due to a negotiation with the other side, e.g., 1N/A ** Cyrus IMAP lmtp program sets maxbuf=4096, 1N/A ** digestmd5 substracts 25 and hence we'll get 4071 1N/A ** instead of 8192 (MAXOUTLEN). 1N/A ** Hack (for now): simply reduce the size, callers are (must be) 1N/A ** able to deal with that and invoke sasl_write() again with 1N/A ** the rest of the data. 1N/A ** Note: it would be better to store this value in the context 1N/A ** after the negotiation. 1N/A /* XXX result == 0? */ 1N/A#
endif /* SASL < 20000 */ 1N/A** SFDCSASL -- create sasl file type and open in and out file pointers 1N/A** for sendmail to read from and write to. 1N/A** fin -- the sm_io file encrypted data to be read from 1N/A** fout -- the sm_io file encrypted data to be written to 1N/A** conn -- the sasl connection pointer 1N/A** The arguments "fin" and "fout" are replaced with the new 1N/A** SM_FILE_T pointers. 1N/A /* no need to do anything */ 1N/A/* Structure used by the "tls" file type */ 1N/A** TLS_GETINFO - returns requested information about a "tls" file 1N/A** fp -- the file descriptor 1N/A** what -- the type of information requested 1N/A** valp -- the thang to return the information in (unused) 1N/A** -1 for unknown requests 1N/A** >=0 on success with valp filled in (if possible). 1N/A** TLS_OPEN -- creates the tls specific information for opening a 1N/A** file of the tls type. 1N/A** fp -- the file pointer associated with the new open 1N/A** info -- the sm_io file pointer holding the open and the 1N/A** TLS encryption connection to be read from or written to 1N/A ** We try to get the "raw" file descriptor that TLS uses to 1N/A ** do the actual read/write with. This is to allow us control 1N/A ** over the file descriptor being a blocking or non-blocking type. 1N/A ** Under the covers TLS handles the change and this allows us 1N/A ** to do timeouts with sm_io. 1N/A** TLS_CLOSE -- close the tls specific parts of the tls file pointer 1N/A** fp -- the file pointer to close 1N/A/* maximum number of retries for TLS related I/O due to handshakes */ 1N/A** TLS_RETRY -- check whether a failed SSL operation can be retried 1N/A** ssl -- TLS structure 1N/A** tlsstart -- start time of TLS operation 1N/A** timeout -- timeout for TLS operation 1N/A** where -- description of operation 1N/A ** For SSL_ERROR_WANT_{READ,WRITE}: 1N/A ** There is not a complete SSL record available yet 1N/A ** or there is only a partial SSL record removed from 1N/A ** the network (socket) buffer into the SSL buffer. 1N/A ** The SSL_connect will only succeed when a full 1N/A ** SSL record is available (assuming a "real" error 1N/A ** doesn't happen). To handle when a "real" error 1N/A ** does happen the select is set for exceptions too. 1N/A ** The connection may be re-negotiated during this time 1N/A ** so both read and write "want errors" need to be handled. 1N/A ** A select() exception loops back so that a proper SSL 1N/A ** error message can be gotten. 1N/A return 0;
/* timeout */ 1N/A "STARTTLS=%s, info: fds=%d/%d, err=%d",
1N/A "STARTTLS=%s, error: fd %d/%d too large",
1N/A/* errno to force refill() etc to stop (see IS_IO_ERROR()) */ 1N/A#
else /* ETIMEDOUT */ 1N/A#
endif /* ETIMEDOUT */ 1N/A** SET_TLS_RD_TMO -- read secured information for the caller 1N/A** rd_tmo -- read timeout 1N/A** This is a hack: there is no way to pass it in 1N/A** TLS_READ -- read secured information for the caller 1N/A** fp -- the file pointer 1N/A** buf -- the location to place the data 1N/A** size -- the number of bytes to read from connection 1N/A** otherwise the number of bytes read 1N/A if (r == 0 &&
errno == 0)
/* out of protocol EOF found */ 1N/A get_last_socket_error()); 1N/A if (r == 0 &&
errno == 0)
/* out of protocol EOF found */ 1N/A#
endif /* DEAL_WITH_ERROR_SSL */ 1N/A /* avoid repeated calls? */ 1N/A#
endif /* DEAL_WITH_ERROR_SSL */ 1N/A "STARTTLS: read error=timeout");
1N/A "STARTTLS: read error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
1N/A "STARTTLS: read error=%s (%d), retry=%d, ssl_err=%d",
1N/A** TLS_WRITE -- write information out through secure connection 1N/A** fp -- the file pointer 1N/A** buf -- holds the data to be securely written 1N/A** size -- the number of bytes to write 1N/A** otherwise number of bytes written 1N/A if (r == 0 &&
errno == 0)
/* out of protocol EOF found */ 1N/A get_last_socket_error()); 1N/A ERR_GET_REASON(ERR_peek_error())); 1N/A /* avoid repeated calls? */ 1N/A#
endif /* DEAL_WITH_ERROR_SSL */ 1N/A "STARTTLS: write error=timeout");
1N/A "STARTTLS: write error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
1N/A "STARTTLS: write error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
1N/A** SFDCTLS -- create tls file type and open in and out file pointers 1N/A** for sendmail to read from and write to. 1N/A** fin -- data input source being replaced 1N/A** fout -- data output source being replaced 1N/A** con -- the tls connection pointer 1N/A** The arguments "fin" and "fout" are replaced with the new 1N/A** SM_FILE_T pointers. 1N/A** The original "fin" and "fout" are preserved in the tls file 1N/A** type but are not actually used because of the design of TLS. 1N/A#
endif /* STARTTLS */