added some basic module config (default perms, uid and gid) for not listed URLs
This commit is contained in:
+1
-1
@@ -59,7 +59,7 @@ int perms_lookup(request_rec *r, struct stat *fperm)
|
||||
}
|
||||
|
||||
if (cnt==0) {
|
||||
sprintf(query, "insert into urls (url, uid, gid, perms) values ('%s', 0, 0, 0)", r->uri);
|
||||
sprintf(query, "insert into urls (url, uid, gid, perms) values ('%s', %d, %d, %d)", r->uri, fperm->st_uid, fperm->st_gid, fperm->st_mode);
|
||||
if (mysql_query(conn, query)) {
|
||||
printf("%s\n", mysql_error(conn));
|
||||
return(0);
|
||||
|
||||
@@ -90,8 +90,6 @@ echo "Running test"
|
||||
./abchgrp 200 /
|
||||
./abls /
|
||||
|
||||
exit
|
||||
|
||||
echo "================"
|
||||
echo "Compiling apache absec module"
|
||||
echo "selected authen :" $ABSEC_AUTHEN_DEP $ABSEC_AUTHEN_FILE
|
||||
|
||||
+68
-207
@@ -62,6 +62,8 @@
|
||||
#include "ap_provider.h"
|
||||
#include "mod_auth.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <sys/types.h>
|
||||
@@ -75,196 +77,71 @@
|
||||
#include "absec_auto.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
/* Main routine - called after request processing */
|
||||
static int absec_handler_last(request_rec *r)
|
||||
// Macro declaration du module
|
||||
module AP_MODULE_DECLARE_DATA absec_module;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// structure de configuration du module
|
||||
typedef struct {
|
||||
int default_uid;
|
||||
int default_gid;
|
||||
int default_perms;
|
||||
} authnz_config_rec;
|
||||
|
||||
static void *authnz_absec_config(apr_pool_t *pool, char *x)
|
||||
{
|
||||
// Is this module really called?
|
||||
if (strcmp(r->handler, "absec")) {
|
||||
return DECLINED;
|
||||
return apr_pcalloc(pool, sizeof(authnz_config_rec));
|
||||
}
|
||||
|
||||
////////
|
||||
/* http method validate the perm asked (r/w vs get/post,put) */
|
||||
ap_rprintf(r, "After Method: %s<br/>\r\n", r->method);
|
||||
int permmask = 0;
|
||||
if (strcmp(r->method,"GET")!=0)
|
||||
static const char* set_default_perms(cmd_parms* cmd, void* cfg, const char* val) {
|
||||
int octal, decimal;
|
||||
octal = atoi(val);
|
||||
decimal = 0;
|
||||
int i=0;
|
||||
while (octal != 0)
|
||||
{
|
||||
// Not a GET, it's too late to do anything
|
||||
ap_rprintf(r, "Not a GET post treatement is too late!\n<br/>");
|
||||
return (DECLINED);
|
||||
decimal = decimal +(octal % 10)* pow(8, i++);
|
||||
octal = octal / 10;
|
||||
}
|
||||
|
||||
r->content_type = "text/html";
|
||||
//ap_rprintf(r, "The sample page from mod_absec.c %s \n<br/>", r->args);
|
||||
ap_rprintf(r, "After GET Url: %s from %s \n<br/>", r->filename, r->uri);
|
||||
return (DECLINED);
|
||||
((authnz_config_rec*)cfg)->default_perms = decimal;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* set_default_uid(cmd_parms* cmd, void* cfg, const char* val) {
|
||||
((authnz_config_rec*)cfg)->default_uid = atoi(val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* set_default_gid(cmd_parms* cmd, void* cfg, const char* val) {
|
||||
((authnz_config_rec*)cfg)->default_gid = atoi(val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
/* Main routine - called before request processing */
|
||||
static int absec_handler_first(request_rec *r)
|
||||
static const command_rec absec_auth_basic_cmds[] =
|
||||
{
|
||||
ap_rprintf(r, "handler first : Before Method: %s<br/>\r\n", r->method);
|
||||
// Is this module really called?
|
||||
/*if (strcmp(r->handler, "absec")) {
|
||||
ap_rprintf(r, "DECLINED<br/>\r\n");
|
||||
return DECLINED;
|
||||
}*/
|
||||
|
||||
|
||||
////////
|
||||
/* http method validate the perm asked (r/w vs get/post,put) */
|
||||
//ap_rprintf(r, "Before Method: %s<br/>\r\n", r->method);
|
||||
|
||||
int permmask = 0;
|
||||
if (strcmp(r->method,"GET")==0) permmask=0444; // r
|
||||
if (strcmp(r->method,"PUT")==0) permmask=0222; // w
|
||||
if (strcmp(r->method,"POST")==0) permmask=0222; // w
|
||||
if (strcmp(r->method,"DELETE")==0) permmask=0111; // x
|
||||
|
||||
////////
|
||||
/* check file permission on filesystem */
|
||||
/* should include <sys/stat.h> */
|
||||
struct stat fperm;
|
||||
int status;
|
||||
//status = stat(r->filename, &fperm);
|
||||
status = perms_lookup(r, &fperm);
|
||||
//ap_rprintf(r, "Result mysql: %d<br/>\r\n", );
|
||||
if (status==-1) {
|
||||
ap_rprintf(r, "stat erreur %d", errno);
|
||||
return (OK);
|
||||
}
|
||||
//ap_rprintf(r, "File perms %o, owner %d, group %d (status %d)<br/>\r\n", fperm.st_mode, fperm.st_uid, fperm.st_gid, status);
|
||||
|
||||
/* check if any permission (ogw) match method (get r, put/post w, delete x) */
|
||||
if ((fperm.st_mode & permmask)==0) {
|
||||
/* no permission match, return don't even have to check user perms */
|
||||
ap_rprintf(r, "Aucune permission pour la methode %s (%o, %o)", r->method, fperm.st_mode, permmask);
|
||||
return (OK);
|
||||
}
|
||||
|
||||
// If file is world accessible for asked method return content
|
||||
if (fperm.st_mode & 0x7 & permmask) {
|
||||
/* if so, return, no need to check user perms */
|
||||
//ap_rprintf(r, "Fichier public<br/>\r\n");
|
||||
return (DECLINED);
|
||||
}
|
||||
|
||||
////////
|
||||
/* Check if we have a basic auth user */
|
||||
const char* auth64p;
|
||||
// Check if we have an auth header
|
||||
auth64p = apr_table_get(r->headers_in,"Authorization");
|
||||
|
||||
// If no basic auth, ask for one
|
||||
if (auth64p==NULL) {
|
||||
r->content_type = "text/html";
|
||||
apr_table_setn(r->err_headers_out,
|
||||
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
|
||||
: "WWW-Authenticate",
|
||||
apr_pstrcat(r->pool, "Basic realm=\"PAS DE USER ", 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;
|
||||
auth64 = apr_pstrdup(r->pool, auth64p+6);
|
||||
char *auth;
|
||||
auth = apr_pcalloc(r->pool, 64);
|
||||
apr_base64_decode(auth, auth64);
|
||||
char *user;
|
||||
char *pass;
|
||||
user = apr_strtok(auth, ":", &pass);
|
||||
|
||||
r->content_type = "text/html";
|
||||
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);
|
||||
|
||||
int pam_result = check_user(user, pass);
|
||||
if ( (pam_result==PAM_ERROR_START) || (pam_result==PAM_ERROR_STOP) ) {
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
if (pam_result==PAM_ERROR_INVALID_CRED) {
|
||||
r->content_type = "text/html";
|
||||
apr_table_setn(r->err_headers_out,
|
||||
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
|
||||
: "WWW-Authenticate",
|
||||
apr_pstrcat(r->pool, "Basic realm=\"USER/PASS INVALIDE ", ap_auth_name(r),
|
||||
"\"", NULL));
|
||||
return HTTP_UNAUTHORIZED;
|
||||
}
|
||||
|
||||
////////
|
||||
// Continue checking permission
|
||||
|
||||
////////
|
||||
/* Retrieve user details from /etc/passwd to get uid and primary group */
|
||||
/* Should include <pwd.h> */
|
||||
struct passwd *pw;
|
||||
if((pw = getpwnam(user)) == NULL)
|
||||
{
|
||||
// Should never happend as already verified with PAM
|
||||
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=\"USER INCONNU ", ap_auth_name(r),
|
||||
"\"", NULL));
|
||||
// User cannot be found, unauthorized
|
||||
return HTTP_UNAUTHORIZED;
|
||||
}
|
||||
|
||||
// If file is user readable and user match return content
|
||||
if ((fperm.st_uid==pw->pw_uid) && (fperm.st_mode & 0700 & permmask)) {
|
||||
ap_rprintf(r, "Fichier propriétaire<br/>\r\n");
|
||||
return (DECLINED);
|
||||
}
|
||||
|
||||
// If file is group readable and primary group match return content
|
||||
if ((fperm.st_gid==pw->pw_gid) && (fperm.st_mode & 0070 & permmask)) {
|
||||
ap_rprintf(r, "Fichier groupe<br/>\r\n");
|
||||
return (DECLINED);
|
||||
}
|
||||
|
||||
////////
|
||||
/* Check supplemental groups */
|
||||
/* Should include <grp.h> */
|
||||
//ap_rprintf(r, "Fichier propriétaire %d %d %o %o<br/>\r\n", fperm.st_uid, i, fperm.st_mode, 0400);
|
||||
gid_t grouplist[16];
|
||||
int grouplistsize = 16;
|
||||
int groupreturn;
|
||||
groupreturn = getgrouplist(user, pw->pw_gid, grouplist, &grouplistsize);
|
||||
if (groupreturn >= 0) {
|
||||
ap_rprintf(r, "OK liste des groupes (%d)<br/>\r\n", grouplistsize);
|
||||
for (int i=0; i<grouplistsize; i++) {
|
||||
ap_rprintf(r, "group: %d\r\n", grouplist[i]);
|
||||
// If file is group readable and match a supplemental group return content
|
||||
if ((fperm.st_gid==grouplist[i]) && (fperm.st_mode & 0070 & permmask)) {
|
||||
ap_rprintf(r, "Fichier groupe supplementaire<br/>\r\n");
|
||||
return (DECLINED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// else decline request
|
||||
ap_rprintf(r, "Aucuns droits de voir le fichier<br/>\r\n");
|
||||
apr_table_setn(r->err_headers_out,
|
||||
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
|
||||
: "WWW-Authenticate",
|
||||
apr_pstrcat(r->pool, "Basic realm=\"NON AUTHORISE", ap_auth_name(r),
|
||||
"\"", NULL));
|
||||
return HTTP_UNAUTHORIZED;
|
||||
|
||||
}
|
||||
/* AP_INIT_ITERATE("AuthBasicProvider", add_authn_provider, NULL, OR_AUTHCFG,
|
||||
"specify the auth providers for a directory or location"),*/
|
||||
AP_INIT_TAKE1("ABSECDefaultPerms", set_default_perms, NULL, OR_AUTHCFG,
|
||||
"Set to default octal value of perms "),
|
||||
AP_INIT_TAKE1("ABSECDefaultUID", set_default_uid, NULL, OR_AUTHCFG,
|
||||
"Set to default octal value of perms "),
|
||||
AP_INIT_TAKE1("ABSECDefaultGID", set_default_gid, NULL, OR_AUTHCFG,
|
||||
"Set to default octal value of perms "),
|
||||
/* AP_INIT_TAKE12("AuthBasicFake", add_basic_fake, NULL, OR_AUTHCFG,
|
||||
"Fake basic authentication using the given expressions for "
|
||||
"username and password, 'off' to disable. Password defaults "
|
||||
"to 'password' if missing."),
|
||||
AP_INIT_TAKE1("AuthBasicUseDigestAlgorithm", set_use_digest_algorithm,
|
||||
NULL, OR_AUTHCFG,
|
||||
"Set to 'MD5' to use the auth provider's authentication "
|
||||
"check for digest auth, using a hash of 'user:realm:pass'"),*/
|
||||
{NULL}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Validate user/pass
|
||||
// Validate authentification (user/pass)
|
||||
static authn_status authn_check_absec(request_rec *r, const char* user, const char* password)
|
||||
{
|
||||
ap_log_rerror("mod_absec.c", 269, 1, APLOG_ERR, APR_SUCCESS, r, "authn_check_absec : user : %s, pass : %s", user, password);
|
||||
@@ -302,13 +179,13 @@ static authn_status authn_check_absec(request_rec *r, const char* user, const ch
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Validate ressource access
|
||||
// Validate autorisation (ressource access)
|
||||
// request_rec contain user/pass if basic auth
|
||||
// it could also contain cookies if cookies based auth
|
||||
static authz_status authz_check_absec(request_rec *r, const char *require_args, const void *parsed_require_args)
|
||||
{
|
||||
char *user = r->user;
|
||||
ap_log_rerror("mod_absec.c", 282, 1, APLOG_ERR, APR_SUCCESS, r, "authz_check_absec : user : %s", user);
|
||||
ap_log_rerror("mod_absec.c", 342, 1, APLOG_ERR, APR_SUCCESS, r, "authz_check_absec : user : %s", user);
|
||||
|
||||
////////
|
||||
/* http method validate the perm asked (r/w vs get/post,put) */
|
||||
@@ -320,10 +197,18 @@ static authz_status authz_check_absec(request_rec *r, const char *require_args,
|
||||
if (strcmp(r->method,"POST")==0) permmask=0222; // w
|
||||
if (strcmp(r->method,"DELETE")==0) permmask=0111; // x
|
||||
|
||||
authnz_config_rec *cfg = ap_get_module_config(r->per_dir_config, &absec_module);
|
||||
struct stat fperm;
|
||||
fperm.st_mode = cfg->default_perms;
|
||||
ap_log_rerror("mod_absec.c", 329, 1, APLOG_ERR, APR_SUCCESS, r, "authz_check_absec : default perms : %o", cfg->default_perms);
|
||||
fperm.st_uid = cfg->default_uid;
|
||||
ap_log_rerror("mod_absec.c", 329, 1, APLOG_ERR, APR_SUCCESS, r, "authz_check_absec : default uid : %o", cfg->default_uid);
|
||||
fperm.st_gid = cfg->default_gid;
|
||||
ap_log_rerror("mod_absec.c", 329, 1, APLOG_ERR, APR_SUCCESS, r, "authz_check_absec : default gid : %o", cfg->default_gid);
|
||||
|
||||
////////
|
||||
/* check file permission on filesystem */
|
||||
/* should include <sys/stat.h> */
|
||||
struct stat fperm;
|
||||
int status;
|
||||
//status = stat(r->filename, &fperm);
|
||||
status = perms_lookup(r, &fperm);
|
||||
@@ -333,6 +218,7 @@ static authz_status authz_check_absec(request_rec *r, const char *require_args,
|
||||
ap_log_rerror("mod_absec.c", 282, 1, APLOG_ERR, APR_SUCCESS, r, "authz_check_absec : stat erreur %d", errno);
|
||||
return (OK);
|
||||
}
|
||||
|
||||
//ap_rprintf(r, "File perms %o, owner %d, group %d (status %d)<br/>\r\n", fperm.st_mode, fperm.st_uid, fperm.st_gid, status);
|
||||
|
||||
/* check if any permission (ogw) match method (get r, put/post w, delete x) */
|
||||
@@ -421,40 +307,15 @@ static const authz_provider authz_absec_provider =
|
||||
////////////////////////////////////////////////////////////////
|
||||
static void absec_register_hooks(apr_pool_t *p)
|
||||
{
|
||||
//ap_hook_handler(absec_handler, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
//ap_hook_handler(absec_handler_last, NULL, NULL, APR_HOOK_LAST);
|
||||
//ap_hook_handler(absec_handler_first, NULL, NULL, APR_HOOK_FIRST);
|
||||
|
||||
ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "absec", "0", &authn_absec_provider, AP_AUTH_INTERNAL_PER_CONF);
|
||||
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "absec", "0", &authz_absec_provider, AP_AUTH_INTERNAL_PER_CONF);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
static const command_rec absec_auth_basic_cmds[] =
|
||||
{
|
||||
/* AP_INIT_ITERATE("AuthBasicProvider", add_authn_provider, NULL, OR_AUTHCFG,
|
||||
"specify the auth providers for a directory or location"),
|
||||
AP_INIT_FLAG("AuthBasicAuthoritative", set_authoritative, NULL, OR_AUTHCFG,
|
||||
"Set to 'Off' to allow access control to be passed along to "
|
||||
"lower modules if the UserID is not known to this module"),
|
||||
AP_INIT_TAKE12("AuthBasicFake", add_basic_fake, NULL, OR_AUTHCFG,
|
||||
"Fake basic authentication using the given expressions for "
|
||||
"username and password, 'off' to disable. Password defaults "
|
||||
"to 'password' if missing."),
|
||||
AP_INIT_TAKE1("AuthBasicUseDigestAlgorithm", set_use_digest_algorithm,
|
||||
NULL, OR_AUTHCFG,
|
||||
"Set to 'MD5' to use the auth provider's authentication "
|
||||
"check for digest auth, using a hash of 'user:realm:pass'"),*/
|
||||
{NULL}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
/* Dispatch list for API hooks */
|
||||
module AP_MODULE_DECLARE_DATA absec_module;
|
||||
|
||||
AP_DECLARE_MODULE(absec) = {
|
||||
STANDARD20_MODULE_STUFF,
|
||||
NULL, /* create per-dir config structures */
|
||||
authnz_absec_config, /* create per-dir config structures */
|
||||
NULL, /* merge per-dir config structures */
|
||||
NULL, /* create per-server config structures */
|
||||
NULL, /* merge per-server config structures */
|
||||
|
||||
Reference in New Issue
Block a user