Commit 55272be5 authored by Kaspar Brand's avatar Kaspar Brand
Browse files

Add ssl_log_xerror() and ssl_log_rxerror(), modeled after ssl_log_cxerror().

Add SSL_X509_NAME_to_string(), which converts an X509 distinguished name
to an RFC 2253 formatted string.
Adapt ssl_log_*error() to make use of SSL_X509_NAME_to_string().


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1172797 13f79535-47bb-0310-9956-ffa450edef68
parent 0607dca4
Loading
Loading
Loading
Loading
+84 −25
Changes for modules/ssl/ssl_engine_log.c: 84 added lines, 25 removed lines.
Original line number Diff line number Diff line
@@ -108,44 +108,49 @@ void ssl_log_ssl_error(const char *file, int line, int level, server_rec *s)
    }
}

void ssl_log_cxerror(const char *file, int line, int level, 
                     apr_status_t rv, conn_rec *c, X509 *cert,
                     const char *format, ...)
static void ssl_log_cert_error(const char *file, int line, int level, 
                               apr_status_t rv, const server_rec *s,
                               const conn_rec *c, const request_rec *r,
                               apr_pool_t *p, X509 *cert, const char *format,
                               va_list ap)
{
    va_list ap;
    char buf[HUGE_STRING_LEN];
    int msglen, n;
    char *name;
    
    if (!APLOG_IS_LEVEL(mySrvFromConn(c),level)) {
        /* Bail early since the rest of this function is expensive. */
        return;
    }

    va_start(ap, format);
    apr_vsnprintf(buf, sizeof buf, format, ap);
    va_end(ap);

    msglen = strlen(buf);

    if (cert) {
        BIO *bio = BIO_new(BIO_s_mem());

        if (bio) {
            int n, msglen;
            /*
             * Limit the maximum length of the subject and issuer DN strings
             * in the log message. 300 characters should always be sufficient
             * for holding both the timestamp, module name, pid etc. stuff
             * at the beginning of the line and the trailing information about
             * serial, notbefore and notafter.
             */
            int maxdnlen = (HUGE_STRING_LEN - msglen - 300) / 2;

            BIO_puts(bio, " [subject: ");
            n = X509_NAME_print_ex(bio, X509_get_subject_name(cert), 0,
                                   XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV);
            if (n == 0) {
            name = SSL_X509_NAME_to_string(p, X509_get_subject_name(cert),
                                           maxdnlen);
            if (!strIsEmpty(name)) {
                BIO_puts(bio, name);
            } else {
                BIO_puts(bio, "-empty-");
            } else if (n < 0) {
                BIO_puts(bio, "(ERROR)");
            }

            BIO_puts(bio, " / issuer: ");
            n = X509_NAME_print_ex(bio, X509_get_issuer_name(cert), 0,
                                   XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV);
            if (n == 0) {
            name = SSL_X509_NAME_to_string(p, X509_get_issuer_name(cert),
                                           maxdnlen);
            if (!strIsEmpty(name)) {
                BIO_puts(bio, name);
            } else {
                BIO_puts(bio, "-empty-");
            } else if (n < 0) {
                BIO_puts(bio, "(ERROR)");
            }

            BIO_puts(bio, " / serial: ");
@@ -160,7 +165,6 @@ void ssl_log_cxerror(const char *file, int line, int level,

            BIO_puts(bio, "]");

            msglen = strlen(buf);
            n = BIO_read(bio, buf + msglen, sizeof buf - msglen - 1);
            if (n > 0)
               buf[msglen + n] = '\0';
@@ -168,7 +172,62 @@ void ssl_log_cxerror(const char *file, int line, int level,
            BIO_free(bio);
        }
    }
    else {
        apr_snprintf(buf + msglen, sizeof buf - msglen,
                     " [certificate: -not available-]");
    }

    if (r) {
        ap_log_rerror(file, line, APLOG_MODULE_INDEX, level, rv, r, "%s", buf);
    }
    else if (c) {
        ap_log_cerror(file, line, APLOG_MODULE_INDEX, level, rv, c, "%s", buf);
    }
    else if (s) {
        ap_log_error(file, line, APLOG_MODULE_INDEX, level, rv, s, "%s", buf);
    }

}

/*
 * Wrappers for ap_log_error/ap_log_cerror/ap_log_rerror which log additional
 * details of the X509 cert. For ssl_log_xerror, a pool needs to be passed in
 * as well (for temporary allocation of the cert's subject/issuer name strings,
 * in the other cases we use the connection and request pool, respectively).
 */
void ssl_log_xerror(const char *file, int line, int level, apr_status_t rv,
                    apr_pool_t *ptemp, server_rec *s, X509 *cert,
                    const char *fmt, ...)
{
    if (APLOG_IS_LEVEL(s,level)) {
       va_list ap;
       va_start(ap, fmt);
       ssl_log_cert_error(file, line, level, rv, s, NULL, NULL, ptemp,
                          cert, fmt, ap);
       va_end(ap);
    }
}

void ssl_log_cxerror(const char *file, int line, int level, apr_status_t rv,
                     conn_rec *c, X509 *cert, const char *fmt, ...)
{
    if (APLOG_IS_LEVEL(mySrvFromConn(c),level)) {
       va_list ap;
       va_start(ap, fmt);
       ssl_log_cert_error(file, line, level, rv, NULL, c, NULL, c->pool,
                          cert, fmt, ap);
       va_end(ap);
    }
}

    ap_log_cerror(file, line, APLOG_MODULE_INDEX, level, rv, c,
                  "%s%s", buf, cert ? "" : " [certificate: -not available-]");
void ssl_log_rxerror(const char *file, int line, int level, apr_status_t rv,
                     request_rec *r, X509 *cert, const char *fmt, ...)
{
    if (APLOG_R_IS_LEVEL(r,level)) {
       va_list ap;
       va_start(ap, fmt);
       ssl_log_cert_error(file, line, level, rv, NULL, NULL, r, r->pool,
                          cert, fmt, ap);
       va_end(ap);
    }
}
+15 −4
Changes for modules/ssl/ssl_private.h: 15 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -852,15 +852,26 @@ int ssl_stapling_mutex_reinit(server_rec *, apr_pool_t *);
void         ssl_die(void);
void         ssl_log_ssl_error(const char *, int, int, server_rec *);

/* ssl_log_cxerror is a wrapper for ap_log_cerror which takes a
 * certificate as an additional argument and appends details of that
 * cert to the log message.  All other arguments interpreted exactly
 * as ap_log_cerror. */
/* ssl_log_xerror, ssl_log_cxerror and ssl_log_rxerror are wrappers for the
 * respective ap_log_*error functions and take a certificate as an
 * additional argument (whose details are appended to the log message).
 * The other arguments are interpreted exactly as with their ap_log_*error
 * counterparts. */
void ssl_log_xerror(const char *file, int line, int level, 
                    apr_status_t rv, apr_pool_t *p, server_rec *s,
                    X509 *cert, const char *format, ...)
    __attribute__((format(printf,8,9)));

void ssl_log_cxerror(const char *file, int line, int level, 
                     apr_status_t rv, conn_rec *c, X509 *cert,
                     const char *format, ...)
    __attribute__((format(printf,7,8)));

void ssl_log_rxerror(const char *file, int line, int level, 
                     apr_status_t rv, request_rec *r, X509 *cert,
                     const char *format, ...)
    __attribute__((format(printf,7,8)));

#define SSLLOG_MARK              __FILE__,__LINE__

/**  Variables  */
+32 −0
Changes for modules/ssl/ssl_util_ssl.c: 32 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -297,6 +297,38 @@ char *SSL_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne)
    return result;
}

/* 
 * convert an X509_NAME to an RFC 2253 formatted string, optionally truncated
 * to maxlen characters (specify a maxlen of 0 for no length limit)
 */
char *SSL_X509_NAME_to_string(apr_pool_t *p, X509_NAME *dn, unsigned int maxlen)
{
    char *result = NULL;
    BIO *bio;
    int len;

    if ((bio = BIO_new(BIO_s_mem())) == NULL)
        return NULL;
    X509_NAME_print_ex(bio, dn, 0, XN_FLAG_RFC2253);
    len = BIO_pending(bio);
    if (len > 0) {
        result = apr_palloc(p, maxlen ? maxlen+1 : len+1);
        if (maxlen && maxlen < len) {
            len = BIO_read(bio, result, maxlen);
            if (maxlen > 2) {
                /* insert trailing ellipsis if there's enough space */
                apr_snprintf(result + maxlen - 3, 4, "...");
            }
        } else {
            len = BIO_read(bio, result, len);
        }
        result[len] = NUL;
    }
    BIO_free(bio);

    return result;
}

/* retrieve subject CommonName of certificate */
BOOL SSL_X509_getCN(apr_pool_t *p, X509 *xs, char **cppCN)
{
+1 −0
Changes for modules/ssl/ssl_util_ssl.h: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ char *SSL_make_ciphersuite(apr_pool_t *, SSL *);
BOOL        SSL_X509_isSGC(X509 *);
BOOL        SSL_X509_getBC(X509 *, int *, int *);
char       *SSL_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne);
char       *SSL_X509_NAME_to_string(apr_pool_t *, X509_NAME *, unsigned int);
BOOL        SSL_X509_getCN(apr_pool_t *, X509 *, char **);
BOOL        SSL_X509_INFO_load_file(apr_pool_t *, STACK_OF(X509_INFO) *, const char *);
BOOL        SSL_X509_INFO_load_path(apr_pool_t *, STACK_OF(X509_INFO) *, const char *);