git.fiddlerwoaroof.com
Browse code

merge branch 'cjpm-5222'

Greg Wiley authored on 07/04/2017 23:21:57
Showing 16 changed files
... ...
@@ -10,5 +10,6 @@ config.status
10 10
 Makefile
11 11
 *.log
12 12
 autom4te.cache/
13
-dual_control_test
14
-.vagrant/
13
+*_test
14
+*_test
15
+
... ...
@@ -1,7 +1,7 @@
1 1
 MODULEFLAGS = -fPIC -fno-stack-protector
2
-MODULEOBJS = dual_control.o logging.o dc_syslog.o
3
-HEADERS = logging.h dc_syslog.h
4
-
2
+MODULEOBJS = dual_control.o logging.o token.o conversation.o
3
+TESTOBJS = $(patsubst %.o, t_%.o, $(MODULEOBJS))
4
+HEADERS = logging.h test_support.h token.h
5 5
 MODULELIB = pam_dual_control.so
6 6
 UNAME_S := $(shell uname -s)
7 7
 
... ...
@@ -15,6 +15,9 @@ dual_control.a: $(MODULEOBJS)
15 15
 $(MODULEOBJS): %.o: %.c $(HEADERS)
16 16
 	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(MODULEFLAGS) $< -o $@
17 17
 
18
+$(TESTOBJS): t_%.o: %.c $(HEADERS)
19
+	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(MODULEFLAGS) -D UNIT_TEST $< -o $@
20
+
18 21
 .PHONY: clean
19 22
 clean:
20 23
 	@rm -f *.o *.a
... ...
@@ -24,15 +27,21 @@ clean:
24 27
 distclean: clean
25 28
 	@rm -f Makefile config.h
26 29
 
27
-dual_control_test: dual_control_test.c dual_control.o
30
+dual_control_test: dual_control_test.c t_dual_control.o
28 31
 	$(CC) $(CFLAGS) $(CPPFLAGS) -lpam -o $@ $^
29
-logging_test: logging_test.c logging.o
32
+
33
+logging_test: logging_test.c t_logging.o
34
+	$(CC) $(CFLAGS) $(CPPFLAGS) -lpam -o $@ $^
35
+
36
+token_test: token_test.c t_token.o
30 37
 	$(CC) $(CFLAGS) $(CPPFLAGS) -lpam -o $@ $^
31 38
 
32 39
 .PHONY: test
33
-test: dual_control_test logging_test
34
-	@./dual_control_test > /dev/null
35
-	@./logging_test > /dev/null
40
+test: dual_control_test logging_test token_test
41
+	@./dual_control_test
42
+	@./logging_test
43
+	@./token_test
44
+	@echo all tests passed
36 45
 
37 46
 .PHONY: install
38 47
 install: $(MODULEOBJS)
... ...
@@ -1,11 +1,13 @@
1 1
 [![Build Status](https://travis-ci.org/cjdev/dual-control.svg?branch=master)](https://travis-ci.org/cjdev/dual-control)
2 2
 
3 3
 # Dual Control
4
+Dual Control is a PAM module that requires a user to input a generated token from another user before being granted sudo access. The module also requires that the user input the reason for his or her access request and, via `syslog`, captures all this information for future reference.
4 5
 
5
-Goal: To remove all non-firefighting developer write-access to production boxes
6
+At **CJ Engineering**, we will be implementing Dual Control on our production boxes to ensure that a single engineer cannot gain write access without meeting the above-stated requirements.
6 7
 
7
-For ZFR
8
+Dual Control is an open source project licensed under the [GNU General Public License](https://github.com/cjdev/dual-control/blob/master/COPYING). As it stands, Dual Control is written only for machines running Linux. However, we graciously welcome contributions, particularly those related to portability to other operating systems.
8 9
 
10
+## For ZFR
9 11
 * setup a native project
10 12
   * for Linux (docker, virtualbox)
11 13
 * installer
12 14
deleted file mode 100644
... ...
@@ -1,17 +0,0 @@
1
-#include <stdarg.h>
2
-#include "dc_syslog.h"
3
-
4
-void dc_openlog(const char *ident, int logopt, int facility) {
5
-    openlog(ident, logopt, facility);
6
-}
7
-
8
-void dc_syslog(int priority, const char *format, ...) {
9
-    va_list varargs;
10
-    va_start(varargs, format);
11
-    vsyslog(priority, format, varargs);
12
-    va_end(varargs);
13
-}
14
-void dc_closelog(void) {
15
-    closelog();
16
-}
17
-
18 0
deleted file mode 100644
... ...
@@ -1,10 +0,0 @@
1
-#ifndef _DC_SYSLOG_H
2
-#define _DC_SYSLOG_H
3
-
4
-#include <syslog.h>
5
-
6
-void dc_openlog(const char *ident, int logopt, int facility);
7
-void dc_syslog(int priority, const char *message, ...);
8
-void dc_closelog(void);
9
-
10
-#endif
... ...
@@ -1,23 +1,39 @@
1 1
 #include <security/pam_appl.h>
2 2
 #include <security/pam_modules.h>
3
-#include <stdio.h>
3
+#include <string.h>
4
+#include <stdlib.h>
5
+
4 6
 #include "logging.h"
5 7
 #include "token.h"
8
+#include "conversation.h"
6 9
 
7 10
 PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
8
-    printf("Authentication\n");
11
+    const char *returned_token = ask_for_token(pamh);
12
+
13
+    int returned_token_length = strlen(returned_token);
14
+    char working_token[returned_token_length + 1];
15
+    strcpy(working_token, returned_token);
16
+    char *colon = strchr(working_token, ':');
17
+    if(!colon) {
18
+        return PAM_AUTH_ERR;
19
+    }
20
+
21
+    *colon = 0;
22
+    char *user = working_token;
23
+    char *token = colon + 1;
9 24
 
10
-    int returned_validation = validate_token("str");
25
+    int returned_validation = validate_token(user, token);
11 26
 
12 27
     if (returned_validation) {
13 28
         log_success();
14 29
         return PAM_SUCCESS;
15 30
     } else {
31
+        log_failure();
16 32
         return PAM_AUTH_ERR;
17 33
     }
18 34
 }
19 35
 
20 36
 PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) {
21
-    printf("Set cred\n");
22 37
     return PAM_SUCCESS;
23 38
 }
39
+
... ...
@@ -4,25 +4,45 @@
4 4
 
5 5
 #include "conversation.h"
6 6
 #include "token.h"
7
+#include "test_util.h"
7 8
 
9
+const char *validated_user = "";
10
+const char *validated_token = "";
8 11
 const char *token_to_return = "";
12
+int validation_to_return = 0;
13
+int log_success_invoked = 0;
14
+int log_failure_invoked = 0;
15
+int at_least_one_failed_test = 0;
9 16
 pam_handle_t *passed_pam_handle = NULL;
17
+
18
+RESET_VARS_START
19
+validated_user = "";
20
+validated_token = "";
21
+validation_to_return = 1;
22
+passed_pam_handle = NULL;
23
+log_success_invoked = 0;
24
+log_failure_invoked = 0;
25
+RESET_VARS_END
26
+
10 27
 const char *ask_for_token(pam_handle_t *pamh) {
11 28
     passed_pam_handle = pamh;
12 29
     return token_to_return;
13 30
 }
14 31
 
15
-int validation_to_return = 0;
16
-int validate_token(const char *token) {
32
+
33
+int validate_token(const char *user, const char *token) {
34
+    validated_user = user;
35
+    validated_token = token;
17 36
     return validation_to_return;
18 37
 }
19 38
 
20
-
21
-int log_success_invoked = 0;
22 39
 void log_success() {
23 40
     log_success_invoked = 1;
24 41
 }
25 42
 
43
+void log_failure() {
44
+    log_failure_invoked = 1;
45
+}
26 46
 
27 47
 int pam_sm_setcred_returns_success() {
28 48
     //given
... ...
@@ -31,19 +51,45 @@ int pam_sm_setcred_returns_success() {
31 51
     int result = pam_sm_setcred(NULL, 0, 0, NULL);
32 52
 
33 53
     //then
34
-    return result == PAM_SUCCESS;
54
+    checkint(PAM_SUCCESS, result, "function return");
55
+    succeed();
56
+
57
+}
58
+
59
+int pam_sm_authenticate_validates_with_received_token() {
60
+    // given
61
+    token_to_return = "user:pin";
62
+    pam_handle_t *handle = (pam_handle_t*)"";
63
+
64
+    // when
65
+    pam_sm_authenticate(handle, 0, 0, NULL);
66
+
67
+    // then
68
+    checkstr("pin",validated_token, "validated token");
69
+    checkstr("user",validated_user, "validated user");
70
+    check(passed_pam_handle == handle, "incorrect handle");
71
+    succeed();
35 72
 }
36 73
 
37 74
 int pam_sm_authenticate_success_invokes_log_success() {
38 75
     // given
39 76
     validation_to_return = 1;
40
-    log_success_invoked = 0;
41 77
 
42 78
     //when
43 79
    pam_sm_authenticate(NULL, 0, 0, NULL);
44 80
    return log_success_invoked;
45 81
 }
46 82
 
83
+int pam_sm_authenticate_fail_invokes_log_failure() {
84
+    // given
85
+    validation_to_return = 0;
86
+
87
+    //when
88
+   pam_sm_authenticate(NULL, 0, 0, NULL);
89
+   check(log_failure_invoked, "log failure should be invoked");
90
+   succeed();
91
+}
92
+
47 93
 int succeeds_with_valid_token() {
48 94
     //given
49 95
     validation_to_return = 1;
... ...
@@ -66,35 +112,17 @@ int fails_with_invalid_token() {
66 112
     return result == PAM_AUTH_ERR;
67 113
 }
68 114
 
69
-int main(int argc, char* argv[]) {
70
-    int test1_result = succeeds_with_valid_token();
71
-    if (!test1_result) {
72
-        fprintf(stderr, "succeds with valid token failed\n");
73
-    }
74
-
75
-    int test3_result = pam_sm_setcred_returns_success();
76
-    if (!test3_result) {
77
-        fprintf(stderr, "set cred failed\n");
78
-    }
79
-
80
-    int test4_result = pam_sm_authenticate_success_invokes_log_success();
81
-    if (!test4_result) {
82
-        fprintf(stderr, "authenticate invokes log_success failed\n");
83
-    }
84
-
85
-    int test5_result = fails_with_invalid_token();
86
-    if (!test5_result) {
87
-        fprintf(stderr, "fails with invalid token failed\n");
88
-    }
89
-
90
-
91
-
92
-    if (test1_result && test3_result && test4_result && test5_result) {
93
-        fprintf(stderr, "success\n");
94
-        return 0;
95
-    } else {
96
-        return 1;
97
-    }
115
+int runtests() {
116
+    test(pam_sm_authenticate_validates_with_received_token);
117
+    test(pam_sm_setcred_returns_success);
118
+    test(pam_sm_authenticate_success_invokes_log_success);
119
+    test(pam_sm_authenticate_fail_invokes_log_failure);
120
+    test(succeeds_with_valid_token);
121
+    test(fails_with_invalid_token);
122
+    succeed();
98 123
 }
99 124
 
125
+int main(int argc, char* argv[]) {
126
+   return !runtests();
127
+}
100 128
 
... ...
@@ -1,12 +1,21 @@
1
+#include <syslog.h>
2
+
1 3
 #include "logging.h"
2
-#include "dc_syslog.h"
4
+#include "test_support.h"
3 5
 
4 6
 
5 7
 static const char program_name[] = "pam_dual_control";
6 8
 
7 9
 void log_success() {
8
-    dc_openlog(program_name, 0, LOG_AUTHPRIV);
9
-    dc_syslog(LOG_NOTICE, "dual control succeeded");
10
-    dc_closelog();
10
+    openlog(program_name, 0, LOG_AUTHPRIV);
11
+    syslog(LOG_NOTICE, "dual control succeeded");
12
+    closelog();
13
+}
14
+
15
+void log_failure() {
16
+    openlog(program_name, 0, LOG_AUTHPRIV);
17
+    syslog(LOG_NOTICE, "dual control failed");
18
+    closelog();
11 19
 }
12 20
 
21
+
... ...
@@ -2,6 +2,6 @@
2 2
 #define __DUAL_CONTROL_LOGGING
3 3
 
4 4
 void log_success();
5
-void log_fail();
5
+void log_failure();
6 6
 
7 7
 #endif
8 8
deleted file mode 100755
9 9
Binary files a/logging_test and /dev/null differ
... ...
@@ -1,53 +1,41 @@
1 1
 #include <stdio.h>
2 2
 #include <string.h>
3
+#include <syslog.h>
3 4
 
4
-#include "dc_syslog.h"
5 5
 #include "logging.h"
6
+#include "test_util.h"
6 7
 
7 8
 int logged_priority = -1000;
8 9
 const char *logged_message = "";
9
-void dc_syslog(int priority, const char *message, ...) {
10
+void fake_syslog(int priority, const char *message, ...) {
10 11
     logged_priority = priority;
11 12
     logged_message = message;
12 13
 }
13 14
 
14 15
 int close_log_invoked = 0;
15
-void dc_closelog(void) {
16
+void fake_closelog(void) {
16 17
     close_log_invoked = 1;
17 18
 }
18 19
 
19 20
 int opened_facility = -1000;
20 21
 const char *opened_program_name = "";
21 22
 int opened_logopt = -1000;
22
-void dc_openlog(const char *ident, int logopt, int facility) {
23
+void fake_openlog(const char *ident, int logopt, int facility) {
23 24
     opened_facility = facility;
24 25
     opened_program_name = ident;
25 26
     opened_logopt = logopt;
26 27
 }
27 28
 
28
-
29
-#define check(assertion, msg) \
30
-    if (!(assertion)) { \
31
-      fprintf(stderr, "assertion failed: %s\n", msg); \
32
-      return 0; \
33
-    }
34
-
35
-#define checkint(expected, actual, name) \
36
-    check(expected == actual, name " should be " #expected)
37
-
38
-#define checkstr(expected, actual, name) \
39
-    check(!strcmp(actual, expected), name " should be '" expected "'")
40
-
41
-#define succeed() return 1
29
+RESET_VARS_START
30
+logged_priority = -1000;
31
+close_log_invoked = 0;
32
+opened_facility = -1000;
33
+const char *opened_program_name = "";
34
+int opened_logopt = -1000;
35
+RESET_VARS_END
42 36
 
43 37
 int test_log_success() {
44 38
     // given
45
-    opened_facility = -1000;
46
-    opened_program_name = "";
47
-    opened_logopt = -1000;
48
-    logged_priority = -1000;
49
-    logged_message = "";
50
-    close_log_invoked = 0;
51 39
 
52 40
     // when
53 41
     log_success();
... ...
@@ -59,17 +47,32 @@ int test_log_success() {
59 47
     check(close_log_invoked, "log closed");
60 48
     checkstr("pam_dual_control", opened_program_name, "program name");
61 49
     checkstr("dual control succeeded", logged_message, "logged message");
50
+    succeed();
51
+}
52
+
53
+int test_log_failure() {
54
+    //given
62 55
 
56
+    //when
57
+    log_failure();
58
+
59
+    //then
60
+    checkint(LOG_AUTHPRIV, opened_facility, "facility");
61
+    checkint(LOG_NOTICE, logged_priority, "priority");
62
+    checkint(0, opened_logopt, "logopt");
63
+    check(close_log_invoked, "log closed");
64
+    checkstr("pam_dual_control", opened_program_name, "program name");
65
+    checkstr("dual control failed", logged_message, "logged message");
63 66
     succeed();
64 67
 }
65 68
 
69
+int test_runner() {
70
+    test(test_log_success);
71
+    test(test_log_failure);
72
+    succeed();
73
+}
66 74
 
67 75
 int main(int numargs, char **args) {
68
-    if(test_log_success()) {
69
-        fprintf(stderr, "Success!\n");
70
-        return 0;
71
-    } else {
72
-        return 1;
73
-    }
76
+    return !test_runner();
74 77
 }
75 78
 
76 79
new file mode 100644
... ...
@@ -0,0 +1,48 @@
1
+/* Include this in a module that will be under test coverage
2
+ *
3
+ */
4
+
5
+#ifndef _TEST_SUPPORT_H
6
+#define _TEST_SUPPORT_H
7
+#include <stdlib.h>
8
+#include <stdio.h>
9
+#include <pwd.h>
10
+#include <sys/stat.h>
11
+// SYSLOG
12
+void fake_openlog(const char *ident, int logopt, int facility);
13
+void fake_syslog(int priority, const char *format, ...);
14
+void fake_closelog(void);
15
+
16
+// PWD
17
+int fake_getpwnam_r(const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result);
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
+
27
+
28
+#ifdef UNIT_TEST
29
+// SYSLOG
30
+#define openlog(IDENT, LOGOPT, FACILITY) fake_openlog(IDENT, LOGOPT, FACILITY)
31
+#define syslog(PRIORITY, ...) fake_syslog(PRIORITY, __VA_ARGS__)
32
+#define closelog() fake_closelog()
33
+
34
+// PWD
35
+#define getpwnam_r(USER, PASSWD, BUFFER, BUFSIZE, PRESULT) fake_getpwnam_r(USER, PASSWD, BUFFER, BUFSIZE, PRESULT)
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
+
45
+#endif
46
+
47
+#endif
48
+
0 49
new file mode 100644
... ...
@@ -0,0 +1,36 @@
1
+#ifndef _TESTUTIL_H
2
+#define _TESTUTIL_H
3
+
4
+#include <string.h>
5
+#include <stdio.h>
6
+#define check(assertion, msg) \
7
+    if (!(assertion)) { \
8
+      fprintf(stderr, "assertion failed: %s\n", msg); \
9
+      return 0; \
10
+    }
11
+
12
+#define checkint(expected, actual, name) \
13
+    check(expected == actual, name " should be " #expected)
14
+
15
+#define checkstr(expected, actual, name) \
16
+    check(!strcmp(expected, actual), name " should be '" expected "'")
17
+
18
+#define RESET_VARS_START void __reset_vars() {
19
+
20
+#define RESET_VARS_END }
21
+
22
+#define test(NAME) \
23
+    { \
24
+      __reset_vars(); \
25
+      int result = NAME (); \
26
+      if (!result) { \
27
+          fprintf(stderr, "test failed: %s\n", #NAME); \
28
+          return 0; \
29
+      } \
30
+    }
31
+
32
+#define succeed() return 1
33
+#define fail() return 0
34
+
35
+#endif
36
+
0 37
new file mode 100644
... ...
@@ -0,0 +1,103 @@
1
+#include <stdlib.h>
2
+#include <string.h>
3
+#include <security/pam_modules.h>
4
+#include <pwd.h>
5
+#include <unistd.h>
6
+#include <stdio.h>
7
+#include <sys/stat.h>
8
+
9
+#include "token.h"
10
+#include "test_support.h"
11
+
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 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);
46
+}
47
+
48
+int validate_token(const char *user, const char *token) {
49
+
50
+
51
+    char *filepath = 0;
52
+    char *working_token = 0;
53
+    buffer_t buffer = allocate_buffer();
54
+
55
+    int ok = 0;
56
+    struct passwd passwd;
57
+    int user_found = get_passwd(user, &passwd, buffer);
58
+
59
+    // check if user is known
60
+    if(!user_found) {
61
+       goto finally;
62
+    }
63
+
64
+    const char *directory = passwd.pw_dir;
65
+
66
+    int dir_len = strlen(directory);
67
+    int fname_len = strlen(".dual_control");
68
+    filepath = (char *)malloc((dir_len + 1 + fname_len + 1) * sizeof(char));
69
+
70
+    strcpy(filepath, directory);
71
+    strcat(filepath, "/");
72
+    strcat(filepath, ".dual_control");
73
+
74
+    struct stat file_stat;
75
+    int check_file = stat(filepath, &file_stat);
76
+    if (check_file) {
77
+        goto finally;
78
+    }
79
+
80
+    // read the file and grab token
81
+    char fetched_token[7];
82
+    FILE *fp = 0;
83
+    fp = fopen(filepath, "r");
84
+    fgets(fetched_token, 7, fp);
85
+    fclose(fp);
86
+
87
+    // check if token matches
88
+    if(strcmp(token, fetched_token)) {
89
+        goto finally;
90
+    }
91
+
92
+    ok = 1;
93
+
94
+    finally:
95
+
96
+    free(filepath);
97
+    free(working_token);
98
+    free_buffer(&buffer);
99
+
100
+    return ok;
101
+}
102
+
103
+
... ...
@@ -1,6 +1,6 @@
1 1
 #ifndef _TOKEN_H
2 2
 #define _TOKEN_H
3 3
 
4
-int validate_token(const char *token);
4
+int validate_token(const char *user, const char *token);
5 5
 
6 6
 #endif
7 7
new file mode 100644
... ...
@@ -0,0 +1,120 @@
1
+#include <string.h>
2
+#include <pwd.h>
3
+#include <stdio.h>
4
+#include <sys/stat.h>
5
+
6
+#include "token.h"
7
+#include "test_util.h"
8
+
9
+const char *fake_user = "";
10
+const char *fake_user_token = "";
11
+
12
+// all the fake system calls
13
+char *fake_home_dir = "";
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;
17
+  int ok = !strcmp(nam, fake_user);
18
+  *result = ok ? pwd : 0;
19
+  return !ok;
20
+}
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
+
62
+RESET_VARS_START
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";
69
+RESET_VARS_END
70
+
71
+
72
+int validate_compares_to_user_token() {
73
+
74
+    // given
75
+
76
+    // when
77
+    int valid = validate_token("msmith", "123456");
78
+
79
+    // then
80
+    check(valid, "expected result to be valid");
81
+
82
+    succeed();
83
+
84
+}
85
+
86
+int validates_from_the_right_user() {
87
+    //given
88
+
89
+    //when
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");
102
+
103
+    //then
104
+    check(!valid, "expected result to be invalid");
105
+    succeed();
106
+}
107
+
108
+int runtests() {
109
+    test(validate_compares_to_user_token);
110
+    test(validates_from_the_right_user);
111
+    test(validates_user_specific_token);
112
+    succeed();
113
+}
114
+
115
+int main(int argc, char **argv) {
116
+    int rval = !runtests();
117
+    return rval;
118
+}
119
+
120
+