summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile21
-rw-r--r--README11
-rw-r--r--mod_intercept_form_submit.c34
-rw-r--r--mod_intercept_form_submit.spec5
4 files changed, 59 insertions, 12 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..67c41e2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,21 @@
+
+NAME=mod_intercept_form_submit
+
+SOURCE0 := $(shell spectool $(NAME).spec)
+SOURCE := $(shell echo $(SOURCE0) | sed 's%^.*/%%')
+NAME_VER := $(shell echo $(SOURCE) | sed 's%\.tar\.gz$$%%')
+
+all:
+ @echo 'Usage: make dist to build the .tar.gz'
+ @echo ' make timestamps set file timestamps to match commit times'
+
+timestamps:
+ git ls-files | while read -r f ; do touch -ch -d "$$(git log -1 --format=%ci "$$f")" "$$f" ; done
+
+dist:
+ @if test -f ../$(SOURCE) ; then ( echo "The source [../$(SOURCE)] already exists." >&2 ; exit 1 ) ; fi
+ @mkdir .dist
+ @mkdir .dist/$(NAME_VER) && cp -rp * .dist/$(NAME_VER)
+ tar cvzf ../$(SOURCE) -C .dist $(NAME_VER)
+ @rm -rf .dist
+
diff --git a/README b/README
index d58b1f5..4b229ac 100644
--- a/README
+++ b/README
@@ -87,6 +87,14 @@ Optional parameters:
By default, no modifications to login happens.
+ InterceptGETOnSuccess on|off
+
+ When the authentication using the POST data passes, the
+ method of the request is internally changed to GET. This
+ stops applications and frameworks that insist on running
+ their own authentication on POST irrespective of REMOTE_USER
+ value to think that they process GET.
+
Example:
LoadModule intercept_form_submit_module modules/mod_intercept_form_submit.so
@@ -99,6 +107,7 @@ Example:
InterceptFormClearRemoteUserForSkipped on
InterceptFormPasswordRedact on
InterceptFormLoginRealms EXAMPLE.COM LAB.EXAMPLE.COM ''
+ InterceptGETOnSuccess on
</Location>
The PAM service needs to be configured. For the above shown
@@ -149,7 +158,7 @@ is logged and authentication does not take place.
License
-------
-Copyright 2013--2014 Jan Pazdziora
+Copyright 2013--2016 Jan Pazdziora
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/mod_intercept_form_submit.c b/mod_intercept_form_submit.c
index eaba481..bc6ca38 100644
--- a/mod_intercept_form_submit.c
+++ b/mod_intercept_form_submit.c
@@ -1,6 +1,6 @@
/*
- * Copyright 2013--2014 Jan Pazdziora
+ * Copyright 2013--2016 Jan Pazdziora
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@ typedef struct ifs_config {
char * pam_service;
apr_hash_t * login_blacklist;
int clear_blacklisted;
+ int success_to_get;
apr_array_header_t * realms;
} ifs_config;
@@ -78,6 +79,7 @@ static const command_rec directives[] = {
AP_INIT_TAKE1("InterceptFormPAMService", ap_set_string_slot, (void *)APR_OFFSETOF(ifs_config, pam_service), ACCESS_CONF, "PAM service to authenticate against"),
AP_INIT_ITERATE("InterceptFormLoginSkip", add_login_to_blacklist, NULL, ACCESS_CONF, "Login name(s) for which no PAM authentication will be done"),
AP_INIT_FLAG("InterceptFormClearRemoteUserForSkipped", ap_set_flag_slot, (void *)APR_OFFSETOF(ifs_config, clear_blacklisted), ACCESS_CONF, "When authentication is skipped for users listed with InterceptFormLoginSkip, clear r->user and REMOTE_USER"),
+ AP_INIT_FLAG("InterceptGETOnSuccess", ap_set_flag_slot, (void *)APR_OFFSETOF(ifs_config, success_to_get), ACCESS_CONF, "When authentication passes, turn the POST request to GET internally"),
AP_INIT_ITERATE("InterceptFormLoginRealms", add_realm, NULL, ACCESS_CONF, "Realm(s) that will be appended to login name which does not have one"),
{ NULL }
};
@@ -234,7 +236,7 @@ static void intercept_form_redact_password(ap_filter_t * f, ifs_config * config)
}
static int intercept_form_submit_process_buffer(ap_filter_t * f, ifs_config * config, char ** login_value, char ** password_value,
- const char * buffer, int buffer_length, apr_bucket * fragment_start_bucket, int fragment_start_bucket_offset) {
+ const char * buffer, int buffer_length, apr_bucket * fragment_start_bucket, int fragment_start_bucket_offset, authn_status * out_status) {
char * sep = memchr(buffer, '=', buffer_length);
if (! sep) {
return 0;
@@ -280,7 +282,7 @@ static int intercept_form_submit_process_buffer(ap_filter_t * f, ifs_config * co
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "mod_intercept_form_submit: pam_authenticate_with_login_password not found; perhaps mod_authnz_pam is not loaded");
return 0;
}
- pam_authenticate_in_realms(r, config->pam_service, *login_value, *password_value, config->realms, 3);
+ (*out_status) = pam_authenticate_in_realms(r, config->pam_service, *login_value, *password_value, config->realms, 3);
if (config->password_redact > 0) {
intercept_form_redact_password(f, config);
}
@@ -301,9 +303,9 @@ static apr_status_t intercept_form_submit_filter(ap_filter_t * f, apr_bucket_bri
return ap_get_brigade(f->next, bb, mode, block, readbytes);
}
-static void intercept_form_submit_filter_prefetch(request_rec * r, ifs_config * config, ap_filter_t * f) {
+static apr_status_t intercept_form_submit_filter_prefetch(request_rec * r, ifs_config * config, ap_filter_t * f) {
if (r->status != 200)
- return;
+ return DECLINED;
ifs_filter_ctx_t * ctx = f->ctx;
if (! ctx) {
@@ -319,6 +321,8 @@ static void intercept_form_submit_filter_prefetch(request_rec * r, ifs_config *
apr_bucket * fragment_start_bucket = NULL;
int fragment_start_bucket_offset = 0;
+ authn_status out_status = AUTH_GENERAL_ERROR;
+
apr_bucket_brigade * bb = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
int fetch_more = 1;
while (fetch_more) {
@@ -334,7 +338,7 @@ static void intercept_form_submit_filter_prefetch(request_rec * r, ifs_config *
if (APR_BUCKET_IS_EOS(b)) {
if (fragment)
intercept_form_submit_process_buffer(f, config, &login_value, &password_value,
- fragment, fragment_length, fragment_start_bucket, fragment_start_bucket_offset);
+ fragment, fragment_length, fragment_start_bucket, fragment_start_bucket_offset, &out_status);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "hit EOS");
fetch_more = 0;
break;
@@ -357,7 +361,7 @@ static void intercept_form_submit_filter_prefetch(request_rec * r, ifs_config *
fragment = realloc(fragment, new_length);
memcpy(fragment + fragment_length, p, e - p);
if (intercept_form_submit_process_buffer(f, config, &login_value, &password_value,
- fragment, new_length, fragment_start_bucket, fragment_start_bucket_offset)) {
+ fragment, new_length, fragment_start_bucket, fragment_start_bucket_offset, &out_status)) {
fetch_more = 0;
break;
}
@@ -365,7 +369,7 @@ static void intercept_form_submit_filter_prefetch(request_rec * r, ifs_config *
fragment = NULL;
} else {
if (intercept_form_submit_process_buffer(f, config, &login_value, &password_value,
- p, e - p, b, (p - buffer))) {
+ p, e - p, b, (p - buffer), &out_status)) {
fetch_more = 0;
break;
}
@@ -384,7 +388,7 @@ static void intercept_form_submit_filter_prefetch(request_rec * r, ifs_config *
} else if (APR_BUCKET_NEXT(b) && APR_BUCKET_IS_EOS(APR_BUCKET_NEXT(b))) {
/* shortcut if this is the last bucket, slurp the rest */
intercept_form_submit_process_buffer(f, config, &login_value, &password_value,
- p, nbytes, b, (p - buffer));
+ p, nbytes, b, (p - buffer), &out_status);
fetch_more = 0;
} else {
fragment = malloc(nbytes);
@@ -398,6 +402,7 @@ static void intercept_form_submit_filter_prefetch(request_rec * r, ifs_config *
}
if (fragment)
free(fragment);
+ return out_status == AUTH_GRANTED ? OK : DECLINED;
}
#define _INTERCEPT_CONTENT_TYPE "application/x-www-form-urlencoded"
@@ -427,7 +432,14 @@ static apr_status_t intercept_form_submit_init(request_rec * r) {
if (!apr_strnatcasecmp(content_type_pure, _INTERCEPT_CONTENT_TYPE)) {
ap_filter_t * the_filter = ap_add_input_filter("intercept_form_submit_filter", NULL, r, r->connection);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "inserted filter intercept_form_submit_filter, starting intercept_form_submit_filter_prefetch");
- intercept_form_submit_filter_prefetch(r, config, the_filter);
+ apr_status_t status = intercept_form_submit_filter_prefetch(r, config, the_filter);
+ if (status == OK && config->success_to_get >= 0) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "intercept_form_submit_filter_prefetch returned OK, turning the method to GET");
+ r->status_line = NULL;
+ r->method = "GET";
+ r->method_number = M_GET;
+ apr_table_unset(r->headers_in, "Content-Length");
+ }
return DECLINED;
}
}
@@ -439,6 +451,7 @@ static void * create_dir_conf(apr_pool_t * pool, char * dir) {
ifs_config * cfg = apr_pcalloc(pool, sizeof(ifs_config));
cfg->password_redact = -1;
cfg->clear_blacklisted = -1;
+ cfg->success_to_get = -1;
return cfg;
}
@@ -449,6 +462,7 @@ static void * merge_dir_conf(apr_pool_t * pool, void * base_void, void * add_voi
cfg->login_name = add->login_name ? add->login_name : base->login_name;
cfg->password_name = add->password_name ? add->password_name : base->password_name;
cfg->password_redact = add->password_redact >= 0 ? add->password_redact : base->password_redact;
+ cfg->success_to_get = add->success_to_get >= 0 ? add->success_to_get : base->success_to_get;
cfg->clear_blacklisted = add->clear_blacklisted >= 0 ? add->clear_blacklisted : base->clear_blacklisted;
cfg->pam_service = add->pam_service ? add->pam_service : base->pam_service;
if (add->login_blacklist) {
diff --git a/mod_intercept_form_submit.spec b/mod_intercept_form_submit.spec
index 8779510..0f123b4 100644
--- a/mod_intercept_form_submit.spec
+++ b/mod_intercept_form_submit.spec
@@ -7,7 +7,7 @@
Summary: Apache module to intercept login form submission and run PAM authentication
Name: mod_intercept_form_submit
-Version: 1.0.0
+Version: 1.0.1
Release: 1%{?dist}
License: ASL 2.0
Group: System Environment/Daemons
@@ -62,6 +62,9 @@ install -Dp -m 0644 intercept_form_submit.confx $RPM_BUILD_ROOT%{_httpd_confdir}
%{_httpd_moddir}/*.so
%changelog
+* Fri May 06 2016 Jan Pazdziora <jpazdziora@redhat.com> - 1.0.1-1
+- Add support for InterceptGETOnSuccess.
+
* Mon Mar 21 2016 Jan Pazdziora <jpazdziora@redhat.com> - 1.0.0-1
- 1319094 - the Requires(pre) httpd does not seem to be needed.