#define SM_DOT 600 /* see above */
#define SM_QUIT 30
#define SM_CLOS 10
+#ifdef CYRUS_SASL
#define SM_AUTH 45
+#endif /* CYRUS_SASL */
static int sm_addrs = 0;
static int sm_alarmed = 0;
static SSL *ssl = NULL;
static BIO *sbior = NULL;
static BIO *sbiow = NULL;
+static BIO *io = NULL;
#endif /* TLS_SUPPORT */
#if defined(CYRUS_SASL) || defined(TLS_SUPPORT)
static int smhear (void);
static int sm_rrecord (char *, int *);
static int sm_rerror (int);
-static RETSIGTYPE alrmser (int);
+static void alrmser (int);
static char *EHLOset (char *);
static int sm_fwrite(char *, int);
static int sm_fputs(char *);
{
#ifdef CYRUS_SASL
char *server_mechs;
+#else /* CYRUS_SASL */
+ NMH_UNUSED (sasl);
+ NMH_UNUSED (saslmech);
+ NMH_UNUSED (user);
#endif /* CYRUS_SASL */
int result, sd1, sd2;
if (clientname) {
client = clientname;
} else {
- client = LocalName(); /* no clientname -> LocalName */
+ client = LocalName(1); /* no clientname -> LocalName */
}
}
*/
if (tls) {
+ BIO *ssl_bio;
+
if (! EHLOset("STARTTLS")) {
sm_end(NOTOK);
return sm_ierror("SMTP server does not support TLS");
}
SSL_set_bio(ssl, sbior, sbiow);
+ SSL_set_connect_state(ssl);
+
+ /*
+ * Set up a BIO to handle buffering for us
+ */
+
+ io = BIO_new(BIO_f_buffer());
+
+ if (! io) {
+ sm_end(NOTOK);
+ return sm_ierror("Unable to create a buffer BIO: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ }
+
+ ssl_bio = BIO_new(BIO_f_ssl());
+
+ if (! ssl_bio) {
+ sm_end(NOTOK);
+ return sm_ierror("Unable to create a SSL BIO: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ }
- if (SSL_connect(ssl) < 1) {
+ BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
+ BIO_push(io, ssl_bio);
+
+ /*
+ * Try doing the handshake now
+ */
+
+ if (BIO_do_handshake(io) < 1) {
sm_end(NOTOK);
return sm_ierror("Unable to negotiate SSL connection: %s",
ERR_error_string(ERR_get_error(), NULL));
return RP_RPLY;
}
}
+#else /* TLS_SUPPORT */
+ NMH_UNUSED (tls);
#endif /* TLS_SUPPORT */
#ifdef CYRUS_SASL
{
#ifdef CYRUS_SASL
char *server_mechs;
+#else /* CYRUS_SASL */
+ NMH_UNUSED (server);
+ NMH_UNUSED (sasl);
+ NMH_UNUSED (saslmech);
+ NMH_UNUSED (user);
#endif /* CYRUS_SASL */
- int i, result, vecp;
+ unsigned int i, result, vecp;
int pdi[2], pdo[2];
char *vec[15];
if (clientname)
client = clientname;
else
- client = LocalName(); /* no clientname -> LocalName */
+ client = LocalName(1); /* no clientname -> LocalName */
}
/*
#ifdef TLS_SUPPORT
if (tls_active) {
- SSL_shutdown(ssl);
- SSL_free(ssl);
+ BIO_ssl_shutdown(io);
+ BIO_free_all(io);
}
#endif /* TLS_SUPPORT */
sm_get_pass(sasl_conn_t *conn, void *context, int id,
sasl_secret_t **psecret)
{
+ NMH_UNUSED (conn);
+
char **pw_context = (char **) context;
char *pass = NULL;
int len;
if (tls_active) {
int ret;
- ret = SSL_write(ssl, buffer, len);
+ ret = BIO_write(io, buffer, len);
- if (SSL_get_error(ssl, ret) != SSL_ERROR_NONE) {
+ if (ret <= 0) {
sm_ierror("TLS error during write: %s",
ERR_error_string(ERR_get_error(), NULL));
return NOTOK;
}
#endif /* CYRUS_SASL */
+#ifdef TLS_SUPPORT
+ if (tls_active) {
+ (void) BIO_flush(io);
+ }
+#endif /* TLS_SUPPORT */
+
fflush(sm_wfp);
}
}
-static RETSIGTYPE
+static void
alrmser (int i)
{
+ NMH_UNUSED (i);
+
#ifndef RELIABLE_SIGNALS
SIGNAL (SIGALRM, alrmser);
#endif