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