From 6d9d0199cde72c1a68258e1e4855e2146bf9f244 Mon Sep 17 00:00:00 2001 From: Jean-Luc Cyr Date: Thu, 31 May 2018 12:45:24 -0400 Subject: [PATCH] version initiale --- Makefile | 45 ++++++++++++ mod_absec.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ modules.mk | 4 ++ 3 files changed, 278 insertions(+) create mode 100644 Makefile create mode 100644 mod_absec.c create mode 100644 modules.mk diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..28cdaa2 --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +## +## Makefile -- Build procedure for sample absec Apache module +## Autogenerated via ``apxs -n absec -g''. +## + +builddir=. +top_srcdir=/usr/local/apache2 +top_builddir=/usr/local/apache2 +include /usr/local/apache2/build/special.mk + +# the used tools +APACHECTL=apachectl + +# additional defines, includes and libraries +#DEFS=-Dmy_define=my_value +#INCLUDES=-Imy/include/dir +#LIBS=-Lmy/lib/dir -lmylib + +# the default target +all: local-shared-build + +# install the shared object file into Apache +install: install-modules-yes + +# cleanup +clean: + -rm -f mod_absec.o mod_absec.lo mod_absec.slo mod_absec.la + +# simple test +test: reload + lynx -mime_header http://localhost/absec + +# install and activate shared object by reloading Apache to +# force a reload of the shared object file +reload: install restart + +# the general Apache start/restart/stop +# procedures +start: + $(APACHECTL) start +restart: + $(APACHECTL) restart +stop: + $(APACHECTL) stop + diff --git a/mod_absec.c b/mod_absec.c new file mode 100644 index 0000000..a9517aa --- /dev/null +++ b/mod_absec.c @@ -0,0 +1,229 @@ +/* +** mod_absec.c -- Apache sample absec module +** [Autogenerated via ``apxs -n absec -g''] +** +** To play with this sample module first compile it into a +** DSO file and install it into Apache's modules directory +** by running: +** +** $ apxs -c -i mod_absec.c +** +** Then activate it in Apache's httpd.conf file for instance +** for the URL /absec in as follows: +** +** # httpd.conf +** LoadModule absec_module modules/mod_absec.so +** +** SetHandler absec +** +** +** Then after restarting Apache via +** +** $ apachectl restart +** +** you immediately can request the URL /absec and watch for the +** output of this module. This can be achieved for instance via: +** +** $ lynx -mime_header http://localhost/absec +** +** The output should be similar to the following one: +** +** HTTP/1.1 200 OK +** Date: Tue, 31 Mar 1998 14:42:22 GMT +** Server: Apache/1.3.4 (Unix) +** Connection: close +** Content-Type: text/html +** +** The sample page from mod_absec.c +*/ + +/* + TEST URL + http://10.211.55.15/absec?joe=blow + + INFORMATION SOURCES + + https://apr.apache.org/docs/apr/1.5/group__apr__strings.html + https://apr.apache.org/docs/apr-util/1.6/files.html + + https://httpd.apache.org/docs/2.4/developer/modguide.html + http://www.ziviani.net/2011/how-to-create-an-apache-module + + https://en.wikipedia.org/wiki/Basic_access_authentication + +*/ + +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "ap_config.h" +#include "apr_base64.h" +#include "apr_strings.h" +#include "apr_portable.h" +#include "apr_user.h" + +#include +#include +#include +#include "apr_want.h" + +#include +#include + +//////////////////////////////////////////////////////////////// +/* The sample content handler */ +static int absec_handler(request_rec *r) +{ + if (strcmp(r->handler, "absec")) { + return DECLINED; + } + + const char* auth64p; + + r->content_type = "text/html"; + + if (!r->header_only) + // Check if we have an auth header + auth64p = apr_table_get(r->headers_in,"Authorization"); + + if (auth64p==NULL) { + apr_table_setn(r->err_headers_out, + (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" + : "WWW-Authenticate", + apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), + "\"", NULL)); + return HTTP_UNAUTHORIZED; + } + +//////// +/* Retrieve user/pass from http basic auth header */ + // Get the basic auth base64 string and decode it + // Start at char 6 to skip 'Basic ' + char *auth64; + //apr_strtok((char*)auth64p, " ", &auth64); + //ap_rprintf(r, "Test: %s \n
", auth64); + auth64 = apr_pstrdup(r->pool, auth64p+6); + //ap_rprintf(r, "Test: %s \n
", auth64); + char *auth; + auth = apr_pcalloc(r->pool, 64); + apr_base64_decode(auth, auth64); + + // Validate user/pass against unix cred + char *user; + char *pass; + user = apr_strtok(auth, ":", &pass); + + // Get UID, GIDs for the user + + ap_rprintf(r, "The sample page from mod_absec.c %s \n
", r->args); + ap_rprintf(r, "Url: %s from %s \n
", r->filename, r->uri); + ap_rprintf(r, "Headers Authorization: %s \n
", auth64); + ap_rprintf(r, "User/Pass: %s/%s \n
", user, pass); + +//////// +/* Working example, but just UID not PW */ + apr_status_t ret; + apr_uid_t i; + apr_gid_t g; + ret = apr_uid_get ( &i, &g, user, r->pool ); + ap_rprintf(r, "Result2: G:%d, I:%d \n
", g,i); + +//////// +/* Retrieve PW from /etc/passwd */ +/* Should include */ + struct passwd *pw; + if((pw = getpwnam(user)) == NULL) + { + ap_rprintf(r, "NULL \n
"); + apr_table_setn(r->err_headers_out, + (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" + : "WWW-Authenticate", + apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), + "\"", NULL)); + return HTTP_UNAUTHORIZED; + } + else + { + ap_rprintf(r, "Unix PW : %s \n
", pw->pw_passwd); + } + +//////// +/* Retrieve PW from /etc/shadow */ +/* Should include */ + struct spwd *spw; + errno = 0; + if((spw = getspnam(user)) == NULL) + { + ap_rprintf(r, "NULL %d\n
", errno); + apr_table_setn(r->err_headers_out, + (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" + : "WWW-Authenticate", + apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), + "\"", NULL)); + return HTTP_UNAUTHORIZED; + } + else + { + ap_rprintf(r, "Shadow PW : %s \n
", spw->sp_pwdp); + } + + if (spw->sp_pwdp[0] == 'x' || spw->sp_pwdp[0] == '*' || spw->sp_pwdp[0] == '!') { + apr_table_setn(r->err_headers_out, + (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" + : "WWW-Authenticate", + apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), + "\"", NULL)); + return HTTP_UNAUTHORIZED; + } + +//////// +/* Encrypt and compare shadow password */ + +// TODO : Valider qu'on a un user +// TODO : Valider qu'il y a un password (pas * ! rien) + char *encrypted; + const char *correct; + int rrr; + encrypted = crypt(pass, spw->sp_pwdp); + rrr = strcmp(encrypted, spw->sp_pwdp); + ap_rprintf(r, "compare pw : %s \n
", encrypted);; + ap_rprintf(r, "compare : %d \n
", rrr); + if (rrr!=0) { + apr_table_setn(r->err_headers_out, + (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate" + : "WWW-Authenticate", + apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), + "\"", NULL)); + return HTTP_UNAUTHORIZED; + } + +//////// +/* check file permission on filesystem */ +/* should include */ + struct stat fperm; + int status; + status = stat(r->filename, &fperm); + ap_rprintf(r, "File perms %o, owner %d, group %d (status %d)", fperm.st_mode, fperm.st_uid, fperm.st_gid, status); + + return OK; +} + +//////////////////////////////////////////////////////////////// +static void absec_register_hooks(apr_pool_t *p) +{ + ap_hook_handler(absec_handler, NULL, NULL, APR_HOOK_MIDDLE); +} + +//////////////////////////////////////////////////////////////// +/* Dispatch list for API hooks */ +module AP_MODULE_DECLARE_DATA absec_module = { + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + NULL, /* table of config file commands */ + absec_register_hooks /* register hooks */ +}; + diff --git a/modules.mk b/modules.mk new file mode 100644 index 0000000..03b9ca7 --- /dev/null +++ b/modules.mk @@ -0,0 +1,4 @@ +mod_absec.la: mod_absec.slo + $(SH_LINK) -rpath $(libexecdir) -module -avoid-version mod_absec.lo +DISTCLEAN_TARGETS = modules.mk +shared = mod_absec.la