*/
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;
}
/*
{
const char *decoded;
size_t decodedlen;
+ NMH_UNUSED(nsc);
int offset = context ? *((int *) context) : 0;
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 /* TLS_SUPPORT */
fprintf(stderr, "=> ");
if (nsc->ns_snoop_cb)
- nsc->ns_snoop_cb(nsc, nsc->ns_outptr, outlen,
+ nsc->ns_snoop_cb(nsc, (char *) nsc->ns_outptr, outlen,
nsc->ns_snoop_context);
else
fprintf(stderr, "%.*s\n", outlen, nsc->ns_outptr);
}
#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));
i = (str[i] == NULL);
- free(str);
free(mlist);
if (i) {
* we ignore it and send a blank message in response. We should
* then get either an +OK or -ERR
*/
- free(errstr);
+ free(*errstr);
nsc->sasl_proto_cb(NETSEC_SASL_WRITE, NULL, 0, NULL, 0, NULL);
rc = nsc->sasl_proto_cb(NETSEC_SASL_FINISH, NULL, 0, NULL, 0,
errstr);
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());