diff options
-rw-r--r-- | src/mod_auth_gssapi.c | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c index 9e3eca3..ed25cc6 100644 --- a/src/mod_auth_gssapi.c +++ b/src/mod_auth_gssapi.c @@ -38,11 +38,19 @@ module AP_MODULE_DECLARE_DATA auth_gssapi_module; APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); +APR_DECLARE_OPTIONAL_FN(int, ssl_get_tls_cb, + (apr_pool_t *, conn_rec *, const char *, + void **, apr_size_t *)); struct mag_config { bool ssl_only; bool map_to_local; bool gss_conn_ctx; + enum { + CB_NONE, + CB_TLS_UNIQUE, + CB_TLS_SERVER_END_POINT, + } gss_use_cb; gss_key_value_set_desc cred_store; }; @@ -106,6 +114,7 @@ static int mag_pre_connection(conn_rec *c, void *csd) } static APR_OPTIONAL_FN_TYPE(ssl_is_https) *mag_is_https = NULL; +static APR_OPTIONAL_FN_TYPE(ssl_get_tls_cb) *mag_get_tls_cb = NULL; static bool mag_conn_is_https(conn_rec *c) { @@ -116,6 +125,16 @@ static bool mag_conn_is_https(conn_rec *c) return false; } +static int mag_conn_tls_cb(apr_pool_t *p, conn_rec *c, const char *type, + void **buf, apr_size_t *size) +{ + if (mag_get_tls_cb) { + return mag_get_tls_cb(p, c, type, buf, size); + } + + return DECLINED; +} + static int mag_auth(request_rec *req) { const char *type; @@ -138,6 +157,8 @@ static int mag_auth(request_rec *req) gss_OID mech_type = GSS_C_NO_OID; gss_buffer_desc lname = GSS_C_EMPTY_BUFFER; struct mag_conn *mc = NULL; + gss_channel_bindings_t cbt = GSS_C_NO_CHANNEL_BINDINGS; + struct gss_channel_bindings_struct cb = { 0 }; type = ap_auth_type(req); if ((type == NULL) || (strcasecmp(type, "GSSAPI") != 0)) { @@ -189,8 +210,39 @@ static int mag_auth(request_rec *req) if (!input.value) goto done; input.length = apr_base64_decode(input.value, auth_header_value); + if (cfg->gss_use_cb != CB_NONE) { + const char *cb_type = NULL; + apr_size_t size; + void *buf; + int res = DECLINED; + switch (cfg->gss_use_cb) { + case CB_TLS_SERVER_END_POINT: + cb_type = "SERVER_TLS_SERVER_END_POINT"; + break; + case CB_TLS_UNIQUE: + cb_type = "SERVER_TLS_UNIQUE"; + break; + default: + /* ?? */ + break; + } + if (cb_type) { + res = mag_conn_tls_cb(req->pool, req->connection, + cb_type, &buf, &size); + } + if (res == OK) { + cb.application_data.length = size; + cb.application_data.value = buf; + cbt = &cb; + } else { + ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req, + "Channel Bindings requested but not available."); + goto done; + } + } + maj = gss_accept_sec_context(&min, &ctx, GSS_C_NO_CREDENTIAL, - &input, GSS_C_NO_CHANNEL_BINDINGS, + &input, cbt, &client, &mech_type, &output, &flags, NULL, &delegated_cred); if (GSS_ERROR(maj)) { @@ -308,6 +360,19 @@ static const char *mag_conn_ctx(cmd_parms *parms, void *mconfig, int on) return NULL; } +static const char *mag_use_cb(cmd_parms *parms, void *mconfig, const char *w) +{ + struct mag_config *cfg = (struct mag_config *)mconfig; + if (strcasecmp(w, "tls-server-end-point") == 0) { + cfg->gss_use_cb = CB_TLS_SERVER_END_POINT; + } else if (strcasecmp(w, "tls-unique") == 0) { + cfg->gss_use_cb = CB_TLS_UNIQUE; + } else { + cfg->gss_use_cb = CB_NONE; + } + return NULL; +} + static const char *mag_cred_store(cmd_parms *parms, void *mconfig, const char *w) { @@ -363,6 +428,8 @@ static const command_rec mag_commands[] = { "Authentication is valid for the life of the connection"), AP_INIT_ITERATE("GSSCredStore", mag_cred_store, NULL, OR_AUTHCFG, "Credential Store"), + AP_INIT_ITERATE("GSSuseCB", mag_use_cb, NULL, OR_AUTHCFG, + "Use Channel Bindings (none|tls-unique)"), { NULL } }; |