⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssl_engine_vars.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 2 页
字号:
    { "UID",   NID_x500UniqueIdentifier   },#else /* old name, OpenSSL < 0.9.7 */    { "UID",   NID_uniqueIdentifier       },#endif    { "Email", NID_pkcs9_emailAddress     },    { NULL,    0                          }};static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *var){    char *result, *ptr;    X509_NAME_ENTRY *xsne;    int i, j, n, idx = 0;    apr_size_t varlen;    /* if an _N suffix is used, find the Nth attribute of given name */    ptr = strchr(var, '_');    if (ptr != NULL && strspn(ptr + 1, "0123456789") == strlen(ptr + 1)) {        idx = atoi(ptr + 1);        varlen = ptr - var;    } else {        varlen = strlen(var);    }    result = NULL;    for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) {        if (strEQn(var, ssl_var_lookup_ssl_cert_dn_rec[i].name, varlen)            && strlen(ssl_var_lookup_ssl_cert_dn_rec[i].name) == varlen) {            for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *)                                                 X509_NAME_get_entries(xsname));                 j++) {                xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *)                                             X509_NAME_get_entries(xsname), j);                n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));                if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid && idx-- == 0) {                    unsigned char *data = X509_NAME_ENTRY_get_data_ptr(xsne);                    /* cast needed from unsigned char to char */                    result = apr_pstrmemdup(p, (char *)data,                                            X509_NAME_ENTRY_get_data_len(xsne));#if APR_CHARSET_EBCDIC                    ap_xlate_proto_from_ascii(result, X509_NAME_ENTRY_get_data_len(xsne));#endif /* APR_CHARSET_EBCDIC */                    break;                }            }            break;        }    }    return result;}static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_UTCTIME *tm){    char *result;    BIO* bio;    int n;    if ((bio = BIO_new(BIO_s_mem())) == NULL)        return NULL;    ASN1_UTCTIME_print(bio, tm);    n = BIO_pending(bio);    result = apr_pcalloc(p, n+1);    n = BIO_read(bio, result, n);    result[n] = NUL;    BIO_free(bio);    return result;}#define DIGIT2NUM(x) (((x)[0] - '0') * 10 + (x)[1] - '0')/* Return a string giving the number of days remaining until 'tm', or * "0" if this can't be determined. */static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_UTCTIME *tm){    apr_time_t then, now = apr_time_now();    apr_time_exp_t exp = {0};    long diff;    /* Fail if the time isn't a valid ASN.1 UTCTIME; RFC3280 mandates     * that the seconds digits are present even though ASN.1     * doesn't. */    if (tm->length < 11 || !ASN1_UTCTIME_check(tm)) {        return apr_pstrdup(p, "0");    }    exp.tm_year = DIGIT2NUM(tm->data);    exp.tm_mon = DIGIT2NUM(tm->data + 2) - 1;    exp.tm_mday = DIGIT2NUM(tm->data + 4) + 1;    exp.tm_hour = DIGIT2NUM(tm->data + 6);    exp.tm_min = DIGIT2NUM(tm->data + 8);    exp.tm_sec = DIGIT2NUM(tm->data + 10);    if (exp.tm_year <= 50) exp.tm_year += 100;    if (apr_time_exp_gmt_get(&then, &exp) != APR_SUCCESS) {        return apr_pstrdup(p, "0");    }    diff = (long)((apr_time_sec(then) - apr_time_sec(now)) / (60*60*24));    return diff > 0 ? apr_ltoa(p, diff) : apr_pstrdup(p, "0");}static char *ssl_var_lookup_ssl_cert_serial(apr_pool_t *p, X509 *xs){    char *result;    BIO *bio;    int n;    if ((bio = BIO_new(BIO_s_mem())) == NULL)        return NULL;    i2a_ASN1_INTEGER(bio, X509_get_serialNumber(xs));    n = BIO_pending(bio);    result = apr_pcalloc(p, n+1);    n = BIO_read(bio, result, n);    result[n] = NUL;    BIO_free(bio);    return result;}static char *ssl_var_lookup_ssl_cert_chain(apr_pool_t *p, STACK_OF(X509) *sk, char *var){    char *result;    X509 *xs;    int n;    result = NULL;    if (strspn(var, "0123456789") == strlen(var)) {        n = atoi(var);        if (n < sk_X509_num(sk)) {            xs = sk_X509_value(sk, n);            result = ssl_var_lookup_ssl_cert_PEM(p, xs);        }    }    return result;}static char *ssl_var_lookup_ssl_cert_PEM(apr_pool_t *p, X509 *xs){    char *result;    BIO *bio;    int n;    if ((bio = BIO_new(BIO_s_mem())) == NULL)        return NULL;    PEM_write_bio_X509(bio, xs);    n = BIO_pending(bio);    result = apr_pcalloc(p, n+1);    n = BIO_read(bio, result, n);    result[n] = NUL;    BIO_free(bio);    return result;}static char *ssl_var_lookup_ssl_cert_verify(apr_pool_t *p, conn_rec *c){    SSLConnRec *sslconn = myConnConfig(c);    char *result;    long vrc;    const char *verr;    const char *vinfo;    SSL *ssl;    X509 *xs;    result = NULL;    ssl   = sslconn->ssl;    verr  = sslconn->verify_error;    vinfo = sslconn->verify_info;    vrc   = SSL_get_verify_result(ssl);    xs    = SSL_get_peer_certificate(ssl);    if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs == NULL)        /* no client verification done at all */        result = "NONE";    else if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs != NULL)        /* client verification done successful */        result = "SUCCESS";    else if (vrc == X509_V_OK && vinfo != NULL && strEQ(vinfo, "GENEROUS"))        /* client verification done in generous way */        result = "GENEROUS";    else        /* client verification failed */        result = apr_psprintf(p, "FAILED:%s", verr);    if (xs)        X509_free(xs);    return result;}static char *ssl_var_lookup_ssl_cipher(apr_pool_t *p, conn_rec *c, char *var){    SSLConnRec *sslconn = myConnConfig(c);    char *result;    BOOL resdup;    int usekeysize, algkeysize;    SSL *ssl;    result = NULL;    resdup = TRUE;    ssl = sslconn->ssl;    ssl_var_lookup_ssl_cipher_bits(ssl, &usekeysize, &algkeysize);    if (ssl && strEQ(var, "")) {        SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);        result = (cipher != NULL ? (char *)SSL_CIPHER_get_name(cipher) : NULL);    }    else if (strcEQ(var, "_EXPORT"))        result = (usekeysize < 56 ? "true" : "false");    else if (strcEQ(var, "_USEKEYSIZE")) {        result = apr_itoa(p, usekeysize);        resdup = FALSE;    }    else if (strcEQ(var, "_ALGKEYSIZE")) {        result = apr_itoa(p, algkeysize);        resdup = FALSE;    }    if (result != NULL && resdup)        result = apr_pstrdup(p, result);    return result;}static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algkeysize){    SSL_CIPHER *cipher;    *usekeysize = 0;    *algkeysize = 0;    if (ssl != NULL)        if ((cipher = SSL_get_current_cipher(ssl)) != NULL)            *usekeysize = SSL_CIPHER_get_bits(cipher, algkeysize);    return;}static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var){    if (strEQ(var, "INTERFACE")) {        return apr_pstrdup(p, var_interface);    }    else if (strEQ(var, "LIBRARY_INTERFACE")) {        return apr_pstrdup(p, var_library_interface);    }    else if (strEQ(var, "LIBRARY")) {        return apr_pstrdup(p, var_library);    }    return NULL;}const char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer,                           const char *oidnum){    SSLConnRec *sslconn = myConnConfig(c);    SSL *ssl;    X509 *xs = NULL;    ASN1_OBJECT *oid;    int count = 0, j;    char *result = NULL;    if (!sslconn || !sslconn->ssl) {        return NULL;    }    ssl = sslconn->ssl;    oid = OBJ_txt2obj(oidnum, 1);    if (!oid) {        ERR_clear_error();        return NULL;    }    xs = peer ? SSL_get_peer_certificate(ssl) : SSL_get_certificate(ssl);    if (xs == NULL) {        return NULL;    }    count = X509_get_ext_count(xs);    for (j = 0; j < count; j++) {        X509_EXTENSION *ext = X509_get_ext(xs, j);        if (OBJ_cmp(ext->object, oid) == 0) {            BIO *bio = BIO_new(BIO_s_mem());            if (X509V3_EXT_print(bio, ext, 0, 0) == 1) {                BUF_MEM *buf;                BIO_get_mem_ptr(bio, &buf);                result = apr_pstrmemdup(p, buf->data, buf->length);            }            BIO_vfree(bio);            break;        }    }    if (peer) {        /* only SSL_get_peer_certificate raises the refcount */        X509_free(xs);    }    ERR_clear_error();    return result;}static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl){    char *result = "NULL";#ifdef OPENSSL_VERSION_NUMBER#if (OPENSSL_VERSION_NUMBER >= 0x00908000)    SSL_SESSION *pSession = SSL_get_session(ssl);    if (pSession) {        switch (pSession->compress_meth) {        case 0:            /* default "NULL" already set */            break;            /* Defined by RFC 3749, deflate is coded by "1" */        case 1:            result = "DEFLATE";            break;            /* IANA assigned compression number for LZS */        case 0x40:            result = "LZS";            break;        default:            result = "UNKNOWN";            break;        }    }#endif#endif    return result;}/*  _________________________________________________________________****  SSL Extension to mod_log_config**  _________________________________________________________________*/#include "../../modules/loggers/mod_log_config.h"static const char *ssl_var_log_handler_c(request_rec *r, char *a);static const char *ssl_var_log_handler_x(request_rec *r, char *a);/* * register us for the mod_log_config function registering phase * to establish %{...}c and to be able to expand %{...}x variables. */void ssl_var_log_config_register(apr_pool_t *p){    static APR_OPTIONAL_FN_TYPE(ap_register_log_handler) *log_pfn_register;    log_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_log_handler);    if (log_pfn_register) {        log_pfn_register(p, "c", ssl_var_log_handler_c, 0);        log_pfn_register(p, "x", ssl_var_log_handler_x, 0);    }    return;}/* * implement the %{..}c log function * (we are the only function) */static const char *ssl_var_log_handler_c(request_rec *r, char *a){    SSLConnRec *sslconn = myConnConfig(r->connection);    char *result;    if (sslconn == NULL || sslconn->ssl == NULL)        return NULL;    result = NULL;    if (strEQ(a, "version"))        result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_PROTOCOL");    else if (strEQ(a, "cipher"))        result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER");    else if (strEQ(a, "subjectdn") || strEQ(a, "clientcert"))        result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_S_DN");    else if (strEQ(a, "issuerdn") || strEQ(a, "cacert"))        result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_I_DN");    else if (strEQ(a, "errcode"))        result = "-";    else if (strEQ(a, "errstr"))        result = (char *)sslconn->verify_error;    if (result != NULL && result[0] == NUL)        result = NULL;    return result;}/* * extend the implementation of the %{..}x log function * (there can be more functions) */static const char *ssl_var_log_handler_x(request_rec *r, char *a){    char *result;    result = ssl_var_lookup(r->pool, r->server, r->connection, r, a);    if (result != NULL && result[0] == NUL)        result = NULL;    return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -