version initiale
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
+229
@@ -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
|
||||||
|
** <Location /absec>
|
||||||
|
** SetHandler absec
|
||||||
|
** </Location>
|
||||||
|
**
|
||||||
|
** 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 <pwd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "apr_want.h"
|
||||||
|
|
||||||
|
#include <shadow.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
/* 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<br/>", auth64);
|
||||||
|
auth64 = apr_pstrdup(r->pool, auth64p+6);
|
||||||
|
//ap_rprintf(r, "Test: %s \n<br/>", 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<br/>", r->args);
|
||||||
|
ap_rprintf(r, "Url: %s from %s \n<br/>", r->filename, r->uri);
|
||||||
|
ap_rprintf(r, "Headers Authorization: %s \n<br/>", auth64);
|
||||||
|
ap_rprintf(r, "User/Pass: %s/%s \n<br/>", 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<br/>", g,i);
|
||||||
|
|
||||||
|
////////
|
||||||
|
/* Retrieve PW from /etc/passwd */
|
||||||
|
/* Should include <pwd.h> */
|
||||||
|
struct passwd *pw;
|
||||||
|
if((pw = getpwnam(user)) == NULL)
|
||||||
|
{
|
||||||
|
ap_rprintf(r, "NULL \n<br/>");
|
||||||
|
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<br/>", pw->pw_passwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////
|
||||||
|
/* Retrieve PW from /etc/shadow */
|
||||||
|
/* Should include <shadow.h> */
|
||||||
|
struct spwd *spw;
|
||||||
|
errno = 0;
|
||||||
|
if((spw = getspnam(user)) == NULL)
|
||||||
|
{
|
||||||
|
ap_rprintf(r, "NULL %d\n<br/>", 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<br/>", 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<br/>", encrypted);;
|
||||||
|
ap_rprintf(r, "compare : %d \n<br/>", 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 <sys/stat.h> */
|
||||||
|
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 */
|
||||||
|
};
|
||||||
|
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user