second pass cleanup code - pam ok with group
This commit is contained in:
+78
-112
@@ -86,64 +86,6 @@ int converse(int n, const struct pam_message **msg,
|
|||||||
// Return globally set response
|
// Return globally set response
|
||||||
*resp = reply;
|
*resp = reply;
|
||||||
return PAM_SUCCESS;
|
return PAM_SUCCESS;
|
||||||
|
|
||||||
// Real code for responding and asking user values
|
|
||||||
struct pam_response *aresp;
|
|
||||||
char buf[PAM_MAX_RESP_SIZE];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
data = data;
|
|
||||||
if (n <= 0 || n > PAM_MAX_NUM_MSG)
|
|
||||||
return (PAM_CONV_ERR);
|
|
||||||
if ((aresp = calloc(n, sizeof *aresp)) == NULL)
|
|
||||||
return (PAM_BUF_ERR);
|
|
||||||
for (i = 0; i < n; ++i) {
|
|
||||||
aresp[i].resp_retcode = 0;
|
|
||||||
aresp[i].resp = NULL;
|
|
||||||
switch (msg[i]->msg_style) {
|
|
||||||
case PAM_PROMPT_ECHO_OFF:
|
|
||||||
//aresp[i].resp = strdup("jlcyrpass01!");
|
|
||||||
aresp[i].resp = strdup(getpass(msg[i]->msg));
|
|
||||||
if (aresp[i].resp == NULL)
|
|
||||||
goto fail;
|
|
||||||
break;
|
|
||||||
case PAM_PROMPT_ECHO_ON:
|
|
||||||
fputs(msg[i]->msg, stderr);
|
|
||||||
if (fgets(buf, sizeof buf, stdin) == NULL)
|
|
||||||
goto fail;
|
|
||||||
aresp[i].resp = strdup(buf);
|
|
||||||
//aresp[i].resp = strdup("jlcyrpass01!");
|
|
||||||
if (aresp[i].resp == NULL)
|
|
||||||
goto fail;
|
|
||||||
break;
|
|
||||||
case PAM_ERROR_MSG:
|
|
||||||
fputs(msg[i]->msg, stderr);
|
|
||||||
if (strlen(msg[i]->msg) > 0 &&
|
|
||||||
msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n')
|
|
||||||
fputc('\n', stderr);
|
|
||||||
break;
|
|
||||||
case PAM_TEXT_INFO:
|
|
||||||
fputs(msg[i]->msg, stdout);
|
|
||||||
if (strlen(msg[i]->msg) > 0 &&
|
|
||||||
msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n')
|
|
||||||
fputc('\n', stdout);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*resp = aresp;
|
|
||||||
return (PAM_SUCCESS);
|
|
||||||
fail:
|
|
||||||
for (i = 0; i < n; ++i) {
|
|
||||||
if (aresp[i].resp != NULL) {
|
|
||||||
memset(aresp[i].resp, 0, strlen(aresp[i].resp));
|
|
||||||
free(aresp[i].resp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memset(aresp, 0, n * sizeof *aresp);
|
|
||||||
*resp = NULL;
|
|
||||||
return (PAM_CONV_ERR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
@@ -158,9 +100,21 @@ static int absec_handler_last(request_rec *r)
|
|||||||
if (strcmp(r->handler, "absec")) {
|
if (strcmp(r->handler, "absec")) {
|
||||||
return DECLINED;
|
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)
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
r->content_type = "text/html";
|
r->content_type = "text/html";
|
||||||
//ap_rprintf(r, "The sample page from mod_absec.c %s \n<br/>", r->args);
|
//ap_rprintf(r, "The sample page from mod_absec.c %s \n<br/>", r->args);
|
||||||
ap_rprintf(r, "After Url: %s from %s \n<br/>", r->filename, r->uri);
|
ap_rprintf(r, "After GET Url: %s from %s \n<br/>", r->filename, r->uri);
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,12 +147,11 @@ static int absec_handler_first(request_rec *r)
|
|||||||
/* check if any permission (ogw) match method (get r, put/post w, delete x) */
|
/* check if any permission (ogw) match method (get r, put/post w, delete x) */
|
||||||
if ((fperm.st_mode & permmask)==0) {
|
if ((fperm.st_mode & permmask)==0) {
|
||||||
/* no permission match, return don't even have to check user perms */
|
/* 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);
|
ap_rprintf(r, "Aucune permission pour la methode %s (%o, %o)", r->method, fperm.st_mode, permmask);
|
||||||
return (OK);
|
return (OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If file is world accessible for asked method return content
|
// If file is world accessible for asked method return content
|
||||||
// TODO : if put/post/delete, must check BEFORE ACTION not AFTER!!!
|
|
||||||
if (fperm.st_mode & 0x7 & permmask) {
|
if (fperm.st_mode & 0x7 & permmask) {
|
||||||
/* if so, return, no need to check user perms */
|
/* if so, return, no need to check user perms */
|
||||||
//ap_rprintf(r, "Fichier public<br/>\r\n");
|
//ap_rprintf(r, "Fichier public<br/>\r\n");
|
||||||
@@ -217,7 +170,7 @@ static int absec_handler_first(request_rec *r)
|
|||||||
apr_table_setn(r->err_headers_out,
|
apr_table_setn(r->err_headers_out,
|
||||||
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
|
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
|
||||||
: "WWW-Authenticate",
|
: "WWW-Authenticate",
|
||||||
apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r),
|
apr_pstrcat(r->pool, "Basic realm=\"PAS DE USER ", ap_auth_name(r),
|
||||||
"\"", NULL));
|
"\"", NULL));
|
||||||
return HTTP_UNAUTHORIZED;
|
return HTTP_UNAUTHORIZED;
|
||||||
}
|
}
|
||||||
@@ -231,29 +184,31 @@ static int absec_handler_first(request_rec *r)
|
|||||||
char *auth;
|
char *auth;
|
||||||
auth = apr_pcalloc(r->pool, 64);
|
auth = apr_pcalloc(r->pool, 64);
|
||||||
apr_base64_decode(auth, auth64);
|
apr_base64_decode(auth, auth64);
|
||||||
|
|
||||||
// Validate user/pass against unix cred
|
|
||||||
char *user;
|
char *user;
|
||||||
char *pass;
|
char *pass;
|
||||||
user = apr_strtok(auth, ":", &pass);
|
user = apr_strtok(auth, ":", &pass);
|
||||||
|
|
||||||
r->content_type = "text/html";
|
r->content_type = "text/html";
|
||||||
//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, "Url: %s from %s \n<br/>", r->filename, r->uri);
|
||||||
//ap_rprintf(r, "Headers Authorization: %s \n<br/>", auth64);
|
//ap_rprintf(r, "Headers Authorization: %s \n<br/>", auth64);
|
||||||
//ap_rprintf(r, "User/Pass: %s/%s \n<br/>", user, pass);
|
//ap_rprintf(r, "User/Pass: %s/%s \n<br/>", user, pass);
|
||||||
|
|
||||||
////////
|
////////
|
||||||
|
// Validate user/pass against unix cred
|
||||||
|
|
||||||
|
////////
|
||||||
// Get UID, GIDs for the user
|
// Get UID, GIDs for the user
|
||||||
/* Working example, but just UID not PW */
|
/* Working example, but just UID not PW */
|
||||||
|
/*
|
||||||
apr_status_t ret;
|
apr_status_t ret;
|
||||||
apr_uid_t i;
|
apr_uid_t i;
|
||||||
apr_gid_t g;
|
apr_gid_t g;
|
||||||
ret = apr_uid_get ( &i, &g, user, r->pool );
|
ret = apr_uid_get ( &i, &g, user, r->pool );
|
||||||
ap_rprintf(r, "Result2: G:%d, I:%d \n<br/>", g,i);
|
ap_rprintf(r, "Result2: G:%d, I:%d \n<br/>", g,i);
|
||||||
|
*/
|
||||||
|
|
||||||
////////
|
////////
|
||||||
/* Retrieve PW from /etc/passwd */
|
/* Retrieve PW (user details) from /etc/passwd */
|
||||||
/* Should include <pwd.h> */
|
/* Should include <pwd.h> */
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
if((pw = getpwnam(user)) == NULL)
|
if((pw = getpwnam(user)) == NULL)
|
||||||
@@ -262,14 +217,11 @@ static int absec_handler_first(request_rec *r)
|
|||||||
apr_table_setn(r->err_headers_out,
|
apr_table_setn(r->err_headers_out,
|
||||||
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
|
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
|
||||||
: "WWW-Authenticate",
|
: "WWW-Authenticate",
|
||||||
apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r),
|
apr_pstrcat(r->pool, "Basic realm=\"USER INCONNU ", ap_auth_name(r),
|
||||||
"\"", NULL));
|
"\"", NULL));
|
||||||
|
// User cannot be found, unauthorized
|
||||||
return HTTP_UNAUTHORIZED;
|
return HTTP_UNAUTHORIZED;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ap_rprintf(r, "Unix PW : %s \n<br/>", pw->pw_passwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////
|
////////
|
||||||
/* Retrieve PW from /etc/shadow */
|
/* Retrieve PW from /etc/shadow */
|
||||||
@@ -300,34 +252,6 @@ static int absec_handler_first(request_rec *r)
|
|||||||
return HTTP_UNAUTHORIZED;
|
return HTTP_UNAUTHORIZED;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// Connect to PAM to auth user
|
|
||||||
pam_handle_t * pamh = NULL;
|
|
||||||
int rret;
|
|
||||||
|
|
||||||
if((rret = pam_start("httpd", pw->pw_name, &conv, &pamh)) != PAM_SUCCESS) {
|
|
||||||
return HTTP_INTERNAL_SERVER_ERROR;
|
|
||||||
printf("Pam start failed\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the PAM callback function response (would call for password)
|
|
||||||
reply = (struct pam_response *)malloc(sizeof(struct pam_response));
|
|
||||||
reply[0].resp = strdup(pass); // password received in basic auth
|
|
||||||
reply[0].resp_retcode = 0;
|
|
||||||
|
|
||||||
if((rret = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
|
|
||||||
return HTTP_UNAUTHORIZED;
|
|
||||||
printf("User auth failed\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pam_end(pamh, rret) != PAM_SUCCESS) {
|
|
||||||
//perror("pam_end");
|
|
||||||
pamh = NULL;
|
|
||||||
return HTTP_INTERNAL_SERVER_ERROR;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////
|
////////
|
||||||
/* Encrypt and compare shadow password */
|
/* Encrypt and compare shadow password */
|
||||||
// TODO : Valider qu'on a un user
|
// TODO : Valider qu'on a un user
|
||||||
@@ -349,18 +273,55 @@ static int absec_handler_first(request_rec *r)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
////////
|
||||||
|
// Connect to PAM to auth user
|
||||||
|
pam_handle_t * pamh = NULL;
|
||||||
|
int rret;
|
||||||
|
|
||||||
|
if((rret = pam_start("httpd", user/*pw->pw_name*/, &conv, &pamh)) != PAM_SUCCESS) {
|
||||||
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
printf("Pam start failed\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the PAM callback function response (would call for password)
|
||||||
|
reply = (struct pam_response *)malloc(sizeof(struct pam_response));
|
||||||
|
reply[0].resp = strdup(pass); // password received in basic auth
|
||||||
|
reply[0].resp_retcode = 0;
|
||||||
|
|
||||||
|
if((rret = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
|
||||||
|
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=\"PASSWORD INVALIDE ", ap_auth_name(r),
|
||||||
|
"\"", NULL));
|
||||||
|
return HTTP_UNAUTHORIZED;
|
||||||
|
printf("User auth failed\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pam_end(pamh, rret) != PAM_SUCCESS) {
|
||||||
|
//perror("pam_end");
|
||||||
|
pamh = NULL;
|
||||||
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////
|
||||||
|
// Continue checking permission
|
||||||
|
|
||||||
// If file is user readable and user match return content
|
// If file is user readable and user match return content
|
||||||
if ((fperm.st_uid==i) && (fperm.st_mode & 0700 & permmask)) {
|
if ((fperm.st_uid==pw->pw_uid) && (fperm.st_mode & 0700 & permmask)) {
|
||||||
ap_rprintf(r, "Fichier propriétaire<br/>\r\n");
|
ap_rprintf(r, "Fichier propriétaire<br/>\r\n");
|
||||||
return (DECLINED);
|
return (DECLINED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If file is group readable and primary group match return content
|
// If file is group readable and primary group match return content
|
||||||
if ((fperm.st_gid==g) && (fperm.st_mode & 0070 & permmask)) {
|
if ((fperm.st_gid==pw->pw_gid) && (fperm.st_mode & 0070 & permmask)) {
|
||||||
ap_rprintf(r, "Fichier groupe<br/>\r\n");
|
ap_rprintf(r, "Fichier groupe<br/>\r\n");
|
||||||
return (DECLINED);
|
return (DECLINED);
|
||||||
}
|
}
|
||||||
return HTTP_OK;
|
|
||||||
|
|
||||||
////////
|
////////
|
||||||
/* Check supplemental groups */
|
/* Check supplemental groups */
|
||||||
@@ -368,11 +329,11 @@ static int absec_handler_first(request_rec *r)
|
|||||||
//ap_rprintf(r, "Fichier propriétaire %d %d %o %o<br/>\r\n", fperm.st_uid, i, fperm.st_mode, 0400);
|
//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];
|
gid_t grouplist[16];
|
||||||
int grouplistsize = 16;
|
int grouplistsize = 16;
|
||||||
int *groupreturn;
|
int groupreturn;
|
||||||
groupreturn = getgrouplist("jlcyr", g, grouplist, &grouplistsize);
|
groupreturn = getgrouplist(user, pw->pw_gid, grouplist, &grouplistsize);
|
||||||
if (groupreturn != -1) {
|
if (groupreturn >= 0) {
|
||||||
ap_rprintf(r, "OK liste des groupes (%d)<br/>\r\n", grouplistsize);
|
ap_rprintf(r, "OK liste des groupes (%d)<br/>\r\n", grouplistsize);
|
||||||
for (i=0; i<grouplistsize; i++) {
|
for (int i=0; i<grouplistsize; i++) {
|
||||||
ap_rprintf(r, "group: %d\r\n", grouplist[i]);
|
ap_rprintf(r, "group: %d\r\n", grouplist[i]);
|
||||||
// If file is group readable and match a supplemental group return content
|
// If file is group readable and match a supplemental group return content
|
||||||
if ((fperm.st_gid==grouplist[i]) && (fperm.st_mode & 0070 & permmask)) {
|
if ((fperm.st_gid==grouplist[i]) && (fperm.st_mode & 0070 & permmask)) {
|
||||||
@@ -381,19 +342,24 @@ static int absec_handler_first(request_rec *r)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ap_rprintf(r, "Erreur<br/>\r\n");
|
/* ap_rprintf(r, "Erreur pas de groupe supplementaires? (code %d)<br/>\r\n", groupreturn);
|
||||||
return OK;
|
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=\"", ap_auth_name(r),
|
||||||
|
"\"", NULL));
|
||||||
|
return HTTP_UNAUTHORIZED;
|
||||||
|
*/ }
|
||||||
|
|
||||||
// else decline
|
// else decline request
|
||||||
ap_rprintf(r, "Aucuns droits de voir le fichier<br/>\r\n");
|
ap_rprintf(r, "Aucuns droits de voir le fichier<br/>\r\n");
|
||||||
apr_table_setn(r->err_headers_out,
|
apr_table_setn(r->err_headers_out,
|
||||||
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
|
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
|
||||||
: "WWW-Authenticate",
|
: "WWW-Authenticate",
|
||||||
apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r),
|
apr_pstrcat(r->pool, "Basic realm=\"NON AUTHORISE", ap_auth_name(r),
|
||||||
"\"", NULL));
|
"\"", NULL));
|
||||||
return HTTP_UNAUTHORIZED;
|
return HTTP_UNAUTHORIZED;
|
||||||
return OK;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user