1
1
#include <security/pam_ext.h>
2
2
#include <security/pam_modules.h>
3
3
#include <security/pam_modutil.h>
4
+ #include <stdio.h>
4
5
#include <stdlib.h>
5
6
#include <string.h>
6
- // debug
7
- #include <stdio.h>
8
- #include <syslog.h>
7
+ #include <sys/wait.h>
8
+ #include <unistd.h>
9
9
10
10
#ifdef sun
11
11
#define PAM_CONST
12
12
#else
13
13
#define PAM_CONST const
14
14
#endif
15
15
#define MAXBUF 1024
16
+
16
17
// source from: github.com/google/google-authenticator-libpam
17
18
static int converse (pam_handle_t * pamh , int nargs , PAM_CONST struct pam_message * * message ,
18
19
struct pam_response * * response )
@@ -51,28 +52,33 @@ static char *request_pass(pam_handle_t *pamh, int echocode, PAM_CONST char *prom
51
52
return ret ;
52
53
}
53
54
54
- int exec_cmd (pam_handle_t * pamh , char * cmd , char * arg , char * res )
55
+ int exec_cmd (char * user_env , char * from_env , char * argv [])
56
+ {
57
+ char * envp [] = {user_env , from_env , NULL };
58
+ pid_t pid = fork ();
59
+ if (pid == -1 ) {
60
+ return PAM_AUTHINFO_UNAVAIL ;
61
+ } else if (pid == 0 ) {
62
+ execve (argv [0 ], argv , envp );
63
+ exit (-1 );
64
+ } else {
65
+ int status ;
66
+ if (wait (& status ) == -1 ) {
67
+ return PAM_AUTHINFO_UNAVAIL ;
68
+ } else if (WIFEXITED (status ) && WEXITSTATUS (status ) == 0 ) {
69
+ return PAM_SUCCESS ;
70
+ }
71
+ }
72
+ return PAM_AUTHINFO_UNAVAIL ;
73
+ }
74
+
75
+ int popen_cmd (char * user_env , char * from_env , char * cmd , char * arg , char * res )
55
76
{
56
- const char * user ;
57
- const void * void_from = NULL ;
58
- const char * from ;
59
77
FILE * fp ;
60
78
char * c ;
61
- char user_env [MAXBUF ], host_env [MAXBUF ];
62
79
char buf [MAXBUF ];
63
- if (pam_get_user (pamh , & user , NULL ) != PAM_SUCCESS || user == NULL || * user == '\0' ) {
64
- return PAM_USER_UNKNOWN ;
65
- }
66
- sprintf (user_env , "USER=%s" , user );
67
80
putenv (user_env );
68
-
69
- if (pam_get_item (pamh , PAM_RHOST , & void_from ) != PAM_SUCCESS ) {
70
- return PAM_ABORT ;
71
- }
72
-
73
- from = void_from ;
74
- sprintf (host_env , "SSH_CONNECTION=%s" , from );
75
- putenv (host_env );
81
+ putenv (from_env );
76
82
77
83
if (arg != NULL ) {
78
84
c = malloc (strlen (cmd ) + strlen (arg ) + 2 );
@@ -106,9 +112,23 @@ int exec_cmd(pam_handle_t *pamh, char *cmd, char *arg, char *res)
106
112
107
113
int pam_sm_authenticate (pam_handle_t * pamh , int flags , int argc , const char * * argv )
108
114
{
109
- char buf [MAXBUF ], res [MAXBUF ];
110
- int ret = exec_cmd (pamh , "/usr/bin/google-web-oauth" , "-only-url" , res );
115
+ char res [MAXBUF ];
116
+ const char * user ;
117
+ const char * from ;
118
+ char user_env [MAXBUF ], from_env [MAXBUF ];
119
+
120
+ if (pam_get_user (pamh , & user , NULL ) != PAM_SUCCESS || user == NULL || * user == '\0' ) {
121
+ return PAM_USER_UNKNOWN ;
122
+ }
123
+
124
+ if (pam_get_item (pamh , PAM_RHOST , (void * )& from ) != PAM_SUCCESS ) {
125
+ return PAM_ABORT ;
126
+ }
127
+
128
+ sprintf (user_env , "USER=%s" , user );
129
+ sprintf (from_env , "SSH_CONNECTION=%s" , from );
111
130
131
+ int ret = popen_cmd (user_env , from_env , "/usr/bin/google-web-oauth" , "-only-url" , res );
112
132
if (ret != 0 ) {
113
133
return PAM_AUTHINFO_UNAVAIL ;
114
134
}
@@ -119,9 +139,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
119
139
return PAM_AUTHINFO_UNAVAIL ;
120
140
}
121
141
122
- sprintf ( buf , "-code %s " , code ) ;
123
- ret = exec_cmd (pamh , "/usr/bin/google-web-oauth" , buf , res );
124
- if (ret != 0 ) {
142
+ char * arg [] = { "/usr/bin/google-web-oauth" , "-code" , code , NULL } ;
143
+ ret = exec_cmd (user_env , from_env , arg );
144
+ if (ret != PAM_SUCCESS ) {
125
145
goto err ;
126
146
}
127
147
0 commit comments