diff --git a/mod_absec.c b/mod_absec.c index bbe3d4a..8c013d7 100644 --- a/mod_absec.c +++ b/mod_absec.c @@ -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
\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
"); + return (DECLINED); + } + r->content_type = "text/html"; //ap_rprintf(r, "The sample page from mod_absec.c %s \n
", r->args); - ap_rprintf(r, "After Url: %s from %s \n
", r->filename, r->uri); + ap_rprintf(r, "After GET Url: %s from %s \n
", 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
\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
", 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); //////// + // 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
", g,i); + */ //////// - /* Retrieve PW from /etc/passwd */ + /* Retrieve PW (user details) from /etc/passwd */ /* Should include */ 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
", 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
\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
\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
\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)
\r\n", grouplistsize); - for (i=0; i\r\n"); - return OK; - } +/* ap_rprintf(r, "Erreur pas de groupe supplementaires? (code %d)
\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; +*/ } - // else decline + // else decline request ap_rprintf(r, "Aucuns droits de voir le fichier
\r\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), + apr_pstrcat(r->pool, "Basic realm=\"NON AUTHORISE", ap_auth_name(r), "\"", NULL)); return HTTP_UNAUTHORIZED; - return OK; }