Changes in / [eebc960:91ccb87] in mod_gnutls


Ignore:
Files:
117 added
94 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • Makefile.am

    reebc960 r91ccb87  
    88                NOTICE LICENSE autogen.sh
    99
    10 SUBDIRS = src
     10SUBDIRS = src test
    1111ACLOCAL_AMFLAGS = -I m4
    12 TESTS = run_tests.sh
  • README

    reebc960 r91ccb87  
    1717  Nikos Mavrogiannopoulos <nmav at gnutls.org>
    1818  Dash Shendy <neuromancer at dash.za.net>
     19  Thomas Klute <thomas2.klute@uni-dortmund.de>
    1920
    2021Prerequisites
    2122-------------
    2223
    23  * GnuTLS          >= 2.12.6 <http://www.gnutls.org/> (3.* preferred)
     24 * GnuTLS          >= 3.1.4 <http://www.gnutls.org/>
    2425 * Apache HTTPD    >= 2.2 <http://httpd.apache.org/> (2.4.* preferred)
    2526 * autotools & gcc
  • configure.ac

    reebc960 r91ccb87  
    2828)
    2929
    30 PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 2.12.6])
     30PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.1.4])
    3131
    3232LIBGNUTLS_VERSION=`pkg-config --modversion gnutls`
     
    5959               [enable Monkeysphere client certificate verification]),
    6060       use_msva=$enableval, use_msva=no)
     61AM_CONDITIONAL([USE_MSVA], [test "$use_msva" = "$enableval"])
    6162
    6263MSVA_CFLAGS=""
     
    8283AC_SUBST(MODULE_LIBS)
    8384
    84 AC_CONFIG_FILES([Makefile src/Makefile include/mod_gnutls.h])
     85AC_CONFIG_FILES([Makefile src/Makefile test/Makefile include/mod_gnutls.h])
    8586AC_OUTPUT
    8687
  • include/mod_gnutls.h.in

    reebc960 r91ccb87  
    104104/* Server Configuration Record */
    105105typedef struct {
    106         /* x509 Certificate Structure */
     106    /* x509 Certificate Structure */
    107107    gnutls_certificate_credentials_t certs;
    108         /* SRP Certificate Structure*/
     108    /* x509 credentials for proxy connections */
     109    gnutls_certificate_credentials_t proxy_x509_creds;
     110    const char* proxy_x509_key_file;
     111    const char* proxy_x509_cert_file;
     112    const char* proxy_x509_ca_file;
     113    /* SRP Certificate Structure*/
    109114    gnutls_srp_server_credentials_t srp_creds;
    110         /* Annonymous Certificate Structure */
     115    /* Anonymous Certificate Structure */
    111116    gnutls_anon_server_credentials_t anon_creds;
     117    /* Anonymous Client Certificate Structure, used for proxy
     118     * connections */
     119    gnutls_anon_client_credentials_t anon_client_creds;
    112120        /* Current x509 Certificate CN [Common Name] */
    113121    char* cert_cn;
     
    171179        /* Connection record */
    172180    conn_rec* c;
     181        /* Is TLS enabled for this connection? */
     182    int enabled;
     183    /* Is this a proxy connection? */
     184    int is_proxy;
    173185        /* GnuTLS Session handle */
    174186    gnutls_session_t session;
     
    381393mgs_srvconf_rec* mgs_find_sni_server(gnutls_session_t session);
    382394
     395const char *mgs_store_cred_path(cmd_parms * parms,
     396                                void *dummy __attribute__((unused)),
     397                                const char *arg);
     398
    383399/* mod_gnutls Hooks. */
    384400
  • src/gnutls_config.c

    reebc960 r91ccb87  
    101101}
    102102
    103 const char *mgs_set_cert_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
    104 
     103const char *mgs_set_cert_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg)
     104{
    105105    int ret;
    106106    gnutls_datum_t data;
     
    620620        return NULL;
    621621    }
     622
     623    /* FIXME: not ideal, should be called only if SSLProxyEngine is
     624     * enabled */
     625    ret = gnutls_anon_allocate_client_credentials(&sc->anon_client_creds);
     626    if (ret < 0)
     627    {
     628        *err = apr_psprintf(p, "GnuTLS: Failed to initialize"
     629                            ": (%d) %s", ret,
     630                            gnutls_strerror(ret));
     631        return NULL;
     632    }
     633
     634    sc->proxy_x509_key_file = NULL;
     635    sc->proxy_x509_cert_file = NULL;
     636    sc->proxy_x509_ca_file = NULL;
     637    ret = gnutls_certificate_allocate_credentials(&sc->proxy_x509_creds);
     638    if (ret < 0)
     639    {
     640        *err = apr_psprintf(p, "GnuTLS: Failed to initialize"
     641                            ": (%d) %s", ret,
     642                            gnutls_strerror(ret));
     643        return NULL;
     644    }
     645
    622646#ifdef ENABLE_SRP
    623647    ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
     
    687711    gnutls_srvconf_merge(dh_params, NULL);
    688712
     713    gnutls_srvconf_merge(proxy_x509_key_file, NULL);
     714    gnutls_srvconf_merge(proxy_x509_cert_file, NULL);
     715    gnutls_srvconf_merge(proxy_x509_ca_file, NULL);
     716
    689717    /* FIXME: the following items are pre-allocated, and should be
    690718     * properly disposed of before assigning in order to avoid leaks;
     
    696724    gnutls_srvconf_assign(certs);
    697725    gnutls_srvconf_assign(anon_creds);
     726    gnutls_srvconf_assign(anon_client_creds);
    698727    gnutls_srvconf_assign(srp_creds);
    699728    gnutls_srvconf_assign(certs_x509_chain);
     
    736765}
    737766
     767/*
     768 * Store paths to proxy credentials
     769 *
     770 * This function copies the paths provided in the configuration file
     771 * into the server configuration. The post configuration hook takes
     772 * care of actually loading the credentials, which means than invalid
     773 * paths or the like will be detected there.
     774 */
     775const char *mgs_store_cred_path(cmd_parms * parms,
     776                                void *dummy __attribute__((unused)),
     777                                const char *arg)
     778{
     779    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     780        ap_get_module_config(parms->server->module_config, &gnutls_module);
     781
     782    /* parms->directive->directive contains the directive string */
     783    if (!strcasecmp(parms->directive->directive, "GnuTLSProxyKeyFile"))
     784        sc->proxy_x509_key_file = apr_pstrdup(parms->pool, arg);
     785    else if (!strcasecmp(parms->directive->directive,
     786                         "GnuTLSProxyCertificateFile"))
     787        sc->proxy_x509_cert_file = apr_pstrdup(parms->pool, arg);
     788    else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyCAFile"))
     789        sc->proxy_x509_ca_file = apr_pstrdup(parms->pool, arg);
     790    /* TODO: Add CRL parameter */
     791    return NULL;
     792}
  • src/gnutls_hooks.c

    reebc960 r91ccb87  
    4040#endif
    4141
     42#define IS_PROXY_STR(c) \
     43    ((c->is_proxy == GNUTLS_ENABLED_TRUE) ? "proxy " : "")
     44
    4245static gnutls_datum_t session_ticket_key = {NULL, 0};
    4346
     
    5053static const char* mgs_x509_construct_uid(request_rec * pool, gnutls_x509_crt_t cert);
    5154#endif
     55static int load_proxy_x509_credentials(server_rec *s);
    5256
    5357/* Pool Cleanup Function */
     
    147151    gnutls_certificate_server_set_request(session, ctxt->sc->client_verify_mode);
    148152
     153    /* Set x509 credentials */
     154    gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);
    149155    /* Set Anon credentials */
    150     gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);
    151         /* Set x509 credentials */
    152156    gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds);
    153157
     
    454458                continue;
    455459            }
     460        }
     461
     462        if (sc->enabled == GNUTLS_ENABLED_TRUE
     463            && sc->proxy_enabled == GNUTLS_ENABLED_TRUE)
     464        {
     465            load_proxy_x509_credentials(s);
    456466        }
    457467    }
     
    620630#endif
    621631
    622 mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session) {
     632mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session)
     633{
    623634    int rv;
    624635    unsigned int sni_type;
     
    671682
    672683        tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    673                 &gnutls_module);
     684                                                       &gnutls_module);
    674685
    675686        if (tsc->enabled != GNUTLS_ENABLED_TRUE) { continue; }
    676687
    677                                 if(check_server_aliases(x, s, tsc)) {
    678                                         return tsc;
    679                                 }
     688        if(check_server_aliases(x, s, tsc)) {
     689            return tsc;
     690        }
     691    }
    680692#endif
    681693    return NULL;
    682694}
    683695
    684 static void create_gnutls_handle(conn_rec * c) {
    685     mgs_handle_t *ctxt;
    686     /* Get mod_gnutls Configuration Record */
    687     mgs_srvconf_rec *sc =(mgs_srvconf_rec *)
    688             ap_get_module_config(c->base_server->module_config,&gnutls_module);
     696/*
     697 * This function is intended as a cleanup handler for connections
     698 * using GnuTLS.
     699 *
     700 * @param data must point to the mgs_handle_t associated with the
     701 * connection
     702 */
     703static apr_status_t cleanup_gnutls_session(void *data)
     704{
     705    /* nothing to do */
     706    if (data == NULL)
     707        return APR_SUCCESS;
     708
     709    /* check if session needs closing */
     710    mgs_handle_t *ctxt = (mgs_handle_t *) data;
     711    if (ctxt->session != NULL)
     712    {
     713        int ret;
     714        /* Try A Clean Shutdown */
     715        do
     716            ret = gnutls_bye(ctxt->session, GNUTLS_SHUT_WR);
     717        while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
     718        if (ret != GNUTLS_E_SUCCESS)
     719            ap_log_cerror(APLOG_MARK, APLOG_INFO, ret, ctxt->c,
     720                          "%s: error while closing TLS %sconnection: %s (%d)",
     721                          __func__, IS_PROXY_STR(ctxt),
     722                          gnutls_strerror(ret), ret);
     723        else
     724            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, ret, ctxt->c,
     725                          "%s: TLS %sconnection closed.",
     726                          __func__, IS_PROXY_STR(ctxt));
     727        /* De-Initialize Session */
     728        gnutls_deinit(ctxt->session);
     729        ctxt->session = NULL;
     730    }
     731    return APR_SUCCESS;
     732}
     733
     734static void create_gnutls_handle(conn_rec * c)
     735{
     736    /* Get mod_gnutls server configuration */
     737    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     738            ap_get_module_config(c->base_server->module_config, &gnutls_module);
    689739
    690740    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    691     ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
     741
     742    /* Get connection specific configuration */
     743    mgs_handle_t *ctxt = (mgs_handle_t *) ap_get_module_config(c->conn_config, &gnutls_module);
     744    if (ctxt == NULL)
     745    {
     746        ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
     747        ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
     748        ctxt->is_proxy = GNUTLS_ENABLED_FALSE;
     749    }
     750    ctxt->enabled = GNUTLS_ENABLED_TRUE;
    692751    ctxt->c = c;
    693752    ctxt->sc = sc;
     
    700759    ctxt->output_blen = 0;
    701760    ctxt->output_length = 0;
     761
    702762    /* Initialize GnuTLS Library */
    703     gnutls_init(&ctxt->session, GNUTLS_SERVER);
    704     /* Initialize Session Tickets */
    705     if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0) {
    706         gnutls_session_ticket_enable_server(ctxt->session,&session_ticket_key);
     763    int err = 0;
     764    if (ctxt->is_proxy == GNUTLS_ENABLED_TRUE)
     765    {
     766        /* this is an outgoing proxy connection, client mode */
     767        err = gnutls_init(&ctxt->session, GNUTLS_CLIENT);
     768        if (err != GNUTLS_E_SUCCESS)
     769            ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
     770                          "gnutls_init for proxy connection failed: %s (%d)",
     771                          gnutls_strerror(err), err);
     772        err = gnutls_session_ticket_enable_client(ctxt->session);
     773        if (err != GNUTLS_E_SUCCESS)
     774            ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
     775                          "gnutls_session_ticket_enable_client failed: %s (%d)",
     776                          gnutls_strerror(err), err);
     777        /* Try to close and deinit the session when the connection
     778         * pool is cleared. Note that mod_proxy might not close
     779         * connections immediately, if you need that, look at the
     780         * "proxy-nokeepalive" environment variable for
     781         * mod_proxy_http. */
     782        apr_pool_pre_cleanup_register(c->pool, ctxt, cleanup_gnutls_session);
     783    }
     784    else
     785    {
     786        /* incoming connection, server mode */
     787        err = gnutls_init(&ctxt->session, GNUTLS_SERVER);
     788        if (err != GNUTLS_E_SUCCESS)
     789            ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
     790                          "gnutls_init for server side failed: %s (%d)",
     791                          gnutls_strerror(err), err);
     792        /* Initialize Session Tickets */
     793        if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0)
     794        {
     795            err = gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key);
     796            if (err != GNUTLS_E_SUCCESS)
     797                ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
     798                              "gnutls_session_ticket_enable_server failed: %s (%d)",
     799                              gnutls_strerror(err), err);
     800        }
    707801    }
    708802
    709803    /* Set Default Priority */
    710         gnutls_priority_set_direct (ctxt->session, "NORMAL", NULL);
     804        err = gnutls_priority_set_direct(ctxt->session, "NORMAL", NULL);
     805    if (err != GNUTLS_E_SUCCESS)
     806        ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c, "gnutls_priority_set_direct failed!");
    711807    /* Set Handshake function */
    712808    gnutls_handshake_set_post_client_hello_function(ctxt->session,
    713809            mgs_select_virtual_server_cb);
     810
     811    /* Set GnuTLS user pointer, so we can access the module session
     812     * context in GnuTLS callbacks */
     813    gnutls_session_set_ptr(ctxt->session, ctxt);
     814
     815    /* If mod_gnutls is the TLS server, mgs_select_virtual_server_cb
     816     * will load appropriate credentials during handshake. However,
     817     * when handling a proxy backend connection, mod_gnutls acts as
     818     * TLS client and credentials must be loaded here. */
     819    if (ctxt->is_proxy == GNUTLS_ENABLED_TRUE)
     820    {
     821        /* Set anonymous client credentials for proxy connections */
     822        gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON,
     823                               ctxt->sc->anon_client_creds);
     824        /* Set x509 credentials */
     825        gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE,
     826                               ctxt->sc->proxy_x509_creds);
     827        /* Load priorities from the server configuration */
     828        err = gnutls_priority_set(ctxt->session, ctxt->sc->priorities);
     829        if (err != GNUTLS_E_SUCCESS)
     830            ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
     831                          "%s: setting priorities for proxy connection failed: %s (%d)",
     832                          __func__, gnutls_strerror(err), err);
     833    }
     834
    714835    /* Initialize Session Cache */
    715836    mgs_cache_session_init(ctxt);
    716837
    717     /* Set this config for this connection */
    718     ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
    719838    /* Set pull, push & ptr functions */
    720839    gnutls_transport_set_pull_function(ctxt->session,
     
    730849}
    731850
    732 int mgs_hook_pre_connection(conn_rec * c, void *csd __attribute__((unused))) {
    733     mgs_srvconf_rec *sc;
    734 
     851int mgs_hook_pre_connection(conn_rec * c, void *csd __attribute__((unused)))
     852{
    735853    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    736854
    737     sc = (mgs_srvconf_rec *) ap_get_module_config(c->base_server->module_config,
    738             &gnutls_module);
    739 
    740     if (sc && (!sc->enabled || sc->proxy_enabled == GNUTLS_ENABLED_TRUE)) {
     855    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     856        ap_get_module_config(c->base_server->module_config, &gnutls_module);
     857    mgs_handle_t *ctxt = (mgs_handle_t *)
     858        ap_get_module_config(c->conn_config, &gnutls_module);
     859
     860    if ((sc && (!sc->enabled)) || (ctxt && ctxt->enabled == GNUTLS_ENABLED_FALSE))
     861    {
     862        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "%s declined connection",
     863                      __func__);
    741864        return DECLINED;
    742865    }
     
    760883    apr_table_t *env = r->subprocess_env;
    761884
    762     ctxt =
    763             ap_get_module_config(r->connection->conn_config,
    764             &gnutls_module);
    765 
    766     if (!ctxt || ctxt->session == NULL) {
     885    ctxt = ap_get_module_config(r->connection->conn_config,
     886                                &gnutls_module);
     887
     888    if (!ctxt || ctxt->enabled != GNUTLS_ENABLED_TRUE || ctxt->session == NULL)
     889    {
     890        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "request declined in %s", __func__);
    767891        return DECLINED;
    768892    }
     
    8791003        }
    8801004        rv = mgs_cert_verify(r, ctxt);
    881         if (rv != DECLINED &&
    882                 (rv != HTTP_FORBIDDEN ||
    883                 dc->client_verify_mode == GNUTLS_CERT_REQUIRE)) {
     1005        if (rv != DECLINED
     1006            && (rv != HTTP_FORBIDDEN
     1007                || dc->client_verify_mode == GNUTLS_CERT_REQUIRE
     1008                || (dc->client_verify_mode == -1
     1009                    && ctxt->sc->client_verify_mode == GNUTLS_CERT_REQUIRE)))
     1010        {
    8841011            return rv;
    8851012        }
     
    15531680}
    15541681
     1682
     1683
     1684/*
     1685 * Callback to check the server certificate for proxy HTTPS
     1686 * connections, to be used with
     1687 * gnutls_certificate_set_verify_function.
     1688
     1689 * Returns: 0 if certificate check was successful (certificate
     1690 * trusted), non-zero otherwise (error during check or untrusted
     1691 * certificate).
     1692 */
     1693static int gtls_check_server_cert(gnutls_session_t session)
     1694{
     1695    mgs_handle_t *ctxt = (mgs_handle_t *) gnutls_session_get_ptr(session);
     1696    unsigned int status;
     1697
     1698    int err = gnutls_certificate_verify_peers3(session, NULL, &status);
     1699    if (err != GNUTLS_E_SUCCESS)
     1700    {
     1701        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, ctxt->c,
     1702                      "%s: server certificate check failed: %s (%d)",
     1703                      __func__, gnutls_strerror(err), err);
     1704        return err;
     1705    }
     1706
     1707    gnutls_datum_t * out = gnutls_malloc(sizeof(gnutls_datum_t));
     1708    /* GNUTLS_CRT_X509: ATM, only X509 is supported for proxy certs
     1709     * 0: according to function API, the last argument should be 0 */
     1710    err = gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509,
     1711                                                       out, 0);
     1712    if (err != GNUTLS_E_SUCCESS)
     1713        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
     1714                      "%s: server verify print failed: %s (%d)",
     1715                      __func__, gnutls_strerror(err), err);
     1716    else
     1717    {
     1718        /* If the certificate is trusted, logging the result is just
     1719         * nice for debugging. But if the back end server provided an
     1720         * untrusted certificate, warn! */
     1721        int level = (status == 0 ? APLOG_DEBUG : APLOG_WARNING);
     1722        ap_log_cerror(APLOG_MARK, level, 0, ctxt->c,
     1723                      "%s: server certificate verify result: %s",
     1724                      __func__, out->data);
     1725    }
     1726
     1727    gnutls_free(out);
     1728    return status;
     1729}
     1730
     1731
     1732
     1733static int load_proxy_x509_credentials(server_rec *s)
     1734{
     1735    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     1736        ap_get_module_config(s->module_config, &gnutls_module);
     1737
     1738    if (sc == NULL)
     1739        return APR_EGENERAL;
     1740
     1741    int ret = APR_SUCCESS;
     1742    int err = GNUTLS_E_SUCCESS;
     1743    if (sc->proxy_x509_key_file && sc->proxy_x509_cert_file)
     1744    {
     1745        err = gnutls_certificate_set_x509_key_file(sc->proxy_x509_creds,
     1746                                                   sc->proxy_x509_cert_file,
     1747                                                   sc->proxy_x509_key_file,
     1748                                                   GNUTLS_X509_FMT_PEM);
     1749        if (err != GNUTLS_E_SUCCESS)
     1750        {
     1751            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
     1752                         "%s: loading proxy client credentials failed: %s (%d)",
     1753                         __func__, gnutls_strerror(err), err);
     1754            ret = APR_EGENERAL;
     1755        }
     1756    }
     1757    else if (!sc->proxy_x509_key_file && sc->proxy_x509_cert_file)
     1758    {
     1759        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
     1760                     "%s: proxy key file not set!", __func__);
     1761        ret = APR_EGENERAL;
     1762    }
     1763    else if (!sc->proxy_x509_cert_file && sc->proxy_x509_key_file)
     1764    {
     1765        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
     1766                     "%s: proxy certificate file not set!", __func__);
     1767        ret = APR_EGENERAL;
     1768    }
     1769    else
     1770        /* if both key and cert are NULL, client auth is not used */
     1771        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
     1772                     "%s: no client credentials for proxy", __func__);
     1773
     1774    /* must be set if the server certificate is to be checked */
     1775    if (sc->proxy_x509_ca_file)
     1776    {
     1777        /* returns number of loaded certificates */
     1778        err = gnutls_certificate_set_x509_trust_file(sc->proxy_x509_creds,
     1779                                                     sc->proxy_x509_ca_file,
     1780                                                     GNUTLS_X509_FMT_PEM);
     1781        if (err <= 0)
     1782            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
     1783                         "%s: proxy CA trust list is empty",
     1784                         __func__);
     1785        else
     1786            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
     1787                         "%s: proxy CA trust list: %d certificates loaded",
     1788                         __func__, err);
     1789    }
     1790    else
     1791        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
     1792                     "%s: no CA trust list for proxy connections missing, "
     1793                     "TLS connections will fail!", __func__);
     1794
     1795    gnutls_certificate_set_verify_function(sc->proxy_x509_creds,
     1796                                           gtls_check_server_cert);
     1797    return ret;
     1798}
  • src/gnutls_io.c

    reebc960 r91ccb87  
    3838                               alloc)
    3939
     40#define IS_PROXY_STR(c) \
     41    ((c->is_proxy == GNUTLS_ENABLED_TRUE) ? "proxy " : "")
     42
    4043static apr_status_t gnutls_io_filter_error(ap_filter_t * f,
    4144        apr_bucket_brigade * bb,
     
    4548
    4649    switch (status) {
    47         case HTTP_BAD_REQUEST:
    48             /* log the situation */
    49             ap_log_error(APLOG_MARK, APLOG_INFO, 0,
    50                     f->c->base_server,
    51                     "GnuTLS handshake failed: HTTP spoken on HTTPS port; "
    52                     "trying to send HTML error page");
    53 
    54                                     mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(
    55                                                                                                                                                                                                                                 f->c->base_server->module_config,
    56                                                                                                                                                                                                                                 &gnutls_module
    57                                                                                                                                                                                                                         );
    58             ctxt->status = -1;
    59             sc->non_ssl_request = 1;
    60 
    61             /* fake the request line */
    62             bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc);
    63             break;
    64 
    65         default:
    66             return status;
     50    case HTTP_BAD_REQUEST:
     51        /* log the situation */
     52        ap_log_error(APLOG_MARK, APLOG_INFO, 0,
     53                     f->c->base_server,
     54                     "GnuTLS handshake failed: HTTP spoken on HTTPS port; "
     55                     "trying to send HTML error page");
     56        mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     57            ap_get_module_config(f->c->base_server->module_config,
     58                                 &gnutls_module);
     59        ctxt->status = -1;
     60        sc->non_ssl_request = 1;
     61
     62        /* fake the request line */
     63        bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc);
     64        break;
     65
     66    default:
     67        return status;
    6768    }
    6869
     
    186187
    187188static apr_status_t gnutls_io_input_read(mgs_handle_t * ctxt,
    188         char *buf, apr_size_t * len) {
     189        char *buf, apr_size_t * len)
     190{
    189191    apr_size_t wanted = *len;
    190192    apr_size_t bytes = 0;
     
    225227
    226228    if (ctxt->session == NULL) {
     229        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, ctxt->c,
     230                      "%s: GnuTLS session is NULL!", __func__);
    227231        return APR_EGENERAL;
    228232    }
     
    230234    while (1) {
    231235
    232         rc = gnutls_record_recv(ctxt->session, buf + bytes,
    233                 wanted - bytes);
     236        do
     237            rc = gnutls_record_recv(ctxt->session, buf + bytes,
     238                                    wanted - bytes);
     239        while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
    234240
    235241        if (rc > 0) {
     
    270276            if (rc == GNUTLS_E_REHANDSHAKE) {
    271277                /* A client has asked for a new Hankshake. Currently, we don't do it */
    272                 ap_log_error(APLOG_MARK, APLOG_INFO,
     278                ap_log_cerror(APLOG_MARK, APLOG_INFO,
    273279                        ctxt->input_rc,
    274                         ctxt->c->base_server,
     280                        ctxt->c,
    275281                        "GnuTLS: Error reading data. Client Requested a New Handshake."
    276282                        " (%d) '%s'", rc,
     
    278284            } else if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
    279285                rc = gnutls_alert_get(ctxt->session);
    280                 ap_log_error(APLOG_MARK, APLOG_INFO,
     286                ap_log_cerror(APLOG_MARK, APLOG_INFO,
    281287                        ctxt->input_rc,
    282                         ctxt->c->base_server,
     288                        ctxt->c,
    283289                        "GnuTLS: Warning Alert From Client: "
    284290                        " (%d) '%s'", rc,
     
    286292            } else if (rc == GNUTLS_E_FATAL_ALERT_RECEIVED) {
    287293                rc = gnutls_alert_get(ctxt->session);
    288                 ap_log_error(APLOG_MARK, APLOG_INFO,
     294                ap_log_cerror(APLOG_MARK, APLOG_INFO,
    289295                        ctxt->input_rc,
    290                         ctxt->c->base_server,
     296                        ctxt->c,
    291297                        "GnuTLS: Fatal Alert From Client: "
    292298                        "(%d) '%s'", rc,
     
    297303                /* Some Other Error. Report it. Die. */
    298304                if (gnutls_error_is_fatal(rc)) {
    299                     ap_log_error(APLOG_MARK,
     305                    ap_log_cerror(APLOG_MARK,
    300306                            APLOG_INFO,
    301307                            ctxt->input_rc,
    302                             ctxt->c->base_server,
     308                            ctxt->c,
    303309                            "GnuTLS: Error reading data. (%d) '%s'",
    304310                            rc,
     
    311317
    312318            if (ctxt->input_rc == APR_SUCCESS) {
     319                ap_log_cerror(APLOG_MARK, APLOG_INFO, ctxt->input_rc, ctxt->c,
     320                              "%s: GnuTLS error: %s (%d)",
     321                              __func__, gnutls_strerror(rc), rc);
    313322                ctxt->input_rc = APR_EGENERAL;
    314323            }
     
    405414            ap_log_error(APLOG_MARK, APLOG_INFO, 0,
    406415                    ctxt->c->base_server,
    407                     "GnuTLS: Hanshake Alert (%d) '%s'.",
     416                    "GnuTLS: Handshake Alert (%d) '%s'.",
    408417                    errcode,
    409418                    gnutls_alert_get_name(errcode));
     
    479488        apr_bucket_brigade * bb,
    480489        ap_input_mode_t mode,
    481         apr_read_type_e block, apr_off_t readbytes) {
     490        apr_read_type_e block, apr_off_t readbytes)
     491{
    482492    apr_status_t status = APR_SUCCESS;
    483493    mgs_handle_t *ctxt = (mgs_handle_t *) f->ctx;
     
    488498                apr_bucket_eos_create(f->c->bucket_alloc);
    489499        APR_BRIGADE_INSERT_TAIL(bb, bucket);
     500        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
     501                      "%s: %sconnection aborted",
     502                      __func__, IS_PROXY_STR(ctxt));
    490503        return APR_ECONNABORTED;
    491504    }
     
    493506    if (ctxt->status == 0) {
    494507        gnutls_do_handshake(ctxt);
     508        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
     509                      "%s: TLS %sconnection opened.",
     510                      __func__, IS_PROXY_STR(ctxt));
    495511    }
    496512
    497513    if (ctxt->status < 0) {
     514        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
     515                      "%s %s: ap_get_brigade", __func__, IS_PROXY_STR(ctxt));
    498516        return ap_get_brigade(f->next, bb, mode, block, readbytes);
    499517    }
     
    589607    if (ctxt->status == 0) {
    590608        gnutls_do_handshake(ctxt);
     609        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
     610                      "%s: TLS %sconnection opened.",
     611                      __func__, IS_PROXY_STR(ctxt));
    591612    }
    592613
     
    615636                    ret = gnutls_bye(ctxt->session, GNUTLS_SHUT_WR);
    616637                } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
     638                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, ret, ctxt->c,
     639                              "%s: TLS %sconnection closed.",
     640                              __func__, IS_PROXY_STR(ctxt));
    617641                /* De-Initialize Session */
    618642                gnutls_deinit(ctxt->session);
  • src/mod_gnutls.c

    reebc960 r91ccb87  
    2020#include "mod_gnutls.h"
    2121
    22 static void gnutls_hooks(apr_pool_t * p __attribute__((unused))) {
    23 
     22#ifdef APLOG_USE_MODULE
     23APLOG_USE_MODULE(gnutls);
     24#endif
     25
     26static void gnutls_hooks(apr_pool_t * p __attribute__((unused)))
     27{
    2428    /* Try Run Post-Config Hook After mod_proxy */
    2529    static const char * const aszPre[] = { "mod_proxy.c", NULL };
    26     ap_hook_post_config(mgs_hook_post_config, aszPre, NULL,APR_HOOK_REALLY_LAST);
     30    ap_hook_post_config(mgs_hook_post_config, aszPre, NULL,
     31                        APR_HOOK_REALLY_LAST);
    2732    /* HTTP Scheme Hook */
    2833#if USING_2_1_RECENT
     
    3237#endif
    3338    /* Default Port Hook */
    34     ap_hook_default_port(mgs_hook_default_port,  NULL,NULL, APR_HOOK_MIDDLE);
     39    ap_hook_default_port(mgs_hook_default_port, NULL, NULL, APR_HOOK_MIDDLE);
    3540    /* Pre-Connect Hook */
    36     ap_hook_pre_connection(mgs_hook_pre_connection, NULL, NULL, APR_HOOK_MIDDLE);
     41    ap_hook_pre_connection(mgs_hook_pre_connection, NULL, NULL,
     42                           APR_HOOK_MIDDLE);
    3743    /* Pre-Config Hook */
    3844    ap_hook_pre_config(mgs_hook_pre_config, NULL, NULL,
    39             APR_HOOK_MIDDLE);
     45                       APR_HOOK_MIDDLE);
    4046    /* Child-Init Hook */
    4147    ap_hook_child_init(mgs_hook_child_init, NULL, NULL,
    42             APR_HOOK_MIDDLE);
     48                       APR_HOOK_MIDDLE);
    4349    /* Authentication Hook */
    4450    ap_hook_access_checker(mgs_hook_authz, NULL, NULL,
    45             APR_HOOK_REALLY_FIRST);
     51                           APR_HOOK_REALLY_FIRST);
    4652    /* Fixups Hook */
    4753    ap_hook_fixups(mgs_hook_fixups, NULL, NULL, APR_HOOK_REALLY_FIRST);
     
    5359
    5460    /* Input Filter */
    55     ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME,
    56             mgs_filter_input, NULL,AP_FTYPE_CONNECTION + 5);
     61    ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME, mgs_filter_input,
     62                             NULL, AP_FTYPE_CONNECTION + 5);
    5763    /* Output Filter */
    58     ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME,
    59             mgs_filter_output, NULL,AP_FTYPE_CONNECTION + 5);
     64    ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME, mgs_filter_output,
     65                              NULL, AP_FTYPE_CONNECTION + 5);
    6066
    6167    /* mod_proxy calls these functions */
     
    6470}
    6571
    66 int ssl_is_https(conn_rec *c) {
     72int ssl_is_https(conn_rec *c)
     73{
    6774    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    68             ap_get_module_config(c->base_server->module_config, &gnutls_module);
     75        ap_get_module_config(c->base_server->module_config, &gnutls_module);
    6976    if(sc->enabled == 0 || sc->non_ssl_request == 1) {
    7077        /* SSL/TLS Disabled or Plain HTTP Connection Detected */
     
    7582}
    7683
    77 int ssl_engine_disable(conn_rec *c) {
     84int ssl_engine_disable(conn_rec *c)
     85{
    7886    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    79             ap_get_module_config(c->base_server->module_config, &gnutls_module);
     87        ap_get_module_config(c->base_server->module_config, &gnutls_module);
    8088    if(sc->enabled == GNUTLS_ENABLED_FALSE) {
    8189        return 1;
    8290    }
    83     ap_remove_input_filter(c->input_filters);
    84     ap_remove_input_filter(c->output_filters);
    85     mgs_cleanup_pre_config(c->pool);
    86     sc->enabled = 0;
     91
     92    /* disable TLS for this connection */
     93    mgs_handle_t *ctxt = (mgs_handle_t *)
     94        ap_get_module_config(c->conn_config, &gnutls_module);
     95    if (ctxt == NULL)
     96    {
     97        ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
     98        ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
     99    }
     100    ctxt->enabled = GNUTLS_ENABLED_FALSE;
     101    ctxt->is_proxy = GNUTLS_ENABLED_TRUE;
     102
     103    if (c->input_filters)
     104        ap_remove_input_filter(c->input_filters);
     105    if (c->output_filters)
     106        ap_remove_output_filter(c->output_filters);
     107
    87108    return 1;
    88109}
    89110
    90 int ssl_proxy_enable(conn_rec *c) {
     111int ssl_proxy_enable(conn_rec *c)
     112{
     113    /* check if TLS proxy support is enabled */
    91114    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    92             ap_get_module_config(c->base_server->module_config, &gnutls_module);
    93     sc->proxy_enabled = 1;
    94     sc->enabled = 0;
     115        ap_get_module_config(c->base_server->module_config, &gnutls_module);
     116    if (sc->proxy_enabled != GNUTLS_ENABLED_TRUE)
     117    {
     118        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
     119                      "%s: mod_proxy requested TLS proxy, but not enabled "
     120                      "for %s", __func__, sc->cert_cn);
     121        return 0;
     122    }
     123
     124    /* enable TLS for this connection */
     125    mgs_handle_t *ctxt = (mgs_handle_t *)
     126        ap_get_module_config(c->conn_config, &gnutls_module);
     127    if (ctxt == NULL)
     128    {
     129        ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
     130        ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
     131    }
     132    ctxt->enabled = GNUTLS_ENABLED_TRUE;
     133    ctxt->is_proxy = GNUTLS_ENABLED_TRUE;
    95134    return 1;
    96135}
     
    185224    RSRC_CONF,
    186225    "Max size to export PEM encoded certificates to CGIs (or off to disable). Default: off"),
     226    AP_INIT_TAKE1("GnuTLSProxyKeyFile", mgs_store_cred_path,
     227    NULL,
     228    RSRC_CONF,
     229    "X509 client private file for proxy connections"),
     230    AP_INIT_TAKE1("GnuTLSProxyCertificateFile", mgs_store_cred_path,
     231    NULL,
     232    RSRC_CONF,
     233    "X509 client certificate file for proxy connections"),
     234    AP_INIT_TAKE1("GnuTLSProxyCAFile", mgs_store_cred_path,
     235    NULL,
     236    RSRC_CONF,
     237    "X509 trusted CA file for proxy connections"),
    187238    { NULL },
    188239};
Note: See TracChangeset for help on using the changeset viewer.