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

📄 cspace_validator.c

📁 开源的OpenId的一个java实现
💻 C
字号:
#include <openssl/ssl.h>#include "mod_cspace_defines.h"#include "cspace_validator.h"/*#ifdef CSPACE_APACHE2*/#include "apr_dso.h"#include "apr_file_info.h"/*#endif*//* In validating the saml token using xmlsec we anyway need the CA cert * of the CA which signed the IdP's cert. Hence, the "promiscuous" and "cert" * validators are the same (does nothing infact) in this module. Yet we include * both these types for completeness. */ typedef enum {    VAL_TYPE_WHITE = 0,    VAL_TYPE_BLACK,    VAL_TYPE_CERT,    VAL_TYPE_PROMISCUOUS,    VAL_TYPE_USER,    VAL_TYPE_FAULT = -1} val_type;char *(val_name[5]) = {"white", "black", "cert", "promiscuous", "user"};static int white_list_validator(const char *uri, const char *issuer,                                const char *ppid, const char *cert,                                const char *w_list);static int black_list_validator(const char *uri, const char *issuer,                                 const char *ppid, const char *cert,                                const char *b_list);static int cert_validator(const char *uri, const char *issuer,                          const char *ppid, const char *cert,                          const void *data);static int user_validator(const char *uri, const char *issuer,                          const char *ppid, const char *cert,    	                  const char *dso_fname, void *cb_data,                          void *data);static val_type valstr2type(const char *validator);static X509 *x509_create_with_buffer(unsigned char *input, int length);static X509 *x509_create_with_buffer(unsigned char *input, int length){    BIO *b64, *bmem;    X509 *x509 = NULL;    char *buffer = NULL;    /*TODO: replace mallocs with apr_palloc when used with apache*/    buffer = (char *)malloc(length);    memset(buffer, 0, length);          b64 = BIO_new(BIO_f_base64());    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);    bmem = BIO_new_mem_buf(input, length);    bmem = BIO_push(b64, bmem);    x509 = d2i_X509_bio(bmem, NULL);    BIO_free_all(bmem);    free(buffer);    return x509;}#define MAXARR  1024#define ISSUER_SELF "http://schemas.xmlsoap.org/ws/2005/05/identity/issuer/self"static int white_list_validator(const char *uri, const char *issuer,                                const char *ppid, const char *cert,                                const char *w_list){    FILE *fp = NULL;    X509 *needle = NULL;    X509 *(haystack[MAXARR]); /* TODO: this list should be made static */    int i = 0, j = 0;    if (issuer && strcmp(issuer, ISSUER_SELF) == 0) {        return FAIL;    }    if (cert) {        needle = x509_create_with_buffer((void *)cert, strlen(cert));    }    /*ideally we would read this file only once per server init*/    i=0;    if ((fp = fopen (w_list, "r"))) {        while (!feof(fp)) {            if (i < MAXARR) {                haystack[i++] = PEM_read_X509(fp, NULL, NULL, NULL);             } else {                break;            }        }    } else {        return FAIL;    }    for (j=0; j<i; j++) {        if (haystack[j] &&                (M_ASN1_BIT_STRING_cmp(haystack[j]->signature,                                       needle->signature) == 0)) {            if (needle) {                X509_free(needle);            }            /* free the haystack */            for (j=0; j<i; j++) {                if (haystack[j]) {                    X509_free(haystack[j]);                }            }	                    fclose(fp);                        return SUCC;         }    }        if (needle) {        X509_free(needle);    }        /* free the haystack */    for (j=0; j<i; j++) {        if (haystack[j]) {            X509_free(haystack[j]);        }    }    fclose(fp);    return FAIL;}#define MAX_HOST_NAME_LEN 1024static int black_list_validator(const char *uri, const char *issuer,                                const char *ppid, const char *cert,                                const char *b_list){    char line[MAX_HOST_NAME_LEN];    FILE *fp = NULL;    X509 *crt= NULL;    char *cn = NULL;    if (cert) {       crt = x509_create_with_buffer((void *)cert, strlen(cert));    }    if ((fp = fopen(b_list, "r"))) {        while (fgets(line, MAX_HOST_NAME_LEN, fp) != NULL) {            if (strstr(line, cn)) {                fclose(fp);                return FAIL;            }        }    } else {        return FAIL;    }        fclose(fp);    /*if not found in black list allow it*/    return SUCC;}static int cert_validator(const char *uri, const char *issuer,                          const char *ppid, const char *cert,                          const void *data){    /* this validation is done at the cert verification */    return SUCC;}/* Allow all the requests in case of promiscuous */#define promiscuous_validator(a, b, c, d, e) SUCC/*TODO: cb_user data should be requested from the user using an init() callback*/static int user_validator(const char *uri, const char *issuer,                          const char *ppid, const char *cert,    	                  const char *dso_fname, void *cb_data,                          void *ctx) {/*#ifdef CSPACE_APACHE2*/    apr_status_t rv;    apr_dso_handle_sym_t sym = NULL;    apr_dso_handle_t *hand = NULL;    char *fname = NULL;    apr_pool_t *p = (apr_pool_t *) ctx;    cspace_user_validator_cb_t func;    if (!ppid || !dso_fname)        return FAIL;    apr_filepath_merge(&fname, NULL, dso_fname, 0, p);    rv = apr_dso_load(&hand, dso_fname, p);    if (rv)    {        /*read error using: apr_dso_error(hand, char [128], 128)*/        /*log error*/        apr_dso_unload(hand);        return FAIL;    }        rv = apr_dso_sym(&sym, hand, "cspace_user_validate");    if (rv)    {        /*read error using: apr_dso_error(hand, char [128], 128)*/        /*log error*/        apr_dso_unload(hand);        return FAIL;    }        /*is it meaningful to do a if(func)?*/    func = (cspace_user_validator_cb_t)sym;    rv = (*func)(uri, issuer, ppid, cert, cb_data);        apr_dso_unload(hand);        return rv;/*#else    return FAIL;#endif*/}static val_type valstr2type(const char *validator){    if (strcmp(validator, val_name[VAL_TYPE_WHITE]) == 0) {        return VAL_TYPE_WHITE;    } else if (strcmp(validator, val_name[VAL_TYPE_BLACK]) == 0) {        return VAL_TYPE_BLACK;    } else if (strcmp(validator, val_name[VAL_TYPE_CERT]) == 0) {        return VAL_TYPE_CERT;    } else if (strcmp(validator, val_name[VAL_TYPE_PROMISCUOUS]) == 0) {        return VAL_TYPE_PROMISCUOUS;    } else {        return VAL_TYPE_FAULT;    }}int validate_with_op_mode(const char *validator, const char *uri,                          const char *issuer, const char *ppid,                          const char *cert, const void *val_data,                          void *ctx){    int flag = FAIL;    val_type v_type = valstr2type(validator);    switch (v_type) {        case VAL_TYPE_WHITE:            flag = white_list_validator(uri, issuer, NULL, cert, val_data);            break;        case VAL_TYPE_BLACK:            flag = black_list_validator(uri, issuer, NULL, cert, val_data);            break;        case VAL_TYPE_CERT:            flag = cert_validator(uri, NULL, NULL, cert, NULL);            break;        case VAL_TYPE_USER:            flag = user_validator(uri, issuer, ppid, cert, (char *)val_data, NULL, ctx);            break;        case VAL_TYPE_PROMISCUOUS:            flag = promiscuous_validator(NULL, NULL, NULL, NULL, NULL);            break;         default:            flag = FAIL;    }        return flag;}

⌨️ 快捷键说明

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