second pass cleanup code - pam ok with group

This commit is contained in:
2018-07-04 13:59:09 -04:00
parent 5620977d66
commit 4af405a4de
+79 -113
View File
@@ -86,64 +86,6 @@ int converse(int n, const struct pam_message **msg,
// Return globally set response
*resp = reply;
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")) {
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";
//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);
}
@@ -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) */
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);
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
// TODO : if put/post/delete, must check BEFORE ACTION not AFTER!!!
if (fperm.st_mode & 0x7 & permmask) {
/* if so, return, no need to check user perms */
//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,
(PROXYREQ_PROXY == r->proxyreq) ? "Proxy-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));
return HTTP_UNAUTHORIZED;
}
@@ -231,29 +184,31 @@ static int absec_handler_first(request_rec *r)
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);
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, "Headers Authorization: %s \n<br/>", auth64);
//ap_rprintf(r, "User/Pass: %s/%s \n<br/>", user, pass);
////////
// Validate user/pass against unix cred
////////
// Get UID, GIDs for the user
/* 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 */
/* Retrieve PW (user details) from /etc/passwd */
/* Should include <pwd.h> */
struct passwd *pw;
if((pw = getpwnam(user)) == NULL)
@@ -262,14 +217,11 @@ static int absec_handler_first(request_rec *r)
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),
apr_pstrcat(r->pool, "Basic realm=\"USER INCONNU ", ap_auth_name(r),
"\"", NULL));
// User cannot be found, unauthorized
return HTTP_UNAUTHORIZED;
}
else
{
ap_rprintf(r, "Unix PW : %s \n<br/>", pw->pw_passwd);
}
////////
/* Retrieve PW from /etc/shadow */
@@ -300,34 +252,6 @@ static int absec_handler_first(request_rec *r)
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 */
// 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 ((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");
return (DECLINED);
}
// 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");
return (DECLINED);
}
return HTTP_OK;
////////
/* 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);
gid_t grouplist[16];
int grouplistsize = 16;
int *groupreturn;
groupreturn = getgrouplist("jlcyr", g, grouplist, &grouplistsize);
if (groupreturn != -1) {
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 (i=0; i<grouplistsize; i++) {
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)) {
@@ -381,19 +342,24 @@ static int absec_handler_first(request_rec *r)
}
}
} else {
ap_rprintf(r, "Erreur<br/>\r\n");
return OK;
}
// else decline
ap_rprintf(r, "Aucuns droits de voir le fichier<br/>\r\n");
/* ap_rprintf(r, "Erreur pas de groupe supplementaires? (code %d)<br/>\r\n", groupreturn);
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;
return OK;
*/ }
// 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;
}