git.fiddlerwoaroof.com
Browse code

factored out user

Greg Wiley authored on 11/04/2017 21:57:21
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
+