summaryrefslogtreecommitdiff
path: root/pam/pam_mfa.c
blob: 5167339ef42a8919a55513e34aff0936684906ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <pwd.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <syslog.h>
#include <sys/types.h>

#include <security/pam_modutil.h>
#include <security/pam_modules.h>
#include <security/pam_ext.h>

#define PAMPY "python3 /usr/bin/pam_mfa.py"

int request_mfa(pam_handle_t *pamh, const char *user, const char *service, char* result) {
	FILE *fp;
	int cmdsize = 256;
	int result_size = 2;

	// Build command line
	char cmd[cmdsize];
	cmd[0] = '\0';
	strcat(cmd, PAMPY);
	strcat(cmd," --user ");
	strcat(cmd,user);
	strcat(cmd," --service ");
	strcat(cmd,service);
	pam_syslog(pamh,LOG_INFO,cmd);

	// Execute pam.py
	if ((fp = popen(cmd,"r")) == NULL) {
		pam_syslog(pamh,LOG_ERR,"Error opening pipe");
		result = "1";
		return 1;
	}

	// Set result to output of pam_mfa.py
	fgets(result,result_size,fp);
	pclose(fp);
	return 0;
}

int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char** argv) {
	const char *user;
	const char *service;

	// Get user and service
	if (pam_get_item(pamh, PAM_USER, (const void **) &user) != PAM_SUCCESS || user == NULL) {
			pam_syslog(pamh,LOG_ERR,"unable to get user");
			return PAM_AUTHINFO_UNAVAIL;
	}
	if (pam_get_item(pamh, PAM_SERVICE, (const void **) &service) != PAM_SUCCESS || service == NULL)  {
			pam_syslog(pamh,LOG_ERR,"unable to get service");
			return PAM_AUTHINFO_UNAVAIL;
	}

	int retval;
	int result_size = 2;
	char result[result_size];
	if ((retval = request_mfa(pamh, user, service, result)) != 0) {
		pam_syslog(pamh,LOG_ERR,"error performing mfa");
		return PAM_AUTH_ERR;
	}
	if (atoi(result) == 0) {
		pam_syslog(pamh,LOG_INFO,"auth success");
		return PAM_SUCCESS;
	} else {
		pam_syslog(pamh,LOG_ERR,"auth error");
		return PAM_AUTH_ERR;
	}
}

int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char** argv) {
	if (flags & PAM_DELETE_CRED || flags & PAM_REFRESH_CRED || flags & PAM_ESTABLISH_CRED) {
		return PAM_SUCCESS;
	}
	if (flags & PAM_REINITIALIZE_CRED) {
		int retval = pam_sm_authenticate(pamh,flags,argc,argv);
		if (retval == PAM_SUCCESS) {
			return PAM_SUCCESS;
		} else {
			return PAM_CRED_ERR;
		}
	}
}