Password function

This commit is contained in:
2018-04-01 01:53:41 +02:00
parent 721f63774c
commit b31cc5948b
19 changed files with 773 additions and 254 deletions

9
src/pam_panic/Makefile Normal file
View File

@ -0,0 +1,9 @@
CFLAGS = --std=gnu11 -O2 -fPIC -DPOWEROFF=\"`which poweroff`\" -DREBOOT=\"`which reboot`\" -DCRYPTSETUP=\"`which cryptsetup`\" -DPPASSFILE=\"$(PPASSFILE)\"
LDFLAGS = -x --shared -lcrypt
all:
mkdir -p ../../obj
mkdir -p ../../build
cc $(CFLAGS) -c pam_panic.c -o ../../obj/pam_panic.o
ld $(LDFLAGS) -o ../../build/pam_panic.so ../../obj/pam_panic.o

193
src/pam_panic/pam_panic.c Normal file
View File

@ -0,0 +1,193 @@
/*
FILENAME : pam_panic.c
DESCRIPTION : The pam_panic PAM module shall protect people who have value data on their computer. It provides a panic function.
AUTHOR : Bandie
DATE : 2018-03-27T02:34:08+02:00
LICENSE : GNU-GPLv3
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <regex.h>
#include <string.h>
#include <security/pam_modules.h>
#include <security/pam_ext.h>
#include <syslog.h>
#include "pam_panic_reject.h"
#include "pam_panic_authdevice.h"
#include "pam_panic_password.h"
#ifdef REBOOT
#ifdef POWEROFF
#ifdef CRYPTSETUP
void argSplit(char **some_arg, char **some_temp, const char *arg){
strncpy(*some_arg, arg, 128);
*some_temp = strtok(*some_arg, "=");
*some_temp = strtok(NULL, "=");
}
void constrPath(char **dst, char **src){
sprintf(*dst, "/dev/disk/by-partuuid/%s", *src);
}
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char *argv[]){
// Devices
char *allowed_arg = malloc(128 * sizeof(char));
char *rejected_arg = malloc(128 * sizeof(char));
char *serious_arg = malloc(128 * sizeof(char));
char *allowed_temp = NULL;
char *rejected_temp = NULL;
char *serious_temp = NULL;
char *allowed = malloc(60 * sizeof(char));
char *rejected = malloc(60 * sizeof(char));
char *serious_dev = malloc(60 * sizeof(char));
// Switches
int8_t bSerious = 0;
int8_t bReboot = 0;
int8_t bPoweroff = 0;
int8_t bPassword = 0;
// Regex for checking arguments
char *pattern = "^[A-Fa-f0-9]\\{8\\}\\-[A-Fa-f0-9]\\{4\\}\\-[A-Fa-f0-9]\\{4\\}\\-[A-Fa-f0-9]\\{4\\}\\-[A-Fa-f0-9]\\{12\\}$";
regex_t regex;
if(regcomp(&regex, pattern, 0)){
pam_syslog(pamh, LOG_CRIT, "ERROR: Problem with regcomp.");
return (PAM_IGNORE);
}
// Argument handling
for(int i=0; i<argc; i++){
if(strstr(argv[i], "allow") != NULL)
argSplit(&allowed_arg, &allowed_temp, argv[i]);
if(strstr(argv[i], "reject") != NULL)
argSplit(&rejected_arg, &rejected_temp, argv[i]);
if(strstr(argv[i], "reboot") != NULL)
bReboot = 1;
if(strstr(argv[i], "poweroff") != NULL)
bPoweroff = 1;
if(strstr(argv[i], "password") != NULL){
bPassword = 1;
}
if(strstr(argv[i], "serious") != NULL){
argSplit(&serious_arg, &serious_temp, argv[i]);
bSerious = 1;
}
}
// Checking arguments
if(
(allowed_temp == NULL && !bPassword)
|| (rejected_temp == NULL && !bPassword)
|| (allowed_temp != NULL && regexec(&regex, allowed_temp, 0, NULL, 0) == REG_NOMATCH)
|| (rejected_temp != NULL && regexec(&regex, rejected_temp, 0, NULL, 0) == REG_NOMATCH)
|| (bSerious && serious_temp == NULL)
) {
pam_syslog(pamh, LOG_ERR, "Arguments invalid. Note that allow and reject must have a valid GPT UUID.");
return (PAM_IGNORE);
}
// Poweroff wins.
if(bReboot && bPoweroff)
bReboot = 0;
// Devices will win
if(bPassword && allowed_temp != NULL && rejected_temp != NULL)
bPassword = 0;
// Construct variables from arguments
if(allowed_temp != NULL && rejected_temp != NULL){
constrPath(&rejected, &rejected_temp);
constrPath(&allowed, &allowed_temp);
}else{
rejected = NULL;
allowed = NULL;
}
if(bSerious)
constrPath(&serious_dev, &serious_temp);
// Free not needed vars
free(rejected_arg);
free(allowed_arg);
free(serious_arg);
// Check if panic key exist
if(bSerious && access(serious_dev, F_OK) == -1){
pam_syslog(pamh, LOG_ALERT, "ALERT for argument \"serious\": Device doesn't exist.");
return (PAM_IGNORE);
}
//////////////////////// AUTH PROMPT ////////////////////////////////
// Prompt for (auth|panic) key
if(allowed != NULL && rejected != NULL){
return authDevice(pamh, allowed, rejected, serious_dev, bSerious, bReboot, bPoweroff);
}else if(bPassword){
return authPassword(pamh, serious_dev, bSerious, bReboot, bPoweroff);
}
return (PAM_IGNORE);
}
// Fuck all of this below.
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);
}
#endif
#endif
#endif

View File

@ -0,0 +1,18 @@
int authDevice(pam_handle_t *pamh, char *allowed, char *rejected, char *serious_dev, int8_t bSerious, int8_t bReboot, int8_t bPoweroff){
int8_t counter = 0;
while(access(allowed, F_OK) == -1 && access(rejected, F_OK) == -1){
pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, NULL, ASK);
if(++counter >= 3){
pam_syslog(pamh, LOG_NOTICE, "Couldn't identify any keys. 3 tries.");
return (PAM_MAXTRIES);
}
}
if(access(allowed, F_OK) != -1)
return (PAM_SUCCESS);
if(access(rejected, F_OK) != -1)
return reject(serious_dev, bSerious, bReboot, bPoweroff);
}

View File

@ -0,0 +1,3 @@
#define ASK "Please enter your secret key to decrypt the firewall and access the mainframe. "
#include "pam_panic_authdevice.c"

View File

@ -0,0 +1,84 @@
int readPassword(pam_handle_t *pamh, char pw[2][99]){
// Open file
if(access(PPASSFILE, F_OK) == -1){
pam_syslog(pamh, LOG_ALERT, "ALERT for password option: No password file detected.");
return 2;
}
FILE *f = fopen(PPASSFILE, "r");
if(f == NULL){
pam_syslog(pamh, LOG_ALERT, "ERROR: Couldn't open file.");
return 1;
}
// Get file contents
size_t nread;
char filecontent[198];
char chr;
nread = fread(filecontent, sizeof(char), 198, f);
fclose(f);
if(nread != 198){
pam_syslog(pamh, LOG_CRIT, "CRITICAL: Password file is corrupt!");
return 3;
}
/* Split file content
* pw[0] := key
* pw[1] := panic key
*/
strcpy(pw[0], strtok(filecontent, "\n"));
strcpy(pw[1], strtok(NULL, "\n"));
if(pw[0] == NULL || pw[1] == NULL)
return 1;
return 0;
}
int authPassword(pam_handle_t *pamh, char *serious_dev, int8_t bSerious, int8_t bReboot, int8_t bPoweroff){
// PAM password response
char resp[256];
char *response = NULL;
// Not so panic password
char *pwkey_tmp;
char pwkey[99];
// Panic password
char *pwpanic_tmp;
char pwpanic[99];
// Read passwords from file
char pw[2][99];
if(readPassword(pamh, pw))
return(PAM_IGNORE);
pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &response, "Password:: ");
strcpy(resp, response);
pwkey_tmp = crypt(resp, pw[0]);
strcpy(pwkey, pwkey_tmp);
pwpanic_tmp = crypt(resp, pw[1]);
strcpy(pwpanic, pwpanic_tmp);
// Key?
if(!strcmp(pwkey, pw[0]))
return (PAM_SUCCESS);
if(!strcmp(pwpanic, pw[1])){
return reject(serious_dev, bSerious, bReboot, bPoweroff);
}
return (PAM_AUTH_ERR);
}

View File

@ -0,0 +1,2 @@
#include <crypt.h>
#include "pam_panic_password.c"

View File

@ -0,0 +1,28 @@
int reject(char *serious_dev, int8_t bSerious, int8_t bReboot, int8_t bPoweroff){
if(bSerious){
int ser_stat;
int yes[2];
pipe(yes);
if(fork() == 0){
close(yes[1]);
dup2(yes[0], 0);
execlp(CRYPTSETUP, CRYPTSETUP, "luksErase", serious_dev, NULL);
}else {
close(yes[0]);
write(yes[1], "YES\n", 4);
close(yes[1]);
wait(&ser_stat);
}
}
if(bReboot)
execlp(REBOOT, REBOOT, NULL);
if(bPoweroff)
execlp(POWEROFF, POWEROFF, NULL);
return (PAM_MAXTRIES);
}

View File

@ -0,0 +1 @@
#include "pam_panic_reject.c"