Browse code
factored out user
Greg Wiley authored on 11/04/2017 21:57:21
Showing 5 changed files
Showing 5 changed files
... | ... |
@@ -26,27 +26,32 @@ distclean: clean |
26 | 26 |
@rm -f Makefile config.h |
27 | 27 |
|
28 | 28 |
|
29 |
-t_%.o: %.c |
|
30 |
- $(CC) -c $(CPPFLAGS) $(CFLAGS) -D UNIT_TEST -o $@ $< |
|
31 | 29 |
|
32 | 30 |
t_%.o: %.cc |
33 | 31 |
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -D UNIT_TEST -o $@ $< |
34 | 32 |
|
35 |
-dual_control_test: dual_control_test.o t_dual_control.o |
|
36 |
- $(CXX) $(CXXFLAGS) $(CPPLAGS) -lpam -o $@ $^ |
|
33 |
+#dual_control_test: dual_control_test.o t_dual_control.o |
|
34 |
+# $(CXX) $(CXXFLAGS) $(CPPLAGS) -lpam -o $@ $^ |
|
35 |
+# |
|
36 |
+#logging_test: logging_test.o t_logging.o |
|
37 |
+# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -lpam -o $@ $^ |
|
38 |
+# |
|
39 |
+#token_test: token_test.o t_token.o |
|
40 |
+# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -lpam -o $@ $^ |
|
37 | 41 |
|
38 |
-logging_test: logging_test.o t_logging.o |
|
39 |
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -lpam -o $@ $^ |
|
42 |
+user_test: user_test.o user.o |
|
43 |
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $^ |
|
40 | 44 |
|
41 |
-token_test: token_test.o t_token.o |
|
42 |
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) -lpam -o $@ $^ |
|
43 | 45 |
|
44 | 46 |
.PHONY: test |
45 |
-test: dual_control_test logging_test token_test |
|
46 |
- @./dual_control_test |
|
47 |
- @./logging_test |
|
48 |
- @./token_test |
|
49 |
- @echo all tests passed |
|
47 |
+test: user_test |
|
48 |
+ @./user_test |
|
49 |
+ |
|
50 |
+ |
|
51 |
+# @./dual_control_test |
|
52 |
+# @./logging_test |
|
53 |
+# @./token_test |
|
54 |
+# @echo all tests passed |
|
50 | 55 |
|
51 | 56 |
.PHONY: install |
52 | 57 |
install: $(OBJS) |
... | ... |
@@ -5,97 +5,71 @@ |
5 | 5 |
#include <unistd.h> |
6 | 6 |
#include <cstdio> |
7 | 7 |
#include <sys/stat.h> |
8 |
+#include <string> |
|
9 |
+#include <vector> |
|
10 |
+#include <memory> |
|
11 |
+#include <fstream> |
|
8 | 12 |
|
9 | 13 |
#include "token.h" |
10 | 14 |
#include "test_support.h" |
11 | 15 |
|
12 |
-typedef struct buffer { |
|
13 |
- size_t size; |
|
14 |
- char *mem; |
|
15 |
-} buffer_t; |
|
16 | 16 |
|
17 |
-buffer_t allocate_buffer() { |
|
18 |
- buffer_t buffer; |
|
17 |
+typedef struct passwd passwd_t; |
|
18 |
+class user { |
|
19 |
+ private: |
|
20 |
+ std::vector<char> passwd_buffer; |
|
21 |
+ std::shared_ptr<passwd_t> sys_user_info; |
|
19 | 22 |
|
20 |
- buffer.size = (size_t) sysconf(_SC_GETPW_R_SIZE_MAX); |
|
21 |
- buffer.mem = (char *) malloc(buffer.size * sizeof(char)); |
|
23 |
+ public: |
|
24 |
+ user(const std::string &user_name); |
|
25 |
+ bool valid(); |
|
26 |
+ const std::string token(); |
|
22 | 27 |
|
23 |
- return buffer; |
|
28 |
+}; |
|
24 | 29 |
|
25 |
-} |
|
26 |
- |
|
27 |
-void free_buffer(buffer_t *buffer) { |
|
28 |
- free(buffer->mem); |
|
29 |
- buffer->mem = 0; |
|
30 |
- buffer->size = 0; |
|
31 |
-} |
|
30 |
+const std::string user::token() { |
|
31 |
+ // compute the token file path |
|
32 |
+ std::string filepath = (std::string)sys_user_info->pw_dir + "/.dual_control"; |
|
33 |
+ // does the file exist? |
|
34 |
+ std::ifstream token_file(filepath); |
|
35 |
+ if (!token_file.good()) { |
|
36 |
+ return ""; |
|
37 |
+ } |
|
32 | 38 |
|
33 |
-char *use_buffer(buffer_t buffer) { |
|
34 |
- return buffer.mem; |
|
35 |
-} |
|
39 |
+ // read file |
|
40 |
+ int token_length = 6; |
|
41 |
+ std::vector<char> token_buffer(token_length + 1); |
|
42 |
+ token_file.read(token_buffer.data(), token_length); |
|
36 | 43 |
|
37 |
-size_t buffer_size(buffer_t buffer) { |
|
38 |
- return buffer.size; |
|
44 |
+ // return contents |
|
45 |
+ return token_buffer.data(); |
|
39 | 46 |
} |
40 | 47 |
|
41 |
- |
|
42 |
-int get_passwd(const char *user, struct passwd *passwd, buffer_t buffer) { |
|
43 |
- struct passwd *found_passwd = 0; |
|
44 |
- getpwnam_r(user, passwd, use_buffer(buffer), buffer_size(buffer), &found_passwd); |
|
45 |
- return (found_passwd != 0); |
|
48 |
+bool user::valid() { |
|
49 |
+ return sys_user_info; |
|
46 | 50 |
} |
47 | 51 |
|
52 |
+user::user(const std::string &user_name) : |
|
53 |
+ passwd_buffer(sysconf(_SC_GETPW_R_SIZE_MAX)) { |
|
54 |
+ std::shared_ptr<passwd> temp_passwd(new passwd); |
|
55 |
+ struct passwd *found_passwd(0); |
|
56 |
+ getpwnam_r(user_name.c_str(), sys_user_info.get(), passwd_buffer.data(), passwd_buffer.size(), &found_passwd); |
|
48 | 57 |
|
49 |
-int validate_token(const char *user, const char *token) { |
|
50 |
- |
|
51 |
- char fetched_token[7]; |
|
52 |
- FILE *fp = 0; |
|
53 |
- char *filepath = 0; |
|
54 |
- char *working_token = 0; |
|
55 |
- buffer_t buffer = allocate_buffer(); |
|
56 |
- |
|
57 |
- int ok = 0; |
|
58 |
- struct passwd passwd; |
|
59 |
- int user_found = get_passwd(user, &passwd, buffer); |
|
60 |
- const char *directory = passwd.pw_dir; |
|
61 |
- int dir_len = strlen(directory); |
|
62 |
- int fname_len = strlen(".dual_control"); |
|
63 |
- struct stat file_stat; |
|
64 |
- filepath = (char *)malloc((dir_len + 1 + fname_len + 1) * sizeof(char)); |
|
65 |
- |
|
66 |
- strcpy(filepath, directory); |
|
67 |
- strcat(filepath, "/"); |
|
68 |
- strcat(filepath, ".dual_control"); |
|
69 |
- int check_file = stat(filepath, &file_stat); |
|
70 |
- // check if user is known |
|
71 |
- if(!user_found) { |
|
72 |
- goto finally; |
|
73 |
- } |
|
74 |
- |
|
75 |
- |
|
76 |
- if (check_file) { |
|
77 |
- goto finally; |
|
58 |
+ if (found_passwd) { |
|
59 |
+ sys_user_info = temp_passwd; |
|
78 | 60 |
} |
61 |
+} |
|
79 | 62 |
|
80 |
- // read the file and grab token |
|
81 |
- fp = fopen(filepath, "r"); |
|
82 |
- fgets(fetched_token, 7, fp); |
|
83 |
- fclose(fp); |
|
63 |
+int validate_token(const char *c_user_name, const char *c_token) { |
|
84 | 64 |
|
85 |
- // check if token matches |
|
86 |
- if(strcmp(token, fetched_token)) { |
|
87 |
- goto finally; |
|
65 |
+ user user(c_user_name); |
|
66 |
+ if (!user.valid()) { |
|
67 |
+ return 0; |
|
88 | 68 |
} |
69 |
+ std::string token(c_token); |
|
89 | 70 |
|
90 |
- ok = 1; |
|
91 |
- |
|
92 |
- finally: |
|
93 |
- |
|
94 |
- free(filepath); |
|
95 |
- free(working_token); |
|
96 |
- free_buffer(&buffer); |
|
71 |
+ return user.token() == token; |
|
97 | 72 |
|
98 |
- return ok; |
|
99 | 73 |
} |
100 | 74 |
|
101 | 75 |
|
102 | 76 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,18 @@ |
1 |
+#include "user.h" |
|
2 |
+ |
|
3 |
+#include <vector> |
|
4 |
+#include <string> |
|
5 |
+#include <pwd.h> |
|
6 |
+ |
|
7 |
+ |
|
8 |
+user::user(struct passwd *sys_info) : info(sys_info) { |
|
9 |
+} |
|
10 |
+ |
|
11 |
+bool user::valid() { |
|
12 |
+ return info; |
|
13 |
+} |
|
14 |
+ |
|
15 |
+std::string user::home_directory() { |
|
16 |
+ return info->pw_dir; |
|
17 |
+} |
|
18 |
+ |
0 | 19 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,27 @@ |
1 |
+#ifndef _USER_H |
|
2 |
+#define _USER_H |
|
3 |
+#include <vector> |
|
4 |
+#include <string> |
|
5 |
+#include <pwd.h> |
|
6 |
+ |
|
7 |
+class user { |
|
8 |
+ private: |
|
9 |
+ struct passwd *info; |
|
10 |
+ |
|
11 |
+ public: |
|
12 |
+ user(struct passwd *sys_info); |
|
13 |
+ bool valid(); |
|
14 |
+ std::string home_directory(); |
|
15 |
+}; |
|
16 |
+ |
|
17 |
+class concrete_user : public user { |
|
18 |
+ private: |
|
19 |
+ std::vector<char> buffer; |
|
20 |
+ std::shared_ptr<struct passwd> store; |
|
21 |
+ public: |
|
22 |
+ concrete_user(const std::string &user_name); |
|
23 |
+}; |
|
24 |
+ |
|
25 |
+ |
|
26 |
+#endif |
|
27 |
+ |
0 | 28 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,31 @@ |
1 |
+#include "user.h" |
|
2 |
+#include "test_util.h" |
|
3 |
+ |
|
4 |
+int gets_home_directory() { |
|
5 |
+ //given |
|
6 |
+ const char *expected_home_directory = "home/msmith"; |
|
7 |
+ struct passwd test_passwd; |
|
8 |
+ test_passwd.pw_dir = const_cast<char *>(expected_home_directory); |
|
9 |
+ user test_user(&test_passwd); |
|
10 |
+ |
|
11 |
+ //when |
|
12 |
+ std::string actual_home_directory = test_user.home_directory(); |
|
13 |
+ |
|
14 |
+ //then |
|
15 |
+ check(expected_home_directory == actual_home_directory, "directories do not match"); |
|
16 |
+ return expected_home_directory == actual_home_directory; |
|
17 |
+} |
|
18 |
+ |
|
19 |
+RESET_VARS_START |
|
20 |
+RESET_VARS_END |
|
21 |
+ |
|
22 |
+int run_tests() { |
|
23 |
+ test(gets_home_directory); |
|
24 |
+ succeed(); |
|
25 |
+} |
|
26 |
+int main(int argc, char *argv[]) { |
|
27 |
+ return !run_tests(); |
|
28 |
+} |
|
29 |
+ |
|
30 |
+ |
|
31 |
+ |