summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mod_auth_gssapi.c69
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 }
};