Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
203 lines (174 sloc) 5.42 KB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <crypt.h>
#include <mysql/mysql.h>
#define LENG_STRING 200
#define PAM_SM_AUTH
#include <security/pam_modules.h>
#ifndef PAM_EXTERN
#define PAM_EXTERN
#endif
/* Les parametres ci-dessous sont a adapter a votre situation */
#define MY_SERVER_HOST "192.168.1.98"
#define MY_SERVER_PORT 0
#define MY_ACCOUNT "root"
#define MY_PASS "root"
#define MY_DB_NAME "pam"
#define MY_TABLE_NAME "pam_login"
#define MY_UX_SOCK NULL
#define MY_CLIENT_FLAG 0
static char password_prompt[] = "Mot de passe : ";
static char origin_salt[] = "adminsys"; // limité à 8 caractères pour md5
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flgs, int argc, const char **argv){
// variables
char temp[LENG_STRING]="";
int result = PAM_AUTH_ERR;
const char *username = NULL;
int retry, err;
struct pam_conv *conv;
struct pam_message msg;
const struct pam_message *msgp;
char *crypt_password, *password;
struct pam_response *resp;
struct passwd *pwd;
char salt[LENG_STRING] = "";
MYSQL *mysql;
MYSQL_RES *res;
MYSQL_ROW row;
char query[LENG_STRING]="";
unsigned int t, f;
enum algos {
des,
md5,
sha256,
sha512
};
typedef enum algos algo; //utiliser l'enum algo au lieu de manipuler les valeurs ascii des chiffres 0 à 3 ?
// mise en place du salt suivant l'algo choisi dans la config de pam
int algo_choice = ((int)*argv[0]-48);
switch (algo_choice){
case 0:
strcat(salt,origin_salt);
syslog(LOG_ERR, "PAM_MYSQL module : DES : %s", salt);
break;
case 1:
strcat(salt, "$1$");
strcat(salt, origin_salt);
strcat(salt, "$");
syslog(LOG_ERR, "PAM_MYSQL module : MD5 : %s", salt);
break;
case 2:
strcat(salt, "$5$");
strcat(salt, origin_salt);
strcat(salt, "$");
syslog(LOG_ERR, "PAM_MYSQL module : SHA256 : %s", salt);
break;
case 3:
strcat(salt, "$6$");
strcat(salt, origin_salt);
strcat(salt, "$");
syslog(LOG_ERR, "PAM_MYSQL module : SHA512 : %s", salt);
break;
default:
strcat(salt, "$6$");
strcat(salt, origin_salt);
strcat(salt, "$");
syslog(LOG_ERR, "PAM_MYSQL module : DEFAULT : SHA512 : %s", salt);
break;
}
// on récupère le nom de l'utilisateur auquel on se connecte
if(pam_get_user(pamh, &username, NULL) != PAM_SUCCESS){
// cas où le nom de l'utilisateur n'est pas reconnu
syslog(LOG_ERR, "PAM_MYSQL module : Username %s is unknown", username);
return PAM_USER_UNKNOWN;
}
// récupération du mot de passe
err = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
if (err != PAM_SUCCESS)
return (PAM_SYSTEM_ERR);
msg.msg_style = PAM_PROMPT_ECHO_OFF; // le mot de passe ne sera pas affiché à l'écran lors de sa saisie
msg.msg = password_prompt; // message de demande de mot de passe
msgp = &msg;
for (retry = 0; retry < 3; ++retry) {
resp = NULL;
err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr);
if (resp != NULL) {
if (err == PAM_SUCCESS)
password = resp->resp;
else
free(resp->resp);
free(resp);
}
if (err == PAM_SUCCESS)
break;
}
// partie MySQL
mysql=mysql_init(NULL);
if (!mysql_real_connect(mysql,MY_SERVER_HOST,MY_ACCOUNT,MY_PASS,
MY_DB_NAME,MY_SERVER_PORT,MY_UX_SOCK,MY_CLIENT_FLAG)) {
syslog(LOG_ERR, "PAM_MYSQL module : Erreur de connexion : %s",mysql_error(mysql));
}
else {
syslog(LOG_INFO, "PAM_MYSQL module : Connexion OK");
// requete mysql avec le nom de l'utilisateur inclus
strcat(query, "select * from pam_login where user='");
strcat(query, username);
strcat(query, "'");
t=mysql_real_query(mysql, query, (unsigned int) strlen(query));
if (t) {
syslog(LOG_ERR, "PAM_MYSQL module : Erreur dans la requete : %s", mysql_error(mysql));
}
else {
if((res=mysql_use_result(mysql))) {
f=mysql_num_fields(res);
while((row=mysql_fetch_row(res))) { // traitement des résultats
/*for(t=0;t<f;t++) {
syslog(LOG_INFO, "%s",row[t]);
}*/
//syslog(LOG_INFO, "PAM_MYSQL module : user : %s",row[0]);
syslog(LOG_INFO, "PAM_MYSQL module : bdd pwd : %s",row[1]);
// mot de passe chiffré avec salt
crypt_password = crypt(password, salt);
syslog(LOG_INFO, "PAM_MYSQL module : Password crypt : %s", crypt_password);
if(strncmp(row[1], crypt_password, strlen(row[1]))==0){ // vérification du mot de passe
result = PAM_SUCCESS;
//syslog(LOG_ERR, "PAM_MYSQL module : len crypt %d", strlen(crypt_password));
//syslog(LOG_ERR, "PAM_MYSQL module : len row %d", strlen(row[1]));
}
else{
syslog(LOG_ERR, "PAM_MYSQL module : Password error for %s", username);
result = PAM_AUTH_ERR;
}
}
mysql_free_result(res);
}
else {
syslog(LOG_ERR, "PAM_MYSQL module : Erreur de recuperation du resultat : %s", mysql_error(mysql));
}
}
}
mysql_close(mysql);
return result;
}
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char *argv[])
{
return (PAM_SUCCESS);
}
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char *argv[])
{
return (PAM_SUCCESS);
}
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char *argv[])
{
return (PAM_SUCCESS);
}
PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char *argv[])
{
return (PAM_SUCCESS);
}
PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char *argv[])
{
return (PAM_SERVICE_ERR);
}
Something went wrong with that request. Please try again.