* Arguments:
*
* ns_context - Network security context
- * fd - File descriptor of network connection.
+ * readfd - Read file descriptor of remote connection.
+ * writefd - Write file descriptor of remote connection
*/
-void netsec_set_fd(netsec_context *ns_context, int fd);
+void netsec_set_fd(netsec_context *ns_context, int readfd, writefd);
/*
* Set the userid used to authenticate to this connection.
* Returns pointer to string, or NULL on error.
*/
-char *netsec_readline(netsec_context *ns_context, size_t *lenght,
+char *netsec_readline(netsec_context *ns_context, size_t *length,
char **errstr);
/*
*/
struct _netsec_context {
- int ns_fd; /* Descriptor for network connection */
+ int ns_readfd; /* Read descriptor for network connection */
+ int ns_writefd; /* Write descriptor for network connection */
int ns_snoop; /* If true, display network data */
int ns_snoop_noend; /* If true, didn't get a CR/LF on last line */
netsec_snoop_callback *ns_snoop_cb; /* Snoop output callback */
{
netsec_context *nsc = mh_xmalloc(sizeof(*nsc));
- nsc->ns_fd = -1;
+ nsc->ns_readfd = -1;
+ nsc->ns_writefd = -1;
nsc->ns_snoop = 0;
nsc->ns_snoop_noend = 0;
nsc->ns_snoop_cb = NULL;
BIO_free_all(nsc->ssl_io);
#endif /* TLS_SUPPORT */
- if (closeflag && nsc->ns_fd != -1)
- close(nsc->ns_fd);
+ if (closeflag) {
+ if (nsc->ns_readfd != -1)
+ close(nsc->ns_readfd);
+ if (nsc->ns_writefd != -1 && nsc->ns_writefd != nsc->ns_readfd)
+ close(nsc->ns_writefd);
+ }
free(nsc);
}
*/
void
-netsec_set_fd(netsec_context *nsc, int fd)
+netsec_set_fd(netsec_context *nsc, int readfd, writefd)
{
- nsc->ns_fd = fd;
+ nsc->ns_readfd = readfd;
+ nsc->ns_writefd = writefd;
}
/*
fd_set rfds;
FD_ZERO(&rfds);
- FD_SET(nsc->ns_fd, &rfds);
+ FD_SET(nsc->ns_readfd, &rfds);
tv.tv_sec = nsc->ns_timeout;
tv.tv_usec = 0;
- rc = select(nsc->ns_fd + 1, &rfds, NULL, NULL, &tv);
+ rc = select(nsc->ns_readfd + 1, &rfds, NULL, NULL, &tv);
if (rc == -1) {
netsec_err(errstr, "select() while reading failed: %s",
* select() above) so this read SHOULDN'T block. Hopefully.
*/
- rc = read(nsc->ns_fd, readbuf, readbufsize);
+ rc = read(nsc->ns_readfd, readbuf, readbufsize);
if (rc == 0) {
netsec_err(errstr, "Received EOF on network read");
}
#endif /* CYRUS_SASL */
- rc = write(nsc->ns_fd, netoutbuf, netoutlen);
+ rc = write(nsc->ns_writefd, netoutbuf, netoutlen);
if (rc < 0) {
netsec_err(errstr, "write() failed: %s", strerror(errno));
if (tls) {
#ifdef TLS_SUPPORT
SSL *ssl;
- BIO *sbio, *ssl_bio;;
+ BIO *rbio, *wbio, *ssl_bio;;
if (! tls_initialized) {
SSL_library_init();
tls_initialized++;
}
- if (nsc->ns_fd == -1) {
+ if (nsc->ns_readfd == -1 || nsc->ns_writefd == -1) {
netsec_err(errstr, "Invalid file descriptor in netsec context");
return NOTOK;
}
* So writes and reads are buffered (we mostly care about writes).
*/
- sbio = BIO_new_socket(nsc->ns_fd, BIO_NOCLOSE);
+ rbio = BIO_new_socket(nsc->ns_readfd, BIO_NOCLOSE);
+
+ if (! rbio) {
+ netsec_err(errstr, "Unable to create a read socket BIO: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ SSL_free(ssl);
+ return NOTOK;
+ }
+
+ wbio = BIO_new_socket(nsc->ns_writefd, BIO_NOCLOSE);
- if (! sbio) {
- netsec_err(errstr, "Unable to create a socket BIO: %s",
+ if (! wbio) {
+ netsec_err(errstr, "Unable to create a write socket BIO: %s",
ERR_error_string(ERR_get_error(), NULL));
SSL_free(ssl);
+ BIO_free(rbio);
return NOTOK;
}
- SSL_set_bio(ssl, sbio, sbio);
+ SSL_set_bio(ssl, rbio, wbio);
SSL_set_connect_state(ssl);
nsc->ssl_io = BIO_new(BIO_f_buffer());