dma: restructure logging
[dragonfly.git] / libexec / dma / crypto.c
index 9182137..afbf993 100644 (file)
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/libexec/dma/crypto.c,v 1.3 2008/09/02 15:11:49 matthias Exp $
+ * $DragonFly: src/libexec/dma/crypto.c,v 1.4 2008/09/30 17:47:21 swildner Exp $
  */
 
-#ifdef HAVE_CRYPTO
-
 #include <openssl/x509.h>
 #include <openssl/md5.h>
 #include <openssl/ssl.h>
 
 #include "dma.h"
 
-extern struct config *config;
-
 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",
-                       it->queueid, path);
+               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",
-                       it->queueid, path);
+               syslog(LOG_ERR, "SSL: Cannot load private key `%s': %s", path, ssl_errstr());
                return (-1);
        }
 
@@ -77,8 +71,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, path);
+               syslog(LOG_ERR, "SSL: Cannot check private key: %s", ssl_errstr());
                return (-1);
        }
 
@@ -86,29 +79,34 @@ 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;
        SSL_METHOD *meth = NULL;
        X509 *cert;
-       char buf[2048];
        int error;
 
+       /* XXX clean up on error/close */
        /* Init SSL library */
        SSL_library_init();
+       SSL_load_error_strings();
 
        meth = TLSv1_client_method();
 
        ctx = SSL_CTX_new(meth);
        if (ctx == NULL) {
-               syslog(LOG_ERR, "%s: remote delivery deferred:"
-                      " SSL init failed: %m", it->queueid);
-               return (2);
+               syslog(LOG_WARNING, "remote delivery deferred: SSL init failed: %s", ssl_errstr());
+               return (1);
        }
 
        /* User supplied a certificate */
-       if (config->certfile != NULL)
-               init_cert_file(it, ctx, config->certfile);
+       if (config->certfile != NULL) {
+               error = init_cert_file(ctx, config->certfile);
+               if (error) {
+                       syslog(LOG_WARNING, "remote delivery deferred");
+                       return (1);
+               }
+       }
 
        /*
         * If the user wants STARTTLS, we have to send EHLO here
@@ -122,10 +120,10 @@ smtp_init_crypto(struct qitem *it, int fd, int feature)
                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 failed:"
-                                 " STARTTLS not available: %m", it->queueid);
+                               syslog(LOG_ERR, "remote delivery deferred:"
+                                 " STARTTLS not available: %s", neterr);
                                config->features &= ~NOSSL;
-                               return (-1);
+                               return (1);
                        }
                }
                /* End of TLS init phase, enable SSL_write/read */
@@ -134,9 +132,9 @@ smtp_init_crypto(struct qitem *it, int fd, int feature)
 
        config->ssl = SSL_new(ctx);
        if (config->ssl == NULL) {
-               syslog(LOG_ERR, "%s: remote delivery deferred:"
-                      " SSL struct creation failed:", it->queueid);
-               return (2);
+               syslog(LOG_NOTICE, "remote delivery deferred: SSL struct creation failed: %s",
+                      ssl_errstr());
+               return (1);
        }
 
        /* Set ssl to work in client mode */
@@ -145,25 +143,24 @@ smtp_init_crypto(struct qitem *it, int fd, int feature)
        /* Set fd for SSL in/output */
        error = SSL_set_fd(config->ssl, fd);
        if (error == 0) {
-               error = SSL_get_error(config->ssl, error);
-               syslog(LOG_ERR, "%s: remote delivery deferred:"
-                      " SSL set fd failed (%d): %m", it->queueid, error);
-               return (2);
+               syslog(LOG_NOTICE, "remote delivery deferred: SSL set fd failed: %s",
+                      ssl_errstr());
+               return (1);
        }
 
        /* Open SSL connection */
        error = SSL_connect(config->ssl);
        if (error < 0) {
-               syslog(LOG_ERR, "%s: remote delivery failed:"
-                      " SSL handshake fataly failed: %m", it->queueid);
-               return (-1);
+               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);
        if (cert == NULL) {
-               syslog(LOG_ERR, "%s: remote delivery deferred:"
-                      " Peer did not provied certificate: %m", it->queueid);
+               syslog(LOG_WARNING, "remote delivery deferred: Peer did not provide certificate: %s",
+                      ssl_errstr());
        }
        X509_free(cert);
 
@@ -173,15 +170,16 @@ smtp_init_crypto(struct qitem *it, int fd, int feature)
 /*
  * hmac_md5() taken out of RFC 2104.  This RFC was written by H. Krawczyk,
  * M. Bellare and R. Canetti.
- */ 
+ *
+ * text      pointer to data stream
+ * text_len  length of data stream
+ * key       pointer to authentication key
+ * key_len   length of authentication key
+ * digest    caller digest to be filled int
+ */
 void
-hmac_md5(text, text_len, key, key_len, digest)
-unsigned char*  text;                /* pointer to data stream */
-int             text_len;            /* length of data stream */
-unsigned char*  key;                 /* pointer to authentication key */
-int             key_len;             /* length of authentication key */
-caddr_t         digest;              /* caller digest to be filled in */
-
+hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len,
+    caddr_t digest)
 {
         MD5_CTX context;
         unsigned char k_ipad[65];    /* inner padding -
@@ -251,7 +249,7 @@ caddr_t         digest;              /* caller digest to be filled in */
  * 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];
        char *temp;
@@ -266,8 +264,8 @@ 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_ERR, "%s: smarthost authentification:"
-                      " AUTH cram-md5 not available: %m", it->queueid);
+               syslog(LOG_DEBUG, "smarthost authentification:"
+                      " AUTH cram-md5 not available: %s", neterr);
                /* if cram-md5 is not available */
                return (-1);
        }
@@ -275,6 +273,7 @@ smtp_auth_md5(struct qitem *it, int fd, char *login, char *password)
        /* skip 3 char status + 1 char space */
        base64_decode(buffer + 4, temp);
        hmac_md5(temp, strlen(temp), password, strlen(password), digest);
+       free(temp);
 
        ascii_digest[32] = 0;
        for (i = 0; i < 16; i++) {
@@ -285,22 +284,21 @@ smtp_auth_md5(struct qitem *it, int fd, char *login, char *password)
        /* prepare answer */
        snprintf(buffer, BUF_SIZE, "%s %s", login, ascii_digest);
 
-       /* temp will be allocated inside base64_encode again */
-       free(temp);
        /* encode answer */
        len = base64_encode(buffer, strlen(buffer), &temp);
-       if (len <= 0)
+       if (len < 0) {
+               syslog(LOG_ERR, "can not encode auth reply: %m");
                return (-1);
+       }
 
        /* send answer */
        send_remote_command(fd, "%s", temp);
+       free(temp);
        if (read_remote(fd, 0, NULL) != 2) {
-               syslog(LOG_ERR, "%s: remote delivery deferred:"
-                               " AUTH cram-md5 failed: %m", it->queueid);
+               syslog(LOG_WARNING, "remote delivery deferred:"
+                               " AUTH cram-md5 failed: %s", neterr);
                return (-2);
        }
 
        return (0);
 }
-
-#endif /* HAVE_CRYPTO */