Compare commits

...

6 Commits

Author SHA1 Message Date
jlcyr 154d770cf3 readme 2018-11-13 16:55:01 -05:00
jlcyr 0d45628f74 start cleanup test_authen with absec_pam and absec_etc 2018-11-13 14:35:41 -05:00
jlcyr 66f9fedca7 Merge branch 'master' of https://source.mescours.ca/ADN/Maitrise/projet
# Conflicts:
#	mod_absec.c
2018-11-13 14:32:44 -05:00
jlcyr ca90192f52 commit all files, will need cleanup later. 2018-11-13 14:29:46 -05:00
jlcyr e2b3cda59f added back mysql database perms from pam version 2018-09-06 10:14:12 -04:00
jlcyr d4f921b6e3 split before/after 2018-07-03 15:24:02 -04:00
20 changed files with 2085 additions and 121 deletions
+1
View File
@@ -15,6 +15,7 @@ APACHECTL=apachectl
#DEFS=-Dmy_define=my_value #DEFS=-Dmy_define=my_value
#INCLUDES=-Imy/include/dir #INCLUDES=-Imy/include/dir
#LIBS=-Lmy/lib/dir -lmylib #LIBS=-Lmy/lib/dir -lmylib
LIBS=absec_pam
# the default target # the default target
all: local-shared-build all: local-shared-build
+20
View File
@@ -0,0 +1,20 @@
////////
//
// header file for authentification
// used either for absec_etc or absec_pam
//
// author: Jean-Luc Cyr
// date: 2018-10
//
// usage: include this file as header definition
// then link the program with either -labsec_etc or -labsec_pam
//
#define PAM_OK 0
#define PAM_ERROR_START -1
#define PAM_ERROR_INVALID_CRED -2
#define PAM_ERROR_STOP -3
#define HTTP_UNAUTHORIZED 401
#define OK 200
int check_user(char* user, char* pass);
+114
View File
@@ -0,0 +1,114 @@
/////
//
// File : absec_etc.c
// Author : Jean-Luc Cyr
// Date : 2018-10
//
// Description: Using /etc/passwd, /etc/shadow, /etc/group as authentification method
//
// Note : doc for using APR in code : https://people.apache.org/~rooneg/talks/portable-c-with-apr/apr.html
//
#include "absec_authen.h"
//#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 <grp.h>
#include <sys/types.h>
#include <unistd.h>
#include <crypt.h>
#include "apr_want.h"
#include <shadow.h>
#include <sys/stat.h>
////////////////////////////////////////////////////////////////
// Unix file based auth
int check_user(char* user, char* pass) {
////////
// 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;
apr_pool_t *pool;
apr_initialize();
apr_pool_create(&pool, NULL);
ret = apr_uid_get( &i, &g, user, pool );
printf( "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)
{
printf( "NULL \n<br/>");
return HTTP_UNAUTHORIZED;
}
else
{
printf( "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)
{
printf("NULL %d\n<br/>", errno);
return HTTP_UNAUTHORIZED;
}
else
{
printf( "Shadow PW : %s \n<br/>", spw->sp_pwdp);
}
if (spw->sp_pwdp[0] == 'x' || spw->sp_pwdp[0] == '*' || spw->sp_pwdp[0] == '!') {
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);
printf("compare pw : %s \n<br/>", encrypted);;
printf("compare : %d \n<br/>", rrr);
if (rrr!=0) {
return HTTP_UNAUTHORIZED;
}
// now check supplemental groups
gid_t grouplist[16];
int grouplistsize = 16;
int groupreturn;
groupreturn = getgrouplist("jlcyr", g, grouplist, &grouplistsize);
if (groupreturn != -1) {
printf( "OK liste des groupes (%d)<br/>\r\n", grouplistsize);
for (i=0; i<grouplistsize; i++) {
printf("group: %d\r\n", grouplist[i]);
// If file is group readable and match a supplemental group return content
}
} else {
printf( "Erreur<br/>\r\n");
return OK;
}
}
+10
View File
@@ -0,0 +1,10 @@
#define PAM_OK 0
#define PAM_ERROR_START -1
#define PAM_ERROR_INVALID_CRED -2
#define PAM_ERROR_STOP -3
#define HTTP_UNAUTHORIZED 401
#define OK 200
int check_user(char* user, char* pass);
+92
View File
@@ -0,0 +1,92 @@
#include <stdio.h>
#include <string.h>
#include <mysql.h>
////////////////////////////////////////////////////////////////
// define PAM callback function
char* perms_to_string(int perms)
{
char* pstring;
pstring = malloc(11);
memcpy(pstring, "----------\0", 11);
if (perms & 1) pstring[9] = 'x';
if (perms & 2) pstring[8] = 'w';
if (perms & 4) pstring[7] = 'r';
if (perms & 8) pstring[6] = 'x';
if (perms & 16) pstring[5] = 'w';
if (perms & 32) pstring[4] = 'r';
if (perms & 64) pstring[3] = 'x';
if (perms & 128) pstring[2] = 'w';
if (perms & 128) pstring[1] = 'r';
//printf("%s", pstring);
return pstring;
}
////////////////////////////////////////////////////////////////
// define PAM callback function
int mysql_lookup()//request_rec *r, struct stat *fperm)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "localhost";
char *user = "jlcyr";
char *password = "password"; /* set me first */
char *database = "absec";
conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
printf("%s\n", mysql_error(conn));
return(0);
}
char query[256];
sprintf(query, "select * from urls"); // where url='%s'", r->uri);
/* send SQL query */
//if (mysql_query(conn, "show tables")) {
if (mysql_query(conn, query)) {
printf("%s\n", mysql_error(conn));
return(-1);
}
res = mysql_use_result(conn);
/* output table name */
printf("ABSEC permissions\n");
int cnt = 0;
while ((row = mysql_fetch_row(res)) != NULL) {
printf("%s\t%d\t%d\t%s \n", perms_to_string(atoi(row[3])), atoi(row[1]), atoi(row[2]), row[0] );
/*fperm->st_uid = atoi(row[1]);
fperm->st_gid = atoi(row[2]);
fperm->st_mode = atoi(row[3]);*/
cnt = cnt + 1;
}
/*if (cnt==0) {
sprintf(query, "insert into urls (url, uid, gid, perms) values ('%s', 0, 0, 0)", r->uri);
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
ap_rprintf(r, "Aucune donnee\n<br/>");
}*/
/* close connection */
mysql_free_result(res);
mysql_close(conn);
return(0);
}
void main(int argc, char** argv)
{
mysql_lookup();
}
+64
View File
@@ -0,0 +1,64 @@
#include <mysql.h>
#include <sys/stat.h>
#include "httpd.h"
////////////////////////////////////////////////////////////////
//
int mysql_lookup(request_rec *r, struct stat *fperm)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "localhost";
char *user = "jlcyr";
char *password = "password"; /* set me first */
char *database = "absec";
conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
printf("%s\n", mysql_error(conn));
return(0);
}
char query[256];
sprintf(query, "select * from urls where url='%s'", r->uri);
/* send SQL query */
//if (mysql_query(conn, "show tables")) {
if (mysql_query(conn, query)) {
printf("%s\n", mysql_error(conn));
return(-1);
}
res = mysql_use_result(conn);
/* output table name */
printf("MySQL data:\n<br/>");
int cnt = 0;
while ((row = mysql_fetch_row(res)) != NULL) {
printf("%s %d %d %o \n<br/>", row[0], atoi(row[1]), atoi(row[2]), atoi(row[3]));
fperm->st_uid = atoi(row[1]);
fperm->st_gid = atoi(row[2]);
fperm->st_mode = atoi(row[3]);
cnt = cnt + 1;
}
if (cnt==0) {
sprintf(query, "insert into urls (url, uid, gid, perms) values ('%s', 0, 0, 0)", r->uri);
if (mysql_query(conn, query)) {
printf("%s\n", mysql_error(conn));
return(0);
}
printf("Aucune donnee\n<br/>");
}
/* close connection */
mysql_free_result(res);
mysql_close(conn);
return(0);
}
+3
View File
@@ -0,0 +1,3 @@
int mysql_lookup(request_rec *r, struct stat *fperm);
+66
View File
@@ -0,0 +1,66 @@
#include "absec_authen.h"
#include <security/pam_appl.h>
#include <security/pam_misc.h>
////////////////////////////////////////////////////////////////
/* Check user autentication against unix user/pass */
/*static int check_autentication(request_rec *r)
{
return 0;
}*/
////////////////////////////////////////////////////////////////
/* Check check file perms */
/*static int check_autorization(request_rec *r)
{
return 0;
}*/
// Global var for passing fake response to PAM callback
struct pam_response *reply;
////////////////////////////////////////////////////////////////
// PAM response callback function
int converse(int n, const struct pam_message **msg,
struct pam_response **resp, void *data)
{
// Return globally set response
*resp = reply;
return PAM_SUCCESS;
}
////////////////////////////////////////////////////////////////
// define PAM callback function
struct pam_conv conv = { converse, 0 };
int check_user(char* user, char* pass) {
////////
// Connect to PAM to auth user
pam_handle_t * pamh = NULL;
int rret;
if((rret = pam_start("httpd", user, &conv, &pamh)) != PAM_SUCCESS) {
return PAM_ERROR_START;
}
// 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 PAM_ERROR_INVALID_CRED;
}
if(pam_end(pamh, rret) != PAM_SUCCESS) {
}
}
////////////////////////////////////////////////////////////////
/*void main(int argc, char** argv) {
printf("absec_pam OK\n");
exit(0);
}*/
+7
View File
@@ -0,0 +1,7 @@
#define PAM_OK 0
#define PAM_ERROR_START -1
#define PAM_ERROR_INVALID_CRED -2
#define PAM_ERROR_STOP -3
int check_user(char* user, char* pass);
+81 -1
View File
@@ -1,4 +1,84 @@
#!/bin/bash
echo "----------------"
echo "Cleaning projets"
rm -fv *.o *.lo *.la *.slo
echo "----------------"
echo "Compiling pam module (absec_pam)"
#/home/jlcyr/apache2/bin/apxs -lpam -lpam_misc `mysql_config --cflags --libs` -c -i mod_absec.c #/home/jlcyr/apache2/bin/apxs -lpam -lpam_misc `mysql_config --cflags --libs` -c -i mod_absec.c
sudo apxs -lpam -lpam_misc `mysql_config --cflags --libs` -c -i mod_absec.c #gcc -fPIC -c -lpam -lpam_misc -o absec_pam.o absec_pam.c
#gcc absec_pam.c -lpam -lpam_misc -o absec_pam
gcc absec_pam.c -lpam -lpam_misc -c
#ld -lpam -lpam_misc --shared -o absec_pam absec_pam.o
#./absec_pam
#exit
echo "----------------"
echo "Compiling authen test with pam (test_authen -labsec_pam)"
#/home/jlcyr/apache2/bin/apxs -lpam -lpam_misc `mysql_config --cflags --libs` -c -i mod_absec.c
gcc test_authen.c absec_pam.o -lpam -lpam_misc -o test_authen
#gcc -o test_pam -lpam -lpam_misc absec_pam.o test_pam.c
#ld -o test_pam -lc --entry main test_pam.o
#ld -lpam -lpam_misc --shared -o test_pam absec_pam.o test_pam.o
echo "Running test"
./test_authen
echo "----------------"
echo "Compiling etc module (absec_etc)"
#/home/jlcyr/apache2/bin/apxs -lpam -lpam_misc `mysql_config --cflags --libs` -c -i mod_absec.c
#gcc -fPIC -c -lpam -lpam_misc -o absec_pam.o absec_pam.c
#gcc absec_pam.c -lpam -lpam_misc -o absec_pam
gcc -I /usr/local/apache2/include -I /usr/include/apr-1.0 absec_etc.c -c
echo "----------------"
echo "Compiling authen test with etc (test_authen -labsec_etc)"
#/home/jlcyr/apache2/bin/apxs -lpam -lpam_misc `mysql_config --cflags --libs` -c -i mod_absec.c
gcc test_authen.c absec_etc.o -L/usr/lib/x86_64-linux-gnu -lapr-1 -lcrypt -o test_authen
#gcc -o test_pam -lpam -lpam_misc absec_pam.o test_pam.c
#ld -o test_pam -lc --entry main test_pam.o
#ld -lpam -lpam_misc --shared -o test_pam absec_pam.o test_pam.o
echo "Running test"
./test_authen
echo "----------------"
echo "Compiling mysql module"
#/home/jlcyr/apache2/bin/apxs -lpam -lpam_misc `mysql_config --cflags --libs` -c -i mod_absec.c
#gcc -fPIC -c -lpam -lpam_misc -o absec_pam.o absec_pam.c
#gcc absec_pam.c -lpam -lpam_misc -o absec_pam
gcc absec_mysql.c `mysql_config --cflags --libs` -I/usr/include/apache2 -I/usr/include/apr-1.0 -c
#ld -lpam -lpam_misc --shared -o absec_pam absec_pam.o
#./absec_pam
#exit
echo "----------------"
echo "Compiling autho test with mysql"
#/home/jlcyr/apache2/bin/apxs -lpam -lpam_misc `mysql_config --cflags --libs` -c -i mod_absec.c
gcc test_mysql.c absec_mysql.o -lpam -lpam_misc `mysql_config --cflags --libs` -o test_mysql
#gcc -o test_pam -lpam -lpam_misc absec_pam.o test_pam.c
#ld -o test_pam -lc --entry main test_pam.o
#ld -lpam -lpam_misc --shared -o test_pam absec_pam.o test_pam.o
echo "Running test"
./test_mysql
echo "----------------"
echo "Compiling absec tools"
echo "- absec_ls"
#/home/jlcyr/apache2/bin/apxs -lpam -lpam_misc `mysql_config --cflags --libs` -c -i mod_absec.c
gcc absec_ls.c `mysql_config --cflags --libs` -o abls
#gcc -o test_pam -lpam -lpam_misc absec_pam.o test_pam.c
#ld -o test_pam -lc --entry main test_pam.o
#ld -lpam -lpam_misc --shared -o test_pam absec_pam.o test_pam.o
echo "Running test"
./abls
exit
echo "----------------"
echo "Compiling absec module"
sudo apxs -lpam -lpam_misc `mysql_config --cflags --libs` -c -i absec_pam.o absec_mysql.o mod_absec.c
#/home/jlcyr/apache2/bin/apachectl restart #/home/jlcyr/apache2/bin/apachectl restart
sudo /etc/init.d/apache2 restart sudo /etc/init.d/apache2 restart
+7 -120
View File
@@ -58,100 +58,8 @@
#include <shadow.h> #include <shadow.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <security/pam_appl.h> #include "absec_pam.h"
#include <security/pam_misc.h> #include "absec_mysql.h"
#include <mysql.h>
////////////////////////////////////////////////////////////////
/* Check user autentication against unix user/pass */
static int check_autentication(request_rec *r)
{
return 0;
}
////////////////////////////////////////////////////////////////
/* Check check file perms */
static int check_autorization(request_rec *r)
{
return 0;
}
// Global var for passing fake response to PAM callback
struct pam_response *reply;
////////////////////////////////////////////////////////////////
// PAM response callback function
int converse(int n, const struct pam_message **msg,
struct pam_response **resp, void *data)
{
// Return globally set response
*resp = reply;
return PAM_SUCCESS;
}
////////////////////////////////////////////////////////////////
// define PAM callback function
struct pam_conv conv = { converse, 0 };
////////////////////////////////////////////////////////////////
// define PAM callback function
int mysql_lookup(request_rec *r, struct stat *fperm)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "localhost";
char *user = "jlcyr";
char *password = "password"; /* set me first */
char *database = "absec";
conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
char query[256];
sprintf(query, "select * from urls where url='%s'", r->uri);
/* send SQL query */
//if (mysql_query(conn, "show tables")) {
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(-1);
}
res = mysql_use_result(conn);
/* output table name */
ap_rprintf(r, "MySQL data:\n<br/>");
int cnt = 0;
while ((row = mysql_fetch_row(res)) != NULL) {
ap_rprintf(r, "%s %d %d %o \n<br/>", row[0], atoi(row[1]), atoi(row[2]), atoi(row[3]));
fperm->st_uid = atoi(row[1]);
fperm->st_gid = atoi(row[2]);
fperm->st_mode = atoi(row[3]);
cnt = cnt + 1;
}
if (cnt==0) {
sprintf(query, "insert into urls (url, uid, gid, perms) values ('%s', 0, 0, 0)", r->uri);
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
ap_rprintf(r, "Aucune donnee\n<br/>");
}
/* close connection */
mysql_free_result(res);
mysql_close(conn);
return(0);
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/* Main routine - called after request processing */ /* Main routine - called after request processing */
@@ -206,8 +114,8 @@ static int absec_handler_first(request_rec *r)
/* should include <sys/stat.h> */ /* should include <sys/stat.h> */
struct stat fperm; struct stat fperm;
int status; int status;
//status = stat(r->filename, &fperm); status = stat(r->filename, &fperm);
status = mysql_lookup(r, &fperm); //status = mysql_lookup(r, &fperm);
//ap_rprintf(r, "Result mysql: %d<br/>\r\n", ); //ap_rprintf(r, "Result mysql: %d<br/>\r\n", );
if (status==-1) { if (status==-1) {
ap_rprintf(r, "stat erreur %d", errno); ap_rprintf(r, "stat erreur %d", errno);
@@ -264,23 +172,11 @@ static int absec_handler_first(request_rec *r)
//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);
//////// int pam_result = pam_check_user(user, pass);
// Connect to PAM to auth user if ( (pam_result==PAM_ERROR_START) || (pam_result==PAM_ERROR_STOP) ) {
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; return HTTP_INTERNAL_SERVER_ERROR;
printf("Pam start failed\n");
exit(0);
} }
if (pam_result==PAM_ERROR_INVALID_CRED) {
// 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"; r->content_type = "text/html";
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"
@@ -288,15 +184,6 @@ static int absec_handler_first(request_rec *r)
apr_pstrcat(r->pool, "Basic realm=\"USER/PASS INVALIDE ", ap_auth_name(r), apr_pstrcat(r->pool, "Basic realm=\"USER/PASS INVALIDE ", ap_auth_name(r),
"\"", NULL)); "\"", NULL));
return HTTP_UNAUTHORIZED; 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);
} }
//////// ////////
+378
View File
@@ -0,0 +1,378 @@
/*
** 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
**
*/
/*
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 <grp.h>
#include <sys/types.h>
#include <unistd.h>
#include "apr_want.h"
#include <shadow.h>
#include <sys/stat.h>
#include <mysql.h>
////////////////////////////////////////////////////////////////
/* Check user autentication against unix user/pass */
static int check_autentication(request_rec *r)
{
return 0;
}
////////////////////////////////////////////////////////////////
/* Check check file perms */
static int check_autorization(request_rec *r)
{
return 0;
}
////////////////////////////////////////////////////////////////
// define PAM callback function
int mysql_lookup(request_rec *r, struct stat *fperm)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "localhost";
char *user = "jlcyr";
char *password = "password"; /* set me first */
char *database = "absec";
conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
char query[256];
sprintf(query, "select * from urls where url='%s'", r->uri);
/* send SQL query */
//if (mysql_query(conn, "show tables")) {
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(-1);
}
res = mysql_use_result(conn);
/* output table name */
ap_rprintf(r, "MySQL data:\n<br/>");
int cnt = 0;
while ((row = mysql_fetch_row(res)) != NULL) {
ap_rprintf(r, "%s %d %d %o \n<br/>", row[0], atoi(row[1]), atoi(row[2]), atoi(row[3]));
fperm->st_uid = atoi(row[1]);
fperm->st_gid = atoi(row[2]);
fperm->st_mode = atoi(row[3]);
cnt = cnt + 1;
}
if (cnt==0) {
sprintf(query, "insert into urls (url, uid, gid, perms) values ('%s', 0, 0, 0)", r->uri);
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
ap_rprintf(r, "Aucune donnee\n<br/>");
}
/* close connection */
mysql_free_result(res);
mysql_close(conn);
return(0);
}
////////////////////////////////////////////////////////////////
/* Main routine */
static int absec_handler_last(request_rec *r)
{
// Is this module really called?
if (strcmp(r->handler, "absec")) {
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);
return (OK);
}
////////////////////////////////////////////////////////////////
/* Main routine */
static int absec_handler_first(request_rec *r)
{
// Is this module really called?
if (strcmp(r->handler, "absec")) {
return DECLINED;
}
////////
/* http method validate the perm asked (r/w vs get/post,put) */
ap_rprintf(r, "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 = mysql_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
// 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");
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=\"", 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);
// 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);
////////
// 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 */
/* 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;
}
// If file is user readable and user match return content
if ((fperm.st_uid==i) && (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)) {
ap_rprintf(r, "Fichier groupe<br/>\r\n");
return (DECLINED);
}
// now check supplemental groups
//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) {
ap_rprintf(r, "OK liste des groupes (%d)<br/>\r\n", grouplistsize);
for (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 {
ap_rprintf(r, "Erreur<br/>\r\n");
return OK;
}
// else decline
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=\"", ap_auth_name(r),
"\"", NULL));
return HTTP_UNAUTHORIZED;
return OK;
}
////////////////////////////////////////////////////////////////
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);
}
////////////////////////////////////////////////////////////////
/* 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 */
};
+378
View File
@@ -0,0 +1,378 @@
/*
** 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
**
*/
/*
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 <grp.h>
#include <sys/types.h>
#include <unistd.h>
#include "apr_want.h"
#include <shadow.h>
#include <sys/stat.h>
#include <mysql.h>
////////////////////////////////////////////////////////////////
/* Check user autentication against unix user/pass */
static int check_autentication(request_rec *r)
{
return 0;
}
////////////////////////////////////////////////////////////////
/* Check check file perms */
static int check_autorization(request_rec *r)
{
return 0;
}
////////////////////////////////////////////////////////////////
// define PAM callback function
int mysql_lookup(request_rec *r, struct stat *fperm)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "localhost";
char *user = "jlcyr";
char *password = "password"; /* set me first */
char *database = "absec";
conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
char query[256];
sprintf(query, "select * from urls where url='%s'", r->uri);
/* send SQL query */
//if (mysql_query(conn, "show tables")) {
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(-1);
}
res = mysql_use_result(conn);
/* output table name */
ap_rprintf(r, "MySQL data:\n<br/>");
int cnt = 0;
while ((row = mysql_fetch_row(res)) != NULL) {
ap_rprintf(r, "%s %d %d %o \n<br/>", row[0], atoi(row[1]), atoi(row[2]), atoi(row[3]));
fperm->st_uid = atoi(row[1]);
fperm->st_gid = atoi(row[2]);
fperm->st_mode = atoi(row[3]);
cnt = cnt + 1;
}
if (cnt==0) {
sprintf(query, "insert into urls (url, uid, gid, perms) values ('%s', 0, 0, 0)", r->uri);
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
ap_rprintf(r, "Aucune donnee\n<br/>");
}
/* close connection */
mysql_free_result(res);
mysql_close(conn);
return(0);
}
////////////////////////////////////////////////////////////////
/* Main routine */
static int absec_handler_last(request_rec *r)
{
// Is this module really called?
if (strcmp(r->handler, "absec")) {
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);
return (OK);
}
////////////////////////////////////////////////////////////////
/* Main routine */
static int absec_handler_first(request_rec *r)
{
// Is this module really called?
if (strcmp(r->handler, "absec")) {
return DECLINED;
}
////////
/* http method validate the perm asked (r/w vs get/post,put) */
ap_rprintf(r, "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 = mysql_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
// 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");
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=\"", 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);
// 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);
////////
// 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 */
/* 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;
}
// If file is user readable and user match return content
if ((fperm.st_uid==i) && (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)) {
ap_rprintf(r, "Fichier groupe<br/>\r\n");
return (DECLINED);
}
// now check supplemental groups
//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) {
ap_rprintf(r, "OK liste des groupes (%d)<br/>\r\n", grouplistsize);
for (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 {
ap_rprintf(r, "Erreur<br/>\r\n");
return OK;
}
// else decline
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=\"", ap_auth_name(r),
"\"", NULL));
return HTTP_UNAUTHORIZED;
return OK;
}
////////////////////////////////////////////////////////////////
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);
}
////////////////////////////////////////////////////////////////
/* 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 */
};
+388
View File
@@ -0,0 +1,388 @@
/*
** mod_absec.c -- Apache absec module
** [base 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 -lpam -lpam_misc -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
**
*/
/*
TEST URL
http://10.211.55.15/absec/<fichier>
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 <grp.h>
#include <sys/types.h>
#include <unistd.h>
#include "apr_want.h"
#include <shadow.h>
#include <sys/stat.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <mysql.h>
////////////////////////////////////////////////////////////////
/* Check user autentication against unix user/pass */
static int check_autentication(request_rec *r)
{
return 0;
}
////////////////////////////////////////////////////////////////
/* Check check file perms */
static int check_autorization(request_rec *r)
{
return 0;
}
// Global var for passing fake response to PAM callback
struct pam_response *reply;
////////////////////////////////////////////////////////////////
// PAM response callback function
int converse(int n, const struct pam_message **msg,
struct pam_response **resp, void *data)
{
// Return globally set response
*resp = reply;
return PAM_SUCCESS;
}
////////////////////////////////////////////////////////////////
// define PAM callback function
struct pam_conv conv = { converse, 0 };
////////////////////////////////////////////////////////////////
// define PAM callback function
int mysql_lookup(request_rec *r, struct stat *fperm)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "localhost";
char *user = "jlcyr";
char *password = "password"; /* set me first */
char *database = "absec";
conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
char query[256];
sprintf(query, "select * from urls where url='%s'", r->uri);
/* send SQL query */
//if (mysql_query(conn, "show tables")) {
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(-1);
}
res = mysql_use_result(conn);
/* output table name */
ap_rprintf(r, "MySQL data:\n<br/>");
int cnt = 0;
while ((row = mysql_fetch_row(res)) != NULL) {
ap_rprintf(r, "%s %d %d %o \n<br/>", row[0], atoi(row[1]), atoi(row[2]), atoi(row[3]));
fperm->st_uid = atoi(row[1]);
fperm->st_gid = atoi(row[2]);
fperm->st_mode = atoi(row[3]);
cnt = cnt + 1;
}
if (cnt==0) {
sprintf(query, "insert into urls (url, uid, gid, perms) values ('%s', 0, 0, 0)", r->uri);
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
ap_rprintf(r, "Aucune donnee\n<br/>");
}
/* close connection */
mysql_free_result(res);
mysql_close(conn);
return(0);
}
////////////////////////////////////////////////////////////////
/* Main routine - called after request processing */
static int absec_handler_last(request_rec *r)
{
// Is this module really called?
if (strcmp(r->handler, "absec")) {
return DECLINED;
}
////////
/* 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)
{
// 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 GET Url: %s from %s \n<br/>", r->filename, r->uri);
return (DECLINED);
}
////////////////////////////////////////////////////////////////
/* Main routine - called before request processing */
static int absec_handler_first(request_rec *r)
{
ap_rprintf(r, "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 = mysql_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);
////////
// 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=\"USER/PASS 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
////////
/* 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;
}
////////////////////////////////////////////////////////////////
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);
// should use HOOK FIXUP
// should use FILTER
}
////////////////////////////////////////////////////////////////
/* 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 */
};
+388
View File
@@ -0,0 +1,388 @@
/*
** mod_absec.c -- Apache absec module
** [base 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 -lpam -lpam_misc -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
**
*/
/*
TEST URL
http://10.211.55.15/absec/<fichier>
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 <grp.h>
#include <sys/types.h>
#include <unistd.h>
#include "apr_want.h"
#include <shadow.h>
#include <sys/stat.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <mysql.h>
////////////////////////////////////////////////////////////////
/* Check user autentication against unix user/pass */
static int check_autentication(request_rec *r)
{
return 0;
}
////////////////////////////////////////////////////////////////
/* Check check file perms */
static int check_autorization(request_rec *r)
{
return 0;
}
// Global var for passing fake response to PAM callback
struct pam_response *reply;
////////////////////////////////////////////////////////////////
// PAM response callback function
int converse(int n, const struct pam_message **msg,
struct pam_response **resp, void *data)
{
// Return globally set response
*resp = reply;
return PAM_SUCCESS;
}
////////////////////////////////////////////////////////////////
// define PAM callback function
struct pam_conv conv = { converse, 0 };
////////////////////////////////////////////////////////////////
// define PAM callback function
int mysql_lookup(request_rec *r, struct stat *fperm)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
char *server = "localhost";
char *user = "jlcyr";
char *password = "password"; /* set me first */
char *database = "absec";
conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
char query[256];
sprintf(query, "select * from urls where url='%s'", r->uri);
/* send SQL query */
//if (mysql_query(conn, "show tables")) {
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(-1);
}
res = mysql_use_result(conn);
/* output table name */
ap_rprintf(r, "MySQL data:\n<br/>");
int cnt = 0;
while ((row = mysql_fetch_row(res)) != NULL) {
ap_rprintf(r, "%s %d %d %o \n<br/>", row[0], atoi(row[1]), atoi(row[2]), atoi(row[3]));
fperm->st_uid = atoi(row[1]);
fperm->st_gid = atoi(row[2]);
fperm->st_mode = atoi(row[3]);
cnt = cnt + 1;
}
if (cnt==0) {
sprintf(query, "insert into urls (url, uid, gid, perms) values ('%s', 0, 0, 0)", r->uri);
if (mysql_query(conn, query)) {
ap_rprintf(r, "%s\n<br/>", mysql_error(conn));
return(0);
}
ap_rprintf(r, "Aucune donnee\n<br/>");
}
/* close connection */
mysql_free_result(res);
mysql_close(conn);
return(0);
}
////////////////////////////////////////////////////////////////
/* Main routine - called after request processing */
static int absec_handler_last(request_rec *r)
{
// Is this module really called?
if (strcmp(r->handler, "absec")) {
return DECLINED;
}
////////
/* 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)
{
// 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 GET Url: %s from %s \n<br/>", r->filename, r->uri);
return (DECLINED);
}
////////////////////////////////////////////////////////////////
/* Main routine - called before request processing */
static int absec_handler_first(request_rec *r)
{
ap_rprintf(r, "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 = mysql_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);
////////
// 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=\"USER/PASS 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
////////
/* 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;
}
////////////////////////////////////////////////////////////////
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);
// should use HOOK FIXUP
// should use FILTER
}
////////////////////////////////////////////////////////////////
/* 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 */
};
+36
View File
@@ -0,0 +1,36 @@
+-------------------------------------------------------+
| projet absec |
| module d'abstraction de l'authentification et de |
| l'autorisation du code applicatif d'un site web |
+-------------------------------------------------------+
Le projet dépend pour être compilé de
* libpam_dev
* libapr1-dev
* libaprutil-dev
* apache2-dev
Un script de compilation est disponible
compile.sh
Le projet consiste principalement en un module pour Apache 2.x
ce module peut être compilé pour utiliser
l'authentification
* via les fichiers systèmes /etc/passwd, /etc/shadow, /etc/group
* via l'utilisation de PAM
les autorisations
* via le système de fichier (permissions unix) map url-fichier
* via une base de donnée MySQL map url-entrée dans la bd
l'authentification a une entête commune soit absec_authen.h
et à l'étape de liaison (link) l'on utilise soit absec_etc ou absec_pam
un outil de test pour l'un ou l'autre selon la liaison est disponible
sous test_authen
l'autorisation a une entête commune soit absec_auto.h
et à l'étape de liaison (link) l'on utilise soit absec_fs ou absec_mysql
un outil de test pour l'un ou l'autre selon la liaison est disponible
sous test_auto
+17
View File
@@ -0,0 +1,17 @@
//#include "absec_pam.h"
//#include "absec_etc.h"
#include "absec_authen.h"
#include <stdio.h>
void main(int argc, char** argv){
char *user = "jlcyr";
char *pass = "jlcyrpass01!";
printf("ABSEC auth pam for %s identified by %s\r\n", user, pass);
int retval = check_user(user, pass);
printf("Retval: %d\r\n", retval);
if (retval == PAM_ERROR_START) printf("Error at start\r\n");
if (retval == PAM_ERROR_INVALID_CRED) printf("Invalid user/pass\r\n");
if (retval == PAM_OK) printf("OK\r\n");
printf("Test completed\r\n");
return;
}
+16
View File
@@ -0,0 +1,16 @@
#include "absec_pam.h"
#include <stdio.h>
void main(int argc, char** argv){
char *user = "jlcyr";
char *pass = "jlcyrpass01!";
printf("ABSEC auth etc for %s identified by %s\r\n", user, pass);
int retval;
retval = check_user(user, pass);
printf("Retval: %d\r\n", retval);
if (retval == PAM_ERROR_START) printf("Error at start\r\n");
if (retval == PAM_ERROR_INVALID_CRED) printf("Invalid user/pass\r\n");
if (retval == PAM_OK) printf("OK\r\n");
printf("Test completed\r\n");
return;
}
+3
View File
@@ -1,3 +1,6 @@
#include <mysql.h> #include <mysql.h>
#include <stdio.h> #include <stdio.h>
+16
View File
@@ -0,0 +1,16 @@
#include "absec_pam.h"
#include "absec_etc.h"
#include <stdio.h>
void main(int argc, char** argv){
char *user = "jlcyr";
char *pass = "jlcyrpass01!";
printf("ABSEC auth pam for %s identified by %s\r\n", user, pass);
int retval = check_user(user, pass);
printf("Retval: %d\r\n", retval);
if (retval == PAM_ERROR_START) printf("Error at start\r\n");
if (retval == PAM_ERROR_INVALID_CRED) printf("Invalid user/pass\r\n");
if (retval == PAM_OK) printf("OK\r\n");
printf("Test completed\r\n");
return;
}