/////
//
// 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;
    }
}