Browse code
token matches user token
Greg Wiley authored on 07/04/2017 21:40:09
Showing 3 changed files
Showing 3 changed files
... | ... |
@@ -5,16 +5,25 @@ |
5 | 5 |
#ifndef _TEST_SUPPORT_H |
6 | 6 |
#define _TEST_SUPPORT_H |
7 | 7 |
#include <stdlib.h> |
8 |
- |
|
8 |
+#include <stdio.h> |
|
9 |
+#include <pwd.h> |
|
10 |
+#include <sys/stat.h> |
|
9 | 11 |
// SYSLOG |
10 | 12 |
void fake_openlog(const char *ident, int logopt, int facility); |
11 | 13 |
void fake_syslog(int priority, const char *format, ...); |
12 | 14 |
void fake_closelog(void); |
13 | 15 |
|
14 | 16 |
// PWD |
15 |
-struct passwd; |
|
16 | 17 |
int fake_getpwnam_r(const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result); |
17 | 18 |
|
19 |
+// SYS_STAT |
|
20 |
+int fake_stat(const char *path, struct stat *stat); |
|
21 |
+ |
|
22 |
+// STDIO |
|
23 |
+FILE *fake_fopen(const char *path, const char *mode); |
|
24 |
+char *fake_fgets(char *buf, int n, FILE *fp); |
|
25 |
+int fake_fclose(FILE *fp); |
|
26 |
+ |
|
18 | 27 |
|
19 | 28 |
#ifdef UNIT_TEST |
20 | 29 |
// SYSLOG |
... | ... |
@@ -25,6 +34,14 @@ int fake_getpwnam_r(const char *nam, struct passwd *pwd, char *buffer, size_t bu |
25 | 34 |
// PWD |
26 | 35 |
#define getpwnam_r(USER, PASSWD, BUFFER, BUFSIZE, PRESULT) fake_getpwnam_r(USER, PASSWD, BUFFER, BUFSIZE, PRESULT) |
27 | 36 |
|
37 |
+// SYS_STAT |
|
38 |
+#define stat(PATH, STRUCT) fake_stat(PATH, STRUCT) |
|
39 |
+ |
|
40 |
+// STDIO |
|
41 |
+#define fopen(PATH, MODE) fake_fopen(PATH, MODE) |
|
42 |
+#define fgets(DEST, DEST_SIZE, FILE_HANDLE) fake_fgets(DEST, DEST_SIZE, FILE_HANDLE) |
|
43 |
+#define fclose(FILE_HANDLE) fake_fclose(FILE_HANDLE) |
|
44 |
+ |
|
28 | 45 |
#endif |
29 | 46 |
|
30 | 47 |
#endif |
... | ... |
@@ -3,30 +3,80 @@ |
3 | 3 |
#include <security/pam_modules.h> |
4 | 4 |
#include <pwd.h> |
5 | 5 |
#include <unistd.h> |
6 |
+#include <stdio.h> |
|
7 |
+#include <sys/stat.h> |
|
6 | 8 |
|
7 | 9 |
#include "token.h" |
8 |
- |
|
9 | 10 |
#include "test_support.h" |
10 | 11 |
|
11 |
-int user_is_known(const char *user) { |
|
12 |
- struct passwd *passwd = (struct passwd *) malloc(sizeof(struct passwd)); |
|
13 |
- size_t bufsize = (size_t) sysconf(_SC_GETPW_R_SIZE_MAX); |
|
14 |
- char * buffer = (char *) malloc(bufsize * sizeof(char)); |
|
12 |
+typedef struct buffer { |
|
13 |
+ size_t size; |
|
14 |
+ char *mem; |
|
15 |
+} buffer_t; |
|
16 |
+ |
|
17 |
+buffer_t allocate_buffer() { |
|
18 |
+ buffer_t buffer; |
|
19 |
+ |
|
20 |
+ buffer.size = (size_t) sysconf(_SC_GETPW_R_SIZE_MAX); |
|
21 |
+ buffer.mem = (char *) malloc(buffer.size * sizeof(char)); |
|
22 |
+ |
|
23 |
+ return buffer; |
|
24 |
+ |
|
25 |
+} |
|
26 |
+ |
|
27 |
+void free_buffer(buffer_t *buffer) { |
|
28 |
+ free(buffer->mem); |
|
29 |
+ buffer->mem = 0; |
|
30 |
+ buffer->size = 0; |
|
31 |
+} |
|
32 |
+ |
|
33 |
+char *use_buffer(buffer_t buffer) { |
|
34 |
+ return buffer.mem; |
|
35 |
+} |
|
36 |
+ |
|
37 |
+size_t buffer_size(buffer_t buffer) { |
|
38 |
+ return buffer.size; |
|
39 |
+} |
|
40 |
+ |
|
41 |
+ |
|
42 |
+int user_is_known(const char *user, buffer_t buffer) { |
|
43 |
+ struct passwd *passwd = 0; |
|
44 |
+ passwd = (struct passwd *) malloc(sizeof(struct passwd)); |
|
15 | 45 |
struct passwd *found_passwd = 0; |
16 |
- getpwnam_r(user, passwd, buffer, bufsize, &found_passwd); |
|
46 |
+ getpwnam_r(user, passwd, use_buffer(buffer), buffer_size(buffer), &found_passwd); |
|
17 | 47 |
int known = found_passwd != 0; |
18 | 48 |
|
19 |
- free(buffer); |
|
20 | 49 |
free(passwd); |
21 | 50 |
|
22 | 51 |
return known; |
23 | 52 |
|
24 | 53 |
} |
25 | 54 |
|
55 |
+char *get_home_directory(const char *user, buffer_t buffer) { |
|
56 |
+ struct passwd *passwd = 0; |
|
57 |
+ passwd = (struct passwd *) malloc(sizeof(struct passwd)); |
|
58 |
+ struct passwd *found_passwd = 0; |
|
59 |
+ getpwnam_r(user, passwd, use_buffer(buffer), buffer_size(buffer), &found_passwd); |
|
60 |
+ |
|
61 |
+ free(passwd); |
|
62 |
+ |
|
63 |
+ if (found_passwd) { |
|
64 |
+ return found_passwd->pw_dir; |
|
65 |
+ } |
|
66 |
+ |
|
67 |
+ return 0; |
|
68 |
+} |
|
69 |
+ |
|
26 | 70 |
int validate_token(const char *token) { |
27 |
- int ok = 0; |
|
28 | 71 |
|
29 | 72 |
char *user = 0; |
73 |
+ char *dup_token = 0; |
|
74 |
+ struct stat *file_stat = 0; |
|
75 |
+ char *filepath = 0; |
|
76 |
+ |
|
77 |
+ |
|
78 |
+ int ok = 0; |
|
79 |
+ |
|
30 | 80 |
|
31 | 81 |
// duplicate |
32 | 82 |
int token_length = strlen(token); |
... | ... |
@@ -42,19 +92,67 @@ int validate_token(const char *token) { |
42 | 92 |
// poke a zero so dup is the username |
43 | 93 |
*colon = 0; |
44 | 94 |
|
95 |
+ dup_token = (char *)malloc((token_length + 1) * sizeof(char)); |
|
96 |
+ strcpy(dup_token, token); |
|
97 |
+ char *token_colon = strchr(dup_token, ':'); |
|
98 |
+ if (!token_colon) { |
|
99 |
+ goto finally; |
|
100 |
+ } |
|
101 |
+ |
|
102 |
+ char *user_token = token_colon + 1; |
|
103 |
+ |
|
104 |
+ |
|
45 | 105 |
// check if user is known |
46 |
- if(!user_is_known(user)) { |
|
106 |
+ buffer_t user_buffer = allocate_buffer(); |
|
107 |
+ if(!user_is_known(user, user_buffer)) { |
|
47 | 108 |
goto finally; |
48 | 109 |
} |
49 | 110 |
|
111 |
+ // find the token for found user |
|
112 |
+ buffer_t directory_buffer = allocate_buffer(); |
|
113 |
+ char *directory = get_home_directory(user, directory_buffer); |
|
114 |
+ if (!directory) { |
|
115 |
+ goto finally; |
|
116 |
+ } |
|
117 |
+ |
|
118 |
+ // stat |
|
119 |
+ |
|
120 |
+ file_stat = (struct stat *) malloc(sizeof(struct stat)); |
|
121 |
+ int dir_len = strlen(directory); |
|
122 |
+ int fname_len = strlen(".dual_control"); |
|
123 |
+ filepath = (char *)malloc((dir_len + 1 + fname_len + 1) * sizeof(char)); |
|
124 |
+ |
|
125 |
+ strcpy(filepath, directory); |
|
126 |
+ strcat(filepath, "/"); |
|
127 |
+ strcat(filepath, ".dual_control"); |
|
128 |
+ |
|
129 |
+ int check_file = stat(filepath, file_stat); |
|
130 |
+ if (check_file) { |
|
131 |
+ goto finally; |
|
132 |
+ } |
|
133 |
+ |
|
134 |
+ |
|
135 |
+ // read the file and grab token |
|
136 |
+ char fetched_token[7]; |
|
137 |
+ FILE *fp = 0; |
|
138 |
+ fp = fopen(filepath, "r"); |
|
139 |
+ fgets(fetched_token, 7, fp); |
|
140 |
+ fclose(fp); |
|
141 |
+ |
|
142 |
+ // check if token matches |
|
143 |
+ if(strcmp(user_token, fetched_token)) { |
|
144 |
+ goto finally; |
|
145 |
+ } |
|
146 |
+ |
|
50 | 147 |
ok = 1; |
51 | 148 |
|
52 |
- // determine if user is system user |
|
53 |
- // fail if not |
|
54 | 149 |
finally: |
55 | 150 |
|
56 | 151 |
free(user); |
57 |
- |
|
152 |
+ free_buffer(&user_buffer); |
|
153 |
+ free_buffer(&directory_buffer); |
|
154 |
+ free(file_stat); |
|
155 |
+ free(filepath); |
|
58 | 156 |
return ok; |
59 | 157 |
} |
60 | 158 |
|
... | ... |
@@ -1,30 +1,77 @@ |
1 | 1 |
#include <string.h> |
2 |
+#include <pwd.h> |
|
3 |
+#include <stdio.h> |
|
4 |
+#include <sys/stat.h> |
|
5 |
+ |
|
2 | 6 |
#include "token.h" |
3 | 7 |
#include "test_util.h" |
4 | 8 |
|
5 | 9 |
const char *fake_user = ""; |
6 | 10 |
const char *fake_user_token = ""; |
7 | 11 |
|
8 |
-struct passwd; |
|
9 |
- |
|
10 | 12 |
// all the fake system calls |
13 |
+char *fake_home_dir = ""; |
|
11 | 14 |
int fake_getpwnam_r(const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result) { |
15 |
+ strcpy(buffer, fake_home_dir); |
|
16 |
+ pwd->pw_dir = buffer; |
|
12 | 17 |
int ok = !strcmp(nam, fake_user); |
13 |
- *result = ok ? (struct passwd *)"" : 0; |
|
18 |
+ *result = ok ? pwd : 0; |
|
14 | 19 |
return !ok; |
15 | 20 |
} |
16 | 21 |
|
22 |
+ |
|
23 |
+char *fake_stat_path = ""; |
|
24 |
+int fake_stat(const char *path, struct stat *stat) { |
|
25 |
+ return (strcmp(fake_stat_path, path)); |
|
26 |
+} |
|
27 |
+ |
|
28 |
+char *fake_fopen_path = ""; |
|
29 |
+char *fake_fopen_mode = ""; |
|
30 |
+FILE *_fhandle = 0; |
|
31 |
+FILE *fake_fopen(const char *path, const char *mode) { |
|
32 |
+ static FILE handle; |
|
33 |
+ int path_matches = !strcmp(fake_fopen_path, path); |
|
34 |
+ int mode_matches = !strcmp(fake_fopen_mode, mode); |
|
35 |
+ if(path_matches && mode_matches) { |
|
36 |
+ _fhandle = &handle; |
|
37 |
+ return &handle; |
|
38 |
+ } else { |
|
39 |
+ _fhandle = 0; |
|
40 |
+ return 0; |
|
41 |
+ } |
|
42 |
+} |
|
43 |
+ |
|
44 |
+char *fake_fgets(char *buf, int n, FILE *fp) { |
|
45 |
+ if (_fhandle == fp && fp != 0) { |
|
46 |
+ strncpy(buf, fake_user_token, n - 1); |
|
47 |
+ return buf; |
|
48 |
+ } else { |
|
49 |
+ return 0; |
|
50 |
+ } |
|
51 |
+} |
|
52 |
+ |
|
53 |
+int fake_fclose(FILE *fp) { |
|
54 |
+ return 0; |
|
55 |
+} |
|
56 |
+ |
|
57 |
+ |
|
58 |
+// STDIO |
|
59 |
+ |
|
60 |
+ |
|
61 |
+ |
|
17 | 62 |
RESET_VARS_START |
18 |
-fake_user = ""; |
|
19 |
-fake_user_token = ""; |
|
63 |
+fake_user = "msmith"; |
|
64 |
+fake_user_token = "123456"; |
|
65 |
+fake_home_dir = "/home/msmith"; |
|
66 |
+fake_stat_path = "/home/msmith/.dual_control"; |
|
67 |
+fake_fopen_path = fake_stat_path; |
|
68 |
+fake_fopen_mode = "r"; |
|
20 | 69 |
RESET_VARS_END |
21 | 70 |
|
22 | 71 |
|
23 | 72 |
int validate_compares_to_user_token() { |
24 | 73 |
|
25 | 74 |
// given |
26 |
- fake_user = "msmith"; |
|
27 |
- fake_user_token = "123456"; |
|
28 | 75 |
|
29 | 76 |
// when |
30 | 77 |
int valid = validate_token("msmith:123456"); |
... | ... |
@@ -38,11 +85,20 @@ int validate_compares_to_user_token() { |
38 | 85 |
|
39 | 86 |
int validates_from_the_right_user() { |
40 | 87 |
//given |
41 |
- fake_user = "jbalcita"; |
|
42 |
- fake_user_token = "123456"; |
|
43 | 88 |
|
44 | 89 |
//when |
45 |
- int valid = validate_token("msmith:12346"); |
|
90 |
+ int valid = validate_token("jbalcita:12346"); |
|
91 |
+ |
|
92 |
+ //then |
|
93 |
+ check(!valid, "expected result to be invalid"); |
|
94 |
+ succeed(); |
|
95 |
+} |
|
96 |
+ |
|
97 |
+int validates_user_specific_token() { |
|
98 |
+ //given |
|
99 |
+ |
|
100 |
+ //when |
|
101 |
+ int valid = validate_token("msmith:654321"); |
|
46 | 102 |
|
47 | 103 |
//then |
48 | 104 |
check(!valid, "expected result to be invalid"); |
... | ... |
@@ -52,11 +108,13 @@ int validates_from_the_right_user() { |
52 | 108 |
int runtests() { |
53 | 109 |
test(validate_compares_to_user_token); |
54 | 110 |
test(validates_from_the_right_user); |
111 |
+ test(validates_user_specific_token); |
|
55 | 112 |
succeed(); |
56 | 113 |
} |
57 | 114 |
|
58 | 115 |
int main(int argc, char **argv) { |
59 |
- return !runtests(); |
|
116 |
+ int rval = !runtests(); |
|
117 |
+ return rval; |
|
60 | 118 |
} |
61 | 119 |
|
62 | 120 |
|