#include <h/oauth.h>
#include <stdarg.h>
#include <sys/select.h>
+#include "base64.h"
#ifdef CYRUS_SASL
#include <sasl/sasl.h>
struct _netsec_context {
int ns_readfd; /* Read descriptor for network connection */
int ns_writefd; /* Write descriptor for network connection */
+ int ns_noclose; /* Do not close file descriptors if set */
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 */
NEW(nsc);
nsc->ns_readfd = -1;
nsc->ns_writefd = -1;
+ nsc->ns_noclose = 0;
nsc->ns_snoop = 0;
nsc->ns_snoop_noend = 0;
nsc->ns_snoop_cb = NULL;
/*
* Shutdown the connection completely and free all resources.
- * The connection is only closed if the flag is given.
*/
void
-netsec_shutdown(netsec_context *nsc, int closeflag)
+netsec_shutdown(netsec_context *nsc)
{
- mh_xfree(nsc->ns_userid);
- mh_xfree(nsc->ns_hostname);
- mh_xfree(nsc->ns_inbuffer);
- mh_xfree(nsc->ns_outbuffer);
- mh_xfree(nsc->sasl_mech);
- mh_xfree(nsc->sasl_chosen_mech);
+ free(nsc->ns_userid);
+ free(nsc->ns_hostname);
+ free(nsc->ns_inbuffer);
+ free(nsc->ns_outbuffer);
+ free(nsc->sasl_mech);
+ free(nsc->sasl_chosen_mech);
#ifdef OAUTH_SERVICE
- mh_xfree(nsc->oauth_service);
+ free(nsc->oauth_service);
#endif /* OAUTH_SERVICE */
#ifdef CYRUS_SASL
if (nsc->sasl_conn)
sasl_dispose(&nsc->sasl_conn);
- mh_xfree(nsc->sasl_cbs);
+ free(nsc->sasl_cbs);
if (nsc->sasl_creds)
nmh_credentials_free(nsc->sasl_creds);
if (nsc->sasl_secret) {
}
free(nsc->sasl_secret);
}
- mh_xfree(nsc->sasl_tmpbuf);
+ free(nsc->sasl_tmpbuf);
#endif /* CYRUS_SASL */
#ifdef TLS_SUPPORT
if (nsc->ssl_io)
BIO_free_all(nsc->ssl_io);
#endif /* TLS_SUPPORT */
- if (closeflag) {
+ if (! nsc->ns_noclose) {
if (nsc->ns_readfd != -1)
close(nsc->ns_readfd);
if (nsc->ns_writefd != -1 && nsc->ns_writefd != nsc->ns_readfd)
if (nsc->ns_snoop_cb)
nsc->ns_snoop_cb(nsc, sptr, strlen(sptr),
nsc->ns_snoop_context);
- else
- fprintf(stderr, "%s\n", sptr);
+ else {
+ fputs(sptr, stderr);
+ putc('\n', stderr);
+ }
}
return sptr;
}
*/
if (count >= nsc->ns_inbufsize / 2) {
- netsec_err(errstr, "Unable to find a line terminator after %d bytes",
+ netsec_err(errstr, "Unable to find a line terminator after %zu bytes",
count);
return NULL;
}
* messages.
*/
- memset(&secprops, 0, sizeof(secprops));
+ ZERO(&secprops);
secprops.maxbufsize = SASL_MAXRECVBUF;
/*
rc = sasl_client_step(nsc->sasl_conn, (char *) outbuf, outbuflen, NULL,
(const char **) &saslbuf, &saslbuflen);
- mh_xfree(outbuf);
+ free(outbuf);
if (rc != SASL_OK && rc != SASL_CONTINUE) {
netsec_err(errstr, "SASL client negotiation failed: %s",
* SSL BIO -> socket BIO.
*/
- rbio = BIO_new_socket(nsc->ns_readfd, BIO_NOCLOSE);
+ rbio = BIO_new_socket(nsc->ns_readfd, BIO_CLOSE);
if (! rbio) {
netsec_err(errstr, "Unable to create a read socket BIO: %s",
return NOTOK;
}
- wbio = BIO_new_socket(nsc->ns_writefd, BIO_NOCLOSE);
+ wbio = BIO_new_socket(nsc->ns_writefd, BIO_CLOSE);
if (! wbio) {
netsec_err(errstr, "Unable to create a write socket BIO: %s",
BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
nsc->ssl_io = ssl_bio;
+ /*
+ * Since SSL now owns these file descriptors, have it handle the
+ * closing of them instead of netsec_shutdown().
+ */
+
+ nsc->ns_noclose = 1;
+
return OK;
}
BIO_free_all(nsc->ssl_io);
if (BIO_get_ssl(nsc->ssl_io, &ssl) < 1) {
netsec_err(errstr, "Certificate verification failed, but "
"cannot retrieve SSL handle: %s",
- ERR_error_string(ERR_get_error(), NULL));
+ ERR_error_string(ERR_get_error(), NULL));
} else {
netsec_err(errstr, "Server certificate verification failed: %s",
X509_verify_cert_error_string(
}
} else {
netsec_err(errstr, "TLS negotiation failed: %s",
- ERR_error_string(errcode, NULL));
+ ERR_error_string(errcode, NULL));
}
/*