Skip to content

Commit 0e161db

Browse files
author
Kazuhiko Yamashita
authored
Merge pull request #3 from pyama86/use-execve
fix shell injection
2 parents 3f618c6 + a372afa commit 0e161db

File tree

1 file changed

+45
-25
lines changed

1 file changed

+45
-25
lines changed

pam/pam.c

+45-25
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
#include <security/pam_ext.h>
22
#include <security/pam_modules.h>
33
#include <security/pam_modutil.h>
4+
#include <stdio.h>
45
#include <stdlib.h>
56
#include <string.h>
6-
// debug
7-
#include <stdio.h>
8-
#include <syslog.h>
7+
#include <sys/wait.h>
8+
#include <unistd.h>
99

1010
#ifdef sun
1111
#define PAM_CONST
1212
#else
1313
#define PAM_CONST const
1414
#endif
1515
#define MAXBUF 1024
16+
1617
// source from: github.com/google/google-authenticator-libpam
1718
static int converse(pam_handle_t *pamh, int nargs, PAM_CONST struct pam_message **message,
1819
struct pam_response **response)
@@ -51,28 +52,33 @@ static char *request_pass(pam_handle_t *pamh, int echocode, PAM_CONST char *prom
5152
return ret;
5253
}
5354

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)
5576
{
56-
const char *user;
57-
const void *void_from = NULL;
58-
const char *from;
5977
FILE *fp;
6078
char *c;
61-
char user_env[MAXBUF], host_env[MAXBUF];
6279
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);
6780
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);
7682

7783
if (arg != NULL) {
7884
c = malloc(strlen(cmd) + strlen(arg) + 2);
@@ -106,9 +112,23 @@ int exec_cmd(pam_handle_t *pamh, char *cmd, char *arg, char *res)
106112

107113
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
108114
{
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);
111130

131+
int ret = popen_cmd(user_env, from_env, "/usr/bin/google-web-oauth", "-only-url", res);
112132
if (ret != 0) {
113133
return PAM_AUTHINFO_UNAVAIL;
114134
}
@@ -119,9 +139,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
119139
return PAM_AUTHINFO_UNAVAIL;
120140
}
121141

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) {
125145
goto err;
126146
}
127147

0 commit comments

Comments
 (0)