1 /*
2  * ProFTPD - FTP server testsuite
3  * Copyright (c) 2015-2017 The ProFTPD Project team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  *
19  * As a special exemption, The ProFTPD Project team and other respective
20  * copyright holders give permission to link this program with OpenSSL, and
21  * distribute the resulting executable, without including the source code for
22  * OpenSSL in the source distribution.
23  */
24 
25 /* Help API tests. */
26 
27 #include "tests.h"
28 
29 static pool *p = NULL;
30 
set_up(void)31 static void set_up(void) {
32   if (p == NULL) {
33     p = permanent_pool = make_sub_pool(NULL);
34   }
35   pr_response_set_pool(p);
36 
37   if (getenv("TEST_VERBOSE") != NULL) {
38     pr_trace_use_stderr(TRUE);
39     pr_trace_set_levels("response", 0, 20);
40   }
41 }
42 
tear_down(void)43 static void tear_down(void) {
44   if (getenv("TEST_VERBOSE") != NULL) {
45     pr_trace_use_stderr(FALSE);
46   }
47 
48   pr_response_set_pool(NULL);
49 
50   if (p) {
51     destroy_pool(p);
52     p = permanent_pool = NULL;
53   }
54 }
55 
START_TEST(help_add_test)56 START_TEST (help_add_test) {
57   const char *cmd, *syntax;
58 
59   mark_point();
60   pr_help_add(NULL, NULL, 0);
61 
62   cmd = "FOO";
63 
64   mark_point();
65   pr_help_add(cmd, NULL, 0);
66 
67   syntax = "<path>";
68 
69   mark_point();
70   pr_help_add(cmd, syntax, FALSE);
71 
72   mark_point();
73   pr_help_add(cmd, syntax, TRUE);
74 
75   cmd = "BAR";
76 
77   mark_point();
78   pr_help_add(cmd, syntax, FALSE);
79 }
80 END_TEST
81 
START_TEST(help_add_response_test)82 START_TEST (help_add_response_test) {
83   int res;
84   const char *resp_code = NULL, *resp_msg = NULL;
85   cmd_rec *cmd;
86 
87   res = pr_help_add_response(NULL, NULL);
88   fail_unless(res == -1, "Failed to handle null arguments");
89   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
90     strerror(errno), errno);
91 
92   mark_point();
93 
94   cmd = pr_cmd_alloc(p, 2, C_HELP, "FOO");
95   res = pr_help_add_response(cmd, NULL);
96   fail_unless(res == -1, "Failed to handle empty help list");
97   fail_unless(errno == ENOENT, "Failed to set errno to ENOENT, got %s (%d)",
98     strerror(errno), errno);
99 
100   mark_point();
101 
102   /* Now add one command to the help list, and try again. */
103   pr_help_add("FOO", "", TRUE);
104 
105   mark_point();
106 
107   res = pr_help_add_response(cmd, NULL);
108   fail_unless(res == 0, "Failed to add help response: %s", strerror(errno));
109 
110   mark_point();
111 
112   resp_code = resp_msg = NULL;
113   res = pr_response_get_last(p, &resp_code, &resp_msg);
114   fail_unless(res == 0, "Failed to get last response: %s", strerror(errno));
115   fail_unless(resp_code != NULL, "Expected non-null response code");
116   fail_unless(strcmp(resp_code, R_214) == 0,
117     "Expected response code %s, got %s", R_214, resp_code);
118   fail_unless(resp_msg != NULL, "Expected non-null response message");
119   fail_unless(strcmp(resp_msg, "Direct comments to ftp-admin") == 0,
120     "Expected response message '%s', got '%s'", "Direct comments to ftp-admin",
121     resp_msg);
122 
123   mark_point();
124 
125   res = pr_help_add_response(cmd, "FOO");
126   fail_unless(res == 0, "Failed to add help response: %s", strerror(errno));
127 
128   mark_point();
129 
130   resp_code = resp_msg = NULL;
131   res = pr_response_get_last(p, &resp_code, &resp_msg);
132   fail_unless(res == 0, "Failed to get last response: %s", strerror(errno));
133   fail_unless(resp_code != NULL, "Expected non-null response code");
134   fail_unless(strcmp(resp_code, R_214) == 0,
135     "Expected response code %s, got %s", R_214, resp_code);
136   fail_unless(resp_msg != NULL, "Expected non-null response message");
137   fail_unless(strcmp(resp_msg, "Syntax: FOO ") == 0,
138     "Expected response message '%s', got '%s'", "Syntax: FOO ", resp_msg);
139 
140   /* Now add an unimplemented command, and test that one. */
141 
142   mark_point();
143 
144   pr_help_add("BAR", "<path>", FALSE);
145 
146   res = pr_help_add_response(cmd, "BAR");
147   fail_unless(res == 0, "Failed to add help response: %s", strerror(errno));
148 
149   mark_point();
150 
151   resp_code = resp_msg = NULL;
152   res = pr_response_get_last(p, &resp_code, &resp_msg);
153   fail_unless(res == 0, "Failed to get last response: %s", strerror(errno));
154   fail_unless(resp_code != NULL, "Expected non-null response code");
155   fail_unless(strcmp(resp_code, R_214) == 0,
156     "Expected response code %s, got %s", R_214, resp_code);
157   fail_unless(resp_msg != NULL, "Expected non-null response message");
158   fail_unless(strcmp(resp_msg, "Syntax: BAR <path>") == 0,
159     "Expected response message '%s', got '%s'", "Syntax: BAR <path>", resp_msg);
160 }
161 END_TEST
162 
tests_get_help_suite(void)163 Suite *tests_get_help_suite(void) {
164   Suite *suite;
165   TCase *testcase;
166 
167   suite = suite_create("help");
168 
169   testcase = tcase_create("base");
170 
171   tcase_add_checked_fixture(testcase, set_up, tear_down);
172 
173   tcase_add_test(testcase, help_add_test);
174   tcase_add_test(testcase, help_add_response_test);
175 
176   suite_add_tcase(suite, testcase);
177   return suite;
178 }
179