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