Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/tests/lib/ssh.c
2065 views
1
/*
2
* Copyright (c) 2021 Baptiste Daroussin <[email protected]>
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer
9
* in this position and unchanged.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
*/
25
26
#include <sys/stat.h>
27
28
#include <atf-c.h>
29
#include <fcntl.h>
30
#include <pkg.h>
31
#include <private/pkg.h>
32
#include <stdlib.h>
33
#include <xmalloc.h>
34
35
ATF_TC_WITHOUT_HEAD(badcommand);
36
ATF_TC_WITHOUT_HEAD(badrestrict);
37
ATF_TC_WITHOUT_HEAD(getfile);
38
ATF_TC_WITHOUT_HEAD(notrestricted);
39
ATF_TC_WITHOUT_HEAD(restricted);
40
41
ATF_TC_BODY(badcommand, tc)
42
{
43
char strout[] =
44
"ok: pkg " PKGVERSION "\n"
45
"ko: unknown command 'plop'\n";
46
char *cwd = getcwd(NULL, 0);
47
int rootfd = open(cwd, O_DIRECTORY);
48
free(cwd);
49
int stdin_pipe[2];
50
ATF_REQUIRE(pipe(stdin_pipe) >= 0);
51
pid_t p = atf_utils_fork();
52
if (p == 0) {
53
close(STDIN_FILENO);
54
dup2(stdin_pipe[0], STDIN_FILENO);
55
close(stdin_pipe[1]);
56
exit(pkg_sshserve(rootfd));
57
}
58
close(stdin_pipe[0]);
59
dprintf(stdin_pipe[1], "plop\n");
60
dprintf(stdin_pipe[1], "quit\n");
61
atf_utils_wait(p, 0, strout, "");
62
}
63
64
ATF_TC_BODY(getfile, tc)
65
{
66
extern ucl_object_t *config;
67
struct stat st;
68
char strout[] =
69
"ok: pkg " PKGVERSION "\n"
70
"ko: bad command get, expecting 'get file age'\n"
71
"ko: bad command get, expecting 'get file age'\n"
72
"ok: 12\n"
73
"testcontent\n"
74
"ok: 0\n"
75
"ko: bad number plop: invalid\n"
76
"ko: file not found\n"
77
"ko: not a file\n"
78
"ko: file not found\n";
79
char * cwd = getcwd(NULL, 0);
80
int rootfd = open(cwd, O_DIRECTORY);
81
free(cwd);
82
int stdin_pipe[2];
83
ATF_REQUIRE(pipe(stdin_pipe) >= 0);
84
FILE *f = fopen("testfile", "w+");
85
ATF_CHECK(f != NULL);
86
fputs("testcontent\n", f);
87
fclose(f);
88
ATF_CHECK(stat("testfile", &st) >= 0);
89
pid_t p = atf_utils_fork();
90
if (p == 0) {
91
close(STDIN_FILENO);
92
dup2(stdin_pipe[0], STDIN_FILENO);
93
close(stdin_pipe[1]);
94
config = ucl_object_typed_new(UCL_OBJECT);
95
char *cwd = getcwd(NULL, 0);
96
ucl_object_insert_key(config, ucl_object_fromstring_common(cwd, 0, UCL_STRING_TRIM),
97
"SSH_RESTRICT_DIR", 16, false);
98
free(cwd);
99
exit(pkg_sshserve(rootfd));
100
}
101
close(stdin_pipe[0]);
102
dprintf(stdin_pipe[1], "get \n");
103
/* get a file without stating the age, should fail */
104
dprintf(stdin_pipe[1], "get /testfile\n");
105
dprintf(stdin_pipe[1], "get /testfile 0\n");
106
/* get a file already in cache */
107
dprintf(stdin_pipe[1], "get /testfile %ld\n", st.st_mtime);
108
/* get a file with a bad age specified */
109
dprintf(stdin_pipe[1], "get /testfile plop\n");
110
dprintf(stdin_pipe[1], "get /nonexistent 0\n");
111
mkdir("test", 0755);
112
dprintf(stdin_pipe[1], "get test 0\n");
113
dprintf(stdin_pipe[1], "get %s/Makefile.autosetup 0\n", atf_tc_get_config_var(tc, "srcdir"));
114
dprintf(stdin_pipe[1], "quit\n");
115
atf_utils_wait(p, 0, strout, "");
116
}
117
118
ATF_TC_BODY(badrestrict, tc)
119
{
120
extern ucl_object_t *config;
121
char strout[] =
122
"ok: pkg " PKGVERSION "\n"
123
"ko: chdir failed (/nonexistent)\n";
124
char *cwd = getcwd(NULL, 0);
125
int rootfd = open(cwd, O_DIRECTORY);
126
free(cwd);
127
int stdin_pipe[2];
128
ATF_REQUIRE(pipe(stdin_pipe) >= 0);
129
pid_t p = atf_utils_fork();
130
if (p == 0) {
131
close(STDIN_FILENO);
132
dup2(stdin_pipe[0], STDIN_FILENO);
133
close(stdin_pipe[1]);
134
config = ucl_object_typed_new(UCL_OBJECT);
135
ucl_object_insert_key(config, ucl_object_fromstring_common("/nonexistent", 0, UCL_STRING_TRIM),
136
"SSH_RESTRICT_DIR", 16, false);
137
exit(pkg_sshserve(rootfd));
138
}
139
close(stdin_pipe[0]);
140
dprintf(stdin_pipe[1], "get /testfile 0\n");
141
dprintf(stdin_pipe[1], "quit\n");
142
atf_utils_wait(p, 0, strout, "");
143
}
144
145
ATF_TC_BODY(notrestricted, tc)
146
{
147
struct stat st;
148
char strout[] =
149
"ok: pkg " PKGVERSION "\n"
150
"ok: 12\n"
151
"testcontent\n";
152
mkdir("test", 0755);
153
int rootfd = open("test", O_DIRECTORY);
154
int stdin_pipe[2];
155
ATF_REQUIRE(pipe(stdin_pipe) >= 0);
156
FILE *f = fopen("testfile", "w+");
157
ATF_CHECK(f != NULL);
158
fputs("testcontent\n", f);
159
fclose(f);
160
ATF_CHECK(stat("testfile", &st) >= 0);
161
pid_t p = atf_utils_fork();
162
if (p == 0) {
163
close(STDIN_FILENO);
164
dup2(stdin_pipe[0], STDIN_FILENO);
165
close(stdin_pipe[1]);
166
exit(pkg_sshserve(rootfd));
167
}
168
close(stdin_pipe[0]);
169
dprintf(stdin_pipe[1], "get ../testfile 0\n");
170
dprintf(stdin_pipe[1], "quit\n");
171
atf_utils_wait(p, 0, strout, "");
172
}
173
174
ATF_TC_BODY(restricted, tc)
175
{
176
extern ucl_object_t *config;
177
struct stat st;
178
char strout[] =
179
"ok: pkg " PKGVERSION "\n"
180
"ko: file not found\n";
181
mkdir("test", 0755);
182
int rootfd = open("test", O_DIRECTORY);
183
int stdin_pipe[2];
184
ATF_REQUIRE(pipe(stdin_pipe) >= 0);
185
FILE *f = fopen("testfile", "w+");
186
ATF_CHECK(f != NULL);
187
fputs("testcontent\n", f);
188
fclose(f);
189
ATF_CHECK(stat("testfile", &st) >= 0);
190
pid_t p = atf_utils_fork();
191
if (p == 0) {
192
close(STDIN_FILENO);
193
dup2(stdin_pipe[0], STDIN_FILENO);
194
close(stdin_pipe[1]);
195
config = ucl_object_typed_new(UCL_OBJECT);
196
char *restriteddir = 0;
197
char *cwd = getcwd(NULL, 0);
198
xasprintf(&restriteddir, "%s/test", cwd);
199
free(cwd);
200
ucl_object_insert_key(config, ucl_object_fromstring_common(restriteddir, 0, UCL_STRING_TRIM),
201
"SSH_RESTRICT_DIR", 16, false);
202
int ret = pkg_sshserve(rootfd);
203
free(restriteddir);
204
exit(ret);
205
}
206
close(stdin_pipe[0]);
207
dprintf(stdin_pipe[1], "get ../testfile 0\n");
208
dprintf(stdin_pipe[1], "quit\n");
209
atf_utils_wait(p, 0, strout, "");
210
}
211
212
ATF_TP_ADD_TCS(tp)
213
{
214
ATF_TP_ADD_TC(tp, badcommand);
215
ATF_TP_ADD_TC(tp, getfile);
216
ATF_TP_ADD_TC(tp, badrestrict);
217
ATF_TP_ADD_TC(tp, notrestricted);
218
ATF_TP_ADD_TC(tp, restricted);
219
220
return (atf_no_error());
221
}
222
223