Changes in / [eea8a16:b324906] in mod_gnutls


Ignore:
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • include/mod_gnutls.h.in

    reea8a16 rb324906  
    108108        /* SRP Certificate Structure*/
    109109    gnutls_srp_server_credentials_t srp_creds;
    110         /* Annonymous Certificate Structure */
     110    /* Anonymous Certificate Structure */
    111111    gnutls_anon_server_credentials_t anon_creds;
     112    /* Anonymous Client Certificate Structure, used for proxy
     113     * connections */
     114    gnutls_anon_client_credentials_t anon_client_creds;
    112115        /* Current x509 Certificate CN [Common Name] */
    113116    char* cert_cn;
     
    173176        /* Is TLS enabled for this connection? */
    174177    int enabled;
     178    /* Is this a proxy connection? */
     179    int is_proxy;
    175180        /* GnuTLS Session handle */
    176181    gnutls_session_t session;
  • src/gnutls_config.c

    reea8a16 rb324906  
    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    }
    622633#ifdef ENABLE_SRP
    623634    ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
     
    696707    gnutls_srvconf_assign(certs);
    697708    gnutls_srvconf_assign(anon_creds);
     709    gnutls_srvconf_assign(anon_client_creds);
    698710    gnutls_srvconf_assign(srp_creds);
    699711    gnutls_srvconf_assign(certs_x509_chain);
  • src/gnutls_hooks.c

    reea8a16 rb324906  
    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
     
    147150    gnutls_certificate_server_set_request(session, ctxt->sc->client_verify_mode);
    148151
     152    /* Set x509 credentials */
     153    gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);
    149154    /* Set Anon credentials */
    150     gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);
    151         /* Set x509 credentials */
    152155    gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds);
    153156
     
    620623#endif
    621624
    622 mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session) {
     625mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session)
     626{
    623627    int rv;
    624628    unsigned int sni_type;
     
    671675
    672676        tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    673                 &gnutls_module);
     677                                                       &gnutls_module);
    674678
    675679        if (tsc->enabled != GNUTLS_ENABLED_TRUE) { continue; }
    676680
    677                                 if(check_server_aliases(x, s, tsc)) {
    678                                         return tsc;
    679                                 }
     681        if(check_server_aliases(x, s, tsc)) {
     682            return tsc;
     683        }
     684    }
    680685#endif
    681686    return NULL;
     687}
     688
     689/*
     690 * This function is intended as a cleanup handler for connections
     691 * using GnuTLS.
     692 *
     693 * @param data must point to the mgs_handle_t associated with the
     694 * connection
     695 */
     696static apr_status_t cleanup_gnutls_session(void *data)
     697{
     698    /* nothing to do */
     699    if (data == NULL)
     700        return APR_SUCCESS;
     701
     702    /* check if session needs closing */
     703    mgs_handle_t *ctxt = (mgs_handle_t *) data;
     704    if (ctxt->session != NULL)
     705    {
     706        int ret;
     707        /* Try A Clean Shutdown */
     708        do
     709            ret = gnutls_bye(ctxt->session, GNUTLS_SHUT_WR);
     710        while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
     711        if (ret != GNUTLS_E_SUCCESS)
     712            ap_log_cerror(APLOG_MARK, APLOG_INFO, ret, ctxt->c,
     713                          "%s: error while closing TLS %sconnection: %s (%d)",
     714                          __func__, IS_PROXY_STR(ctxt),
     715                          gnutls_strerror(ret), ret);
     716        else
     717            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, ret, ctxt->c,
     718                          "%s: TLS %sconnection closed.",
     719                          __func__, IS_PROXY_STR(ctxt));
     720        /* De-Initialize Session */
     721        gnutls_deinit(ctxt->session);
     722        ctxt->session = NULL;
     723    }
     724    return APR_SUCCESS;
    682725}
    683726
     
    694737    if (ctxt == NULL)
    695738    {
    696         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "%s: allocating connection memory", __func__);
    697739        ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
    698740        ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
     741        ctxt->is_proxy = GNUTLS_ENABLED_FALSE;
    699742    }
    700743    ctxt->enabled = GNUTLS_ENABLED_TRUE;
     
    711754
    712755    /* Initialize GnuTLS Library */
    713     int err = gnutls_init(&ctxt->session, GNUTLS_SERVER);
    714     if (err != GNUTLS_E_SUCCESS)
    715         ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c, "gnutls_init failed!");
    716     /* Initialize Session Tickets */
    717     if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0) {
    718         err = gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key);
     756    int err = 0;
     757    if (ctxt->is_proxy == GNUTLS_ENABLED_TRUE)
     758    {
     759        /* this is an outgoing proxy connection, client mode */
     760        err = gnutls_init(&ctxt->session, GNUTLS_CLIENT);
    719761        if (err != GNUTLS_E_SUCCESS)
    720             ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c, "gnutls_session_ticket_enable_server failed!");
     762            ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
     763                          "gnutls_init for proxy connection failed: %s (%d)",
     764                          gnutls_strerror(err), err);
     765        err = gnutls_session_ticket_enable_client(ctxt->session);
     766        if (err != GNUTLS_E_SUCCESS)
     767            ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
     768                          "gnutls_session_ticket_enable_client failed: %s (%d)",
     769                          gnutls_strerror(err), err);
     770        /* Try to close and deinit the session when the connection
     771         * pool is cleared. Note that mod_proxy might not close
     772         * connections immediately, if you need that, look at the
     773         * "proxy-nokeepalive" environment variable for
     774         * mod_proxy_http. */
     775        apr_pool_pre_cleanup_register(c->pool, ctxt, cleanup_gnutls_session);
     776    }
     777    else
     778    {
     779        /* incoming connection, server mode */
     780        err = gnutls_init(&ctxt->session, GNUTLS_SERVER);
     781        if (err != GNUTLS_E_SUCCESS)
     782            ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
     783                          "gnutls_init for server side failed: %s (%d)",
     784                          gnutls_strerror(err), err);
     785        /* Initialize Session Tickets */
     786        if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0)
     787        {
     788            err = gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key);
     789            if (err != GNUTLS_E_SUCCESS)
     790                ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
     791                              "gnutls_session_ticket_enable_server failed: %s (%d)",
     792                              gnutls_strerror(err), err);
     793        }
    721794    }
    722795
     
    728801    gnutls_handshake_set_post_client_hello_function(ctxt->session,
    729802            mgs_select_virtual_server_cb);
     803
     804    /* If mod_gnutls is the TLS server, mgs_select_virtual_server_cb
     805     * will load appropriate credentials during handshake. However,
     806     * when handling a proxy backend connection, mod_gnutls acts as
     807     * TLS client and credentials must be loaded here. */
     808    if (ctxt->is_proxy == GNUTLS_ENABLED_TRUE)
     809    {
     810        /* Set anonymous client credentials for proxy connections */
     811        gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON,
     812                               ctxt->sc->anon_client_creds);
     813        /* Set x509 credentials */
     814        gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE,
     815                               ctxt->sc->certs);
     816        /* Load priorities from the server configuration */
     817        err = gnutls_priority_set(ctxt->session, ctxt->sc->priorities);
     818        if (err != GNUTLS_E_SUCCESS)
     819            ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
     820                          "%s: setting priorities for proxy connection failed: %s (%d)",
     821                          __func__, gnutls_strerror(err), err);
     822    }
     823
    730824    /* Initialize Session Cache */
    731825    mgs_cache_session_init(ctxt);
     
    753847        ap_get_module_config(c->conn_config, &gnutls_module);
    754848
    755     if ((sc && (!sc->enabled || sc->proxy_enabled == GNUTLS_ENABLED_TRUE))
    756         || (ctxt && ctxt->enabled == GNUTLS_ENABLED_FALSE))
     849    if ((sc && (!sc->enabled)) || (ctxt && ctxt->enabled == GNUTLS_ENABLED_FALSE))
    757850    {
    758851        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "%s declined connection",
  • src/gnutls_io.c

    reea8a16 rb324906  
    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

    reea8a16 rb324906  
    2828    /* Try Run Post-Config Hook After mod_proxy */
    2929    static const char * const aszPre[] = { "mod_proxy.c", NULL };
    30     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);
    3132    /* HTTP Scheme Hook */
    3233#if USING_2_1_RECENT
     
    3637#endif
    3738    /* Default Port Hook */
    38     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);
    3940    /* Pre-Connect Hook */
    40     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);
    4143    /* Pre-Config Hook */
    4244    ap_hook_pre_config(mgs_hook_pre_config, NULL, NULL,
    43             APR_HOOK_MIDDLE);
     45                       APR_HOOK_MIDDLE);
    4446    /* Child-Init Hook */
    4547    ap_hook_child_init(mgs_hook_child_init, NULL, NULL,
    46             APR_HOOK_MIDDLE);
     48                       APR_HOOK_MIDDLE);
    4749    /* Authentication Hook */
    4850    ap_hook_access_checker(mgs_hook_authz, NULL, NULL,
    49             APR_HOOK_REALLY_FIRST);
     51                           APR_HOOK_REALLY_FIRST);
    5052    /* Fixups Hook */
    5153    ap_hook_fixups(mgs_hook_fixups, NULL, NULL, APR_HOOK_REALLY_FIRST);
     
    5759
    5860    /* Input Filter */
    59     ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME,
    60             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);
    6163    /* Output Filter */
    62     ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME,
    63             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);
    6466
    6567    /* mod_proxy calls these functions */
     
    6870}
    6971
    70 int ssl_is_https(conn_rec *c) {
     72int ssl_is_https(conn_rec *c)
     73{
    7174    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    72             ap_get_module_config(c->base_server->module_config, &gnutls_module);
     75        ap_get_module_config(c->base_server->module_config, &gnutls_module);
    7376    if(sc->enabled == 0 || sc->non_ssl_request == 1) {
    7477        /* SSL/TLS Disabled or Plain HTTP Connection Detected */
     
    8891
    8992    /* disable TLS for this connection */
    90     mgs_handle_t *ctxt = (mgs_handle_t *) ap_get_module_config(c->conn_config, &gnutls_module);
     93    mgs_handle_t *ctxt = (mgs_handle_t *)
     94        ap_get_module_config(c->conn_config, &gnutls_module);
    9195    if (ctxt == NULL)
    9296    {
    93         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "%s: allocating connection memory", __func__);
    9497        ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
    9598        ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
    9699    }
    97100    ctxt->enabled = GNUTLS_ENABLED_FALSE;
     101    ctxt->is_proxy = GNUTLS_ENABLED_TRUE;
    98102
    99103    if (c->input_filters)
     
    105109}
    106110
    107 int ssl_proxy_enable(conn_rec *c) {
     111int ssl_proxy_enable(conn_rec *c)
     112{
     113    /* check if TLS proxy support is enabled */
    108114    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    109             ap_get_module_config(c->base_server->module_config, &gnutls_module);
    110     sc->proxy_enabled = GNUTLS_ENABLED_TRUE;
    111     sc->enabled = GNUTLS_ENABLED_FALSE;
     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;
    112134    return 1;
    113135}
Note: See TracChangeset for help on using the changeset viewer.