From 5b342d02e38a25d0dbeda11ed9d38177e3aaa87e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 19 Feb 2017 10:31:22 -0500 Subject: [PATCH 1/3] Fix style issues in recently committed code Function declaration and comments should not exceed 80 chars. Do not use C++ style comments Signed-off-by: Simo Sorce --- src/environ.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/environ.c b/src/environ.c index 840ccd2..ba12d78 100644 --- a/src/environ.c +++ b/src/environ.c @@ -97,24 +97,26 @@ static void mag_set_env_name_attr(request_rec *req, struct mag_conn *mc, } } -static char* mag_escape_display_value(request_rec *req, gss_buffer_desc disp_value) +static char *mag_escape_display_value(request_rec *req, + gss_buffer_desc disp_value) { - /* This function returns a copy (in the pool) of the given gss_buffer_t where every - * occurrence of " has been replaced by \". This string is NULL terminated */ + /* This function returns a copy (in the pool) of the given gss_buffer_t + * where every occurrence of " has been replaced by \". This string is + * NULL terminated */ int i = 0, j = 0, n_quotes = 0; char *escaped_value = NULL; char *value = (char*) disp_value.value; - // count number of quotes in the input string + /* count number of quotes in the input string */ for (i = 0, j = 0; i < disp_value.length; i++) if (value[i] == '"') n_quotes++; - // if there are no quotes, just return a copy of the string + /* if there are no quotes, just return a copy of the string */ if (n_quotes == 0) return apr_pstrndup(req->pool, value, disp_value.length); - // gss_buffer_t are not \0 terminated, but our result will be + /* gss_buffer_t are not \0 terminated, but our result will be */ escaped_value = apr_palloc(req->pool, disp_value.length + n_quotes + 1); for (i = 0,j = 0; i < disp_value.length; i++, j++) { if (value[i] == '"') { @@ -123,7 +125,7 @@ static char* mag_escape_display_value(request_rec *req, gss_buffer_desc disp_val } escaped_value[j] = value[i]; } - // make the string NULL terminated + /* make the string NULL terminated */ escaped_value[j] = '\0'; return escaped_value; } From fd316a99daa7109f3a7dd89809c1fd93ea76d353 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 19 Feb 2017 12:37:48 -0500 Subject: [PATCH 2/3] Allow to export errors as environment variables Introduce a new option to export errors in environment variables. This allows applications to display better errors or take actions based on the returned error type. Signed-off-by: Simo Sorce Resolves #128 Resolves #129 --- README | 19 +++++ src/environ.c | 14 ++++ src/environ.h | 3 + src/mod_auth_gssapi.c | 166 ++++++++++++++++++++++++------------------ src/mod_auth_gssapi.h | 1 + 5 files changed, 131 insertions(+), 72 deletions(-) diff --git a/README b/README index af16d16..f681e49 100644 --- a/README +++ b/README @@ -379,3 +379,22 @@ the default owners and/or mode will be retained. #### Example GssapiDelegCcachePerms mode:0660 gid:webuiworkers + + +### GssapiPublishErrors + +This option is used to publish errors as Environment Variables for use by +httpd processes. + +A general error type is provided in the MAG_ERROR variable, and can have the +following values: "GSS ERROR", "INTERNAL ERROR", "AUTH NOT ALLOWED" +Additionally, in the variable named MAG_ERROR_TEXT there may be a free form +error message. + +When the error type is "GSS ERROR" the variables GSS_ERROR_MAJ and +GSS_ERROR_MIN contain the numeric errors returned by GSSAPI, and the +MAG_ERROR_TEXT will contain a GSS Error message, possibly prepended by +an additional message that provides more context. + +- **Enable with:** GssapiPublishErrors On +- **Default:** GssapiPublishErrors Off diff --git a/src/environ.c b/src/environ.c index ba12d78..2bbc7df 100644 --- a/src/environ.c +++ b/src/environ.c @@ -366,3 +366,17 @@ void mag_set_req_data(request_rec *req, ap_set_module_config(req->request_config, &auth_gssapi_module, mc->env); mag_export_req_env(req, mc->env); } + +void mag_publish_error(request_rec *req, uint32_t maj, uint32_t min, + const char *gss_err, const char *mag_err) +{ + if (gss_err) { + apr_table_set(req->subprocess_env, "GSS_ERROR_MAJ", + apr_psprintf(req->pool, "%u", (unsigned)maj)); + apr_table_set(req->subprocess_env, "GSS_ERROR_MIN", + apr_psprintf(req->pool, "%u", (unsigned)min)); + apr_table_set(req->subprocess_env, "MAG_ERROR_TEXT", gss_err); + } + if (mag_err) + apr_table_set(req->subprocess_env, "MAG_ERROR", mag_err); +} diff --git a/src/environ.h b/src/environ.h index 1169406..dd9cc7e 100644 --- a/src/environ.h +++ b/src/environ.h @@ -13,3 +13,6 @@ void mag_export_req_env(request_rec *req, apr_table_t *env); void mag_set_req_data(request_rec *req, struct mag_config *cfg, struct mag_conn *mc); + +void mag_publish_error(request_rec *req, uint32_t maj, uint32_t min, + const char *gss_err, const char *mag_err); diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c index 8226ecc..05c2782 100644 --- a/src/mod_auth_gssapi.c +++ b/src/mod_auth_gssapi.c @@ -68,6 +68,42 @@ char *mag_error(request_rec *req, const char *msg, uint32_t maj, uint32_t min) return apr_psprintf(req->pool, "%s: [%s (%s)]", msg, msg_maj, msg_min); } +enum mag_err_code { + MAG_GSS_ERR = 1, + MAG_INTERNAL, + MAG_AUTH_NOT_ALLOWED +}; + +static const char *mag_err_text(enum mag_err_code err) +{ + switch (err) { + case MAG_GSS_ERR: + return "GSS ERROR"; + case MAG_INTERNAL: + return "INTERNAL ERROR"; + case MAG_AUTH_NOT_ALLOWED: + return "AUTH NOT ALLOWED"; + default: + return "INVALID ERROR CODE"; + } +} + +static void mag_post_error(request_rec *req, struct mag_config *cfg, + enum mag_err_code err, uint32_t maj, uint32_t min, + const char *msg) +{ + const char *text = NULL; + + if (maj) + text = mag_error(req, msg, maj, min); + + if (cfg->enverrs) + mag_publish_error(req, maj, min, text ? text : msg, mag_err_text(err)); + + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s %s", mag_err_text(err), + text ? text : msg); +} + static APR_OPTIONAL_FN_TYPE(ssl_is_https) *mag_is_https = NULL; static int mag_post_config(apr_pool_t *cfgpool, apr_pool_t *log, @@ -160,10 +196,8 @@ static bool mag_acquire_creds(request_rec *req, #endif if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s", - mag_error(req, "gss_acquire_cred[_from]() " - "failed to get server creds", - maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "gss_acquire_cred[_from]() failed to get server creds"); return false; } @@ -355,6 +389,7 @@ gss_OID_set mag_filter_unwanted_mechs(gss_OID_set src) static uint32_t mag_context_loop(uint32_t *min, request_rec *req, + struct mag_config *cfg, gss_cred_id_t init_cred, gss_cred_id_t accept_cred, gss_OID mech_type, @@ -373,9 +408,8 @@ static uint32_t mag_context_loop(uint32_t *min, maj = gss_inquire_cred_by_mech(min, accept_cred, mech_type, &accept_name, NULL, NULL, NULL); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "%s", mag_error(req, "gss_inquired_cred_by_mech() " - "failed", maj, *min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, *min, + "gss_inquired_cred_by_mech() failed"); return maj; } @@ -387,8 +421,8 @@ static uint32_t mag_context_loop(uint32_t *min, &accept_token, NULL, &init_token, NULL, NULL); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s", - mag_error(req, "gss_init_sec_context()", maj, *min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, *min, + "gss_init_sec_context()"); goto done; } gss_release_buffer(&tmin, &accept_token); @@ -398,9 +432,8 @@ static uint32_t mag_context_loop(uint32_t *min, client, NULL, &accept_token, NULL, lifetime, delegated_cred); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s", - mag_error(req, "gss_accept_sec_context()", - maj, *min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, *min, + "gss_accept_sec_context()"); goto done; } gss_release_buffer(&tmin, &init_token); @@ -442,10 +475,8 @@ static bool mag_auth_basic(request_rec *req, maj = gss_import_name(&min, &ba_user, GSS_C_NT_USER_NAME, &user); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "In Basic Auth, %s", - mag_error(req, "gss_import_name() failed", - maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "In Basic Auth: gss_import_name() failed"); goto done; } @@ -484,8 +515,8 @@ static bool mag_auth_basic(request_rec *req, /* in case filtered_mechs was not allocated here don't free it */ filtered_mechs = GSS_C_NO_OID_SET; } else if (filtered_mechs == GSS_C_NO_OID_SET) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, req, "Fatal " - "failure while filtering mechs, aborting"); + mag_post_error(req, cfg, MAG_INTERNAL, 0, 0, + "Fatal failure while filtering mechs, aborting"); goto done; } else { /* use the filtered list */ @@ -502,27 +533,23 @@ static bool mag_auth_basic(request_rec *req, maj = gss_test_oid_set_member(&min, discard_const(gss_mech_krb5), allowed_mechs, &present); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "In Basic Auth, %s", - mag_error(req, "gss_test_oid_set_member() failed", - maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "In Basic Auth: gss_test_oid_set_member() failed"); goto done; } if (present) { rs = apr_generate_random_bytes((unsigned char *)(&rndname), sizeof(long long unsigned int)); if (rs != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "Failed to generate random ccache name"); + mag_post_error(req, cfg, MAG_INTERNAL, 0, 0, + "Failed to generate random ccache name"); goto done; } user_ccache = apr_psprintf(req->pool, "MEMORY:user_%qu", rndname); maj = gss_krb5_ccache_name(&min, user_ccache, &orig_ccache); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "In Basic Auth, %s", - mag_error(req, "gss_krb5_ccache_name() " - "failed", maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "In Basic Auth: gss_krb5_ccache_name() failed"); goto done; } } @@ -534,10 +561,9 @@ static bool mag_auth_basic(request_rec *req, GSS_C_INITIATE, &user_cred, &actual_mechs, NULL); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "In Basic Auth, %s", - mag_error(req, "gss_acquire_cred_with_password() " - "failed", maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "In Basic Auth: gss_acquire_cred_with_password() " + "failed"); goto done; } @@ -548,7 +574,7 @@ static bool mag_auth_basic(request_rec *req, } for (int i = 0; i < actual_mechs->count; i++) { - maj = mag_context_loop(&min, req, user_cred, server_cred, + maj = mag_context_loop(&min, req, cfg, user_cred, server_cred, &actual_mechs->elements[i], 300, client, vtime, delegated_cred); if (maj == GSS_S_COMPLETE) { @@ -567,7 +593,7 @@ static bool mag_auth_basic(request_rec *req, if (user_ccache != NULL) { maj = gss_krb5_ccache_name(&min, orig_ccache, NULL); if (maj != GSS_S_COMPLETE) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, req, "Failed to restore per-thread ccache, %s", mag_error(req, "gss_krb5_ccache_name() " "failed", maj, min)); @@ -686,10 +712,8 @@ static apr_status_t mag_s4u2self(request_rec *req) user_name.length = strlen(user_name.value); maj = gss_import_name(&min, &user_name, GSS_C_NT_USER_NAME, &user); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "Failed to import user's name: %s", - mag_error(req, "gss_import_name()", - maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "In S4U2Self: gss_import_name()"); goto done; } @@ -699,26 +723,24 @@ static apr_status_t mag_s4u2self(request_rec *req) GSS_C_INITIATE, &user_cred, NULL, NULL); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "Failed to impersonate %s: %s", req->user, - mag_error(req, "gss_acquire_cred_impersonate_name()", - maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "In S4U2Self: gss_acquire_cred_impersonate_name()"); goto done; } /* the following exchange is needed to decrypt the ticket and get named * attributes as well as check if the ticket is forwardable when * delegated credentials are requested */ - maj = mag_context_loop(&min, req, user_cred, server_cred, + maj = mag_context_loop(&min, req, cfg, user_cred, server_cred, discard_const(gss_mech_krb5), GSS_C_INDEFINITE, &client, &vtime, &delegated_cred); if (GSS_ERROR(maj)) goto done; if (cfg->deleg_ccache_dir && delegated_cred == GSS_C_NO_CREDENTIAL) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "Failed to obtain delegated credentials, " - "does service have +ok_to_auth_as_delegate?"); + mag_post_error(req, cfg, MAG_INTERNAL, 0, 0, + "Failed to obtain delegated credentials, " + "does service have +ok_to_auth_as_delegate?"); goto done; } @@ -821,9 +843,9 @@ static int mag_auth(request_rec *req) if ((req_cfg->desired_mechs == GSS_C_NO_OID_SET) || (req_cfg->desired_mechs->count == 0)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "List of desired mechs is missing or empty, " - "can't proceed!"); + mag_post_error(req, cfg, MAG_INTERNAL, 0, 0, + "List of desired mechs is missing or empty, " + "can't proceed!"); return HTTP_UNAUTHORIZED; } @@ -884,8 +906,8 @@ static int mag_auth(request_rec *req) if (cfg->ssl_only) { if (!mag_conn_is_https(req->connection)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "Not a TLS connection, refusing to authenticate!"); + mag_post_error(req, cfg, MAG_AUTH_NOT_ALLOWED, 0, 0, + "Not a TLS connection, refusing to authenticate!"); goto done; } } @@ -949,7 +971,7 @@ static int mag_auth(request_rec *req) desired_mechs = mag_get_negotiate_mechs(req->pool, req_cfg->desired_mechs); if (desired_mechs == GSS_C_NO_OID_SET) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, req, "Failed to get negotiate_mechs"); goto done; } @@ -967,7 +989,7 @@ static int mag_auth(request_rec *req) if (((char *)ba_user.value)[0] == '\0' || ((char *)ba_pwd.value)[0] == '\0') { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, req, "Invalid empty user or password for Basic Auth"); goto done; } @@ -988,8 +1010,8 @@ static int mag_auth(request_rec *req) case AUTH_TYPE_RAW_NTLM: if (!is_mech_allowed(desired_mechs, gss_mech_ntlmssp, cfg->gss_conn_ctx)) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, req, - "NTLM Authentication is not allowed!"); + mag_post_error(req, cfg, MAG_AUTH_NOT_ALLOWED, 0, 0, + "NTLM Authentication is not allowed!"); goto done; } @@ -999,8 +1021,8 @@ static int mag_auth(request_rec *req) desired_mechs = discard_const(gss_mech_set_ntlmssp); if (desired_mechs == GSS_C_NO_OID_SET) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "No support for ntlmssp mech"); + mag_post_error(req, cfg, MAG_INTERNAL, 0 ,0, + "No support for ntlmssp mech"); goto done; } break; @@ -1046,9 +1068,8 @@ static int mag_auth(request_rec *req) cfg->allowed_mechs != GSS_C_NO_OID_SET) { maj = gss_set_neg_mechs(&min, acquired_cred, cfg->allowed_mechs); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s", - mag_error(req, "gss_set_neg_mechs() failed", - maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "In Negotiate Auth: gss_set_neg_mechs() failed"); goto done; } } @@ -1058,16 +1079,15 @@ static int mag_auth(request_rec *req) &client, &mech_type, &output, NULL, &vtime, &delegated_cred); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s", - mag_error(req, "gss_accept_sec_context() failed", - maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "In Negotiate Auth: gss_accept_sec_context() failed"); goto done; } else if (maj == GSS_S_CONTINUE_NEEDED) { if (!mc->is_preserved) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, - "Mechanism needs continuation but neither " - "GssapiConnectionBound nor " - "GssapiUseSessions are available"); + mag_post_error(req, cfg, MAG_INTERNAL, 0, 0, + "Mechanism needs continuation but neither " + "GssapiConnectionBound nor " + "GssapiUseSessions are configured"); gss_release_buffer(&min, &output); output.length = 0; } @@ -1131,9 +1151,8 @@ static int mag_complete(struct mag_req_cfg *req_cfg, struct mag_conn *mc, maj = gss_display_name(&min, client, &name, NULL); if (GSS_ERROR(maj)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s", - mag_error(req, "gss_display_name() failed", - maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "gss_display_name() failed"); goto done; } @@ -1178,8 +1197,8 @@ static int mag_complete(struct mag_req_cfg *req_cfg, struct mag_conn *mc, if (cfg->map_to_local) { maj = gss_localname(&min, client, mech_type, &lname); if (maj != GSS_S_COMPLETE) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s", - mag_error(req, "gss_localname() failed", maj, min)); + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "gss_localname() failed"); goto done; } mc->user_name = apr_pstrndup(mc->pool, lname.value, lname.length); @@ -1745,6 +1764,9 @@ static const command_rec mag_commands[] = { "Don't resend negotiate header on negotiate failure"), AP_INIT_RAW_ARGS("GssapiNameAttributes", mag_name_attrs, NULL, OR_AUTHCFG, "Name Attributes to be exported as environ variables"), + AP_INIT_FLAG("GssapiPublishErrors", ap_set_flag_slot, + (void *)APR_OFFSETOF(struct mag_config, enverrs), OR_AUTHCFG, + "Publish GSSAPI Errors in Envionment Variables"), { NULL } }; diff --git a/src/mod_auth_gssapi.h b/src/mod_auth_gssapi.h index 14bc10b..601a97f 100644 --- a/src/mod_auth_gssapi.h +++ b/src/mod_auth_gssapi.h @@ -91,6 +91,7 @@ struct mag_config { gss_OID_set_desc *basic_mechs; bool negotiate_once; struct mag_name_attributes *name_attributes; + bool enverrs; }; struct mag_server_config { From d8c4ed02f54568870368131a6a54d12831366206 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 19 Feb 2017 12:37:19 -0500 Subject: [PATCH 3/3] Test that error env vars are properly exported. Signed-off-by: Simo Sorce --- src/mod_auth_gssapi.c | 19 ++++++++++++++++--- tests/401.html | 1 + tests/httpd.conf | 4 ++++ tests/magtests.py | 2 ++ tests/t_basic_k5_fail_second.py | 3 +++ 5 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 tests/401.html diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c index 05c2782..13bec7a 100644 --- a/src/mod_auth_gssapi.c +++ b/src/mod_auth_gssapi.c @@ -69,7 +69,8 @@ char *mag_error(request_rec *req, const char *msg, uint32_t maj, uint32_t min) } enum mag_err_code { - MAG_GSS_ERR = 1, + MAG_NO_AUTH = 1, + MAG_GSS_ERR, MAG_INTERNAL, MAG_AUTH_NOT_ALLOWED }; @@ -77,6 +78,8 @@ enum mag_err_code { static const char *mag_err_text(enum mag_err_code err) { switch (err) { + case MAG_NO_AUTH: + return "NO AUTH DATA"; case MAG_GSS_ERR: return "GSS ERROR"; case MAG_INTERNAL: @@ -948,10 +951,18 @@ static int mag_auth(request_rec *req) } /* We can proceed only if we do have an auth header */ - if (!auth_header) goto done; + if (!auth_header) { + mag_post_error(req, cfg, MAG_NO_AUTH, 0, 0, + "Client did not send any authentication headers"); + goto done; + } auth_header_type = ap_getword_white(req->pool, &auth_header); - if (!auth_header_type) goto done; + if (!auth_header_type) { + mag_post_error(req, cfg, MAG_NO_AUTH, 0, 0, + "Client sent malformed authentication headers"); + goto done; + } /* We got auth header, sending auth header would mean re-auth */ send_auth_header = !cfg->negotiate_once; @@ -1028,6 +1039,8 @@ static int mag_auth(request_rec *req) break; default: + mag_post_error(req, cfg, MAG_NO_AUTH, 0, 0, + "Client sent unknown authentication headers"); goto done; } diff --git a/tests/401.html b/tests/401.html new file mode 100644 index 0000000..4a1ad85 --- /dev/null +++ b/tests/401.html @@ -0,0 +1 @@ +MAG_ERROR:[] MAG_ERROR_TEXT:[] GSS_ERROR_MAJ:[] GSS_ERROR_MIN:[] diff --git a/tests/httpd.conf b/tests/httpd.conf index 48122e3..8b64000 100644 --- a/tests/httpd.conf +++ b/tests/httpd.conf @@ -93,6 +93,8 @@ DocumentRoot "${HTTPROOT}/html" Options Indexes FollowSymLinks + Options +Includes + AddOutputFilter INCLUDES .html AllowOverride None Require all granted @@ -112,6 +114,7 @@ LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combine CustomLog "logs/access_log" combined +ErrorDocument 401 /401.html ErrorLog "logs/error_log" LogLevel debug @@ -193,6 +196,7 @@ CoreDumpDirectory "${HTTPROOT}" GssapiBasicAuth On GssapiBasicAuthMech krb5 GssapiConnectionBound On + GssapiPublishErrors On Require valid-user diff --git a/tests/magtests.py b/tests/magtests.py index b60e648..f0b642a 100755 --- a/tests/magtests.py +++ b/tests/magtests.py @@ -239,6 +239,8 @@ def setup_http(testdir, wrapenv): with open(config, 'w+') as f: f.write(text) + shutil.copy('tests/401.html', os.path.join(httpdir, 'html')) + httpenv = {'PATH': '/sbin:/bin:/usr/sbin:/usr/bin', 'MALLOC_CHECK_': '3', 'MALLOC_PERTURB_': str(random.randint(0, 32767) % 255 + 1)} diff --git a/tests/t_basic_k5_fail_second.py b/tests/t_basic_k5_fail_second.py index 15727b8..cdbec26 100755 --- a/tests/t_basic_k5_fail_second.py +++ b/tests/t_basic_k5_fail_second.py @@ -3,6 +3,7 @@ import os import requests +import sys from requests.auth import HTTPBasicAuth @@ -22,6 +23,8 @@ r = s.get(url) if r.status_code == 200: raise ValueError('Basic Auth: Got Success while expecting Error') + if not 'GSS ERROR' in r.text: + raise ValueError('Basic Auth: Expected error variable is missing') url = 'http://%s:%s@%s/basic_auth_krb5/' % (os.environ['MAG_USER_NAME_2'], os.environ['MAG_USER_PASSWORD_2'],