]> git.ipfire.org Git - people/ms/dma.git/blobdiff - crypto.c
dns: do not treat unreachable DNS server as permanent error
[people/ms/dma.git] / crypto.c
index 01941cf2974d7611a2daeb3cf970d5f2ea76a257..897b55bfdcfcc94814ba8482056c72e3d4a31f35 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -31,8 +31,6 @@
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- * $DragonFly: src/libexec/dma/crypto.c,v 1.4 2008/09/30 17:47:21 swildner Exp $
  */
 
 #include <openssl/x509.h>
 #include "dma.h"
 
 static int
-init_cert_file(struct qitem *it, SSL_CTX *ctx, const char *path)
+init_cert_file(SSL_CTX *ctx, const char *path)
 {
        int error;
 
        /* Load certificate into ctx */
        error = SSL_CTX_use_certificate_chain_file(ctx, path);
        if (error < 1) {
-               syslog(LOG_ERR, "%s: SSL: Cannot load certificate `%s': %s",
-                       it->queueid, path, ssl_errstr());
+               syslog(LOG_ERR, "SSL: Cannot load certificate `%s': %s", path, ssl_errstr());
                return (-1);
        }
 
        /* Add private key to ctx */
        error = SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM);
        if (error < 1) {
-               syslog(LOG_ERR, "%s: SSL: Cannot load private key `%s': %s",
-                       it->queueid, path, ssl_errstr());
+               syslog(LOG_ERR, "SSL: Cannot load private key `%s': %s", path, ssl_errstr());
                return (-1);
        }
 
@@ -73,8 +69,7 @@ init_cert_file(struct qitem *it, SSL_CTX *ctx, const char *path)
         */
        error = SSL_CTX_check_private_key(ctx);
        if (error < 1) {
-               syslog(LOG_ERR, "%s: SSL: Cannot check private key: %s",
-                       it->queueid, ssl_errstr());
+               syslog(LOG_ERR, "SSL: Cannot check private key: %s", ssl_errstr());
                return (-1);
        }
 
@@ -82,10 +77,14 @@ init_cert_file(struct qitem *it, SSL_CTX *ctx, const char *path)
 }
 
 int
-smtp_init_crypto(struct qitem *it, int fd, int feature)
+smtp_init_crypto(int fd, int feature)
 {
        SSL_CTX *ctx = NULL;
+#if (OPENSSL_VERSION_NUMBER >= 0x00909000L)
+       const SSL_METHOD *meth = NULL;
+#else
        SSL_METHOD *meth = NULL;
+#endif
        X509 *cert;
        int error;
 
@@ -98,16 +97,15 @@ smtp_init_crypto(struct qitem *it, int fd, int feature)
 
        ctx = SSL_CTX_new(meth);
        if (ctx == NULL) {
-               syslog(LOG_WARNING, "%s: remote delivery deferred: SSL init failed: %s",
-                      it->queueid, ssl_errstr());
+               syslog(LOG_WARNING, "remote delivery deferred: SSL init failed: %s", ssl_errstr());
                return (1);
        }
 
        /* User supplied a certificate */
-       if (config->certfile != NULL) {
-               error = init_cert_file(it, ctx, config->certfile);
+       if (config.certfile != NULL) {
+               error = init_cert_file(ctx, config.certfile);
                if (error) {
-                       syslog(LOG_WARNING, "%s: remote delivery deferred", it->queueid);
+                       syslog(LOG_WARNING, "remote delivery deferred");
                        return (1);
                }
        }
@@ -118,54 +116,56 @@ smtp_init_crypto(struct qitem *it, int fd, int feature)
        if (((feature & SECURETRANS) != 0) &&
             (feature & STARTTLS) != 0) {
                /* TLS init phase, disable SSL_write */
-               config->features |= NOSSL;
+               config.features |= NOSSL;
 
                send_remote_command(fd, "EHLO %s", hostname());
                if (read_remote(fd, 0, NULL) == 2) {
                        send_remote_command(fd, "STARTTLS");
                        if (read_remote(fd, 0, NULL) != 2) {
-                               syslog(LOG_ERR, "%s: remote delivery deferred:"
-                                 " STARTTLS not available: %s", it->queueid,
-                                 neterr);
-                               config->features &= ~NOSSL;
-                               return (1);
+                               if ((feature & TLS_OPP) == 0) {
+                                       syslog(LOG_ERR, "remote delivery deferred: STARTTLS not available: %s", neterr);
+                                       return (1);
+                               } else {
+                                       syslog(LOG_INFO, "in opportunistic TLS mode, STARTTLS not available: %s", neterr);
+                                       return (0);
+                               }
                        }
                }
                /* End of TLS init phase, enable SSL_write/read */
-               config->features &= ~NOSSL;
+               config.features &= ~NOSSL;
        }
 
-       config->ssl = SSL_new(ctx);
-       if (config->ssl == NULL) {
-               syslog(LOG_NOTICE, "%s: remote delivery deferred: SSL struct creation failed: %s",
-                      it->queueid, ssl_errstr());
+       config.ssl = SSL_new(ctx);
+       if (config.ssl == NULL) {
+               syslog(LOG_NOTICE, "remote delivery deferred: SSL struct creation failed: %s",
+                      ssl_errstr());
                return (1);
        }
 
        /* Set ssl to work in client mode */
-       SSL_set_connect_state(config->ssl);
+       SSL_set_connect_state(config.ssl);
 
        /* Set fd for SSL in/output */
-       error = SSL_set_fd(config->ssl, fd);
+       error = SSL_set_fd(config.ssl, fd);
        if (error == 0) {
-               syslog(LOG_NOTICE, "%s: remote delivery deferred: SSL set fd failed: %s",
-                      it->queueid, ssl_errstr());
+               syslog(LOG_NOTICE, "remote delivery deferred: SSL set fd failed: %s",
+                      ssl_errstr());
                return (1);
        }
 
        /* Open SSL connection */
-       error = SSL_connect(config->ssl);
+       error = SSL_connect(config.ssl);
        if (error < 0) {
-               syslog(LOG_ERR, "%s: remote delivery deferred: SSL handshake failed fatally: %s",
-                      it->queueid, ssl_errstr());
+               syslog(LOG_ERR, "remote delivery deferred: SSL handshake failed fatally: %s",
+                      ssl_errstr());
                return (1);
        }
 
        /* Get peer certificate */
-       cert = SSL_get_peer_certificate(config->ssl);
+       cert = SSL_get_peer_certificate(config.ssl);
        if (cert == NULL) {
-               syslog(LOG_WARNING, "%s: remote delivery deferred: Peer did not provide certificate: %s",
-                      it->queueid, ssl_errstr());
+               syslog(LOG_WARNING, "remote delivery deferred: Peer did not provide certificate: %s",
+                      ssl_errstr());
        }
        X509_free(cert);
 
@@ -184,7 +184,7 @@ smtp_init_crypto(struct qitem *it, int fd, int feature)
  */
 void
 hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len,
-    caddr_t digest)
+    unsigned char* digest)
 {
         MD5_CTX context;
         unsigned char k_ipad[65];    /* inner padding -
@@ -254,9 +254,10 @@ hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len,
  * CRAM-MD5 authentication
  */
 int
-smtp_auth_md5(struct qitem *it, int fd, char *login, char *password)
+smtp_auth_md5(int fd, char *login, char *password)
 {
-       unsigned char buffer[BUF_SIZE], digest[BUF_SIZE], ascii_digest[33];
+       unsigned char digest[BUF_SIZE];
+       char buffer[BUF_SIZE], ascii_digest[33];
        char *temp;
        int len, i;
        static char hextab[] = "0123456789abcdef";
@@ -269,16 +270,17 @@ smtp_auth_md5(struct qitem *it, int fd, char *login, char *password)
        /* Send AUTH command according to RFC 2554 */
        send_remote_command(fd, "AUTH CRAM-MD5");
        if (read_remote(fd, sizeof(buffer), buffer) != 3) {
-               syslog(LOG_DEBUG, "%s: smarthost authentification:"
-                      " AUTH cram-md5 not available: %s", it->queueid,
-                      neterr);
+               syslog(LOG_DEBUG, "smarthost authentication:"
+                      " AUTH cram-md5 not available: %s", neterr);
                /* if cram-md5 is not available */
+               free(temp);
                return (-1);
        }
 
        /* skip 3 char status + 1 char space */
        base64_decode(buffer + 4, temp);
-       hmac_md5(temp, strlen(temp), password, strlen(password), digest);
+       hmac_md5((unsigned char *)temp, strlen(temp),
+                (unsigned char *)password, strlen(password), digest);
        free(temp);
 
        ascii_digest[32] = 0;
@@ -293,8 +295,7 @@ smtp_auth_md5(struct qitem *it, int fd, char *login, char *password)
        /* encode answer */
        len = base64_encode(buffer, strlen(buffer), &temp);
        if (len < 0) {
-               syslog(LOG_ERR, "%s: can not encode auth reply: %m",
-                      it->queueid);
+               syslog(LOG_ERR, "can not encode auth reply: %m");
                return (-1);
        }
 
@@ -302,9 +303,8 @@ smtp_auth_md5(struct qitem *it, int fd, char *login, char *password)
        send_remote_command(fd, "%s", temp);
        free(temp);
        if (read_remote(fd, 0, NULL) != 2) {
-               syslog(LOG_WARNING, "%s: remote delivery deferred:"
-                               " AUTH cram-md5 failed: %s", it->queueid,
-                               neterr);
+               syslog(LOG_WARNING, "remote delivery deferred:"
+                               " AUTH cram-md5 failed: %s", neterr);
                return (-2);
        }