1 /* Test suite for auth_external. */
2
3 #define LIBTEST_NEW_FORMAT 1
4
5 #include "portable/system.h"
6
7 #include "inn/messages.h"
8 #include "tap/basic.h"
9 #include "tap/messages.h"
10 #include "tap/string.h"
11
12 #include "../../nnrpd/nnrpd.h"
13
14 /* Need this because nnrpd is still bad about global variables. */
15 double IDLEtime = 0;
16
17 /* The basic information that we always send to the program. */
18 static const char info[] = "\
19 ClientHost: example.com\r\n\
20 ClientIP: 10.10.10.10\r\n\
21 ClientPort: 50000\r\n\
22 LocalIP: 10.0.0.2\r\n\
23 LocalPort: 119\r\n";
24
25 /* The additional information sent to authenticators. */
26 static const char userinfo[] = "\
27 ClientAuthname: tester\r\n\
28 ClientPassword: s0pers3cret\r\n";
29
30 /* Allocate a new client struct and fill it out with our test data. */
31 static struct client *
client_new(void)32 client_new(void)
33 {
34 struct client *client;
35
36 client = xmalloc(sizeof(struct client));
37 strlcpy(client->host, "example.com", sizeof(client->host));
38 strlcpy(client->ip, "10.10.10.10", sizeof(client->ip));
39 strlcpy(client->serverip, "10.0.0.2", sizeof(client->serverip));
40 client->port = 50000;
41 client->serverport = 119;
42 return client;
43 }
44
45 /* Validate the input file against the expected data. Takes a flag indicating
46 whether we ran an authenticator. */
47 static void
validate_input(bool auth)48 validate_input(bool auth)
49 {
50 char *wanted, *seen;
51
52 if (auth)
53 wanted = concat(info, userinfo, ".\r\n", (char *) 0);
54 else
55 wanted = concat(info, ".\r\n", (char *) 0);
56 seen = ReadInFile("input", NULL);
57 if (seen == NULL) {
58 syswarn("unable to read input");
59 ok(false, "no input");
60 } else {
61 is_string(wanted, seen, "input is as expected");
62 free(seen);
63 }
64 unlink("input");
65 free(wanted);
66 }
67
68 /* Run the test authenticator, checking its input and output. Takes the fake
69 client struct, the argument to pass to the authenticator, the expected
70 username, and the expected error output. Tries it both as a resolver and
71 an authenticator to be sure there are no surprises. Returns the next test
72 number. */
73 static void
test_external(struct client * client,const char * arg,const char * user,const char * error)74 test_external(struct client *client, const char *arg, const char *user,
75 const char *error)
76 {
77 char *auth_test_path, *result, *command;
78
79 diag("mode %s", arg);
80
81 auth_test_path = test_file_path("nnrpd/auth-test");
82 if (auth_test_path == NULL)
83 bail("cannot find nnrpd/auth-test helper");
84
85 basprintf(&command, "%s %s", auth_test_path, arg);
86 errors_capture();
87 result = auth_external(client, command, ".", NULL, NULL);
88 errors_uncapture();
89 validate_input(false);
90 is_string(user, result, "user");
91 is_string(error, errors, "errors");
92 if (errors && (error == NULL || strcmp(error, errors) != 0))
93 warn("%s", errors);
94 free(errors);
95 errors = NULL;
96
97 errors_capture();
98 result = auth_external(client, command, ".", "tester", "s0pers3cret");
99 errors_uncapture();
100 validate_input(true);
101 is_string(user, result, "user with username and password");
102 is_string(error, errors, "errors with username and password");
103 if (errors && (error == NULL || strcmp(error, errors) != 0))
104 warn("%s", errors);
105 free(errors);
106 errors = NULL;
107
108 test_file_path_free(auth_test_path);
109 }
110
111 int
main(void)112 main(void)
113 {
114 struct client *client;
115
116 plan(12 * 6);
117
118 client = client_new();
119
120 test_external(client, "okay", "tester", NULL);
121 test_external(client, "garbage", "tester", NULL);
122 test_external(client, "error", NULL,
123 "example.com auth: program error: This is an error\n");
124 test_external(client, "interspersed", "tester",
125 "example.com auth: program error: This is an error\n");
126 test_external(client, "empty", NULL, NULL);
127 test_external(client, "empty-error", NULL,
128 "example.com auth: program exited with status 1\n");
129 test_external(client, "okay-error", NULL,
130 "example.com auth: program exited with status 1\n");
131 test_external(client, "signal", NULL,
132 "example.com auth: program caught signal 1\n");
133 test_external(client, "newline", "tester", NULL);
134 test_external(client, "partial", "tester", NULL);
135 test_external(client, "partial-close", "tester", NULL);
136 test_external(client, "partial-error", NULL,
137 "example.com auth: program error: This is an error\n");
138
139 return 0;
140 }
141