1 /*
2 * ProFTPD - FTP server testsuite
3 * Copyright (c) 2008-2020 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 /* NetIO API tests. */
26
27 #include "tests.h"
28
29 /* See RFC 854 for the definition of these Telnet values */
30
31 /* Telnet "Interpret As Command" indicator */
32 #define TELNET_IAC 255
33 #define TELNET_DONT 254
34 #define TELNET_DO 253
35 #define TELNET_WONT 252
36 #define TELNET_WILL 251
37 #define TELNET_IP 244
38 #define TELNET_DM 242
39
40 static pool *p = NULL;
41 static int xfer_bufsz = -1;
42
43 static int tmp_fd = -1;
44 static const char *tmp_path = NULL;
45
test_cleanup(void)46 static void test_cleanup(void) {
47 (void) close(tmp_fd);
48 tmp_fd = -1;
49
50 if (tmp_path != NULL) {
51 (void) unlink(tmp_path);
52 tmp_path = NULL;
53 }
54
55 pr_unregister_netio(PR_NETIO_STRM_CTRL|PR_NETIO_STRM_DATA|PR_NETIO_STRM_OTHR);
56 }
57
open_tmpfile(void)58 static int open_tmpfile(void) {
59 int fd;
60
61 if (tmp_path != NULL) {
62 test_cleanup();
63 }
64
65 tmp_path = "/tmp/netio-test.dat";
66 fd = open(tmp_path, O_RDWR|O_CREAT, 0666);
67 fail_unless(fd >= 0, "Failed to open '%s': %s", tmp_path, strerror(errno));
68 tmp_fd = fd;
69
70 return fd;
71 }
72
set_up(void)73 static void set_up(void) {
74 if (p == NULL) {
75 p = permanent_pool = make_sub_pool(NULL);
76 }
77
78 init_netio();
79 xfer_bufsz = pr_config_get_server_xfer_bufsz(PR_NETIO_IO_RD);
80
81 if (getenv("TEST_VERBOSE") != NULL) {
82 pr_trace_set_levels("netio", 1, 20);
83 }
84 }
85
tear_down(void)86 static void tear_down(void) {
87 if (getenv("TEST_VERBOSE") != NULL) {
88 pr_trace_set_levels("netio", 0, 0);
89 }
90
91 test_cleanup();
92
93 if (p) {
94 destroy_pool(p);
95 p = permanent_pool = NULL;
96 }
97 }
98
99 /* Tests */
100
START_TEST(netio_open_test)101 START_TEST (netio_open_test) {
102 pr_netio_stream_t *nstrm;
103 int fd = -1;
104
105 nstrm = pr_netio_open(NULL, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
106 fail_unless(nstrm == NULL, "Failed to handle null pool argument");
107 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
108 strerror(errno), errno);
109
110 nstrm = pr_netio_open(p, 7777, fd, PR_NETIO_IO_RD);
111 fail_unless(nstrm == NULL, "Failed to handle unknown stream type argument");
112 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
113 strerror(errno), errno);
114
115 /* open/close CTRL stream */
116 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
117 fail_unless(nstrm != NULL, "Failed to open ctrl stream on fd %d: %s", fd,
118 strerror(errno));
119 fail_unless(nstrm->strm_netio != NULL,
120 "Failed to assign owning NetIO to stream");
121 pr_netio_close(nstrm);
122
123 /* open/close DATA stream */
124 nstrm = pr_netio_open(p, PR_NETIO_STRM_DATA, fd, PR_NETIO_IO_WR);
125 fail_unless(nstrm != NULL, "Failed to open data stream on fd %d: %s", fd,
126 strerror(errno));
127 fail_unless(nstrm->strm_netio != NULL,
128 "Failed to assign owning NetIO to stream");
129 pr_netio_close(nstrm);
130
131 /* open/close OTHR stream */
132 nstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, fd, PR_NETIO_IO_WR);
133 fail_unless(nstrm != NULL, "Failed to open othr stream on fd %d: %s", fd,
134 strerror(errno));
135 fail_unless(nstrm->strm_netio != NULL,
136 "Failed to assign owning NetIO to stream");
137 pr_netio_close(nstrm);
138 }
139 END_TEST
140
START_TEST(netio_postopen_test)141 START_TEST (netio_postopen_test) {
142 pr_netio_stream_t *nstrm;
143 int fd = -1, res;
144
145 res = pr_netio_postopen(NULL);
146 fail_unless(res < 0, "Failed to handle null argument");
147 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
148 strerror(errno), errno);
149
150 /* open/postopen/close CTRL stream */
151 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
152 fail_unless(nstrm != NULL, "Failed to open stream on fd %d: %s", fd,
153 strerror(errno));
154
155 res = pr_netio_postopen(nstrm);
156 fail_unless(res == 0, "Failed to post-open ctrl stream: %s", strerror(errno));
157 (void) pr_netio_close(nstrm);
158
159 /* open/postopen/close DATA stream */
160 nstrm = pr_netio_open(p, PR_NETIO_STRM_DATA, fd, PR_NETIO_IO_RD);
161 fail_unless(nstrm != NULL, "Failed to open stream on fd %d: %s", fd,
162 strerror(errno));
163
164 res = pr_netio_postopen(nstrm);
165 fail_unless(res == 0, "Failed to post-open data stream: %s", strerror(errno));
166 (void) pr_netio_close(nstrm);
167
168 /* open/postopen/close OTHR stream */
169 nstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, fd, PR_NETIO_IO_RD);
170 fail_unless(nstrm != NULL, "Failed to open stream on fd %d: %s", fd,
171 strerror(errno));
172
173 res = pr_netio_postopen(nstrm);
174 fail_unless(res == 0, "Failed to post-open othr stream: %s", strerror(errno));
175 (void) pr_netio_close(nstrm);
176 }
177 END_TEST
178
START_TEST(netio_close_test)179 START_TEST (netio_close_test) {
180 pr_netio_stream_t *nstrm;
181 int res, fd = -1;
182
183 res = pr_netio_close(NULL);
184 fail_unless(res == -1, "Failed to handle null stream argument");
185 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
186 strerror(errno), errno);
187
188 /* Open/close CTRL stream */
189 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
190 nstrm->strm_type = 7777;
191
192 res = pr_netio_close(nstrm);
193 fail_unless(res == -1, "Failed to handle unknown stream type argument");
194 fail_unless(errno == EPERM, "Failed to set errno to EPERM, got %s (%d)",
195 strerror(errno), errno);
196
197 nstrm->strm_type = PR_NETIO_STRM_CTRL;
198 res = pr_netio_close(nstrm);
199 fail_unless(res == -1, "Failed to handle bad file descriptor");
200 fail_unless(errno == EBADF, "Failed to set errno to EBADF, got %s (%d)",
201 strerror(errno), errno);
202
203 /* Open/close DATA stream */
204 nstrm = pr_netio_open(p, PR_NETIO_STRM_DATA, fd, PR_NETIO_IO_RD);
205 res = pr_netio_close(nstrm);
206 fail_unless(res == -1, "Failed to handle bad file descriptor");
207 fail_unless(errno == EBADF, "Failed to set errno to EBADF, got %s (%d)",
208 strerror(errno), errno);
209
210 /* Open/close OTHR stream */
211 nstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, fd, PR_NETIO_IO_RD);
212 res = pr_netio_close(nstrm);
213 fail_unless(res == -1, "Failed to handle bad file descriptor");
214 fail_unless(errno == EBADF, "Failed to set errno to EBADF, got %s (%d)",
215 strerror(errno), errno);
216 }
217 END_TEST
218
START_TEST(netio_lingering_close_test)219 START_TEST (netio_lingering_close_test) {
220 pr_netio_stream_t *nstrm;
221 int res, fd = -1;
222 long linger = 0L;
223
224 res = pr_netio_lingering_close(NULL, linger);
225 fail_unless(res == -1, "Failed to handle null stream argument");
226 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
227 strerror(errno), errno);
228
229 /* Open/close CTRL stream */
230 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
231 nstrm->strm_type = 7777;
232
233 res = pr_netio_lingering_close(nstrm, linger);
234 fail_unless(res < 0, "Failed to handle unknown stream type argument");
235 fail_unless(errno == EPERM, "Failed to set errno to EPERM, got %s (%d)",
236 strerror(errno), errno);
237
238 nstrm->strm_type = PR_NETIO_STRM_CTRL;
239 res = pr_netio_lingering_close(nstrm, linger);
240 fail_unless(res == 0, "Failed to close stream: %s", strerror(errno));
241
242 /* Open/close DATA stream */
243 nstrm = pr_netio_open(p, PR_NETIO_STRM_DATA, fd, PR_NETIO_IO_RD);
244 res = pr_netio_lingering_close(nstrm, linger);
245 fail_unless(res == 0, "Failed to close stream: %s", strerror(errno));
246
247 /* Open/close OTHR stream */
248 nstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, fd, PR_NETIO_IO_RD);
249 res = pr_netio_lingering_close(nstrm, linger);
250 fail_unless(res == 0, "Failed to close stream: %s", strerror(errno));
251 }
252 END_TEST
253
START_TEST(netio_reopen_test)254 START_TEST (netio_reopen_test) {
255 pr_netio_stream_t *nstrm, *nstrm2;
256 int res, fd = -1;
257
258 nstrm2 = pr_netio_reopen(NULL, fd, PR_NETIO_IO_RD);
259 fail_unless(nstrm2 == NULL, "Failed to handle null stream argument");
260 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
261 strerror(errno), errno);
262
263 /* Open/reopen/close CTRL stream */
264 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
265 nstrm->strm_type = 7777;
266
267 nstrm2 = pr_netio_reopen(nstrm, fd, PR_NETIO_IO_RD);
268 fail_unless(nstrm2 == NULL, "Failed to handle unknown stream type argument");
269 fail_unless(errno == EPERM, "Failed to set errno to EPERM, got %s (%d)",
270 strerror(errno), errno);
271
272 nstrm->strm_type = PR_NETIO_STRM_CTRL;
273 nstrm2 = pr_netio_reopen(nstrm, fd, PR_NETIO_IO_RD);
274 fail_unless(nstrm2 != NULL, "Failed to reopen ctrl stream: %s",
275 strerror(errno));
276
277 /* Open/reopen/close DATA stream */
278 nstrm = pr_netio_open(p, PR_NETIO_STRM_DATA, fd, PR_NETIO_IO_RD);
279 nstrm2 = pr_netio_reopen(nstrm, fd, PR_NETIO_IO_RD);
280 fail_unless(nstrm2 != NULL, "Failed to reopen data stream: %s",
281 strerror(errno));
282
283 res = pr_netio_close(nstrm);
284 fail_unless(res == -1, "Failed to handle bad file descriptor");
285 fail_unless(errno == EBADF, "Failed to set errno to EBADF, got %s (%d)",
286 strerror(errno), errno);
287
288 /* Open/reopen/close OTHR stream */
289 nstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, fd, PR_NETIO_IO_RD);
290 nstrm2 = pr_netio_reopen(nstrm, fd, PR_NETIO_IO_RD);
291 fail_unless(nstrm2 != NULL, "Failed to reopen othr stream: %s",
292 strerror(errno));
293
294 res = pr_netio_close(nstrm);
295 fail_unless(res == -1, "Failed to handle bad file descriptor");
296 fail_unless(errno == EBADF, "Failed to set errno to EBADF, got %s (%d)",
297 strerror(errno), errno);
298 }
299 END_TEST
300
START_TEST(netio_buffer_alloc_test)301 START_TEST (netio_buffer_alloc_test) {
302 pr_buffer_t *pbuf;
303 pr_netio_stream_t *nstrm;
304
305 pbuf = pr_netio_buffer_alloc(NULL);
306 fail_unless(pbuf == NULL, "Failed to handle null arguments");
307 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
308 strerror(errno), errno);
309
310 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
311
312 pbuf = pr_netio_buffer_alloc(nstrm);
313 fail_unless(pbuf != NULL, "Failed to allocate buffer: %s", strerror(errno));
314
315 pr_netio_close(nstrm);
316 }
317 END_TEST
318
START_TEST(netio_telnet_gets_args_test)319 START_TEST (netio_telnet_gets_args_test) {
320 char *buf, *res;
321 pr_netio_stream_t *in, *out;
322
323 res = pr_netio_telnet_gets(NULL, 0, NULL, NULL);
324 fail_unless(res == NULL, "Failed to handle null arguments");
325 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
326 strerror(errno), errno);
327
328 buf = "";
329 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
330 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
331
332 res = pr_netio_telnet_gets(buf, 0, in, out);
333 fail_unless(res == NULL,
334 "Failed to handle zero-length buffer length argument");
335 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
336 strerror(errno), errno);
337
338 res = pr_netio_telnet_gets(buf, 1, NULL, out);
339 fail_unless(res == NULL, "Failed to handle null input stream argument");
340 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
341 strerror(errno), errno);
342
343 res = pr_netio_telnet_gets(buf, 1, in, NULL);
344 fail_unless(res == NULL, "Failed to handle null output stream argument");
345 fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %s (%d)",
346 strerror(errno), errno);
347
348 pr_netio_close(in);
349 pr_netio_close(out);
350 }
351 END_TEST
352
START_TEST(netio_telnet_gets_single_line_test)353 START_TEST (netio_telnet_gets_single_line_test) {
354 char buf[256], *cmd, *res;
355 pr_netio_stream_t *in, *out;
356 pr_buffer_t *pbuf;
357 int len, xerrno;
358
359 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
360 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
361
362 cmd = "Hello, World!\n";
363
364 pr_netio_buffer_alloc(in);
365 pbuf = in->strm_buf;
366 len = snprintf(pbuf->buf, pbuf->buflen-1, "%s", cmd);
367 pbuf->remaining = pbuf->buflen - len;
368 pbuf->current = pbuf->buf;
369
370 buf[sizeof(buf)-1] = '\0';
371
372 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
373 xerrno = errno;
374
375 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
376 xerrno, strerror(xerrno));
377 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
378 buf);
379 fail_unless(pbuf->remaining == (size_t) xfer_bufsz,
380 "Expected %d remaining bytes, got %lu", xfer_bufsz,
381 (unsigned long) pbuf->remaining);
382
383 pr_netio_close(in);
384 pr_netio_close(out);
385 }
386 END_TEST
387
START_TEST(netio_telnet_gets_multi_line_test)388 START_TEST (netio_telnet_gets_multi_line_test) {
389 char buf[256], *cmd, *first_cmd, *second_cmd, *res;
390 pr_netio_stream_t *in, *out;
391 pr_buffer_t *pbuf;
392 int len, xerrno;
393
394 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
395 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
396
397 /* Note: the line terminator in Telnet is CRLF, not just a bare LF. */
398 cmd = "Hello, World!\r\nHow are you?\r\n";
399 first_cmd = "Hello, World!\n";
400 second_cmd = "How are you?\n";
401
402 pr_netio_buffer_alloc(in);
403 pbuf = in->strm_buf;
404 len = snprintf(pbuf->buf, pbuf->buflen-1, "%s", cmd);
405 pbuf->remaining = pbuf->buflen - len;
406 pbuf->current = pbuf->buf;
407
408 buf[sizeof(buf)-1] = '\0';
409
410 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
411 xerrno = errno;
412
413 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
414 xerrno, strerror(xerrno));
415 fail_unless(strcmp(buf, first_cmd) == 0, "Expected string '%s', got '%s'",
416 first_cmd, buf);
417
418 memset(buf, '\0', sizeof(buf));
419 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
420 xerrno = errno;
421
422 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
423 xerrno, strerror(xerrno));
424 fail_unless(strcmp(buf, second_cmd) == 0, "Expected string '%s', got '%s'",
425 second_cmd, buf);
426
427 fail_unless(pbuf->remaining == (size_t) xfer_bufsz,
428 "Expected %d remaining bytes, got %lu", xfer_bufsz,
429 (unsigned long) pbuf->remaining);
430
431 pr_netio_close(in);
432 pr_netio_close(out);
433 }
434 END_TEST
435
START_TEST(netio_telnet_gets_no_newline_test)436 START_TEST (netio_telnet_gets_no_newline_test) {
437 char buf[8], *cmd, *res;
438 pr_netio_stream_t *in, *out;
439 pr_buffer_t *pbuf;
440 int len, xerrno;
441
442 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
443 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
444
445 cmd = "Hello, World!";
446
447 pr_netio_buffer_alloc(in);
448 pbuf = in->strm_buf;
449 len = snprintf(pbuf->buf, pbuf->buflen-1, "%s", cmd);
450 pbuf->remaining = pbuf->buflen - len;
451 pbuf->current = pbuf->buf;
452
453 buf[sizeof(buf)-1] = '\0';
454
455 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
456 xerrno = errno;
457
458 fail_unless(res == NULL, "Read in string unexpectedly, got '%s'", buf);
459 fail_unless(xerrno == E2BIG, "Failed to set errno to E2BIG, got (%d) %s",
460 xerrno, strerror(xerrno));
461
462 pr_netio_close(in);
463 pr_netio_close(out);
464 }
465 END_TEST
466
START_TEST(netio_telnet_gets_telnet_will_test)467 START_TEST (netio_telnet_gets_telnet_will_test) {
468 char buf[256], *cmd, *res, telnet_opt;
469 pr_netio_stream_t *in, *out;
470 pr_buffer_t *pbuf;
471 int len, out_fd, xerrno;
472
473 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
474
475 out_fd = open_tmpfile();
476 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, out_fd, PR_NETIO_IO_WR);
477
478 cmd = "Hello, World!\n";
479
480 pr_netio_buffer_alloc(in);
481 pbuf = in->strm_buf;
482
483 telnet_opt = 7;
484 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%c%cWorld!\n", TELNET_IAC,
485 TELNET_WILL, telnet_opt);
486 pbuf->remaining = pbuf->buflen - len;
487 pbuf->current = pbuf->buf;
488
489 buf[sizeof(buf)-1] = '\0';
490
491 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
492 xerrno = errno;
493
494 pr_netio_close(in);
495
496 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
497 xerrno, strerror(xerrno));
498 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
499 buf);
500
501 /* Rewind the output stream fd. */
502 lseek(out_fd, 0, SEEK_SET);
503 len = read(out_fd, buf, sizeof(buf)-1);
504 pr_netio_close(out);
505
506 fail_unless(len == 3, "Expected to read 3 bytes from output stream, got %d",
507 len);
508 fail_unless(buf[0] == (char) TELNET_IAC, "Expected IAC at index 0, got %d",
509 buf[0]);
510 fail_unless(buf[1] == (char) TELNET_DONT, "Expected DONT at index 1, got %d",
511 buf[1]);
512 fail_unless(buf[2] == telnet_opt, "Expected opt '%c' at index 2, got %c",
513 telnet_opt, buf[2]);
514
515 test_cleanup();
516 }
517 END_TEST
518
START_TEST(netio_telnet_gets_telnet_bare_will_test)519 START_TEST (netio_telnet_gets_telnet_bare_will_test) {
520 char buf[256], *cmd, *res, telnet_opt;
521 pr_netio_stream_t *in, *out;
522 pr_buffer_t *pbuf;
523 int len, xerrno;
524
525 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
526 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
527
528 cmd = "Hello, World!\n";
529
530 pr_netio_buffer_alloc(in);
531 pbuf = in->strm_buf;
532
533 telnet_opt = 7;
534 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%cWorld!\n", TELNET_WILL,
535 telnet_opt);
536 pbuf->remaining = pbuf->buflen - len;
537 pbuf->current = pbuf->buf;
538
539 buf[sizeof(buf)-1] = '\0';
540
541 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
542 xerrno = errno;
543
544 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
545 xerrno, strerror(xerrno));
546 fail_unless(strncmp(buf, cmd, 7) == 0, "Expected string '%*s', got '%*s'",
547 7, cmd, 7, buf);
548 fail_unless(buf[7] == (char) TELNET_WILL, "Expected WILL at index 7, got %d",
549 buf[7]);
550 fail_unless(buf[8] == telnet_opt, "Expected Telnet opt %c at index 8, got %d",
551 telnet_opt, buf[8]);
552 fail_unless(strcmp(buf + 9, cmd + 7) == 0, "Expected string '%s', got '%s'",
553 cmd + 7, buf + 9);
554
555 pr_netio_close(in);
556 pr_netio_close(out);
557 }
558 END_TEST
559
START_TEST(netio_telnet_gets_telnet_will_multi_read_test)560 START_TEST (netio_telnet_gets_telnet_will_multi_read_test) {
561 char buf[256], *cmd, *res, telnet_opt;
562 pr_netio_stream_t *in, *out;
563 pr_buffer_t *pbuf;
564 int len, out_fd, xerrno;
565
566 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
567
568 out_fd = open_tmpfile();
569 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, out_fd, PR_NETIO_IO_WR);
570
571 cmd = "Hello, World!\n";
572
573 pr_netio_buffer_alloc(in);
574 pbuf = in->strm_buf;
575
576 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%c", TELNET_IAC,
577 TELNET_WILL);
578 pbuf->remaining = pbuf->buflen - len;
579 pbuf->current = pbuf->buf;
580
581 buf[sizeof(buf)-1] = '\0';
582
583 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
584 xerrno = errno;
585
586 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
587 xerrno, strerror(xerrno));
588 fail_unless(strncmp(buf, cmd, 7) == 0, "Expected string '%*s', got '%*s'",
589 7, cmd, 7, buf);
590
591 /* Fill up the input stream's buffer with the rest of the Telnet WILL
592 * sequence.
593 */
594 telnet_opt = 7;
595 len = snprintf(pbuf->buf, pbuf->buflen-1, "%cWorld!\n", telnet_opt);
596 pbuf->remaining = pbuf->buflen - len;
597 pbuf->current = pbuf->buf;
598
599 /* Read again, to see if the state was preserved across multiple calls
600 * to pr_netio_telnet_gets().
601 */
602 res = pr_netio_telnet_gets(buf + 7, sizeof(buf)-8, in, out);
603 xerrno = errno;
604
605 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
606 xerrno, strerror(xerrno));
607 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'",
608 cmd, buf);
609
610 pr_netio_close(in);
611
612 /* Rewind the output stream fd. */
613 lseek(out_fd, 0, SEEK_SET);
614 len = read(out_fd, buf, sizeof(buf)-1);
615 pr_netio_close(out);
616
617 fail_unless(len == 3, "Expected to read 3 bytes from output stream, got %d",
618 len);
619 fail_unless(buf[0] == (char) TELNET_IAC, "Expected IAC at index 0, got %d",
620 buf[0]);
621 fail_unless(buf[1] == (char) TELNET_DONT, "Expected DONT at index 1, got %d",
622 buf[1]);
623 fail_unless(buf[2] == telnet_opt, "Expected %c at index 2, got %d",
624 telnet_opt, buf[2]);
625
626 test_cleanup();
627 }
628 END_TEST
629
START_TEST(netio_telnet_gets_telnet_wont_test)630 START_TEST (netio_telnet_gets_telnet_wont_test) {
631 char buf[256], *cmd, *res, telnet_opt;
632 pr_netio_stream_t *in, *out;
633 pr_buffer_t *pbuf;
634 int len, out_fd, xerrno;
635
636 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
637
638 out_fd = open_tmpfile();
639 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, out_fd, PR_NETIO_IO_WR);
640
641 cmd = "Hello, World!\n";
642
643 pr_netio_buffer_alloc(in);
644 pbuf = in->strm_buf;
645
646 telnet_opt = 7;
647 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%c%cWorld!\n", TELNET_IAC,
648 TELNET_WONT, telnet_opt);
649 pbuf->remaining = pbuf->buflen - len;
650 pbuf->current = pbuf->buf;
651
652 buf[sizeof(buf)-1] = '\0';
653
654 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
655 xerrno = errno;
656
657 pr_netio_close(in);
658
659 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
660 xerrno, strerror(xerrno));
661 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
662 buf);
663
664 /* Rewind the output stream fd. */
665 lseek(out_fd, 0, SEEK_SET);
666 len = read(out_fd, buf, sizeof(buf)-1);
667 pr_netio_close(out);
668
669 fail_unless(len == 3, "Expected to read 3 bytes from output stream, got %d",
670 len);
671 fail_unless(buf[0] == (char) TELNET_IAC, "Expected IAC at index 0, got %d",
672 buf[0]);
673 fail_unless(buf[1] == (char) TELNET_DONT, "Expected DONT at index 1, got %d",
674 buf[1]);
675 fail_unless(buf[2] == telnet_opt, "Expected opt '%c' at index 2, got %c",
676 telnet_opt, buf[2]);
677
678 test_cleanup();
679 }
680 END_TEST
681
START_TEST(netio_telnet_gets_telnet_bare_wont_test)682 START_TEST (netio_telnet_gets_telnet_bare_wont_test) {
683 char buf[256], *cmd, *res, telnet_opt;
684 pr_netio_stream_t *in, *out;
685 pr_buffer_t *pbuf;
686 int len, xerrno;
687
688 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
689 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
690
691 cmd = "Hello, World!\n";
692
693 pr_netio_buffer_alloc(in);
694 pbuf = in->strm_buf;
695
696 telnet_opt = 7;
697 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%cWorld!\n", TELNET_WONT,
698 telnet_opt);
699 pbuf->remaining = pbuf->buflen - len;
700 pbuf->current = pbuf->buf;
701
702 buf[sizeof(buf)-1] = '\0';
703
704 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
705 xerrno = errno;
706
707 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
708 xerrno, strerror(xerrno));
709 fail_unless(strncmp(buf, cmd, 7) == 0, "Expected string '%*s', got '%*s'",
710 7, cmd, 7, buf);
711 fail_unless(buf[7] == (char) TELNET_WONT, "Expected WONT at index 7, got %d",
712 buf[7]);
713 fail_unless(buf[8] == telnet_opt, "Expected Telnet opt %c at index 8, got %d",
714 telnet_opt, buf[8]);
715 fail_unless(strcmp(buf + 9, cmd + 7) == 0, "Expected string '%s', got '%s'",
716 cmd + 7, buf + 9);
717
718 pr_netio_close(in);
719 pr_netio_close(out);
720 }
721 END_TEST
722
START_TEST(netio_telnet_gets_telnet_do_test)723 START_TEST (netio_telnet_gets_telnet_do_test) {
724 char buf[256], *cmd, *res, telnet_opt;
725 pr_netio_stream_t *in, *out;
726 pr_buffer_t *pbuf;
727 int len, out_fd, xerrno;
728
729 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
730
731 out_fd = open_tmpfile();
732 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, out_fd, PR_NETIO_IO_WR);
733
734 cmd = "Hello, World!\n";
735
736 pr_netio_buffer_alloc(in);
737 pbuf = in->strm_buf;
738
739 telnet_opt = 7;
740 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%c%cWorld!\n", TELNET_IAC,
741 TELNET_DO, telnet_opt);
742 pbuf->remaining = pbuf->buflen - len;
743 pbuf->current = pbuf->buf;
744
745 buf[sizeof(buf)-1] = '\0';
746
747 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
748 xerrno = errno;
749
750 pr_netio_close(in);
751
752 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
753 xerrno, strerror(xerrno));
754 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
755 buf);
756
757 /* Rewind the output stream fd. */
758 lseek(out_fd, 0, SEEK_SET);
759 len = read(out_fd, buf, sizeof(buf)-1);
760 pr_netio_close(out);
761
762 fail_unless(len == 3, "Expected to read 3 bytes from output stream, got %d",
763 len);
764 fail_unless(buf[0] == (char) TELNET_IAC, "Expected IAC at index 0, got %d",
765 buf[0]);
766 fail_unless(buf[1] == (char) TELNET_WONT, "Expected WONT at index 1, got %d",
767 buf[1]);
768 fail_unless(buf[2] == telnet_opt, "Expected opt '%c' at index 2, got %c",
769 telnet_opt, buf[2]);
770
771 test_cleanup();
772 }
773 END_TEST
774
START_TEST(netio_telnet_gets_telnet_bare_do_test)775 START_TEST (netio_telnet_gets_telnet_bare_do_test) {
776 char buf[256], *cmd, *res, telnet_opt;
777 pr_netio_stream_t *in, *out;
778 pr_buffer_t *pbuf;
779 int len, xerrno;
780
781 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
782 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
783
784 cmd = "Hello, World!\n";
785
786 pr_netio_buffer_alloc(in);
787 pbuf = in->strm_buf;
788
789 telnet_opt = 7;
790 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%cWorld!\n", TELNET_DO,
791 telnet_opt);
792 pbuf->remaining = pbuf->buflen - len;
793 pbuf->current = pbuf->buf;
794
795 buf[sizeof(buf)-1] = '\0';
796
797 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
798 xerrno = errno;
799
800 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
801 xerrno, strerror(xerrno));
802 fail_unless(strncmp(buf, cmd, 7) == 0, "Expected string '%*s', got '%*s'",
803 7, cmd, 7, buf);
804 fail_unless(buf[7] == (char) TELNET_DO, "Expected DO at index 7, got %d",
805 buf[7]);
806 fail_unless(buf[8] == telnet_opt, "Expected Telnet opt %c at index 8, got %d",
807 telnet_opt, buf[8]);
808 fail_unless(strcmp(buf + 9, cmd + 7) == 0, "Expected string '%s', got '%s'",
809 cmd + 7, buf + 9);
810
811 pr_netio_close(in);
812 pr_netio_close(out);
813 }
814 END_TEST
815
START_TEST(netio_telnet_gets_telnet_dont_test)816 START_TEST (netio_telnet_gets_telnet_dont_test) {
817 char buf[256], *cmd, *res, telnet_opt;
818 pr_netio_stream_t *in, *out;
819 pr_buffer_t *pbuf;
820 int len, out_fd, xerrno;
821
822 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
823
824 out_fd = open_tmpfile();
825 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, out_fd, PR_NETIO_IO_WR);
826
827 cmd = "Hello, World!\n";
828
829 pr_netio_buffer_alloc(in);
830 pbuf = in->strm_buf;
831
832 telnet_opt = 7;
833 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%c%cWorld!\n", TELNET_IAC,
834 TELNET_DONT, telnet_opt);
835 pbuf->remaining = pbuf->buflen - len;
836 pbuf->current = pbuf->buf;
837
838 buf[sizeof(buf)-1] = '\0';
839
840 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
841 xerrno = errno;
842
843 pr_netio_close(in);
844
845 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
846 xerrno, strerror(xerrno));
847 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
848 buf);
849
850 /* Rewind the output stream fd. */
851 lseek(out_fd, 0, SEEK_SET);
852 len = read(out_fd, buf, sizeof(buf)-1);
853 pr_netio_close(out);
854
855 fail_unless(len == 3, "Expected to read 3 bytes from output stream, got %d",
856 len);
857 fail_unless(buf[0] == (char) TELNET_IAC, "Expected IAC at index 0, got %d",
858 buf[0]);
859 fail_unless(buf[1] == (char) TELNET_WONT, "Expected WONT at index 1, got %d",
860 buf[1]);
861 fail_unless(buf[2] == telnet_opt, "Expected opt '%c' at index 2, got %c",
862 telnet_opt, buf[2]);
863
864 test_cleanup();
865 }
866 END_TEST
867
START_TEST(netio_telnet_gets_telnet_bare_dont_test)868 START_TEST (netio_telnet_gets_telnet_bare_dont_test) {
869 char buf[256], *cmd, *res, telnet_opt;
870 pr_netio_stream_t *in, *out;
871 pr_buffer_t *pbuf;
872 int len, xerrno;
873
874 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
875 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
876
877 cmd = "Hello, World!\n";
878
879 pr_netio_buffer_alloc(in);
880 pbuf = in->strm_buf;
881
882 telnet_opt = 7;
883 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%cWorld!\n", TELNET_DONT,
884 telnet_opt);
885 pbuf->remaining = pbuf->buflen - len;
886 pbuf->current = pbuf->buf;
887
888 buf[sizeof(buf)-1] = '\0';
889
890 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
891 xerrno = errno;
892
893 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
894 xerrno, strerror(xerrno));
895 fail_unless(strncmp(buf, cmd, 7) == 0, "Expected string '%*s', got '%*s'",
896 7, cmd, 7, buf);
897 fail_unless(buf[7] == (char) TELNET_DONT, "Expected DONT at index 7, got %d",
898 buf[7]);
899 fail_unless(buf[8] == telnet_opt, "Expected Telnet opt %c at index 8, got %d",
900 telnet_opt, buf[8]);
901 fail_unless(strcmp(buf + 9, cmd + 7) == 0, "Expected string '%s', got '%s'",
902 cmd + 7, buf + 9);
903
904 pr_netio_close(in);
905 pr_netio_close(out);
906 }
907 END_TEST
908
START_TEST(netio_telnet_gets_telnet_ip_test)909 START_TEST (netio_telnet_gets_telnet_ip_test) {
910 char buf[256], *cmd, *res;
911 pr_netio_stream_t *in, *out;
912 pr_buffer_t *pbuf;
913 int len, xerrno;
914
915 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
916 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
917
918 cmd = "Hello, World!\n";
919
920 pr_netio_buffer_alloc(in);
921 pbuf = in->strm_buf;
922
923 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%cWorld!\n", TELNET_IAC,
924 TELNET_IP);
925 pbuf->remaining = pbuf->buflen - len;
926 pbuf->current = pbuf->buf;
927
928 buf[sizeof(buf)-1] = '\0';
929
930 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
931 xerrno = errno;
932
933 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
934 xerrno, strerror(xerrno));
935 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
936 buf);
937
938 pr_netio_close(in);
939 pr_netio_close(out);
940 }
941 END_TEST
942
START_TEST(netio_telnet_gets_telnet_bare_ip_test)943 START_TEST (netio_telnet_gets_telnet_bare_ip_test) {
944 char buf[256], *cmd, *res;
945 pr_netio_stream_t *in, *out;
946 pr_buffer_t *pbuf;
947 int len, xerrno;
948
949 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
950 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
951
952 cmd = "Hello, World!\n";
953
954 pr_netio_buffer_alloc(in);
955 pbuf = in->strm_buf;
956
957 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %cWorld!\n", TELNET_IP);
958 pbuf->remaining = pbuf->buflen - len;
959 pbuf->current = pbuf->buf;
960
961 buf[sizeof(buf)-1] = '\0';
962
963 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
964 xerrno = errno;
965
966 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
967 xerrno, strerror(xerrno));
968 fail_unless(strncmp(buf, cmd, 7) == 0, "Expected string '%*s', got '%*s'",
969 7, cmd, 7, buf);
970 fail_unless(buf[7] == (char) TELNET_IP, "Expected IP at index 7, got %d",
971 buf[7]);
972 fail_unless(strcmp(buf + 8, cmd + 7) == 0, "Expected string '%s', got '%s'",
973 cmd + 7, buf + 8);
974
975 pr_netio_close(in);
976 pr_netio_close(out);
977 }
978 END_TEST
979
START_TEST(netio_telnet_gets_telnet_dm_test)980 START_TEST (netio_telnet_gets_telnet_dm_test) {
981 char buf[256], *cmd, *res;
982 pr_netio_stream_t *in, *out;
983 pr_buffer_t *pbuf;
984 int len, xerrno;
985
986 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
987 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
988
989 cmd = "Hello, World!\n";
990
991 pr_netio_buffer_alloc(in);
992 pbuf = in->strm_buf;
993
994 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%cWorld!\n", TELNET_IAC,
995 TELNET_DM);
996 pbuf->remaining = pbuf->buflen - len;
997 pbuf->current = pbuf->buf;
998
999 buf[sizeof(buf)-1] = '\0';
1000
1001 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
1002 xerrno = errno;
1003
1004 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
1005 xerrno, strerror(xerrno));
1006 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
1007 buf);
1008
1009 pr_netio_close(in);
1010 pr_netio_close(out);
1011 }
1012 END_TEST
1013
START_TEST(netio_telnet_gets_telnet_bare_dm_test)1014 START_TEST (netio_telnet_gets_telnet_bare_dm_test) {
1015 char buf[256], *cmd, *res;
1016 pr_netio_stream_t *in, *out;
1017 pr_buffer_t *pbuf;
1018 int len, xerrno;
1019
1020 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
1021 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
1022
1023 cmd = "Hello, World!\n";
1024
1025 pr_netio_buffer_alloc(in);
1026 pbuf = in->strm_buf;
1027
1028 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %cWorld!\n", TELNET_DM);
1029 pbuf->remaining = pbuf->buflen - len;
1030 pbuf->current = pbuf->buf;
1031
1032 buf[sizeof(buf)-1] = '\0';
1033
1034 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
1035 xerrno = errno;
1036
1037 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
1038 xerrno, strerror(xerrno));
1039 fail_unless(strncmp(buf, cmd, 7) == 0, "Expected string '%*s', got '%*s'",
1040 7, cmd, 7, buf);
1041 fail_unless(buf[7] == (char) TELNET_DM, "Expected DM at index 7, got %d",
1042 buf[7]);
1043 fail_unless(strcmp(buf + 8, cmd + 7) == 0, "Expected string '%s', got '%s'",
1044 cmd + 7, buf + 8);
1045
1046 pr_netio_close(in);
1047 pr_netio_close(out);
1048 }
1049 END_TEST
1050
START_TEST(netio_telnet_gets_telnet_single_iac_test)1051 START_TEST (netio_telnet_gets_telnet_single_iac_test) {
1052 char buf[256], *cmd, *res;
1053 pr_netio_stream_t *in, *out;
1054 pr_buffer_t *pbuf;
1055 int len, xerrno;
1056
1057 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
1058 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
1059
1060 cmd = "Hello, World!\n";
1061
1062 pr_netio_buffer_alloc(in);
1063 pbuf = in->strm_buf;
1064
1065 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %cWorld!\n", TELNET_IAC);
1066 pbuf->remaining = pbuf->buflen - len;
1067 pbuf->current = pbuf->buf;
1068
1069 buf[sizeof(buf)-1] = '\0';
1070
1071 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
1072 xerrno = errno;
1073
1074 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
1075 xerrno, strerror(xerrno));
1076 fail_unless(strncmp(buf, cmd, 7) == 0, "Expected string '%*s', got '%*s'",
1077 7, cmd, 7, buf);
1078 fail_unless(buf[7] == (char) TELNET_IAC, "Expected IAC at index 7, got %d",
1079 buf[7]);
1080 fail_unless(strcmp(buf + 8, cmd + 7) == 0, "Expected string '%s', got '%s'",
1081 cmd + 7, buf + 8);
1082
1083 pr_netio_close(in);
1084 pr_netio_close(out);
1085 }
1086 END_TEST
1087
START_TEST(netio_telnet_gets_bug3521_test)1088 START_TEST (netio_telnet_gets_bug3521_test) {
1089 char buf[10], *res, telnet_opt;
1090 pr_netio_stream_t *in, *out;
1091 pr_buffer_t *pbuf;
1092 int len, xerrno;
1093
1094 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
1095 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
1096
1097 pr_netio_buffer_alloc(in);
1098 pbuf = in->strm_buf;
1099
1100 telnet_opt = 7;
1101 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%c%c%cWorld!\n",
1102 TELNET_IAC, TELNET_IAC, TELNET_WILL, telnet_opt);
1103 pbuf->remaining = pbuf->buflen - len;
1104 pbuf->current = pbuf->buf;
1105
1106 buf[sizeof(buf)-1] = '\0';
1107
1108 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
1109 xerrno = errno;
1110
1111 fail_unless(res == NULL, "Expected null");
1112 fail_unless(xerrno == E2BIG, "Failed to set errno to E2BIG, got %s (%d)",
1113 strerror(xerrno), xerrno);
1114
1115 pr_netio_close(in);
1116 pr_netio_close(out);
1117 }
1118 END_TEST
1119
START_TEST(netio_telnet_gets_bug3697_test)1120 START_TEST (netio_telnet_gets_bug3697_test) {
1121 char buf[256], *cmd, *res;
1122 pr_netio_stream_t *in, *out;
1123 pr_buffer_t *pbuf;
1124 int len, xerrno;
1125
1126 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
1127 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
1128
1129 cmd = "Hello, World!\n";
1130
1131 pr_netio_buffer_alloc(in);
1132 pbuf = in->strm_buf;
1133
1134 len = snprintf(pbuf->buf, pbuf->buflen-1, "Hello, %c%cWorld!\n", TELNET_IAC,
1135 TELNET_IAC);
1136 pbuf->remaining = pbuf->buflen - len;
1137 pbuf->current = pbuf->buf;
1138
1139 buf[sizeof(buf)-1] = '\0';
1140
1141 res = pr_netio_telnet_gets(buf, sizeof(buf)-1, in, out);
1142 xerrno = errno;
1143
1144 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
1145 xerrno, strerror(xerrno));
1146 fail_unless(strncmp(buf, cmd, 7) == 0, "Expected string '%*s', got '%*s'",
1147 7, cmd, 7, buf);
1148 fail_unless(buf[7] == (char) TELNET_IAC, "Expected IAC at index 7, got %d",
1149 buf[7]);
1150 fail_unless(strcmp(buf + 8, cmd + 7) == 0, "Expected string '%s', got '%s'",
1151 cmd + 7, buf + 8);
1152
1153 pr_netio_close(in);
1154 pr_netio_close(out);
1155 }
1156 END_TEST
1157
START_TEST(netio_telnet_gets_eof_test)1158 START_TEST (netio_telnet_gets_eof_test) {
1159 char buf[256], *cmd, *res;
1160 pr_netio_stream_t *in, *out;
1161 pr_buffer_t *pbuf;
1162 int len, xerrno;
1163
1164 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
1165 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
1166
1167 cmd = "Hello, World!";
1168
1169 pr_netio_buffer_alloc(in);
1170 pbuf = in->strm_buf;
1171
1172 len = snprintf(pbuf->buf, pbuf->buflen-1, "%s", cmd);
1173 pbuf->remaining = pbuf->buflen - len;
1174 pbuf->current = pbuf->buf;
1175
1176 buf[sizeof(buf)-1] = '\0';
1177
1178 /* In this scenario, we have not supplied an LF, but the resulting buffer
1179 * is terminated with a NUL because of the end-of-stream (or error) checks
1180 * in pr_netio_telnet_gets(), when we read the input stream for more data
1181 * looking for that LF.
1182 */
1183 res = pr_netio_telnet_gets(buf, strlen(cmd) + 2, in, out);
1184 xerrno = errno;
1185
1186 fail_unless(res != NULL, "Failed to get string from stream: (%d) %s",
1187 xerrno, strerror(xerrno));
1188 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
1189 buf);
1190
1191 pr_netio_close(in);
1192 pr_netio_close(out);
1193 }
1194 END_TEST
1195
START_TEST(netio_telnet_gets2_single_line_test)1196 START_TEST (netio_telnet_gets2_single_line_test) {
1197 int res;
1198 char buf[256], *cmd;
1199 size_t cmd_len;
1200 pr_netio_stream_t *in, *out;
1201 pr_buffer_t *pbuf;
1202 int len, xerrno;
1203
1204 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
1205 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
1206
1207 cmd = "Hello, World!\n";
1208 cmd_len = strlen(cmd);
1209
1210 pr_netio_buffer_alloc(in);
1211 pbuf = in->strm_buf;
1212 len = snprintf(pbuf->buf, pbuf->buflen-1, "%s", cmd);
1213 pbuf->remaining = pbuf->buflen - len;
1214 pbuf->current = pbuf->buf;
1215
1216 buf[sizeof(buf)-1] = '\0';
1217
1218 res = pr_netio_telnet_gets2(buf, sizeof(buf)-1, in, out);
1219 xerrno = errno;
1220
1221 fail_unless(res > 0, "Failed to get string from stream: (%d) %s",
1222 xerrno, strerror(xerrno));
1223 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
1224 buf);
1225
1226 fail_unless((size_t) res == cmd_len, "Expected length %lu, got %d",
1227 (unsigned long) cmd_len, res);
1228 fail_unless(pbuf->remaining == (size_t) xfer_bufsz,
1229 "Expected %d remaining bytes, got %lu", xfer_bufsz,
1230 (unsigned long) pbuf->remaining);
1231
1232 pr_netio_close(in);
1233 pr_netio_close(out);
1234 }
1235 END_TEST
1236
START_TEST(netio_telnet_gets2_single_line_crnul_test)1237 START_TEST (netio_telnet_gets2_single_line_crnul_test) {
1238 int res;
1239 char buf[256], *cmd;
1240 size_t cmd_len;
1241 pr_netio_stream_t *in, *out;
1242 pr_buffer_t *pbuf;
1243 int xerrno;
1244
1245 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
1246 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
1247
1248 /* See Bug#4167. We cannot use strlen(3) due to the embedded NUL. */
1249 cmd = "Hello, \015\000World!\n";
1250 cmd_len = 14;
1251
1252 pr_netio_buffer_alloc(in);
1253 pbuf = in->strm_buf;
1254 memcpy(pbuf->buf, cmd, cmd_len);
1255 pbuf->remaining = pbuf->buflen - cmd_len;
1256 pbuf->current = pbuf->buf;
1257
1258 buf[sizeof(buf)-1] = '\0';
1259
1260 res = pr_netio_telnet_gets2(buf, sizeof(buf)-1, in, out);
1261 xerrno = errno;
1262
1263 fail_unless(res > 0, "Failed to get string from stream: (%d) %s",
1264 xerrno, strerror(xerrno));
1265 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
1266 buf);
1267
1268 fail_unless((size_t) res == cmd_len, "Expected length %lu, got %d",
1269 (unsigned long) cmd_len, res);
1270 fail_unless(pbuf->remaining == (size_t) xfer_bufsz,
1271 "Expected %d remaining bytes, got %lu", xfer_bufsz,
1272 (unsigned long) pbuf->remaining);
1273
1274 pr_netio_close(in);
1275 pr_netio_close(out);
1276 }
1277 END_TEST
1278
START_TEST(netio_telnet_gets2_single_line_lf_test)1279 START_TEST (netio_telnet_gets2_single_line_lf_test) {
1280 int res;
1281 char buf[256], *cmd;
1282 size_t cmd_len;
1283 pr_netio_stream_t *in, *out;
1284 pr_buffer_t *pbuf;
1285 int xerrno;
1286
1287 in = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
1288 out = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_WR);
1289
1290 cmd = "Hello, \012World!\n";
1291 cmd_len = strlen(cmd);
1292
1293 pr_netio_buffer_alloc(in);
1294 pbuf = in->strm_buf;
1295 memcpy(pbuf->buf, cmd, cmd_len);
1296 pbuf->remaining = pbuf->buflen - cmd_len;
1297 pbuf->current = pbuf->buf;
1298
1299 buf[sizeof(buf)-1] = '\0';
1300
1301 res = pr_netio_telnet_gets2(buf, sizeof(buf)-1, in, out);
1302 xerrno = errno;
1303
1304 fail_unless(res > 0, "Failed to get string from stream: (%d) %s",
1305 xerrno, strerror(xerrno));
1306 fail_unless(strcmp(buf, cmd) == 0, "Expected string '%s', got '%s'", cmd,
1307 buf);
1308
1309 fail_unless((size_t) res == cmd_len, "Expected length %lu, got %d",
1310 (unsigned long) cmd_len, res);
1311 fail_unless(pbuf->remaining == (size_t) xfer_bufsz,
1312 "Expected %d remaining bytes, got %lu", xfer_bufsz,
1313 (unsigned long) pbuf->remaining);
1314
1315 pr_netio_close(in);
1316 pr_netio_close(out);
1317 }
1318 END_TEST
1319
netio_poll_cb(pr_netio_stream_t * nstrm)1320 static int netio_poll_cb(pr_netio_stream_t *nstrm) {
1321 /* Always return >0, to indicate that we haven't timed out, AND that there
1322 * is a writable fd available.
1323 */
1324 return 7;
1325 }
1326
1327 static int netio_read_eof = FALSE;
1328 static int netio_read_epipe = FALSE;
1329
netio_read_cb(pr_netio_stream_t * nstrm,char * buf,size_t buflen)1330 static int netio_read_cb(pr_netio_stream_t *nstrm, char *buf, size_t buflen) {
1331 const char *text;
1332 int res;
1333
1334 if (netio_read_eof) {
1335 netio_read_eof = FALSE;
1336 return 0;
1337 }
1338
1339 if (netio_read_epipe) {
1340 netio_read_epipe = FALSE;
1341 errno = EPIPE;
1342 return -1;
1343 }
1344
1345 text = "Hello, World!\r\n";
1346 sstrncpy(buf, text, buflen);
1347
1348 /* Make sure the next read returns EOF. */
1349 netio_read_eof = TRUE;
1350
1351 res = strlen(text);
1352 return res;
1353 }
1354
1355 static int netio_write_epipe = FALSE;
1356
netio_write_cb(pr_netio_stream_t * nstrm,char * buf,size_t buflen)1357 static int netio_write_cb(pr_netio_stream_t *nstrm, char *buf, size_t buflen) {
1358 if (netio_write_epipe) {
1359 netio_write_epipe = FALSE;
1360 errno = EPIPE;
1361 return -1;
1362 }
1363
1364 return buflen;
1365 }
1366
netio_read_from_stream(int strm_type)1367 static int netio_read_from_stream(int strm_type) {
1368 int fd = 2, res;
1369 char buf[1024], *expected_text;
1370 size_t expected_sz;
1371 pr_netio_stream_t *nstrm;
1372
1373 res = pr_netio_read(NULL, NULL, 0, 0);
1374 if (res == 0) {
1375 errno = EINVAL;
1376 return -1;
1377 }
1378
1379 nstrm = pr_netio_open(p, strm_type, fd, PR_NETIO_IO_RD);
1380 if (nstrm == NULL) {
1381 int xerrno = errno;
1382
1383 pr_trace_msg("netio", 1, "error opening custom netio stream: %s",
1384 strerror(xerrno));
1385 errno = xerrno;
1386 return -1;
1387 }
1388
1389 res = pr_netio_read(nstrm, NULL, 0, 0);
1390 if (res == 0) {
1391 pr_netio_close(nstrm);
1392 errno = EINVAL;
1393 return -1;
1394 }
1395
1396 res = pr_netio_read(nstrm, buf, 0, 0);
1397 if (res == 0) {
1398 pr_netio_close(nstrm);
1399 errno = EINVAL;
1400 return -1;
1401 }
1402
1403 expected_text = "Hello, World!\r\n";
1404 expected_sz = strlen(expected_text);
1405
1406 memset(buf, '\0', sizeof(buf));
1407 res = pr_netio_read(nstrm, buf, sizeof(buf)-1, 1);
1408
1409 if (res != (int) expected_sz) {
1410 pr_trace_msg("netio", 1, "Expected %lu bytes, got %d",
1411 (unsigned long) expected_sz, res);
1412 pr_netio_close(nstrm);
1413
1414 if (res < 0) {
1415 return -1;
1416 }
1417
1418 errno = EIO;
1419 return -1;
1420 }
1421
1422 if (strcmp(buf, expected_text) != 0) {
1423 pr_trace_msg("netio", 1, "Expected '%s', got '%s'", expected_text, buf);
1424 pr_netio_close(nstrm);
1425
1426 errno = EIO;
1427 return -1;
1428 }
1429
1430 netio_read_eof = TRUE;
1431 res = pr_netio_read(nstrm, buf, sizeof(buf)-1, 1);
1432 if (res > 0) {
1433 pr_trace_msg("netio", 1, "Expected EOF (0), got %d", res);
1434 pr_netio_close(nstrm);
1435
1436 errno = EIO;
1437 return -1;
1438 }
1439
1440 netio_read_epipe = TRUE;
1441 res = pr_netio_read(nstrm, buf, sizeof(buf)-1, sizeof(buf)-1);
1442 if (res >= 0) {
1443 pr_trace_msg("netio", 1, "Expected EPIPE (-1), got %d", res);
1444 pr_netio_close(nstrm);
1445
1446 errno = EIO;
1447 return -1;
1448 }
1449
1450 mark_point();
1451 pr_netio_close(nstrm);
1452 return 0;
1453 }
1454
netio_write_to_stream(int strm_type,int use_async)1455 static int netio_write_to_stream(int strm_type, int use_async) {
1456 int fd = 2, res;
1457 char *buf;
1458 size_t buflen;
1459 pr_netio_stream_t *nstrm;
1460
1461 res = pr_netio_write(NULL, NULL, 0);
1462 if (res == 0) {
1463 errno = EINVAL;
1464 return -1;
1465 }
1466
1467 nstrm = pr_netio_open(p, strm_type, fd, PR_NETIO_IO_WR);
1468 if (nstrm == NULL) {
1469 int xerrno = errno;
1470
1471 pr_trace_msg("netio", 1, "error opening custom netio stream: %s",
1472 strerror(xerrno));
1473 errno = xerrno;
1474 return -1;
1475 }
1476
1477 res = pr_netio_write(nstrm, NULL, 0);
1478 if (res == 0) {
1479 pr_netio_close(nstrm);
1480 errno = EINVAL;
1481 return -1;
1482 }
1483
1484 buf = "Hello, World!\n";
1485 buflen = strlen(buf);
1486
1487 res = pr_netio_write(nstrm, buf, 0);
1488 if (res == 0) {
1489 pr_netio_close(nstrm);
1490 errno = EINVAL;
1491 return -1;
1492 }
1493
1494 if (use_async) {
1495 res = pr_netio_write_async(nstrm, buf, buflen);
1496
1497 } else {
1498 res = pr_netio_write(nstrm, buf, buflen);
1499 }
1500
1501 if ((size_t) res != buflen) {
1502 pr_trace_msg("netio", 1, "wrote buffer (%lu bytes), got %d",
1503 (unsigned long) buflen, res);
1504 pr_netio_close(nstrm);
1505
1506 if (res < 0) {
1507 return -1;
1508 }
1509
1510 errno = EIO;
1511 return -1;
1512 }
1513
1514 netio_write_epipe = TRUE;
1515 res = pr_netio_write(nstrm, buf, buflen);
1516 if (res >= 0) {
1517 pr_trace_msg("netio", 1, "Expected EPIPE (-1), got %d", res);
1518 pr_netio_close(nstrm);
1519 errno = EIO;
1520 return -1;
1521 }
1522
1523 mark_point();
1524 pr_netio_close(nstrm);
1525 return 0;
1526 }
1527
START_TEST(netio_read_test)1528 START_TEST (netio_read_test) {
1529 int res;
1530 pr_netio_t *netio, *netio2;
1531
1532 netio = pr_alloc_netio2(p, NULL, "testsuite");
1533 netio->poll = netio_poll_cb;
1534 netio->read = netio_read_cb;
1535
1536 /* Write to control stream */
1537 res = pr_register_netio(netio, PR_NETIO_STRM_CTRL);
1538 fail_unless(res == 0, "Failed to register custom ctrl NetIO: %s",
1539 strerror(errno));
1540
1541 netio2 = pr_get_netio(PR_NETIO_STRM_CTRL);
1542 fail_unless(netio2 != NULL, "Failed to get custom ctrl NetIO: %s",
1543 strerror(errno));
1544 fail_unless(netio2 == netio, "Expected custom ctrl NetIO %p, got %p",
1545 netio, netio2);
1546
1547 res = netio_read_from_stream(PR_NETIO_STRM_CTRL);
1548 fail_unless(res == 0, "Failed to read from custom ctrl NetIO: %s",
1549 strerror(errno));
1550
1551 mark_point();
1552 pr_unregister_netio(PR_NETIO_STRM_CTRL);
1553
1554 /* Read from data stream */
1555 res = pr_register_netio(netio, PR_NETIO_STRM_DATA);
1556 fail_unless(res == 0, "Failed to register custom data NetIO: %s",
1557 strerror(errno));
1558
1559 netio2 = pr_get_netio(PR_NETIO_STRM_DATA);
1560 fail_unless(netio2 != NULL, "Failed to get custom data NetIO: %s",
1561 strerror(errno));
1562 fail_unless(netio2 == netio, "Expected custom data NetIO %p, got %p",
1563 netio, netio2);
1564
1565 res = netio_read_from_stream(PR_NETIO_STRM_DATA);
1566 fail_unless(res == 0, "Failed to read from custom data NetIO: %s",
1567 strerror(errno));
1568
1569 mark_point();
1570 pr_unregister_netio(PR_NETIO_STRM_DATA);
1571
1572 /* Read from other stream */
1573 res = pr_register_netio(netio, PR_NETIO_STRM_OTHR);
1574 fail_unless(res == 0, "Failed to register custom other NetIO: %s",
1575 strerror(errno));
1576
1577 netio2 = pr_get_netio(PR_NETIO_STRM_OTHR);
1578 fail_unless(netio2 != NULL, "Failed to get custom othr NetIO: %s",
1579 strerror(errno));
1580 fail_unless(netio2 == netio, "Expected custom othr NetIO %p, got %p",
1581 netio, netio2);
1582
1583 res = netio_read_from_stream(PR_NETIO_STRM_OTHR);
1584 fail_unless(res == 0, "Failed to read from custom other NetIO: %s",
1585 strerror(errno));
1586
1587 mark_point();
1588 pr_unregister_netio(PR_NETIO_STRM_OTHR);
1589 }
1590 END_TEST
1591
START_TEST(netio_gets_test)1592 START_TEST (netio_gets_test) {
1593 int fd = 2, res;
1594 char *buf, *expected, *text;
1595 size_t buflen;
1596 pr_netio_t *netio;
1597 pr_netio_stream_t *nstrm;
1598
1599 text = pr_netio_gets(NULL, 0, NULL);
1600 fail_unless(text == NULL, "Failed to handle null arguments");
1601 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1602 strerror(errno), errno);
1603
1604 netio = pr_alloc_netio2(p, NULL, "testsuite");
1605 netio->poll = netio_poll_cb;
1606 netio->read = netio_read_cb;
1607
1608 res = pr_register_netio(netio, PR_NETIO_STRM_CTRL);
1609 fail_unless(res == 0, "Failed to register custom ctrl NetIO: %s",
1610 strerror(errno));
1611
1612 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
1613 fail_unless(nstrm != NULL, "Failed to open stream: %s", strerror(errno));
1614
1615 text = pr_netio_gets(NULL, 0, nstrm);
1616 fail_unless(text == NULL, "Failed to handle null buffer");
1617 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1618 strerror(errno), errno);
1619
1620 buflen = 1024;
1621 buf = pcalloc(p, buflen);
1622
1623 text = pr_netio_gets(buf, 0, nstrm);
1624 fail_unless(text == NULL, "Failed to handle zero buffer length");
1625 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1626 strerror(errno), errno);
1627
1628 expected = "Hello, World!\r\n";
1629 text = pr_netio_gets(buf, buflen-1, nstrm);
1630 fail_unless(text != NULL, "Failed to get text: %s", strerror(errno));
1631 fail_unless(strcmp(text, expected) == 0, "Expected '%s', got '%s'",
1632 expected, text);
1633
1634 mark_point();
1635 pr_unregister_netio(PR_NETIO_STRM_CTRL);
1636 }
1637 END_TEST
1638
START_TEST(netio_write_test)1639 START_TEST (netio_write_test) {
1640 int res;
1641 pr_netio_t *netio, *netio2;
1642
1643 netio = pr_alloc_netio2(p, NULL, "testsuite");
1644 netio->poll = netio_poll_cb;
1645 netio->write = netio_write_cb;
1646
1647 /* Write to control stream */
1648 res = pr_register_netio(netio, PR_NETIO_STRM_CTRL);
1649 fail_unless(res == 0, "Failed to register custom ctrl NetIO: %s",
1650 strerror(errno));
1651
1652 netio2 = pr_get_netio(PR_NETIO_STRM_CTRL);
1653 fail_unless(netio2 != NULL, "Failed to get custom ctrl NetIO: %s",
1654 strerror(errno));
1655 fail_unless(netio2 == netio, "Expected custom ctrl NetIO %p, got %p",
1656 netio, netio2);
1657
1658 res = netio_write_to_stream(PR_NETIO_STRM_CTRL, FALSE);
1659 fail_unless(res == 0, "Failed to write to custom ctrl NetIO: %s",
1660 strerror(errno));
1661
1662 mark_point();
1663 pr_unregister_netio(PR_NETIO_STRM_CTRL);
1664
1665 /* Write to data stream */
1666 res = pr_register_netio(netio, PR_NETIO_STRM_DATA);
1667 fail_unless(res == 0, "Failed to register custom data NetIO: %s",
1668 strerror(errno));
1669
1670 netio2 = pr_get_netio(PR_NETIO_STRM_DATA);
1671 fail_unless(netio2 != NULL, "Failed to get custom data NetIO: %s",
1672 strerror(errno));
1673 fail_unless(netio2 == netio, "Expected custom data NetIO %p, got %p",
1674 netio, netio2);
1675
1676 res = netio_write_to_stream(PR_NETIO_STRM_DATA, FALSE);
1677 fail_unless(res == 0, "Failed to write to custom data NetIO: %s",
1678 strerror(errno));
1679
1680 mark_point();
1681 pr_unregister_netio(PR_NETIO_STRM_DATA);
1682
1683 /* Write to other stream */
1684 res = pr_register_netio(netio, PR_NETIO_STRM_OTHR);
1685 fail_unless(res == 0, "Failed to register custom other NetIO: %s",
1686 strerror(errno));
1687
1688 netio2 = pr_get_netio(PR_NETIO_STRM_OTHR);
1689 fail_unless(netio2 != NULL, "Failed to get custom othr NetIO: %s",
1690 strerror(errno));
1691 fail_unless(netio2 == netio, "Expected custom othr NetIO %p, got %p",
1692 netio, netio2);
1693
1694 res = netio_write_to_stream(PR_NETIO_STRM_OTHR, FALSE);
1695 fail_unless(res == 0, "Failed to write to custom other NetIO: %s",
1696 strerror(errno));
1697
1698 mark_point();
1699 pr_unregister_netio(PR_NETIO_STRM_OTHR);
1700 }
1701 END_TEST
1702
START_TEST(netio_write_async_test)1703 START_TEST (netio_write_async_test) {
1704 int res;
1705 pr_netio_t *netio;
1706
1707 netio = pr_alloc_netio2(p, NULL, "testsuite");
1708 netio->poll = netio_poll_cb;
1709 netio->write = netio_write_cb;
1710
1711 res = pr_register_netio(netio, PR_NETIO_STRM_CTRL);
1712 fail_unless(res == 0, "Failed to register custom ctrl NetIO: %s",
1713 strerror(errno));
1714
1715 res = netio_write_to_stream(PR_NETIO_STRM_CTRL, TRUE);
1716 fail_unless(res == 0, "Failed to write to custom ctrl NetIO: %s",
1717 strerror(errno));
1718
1719 mark_point();
1720 pr_unregister_netio(PR_NETIO_STRM_CTRL);
1721 }
1722 END_TEST
1723
netio_print_to_stream(int strm_type,int use_async)1724 static int netio_print_to_stream(int strm_type, int use_async) {
1725 int fd = 2, res;
1726 char *buf;
1727 size_t buflen;
1728 pr_netio_stream_t *nstrm;
1729
1730 nstrm = pr_netio_open(p, strm_type, fd, PR_NETIO_IO_WR);
1731 if (nstrm == NULL) {
1732 int xerrno = errno;
1733
1734 pr_trace_msg("netio", 1, "error opening custom netio stream: %s",
1735 strerror(xerrno));
1736 errno = xerrno;
1737 return -1;
1738 }
1739
1740 buf = "Hello, World!\n";
1741 buflen = strlen(buf);
1742
1743 if (use_async) {
1744 res = pr_netio_printf_async(nstrm, "%s", buf);
1745
1746 } else {
1747 res = pr_netio_printf(nstrm, "%s", buf);
1748 }
1749
1750 if ((size_t) res != buflen) {
1751 pr_trace_msg("netio", 1, "printed buffer (%lu bytes), got %d",
1752 (unsigned long) buflen, res);
1753 pr_netio_close(nstrm);
1754
1755 if (res < 0) {
1756 return -1;
1757 }
1758
1759 errno = EIO;
1760 return -1;
1761 }
1762
1763 mark_point();
1764 pr_netio_close(nstrm);
1765 return 0;
1766 }
1767
START_TEST(netio_printf_test)1768 START_TEST (netio_printf_test) {
1769 int res;
1770 pr_netio_t *netio;
1771
1772 netio = pr_alloc_netio2(p, NULL, "testsuite");
1773 netio->poll = netio_poll_cb;
1774 netio->write = netio_write_cb;
1775
1776 res = pr_register_netio(netio, PR_NETIO_STRM_CTRL);
1777 fail_unless(res == 0, "Failed to register custom ctrl NetIO: %s",
1778 strerror(errno));
1779
1780 res = netio_print_to_stream(PR_NETIO_STRM_CTRL, FALSE);
1781 fail_unless(res == 0, "Failed to print to custom ctrl NetIO: %s",
1782 strerror(errno));
1783
1784 mark_point();
1785 pr_unregister_netio(PR_NETIO_STRM_CTRL);
1786 }
1787 END_TEST
1788
START_TEST(netio_printf_async_test)1789 START_TEST (netio_printf_async_test) {
1790 int res;
1791 pr_netio_t *netio;
1792
1793 netio = pr_alloc_netio2(p, NULL, "testsuite");
1794 netio->poll = netio_poll_cb;
1795 netio->write = netio_write_cb;
1796
1797 res = pr_register_netio(netio, PR_NETIO_STRM_CTRL);
1798 fail_unless(res == 0, "Failed to register custom ctrl NetIO: %s",
1799 strerror(errno));
1800
1801 res = netio_print_to_stream(PR_NETIO_STRM_CTRL, TRUE);
1802 fail_unless(res == 0, "Failed to print to custom ctrl NetIO: %s",
1803 strerror(errno));
1804
1805 mark_point();
1806 pr_unregister_netio(PR_NETIO_STRM_CTRL);
1807 }
1808 END_TEST
1809
START_TEST(netio_abort_test)1810 START_TEST (netio_abort_test) {
1811 pr_netio_stream_t *nstrm;
1812 int fd = -1;
1813
1814 mark_point();
1815 pr_netio_abort(NULL);
1816
1817 /* open/abort/close CTRL stream */
1818 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
1819 fail_unless(nstrm != NULL, "Failed to open ctrl stream on fd %d: %s", fd,
1820 strerror(errno));
1821
1822 pr_netio_abort(nstrm);
1823 fail_unless(nstrm->strm_flags & PR_NETIO_SESS_ABORT,
1824 "Failed to set PR_NETIO_SESS_ABORT flags on ctrl stream");
1825
1826 pr_netio_close(nstrm);
1827
1828 /* open/abort/close DATA stream */
1829 nstrm = pr_netio_open(p, PR_NETIO_STRM_DATA, fd, PR_NETIO_IO_WR);
1830 fail_unless(nstrm != NULL, "Failed to open data stream on fd %d: %s", fd,
1831 strerror(errno));
1832
1833 pr_netio_abort(nstrm);
1834 fail_unless(nstrm->strm_flags & PR_NETIO_SESS_ABORT,
1835 "Failed to set PR_NETIO_SESS_ABORT flags on data stream");
1836
1837 pr_netio_close(nstrm);
1838
1839 /* open/abort/close OTHR stream */
1840 nstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, fd, PR_NETIO_IO_WR);
1841 fail_unless(nstrm != NULL, "Failed to open othr stream on fd %d: %s", fd,
1842 strerror(errno));
1843
1844 pr_netio_abort(nstrm);
1845 fail_unless(nstrm->strm_flags & PR_NETIO_SESS_ABORT,
1846 "Failed to set PR_NETIO_SESS_ABORT flags on othr stream");
1847
1848 pr_netio_close(nstrm);
1849 }
1850 END_TEST
1851
netio_close_cb(pr_netio_stream_t * nstrm)1852 static int netio_close_cb(pr_netio_stream_t *nstrm) {
1853 return 0;
1854 }
1855
START_TEST(netio_lingering_abort_test)1856 START_TEST (netio_lingering_abort_test) {
1857 pr_netio_t *netio;
1858 pr_netio_stream_t *nstrm;
1859 int fd = 0, res;
1860 long linger = 0L;
1861
1862 mark_point();
1863 res = pr_netio_lingering_abort(NULL, linger);
1864 fail_unless(res < 0, "Failed to handle null arguments");
1865 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1866 strerror(errno), errno);
1867
1868 netio = pr_alloc_netio2(p, NULL, "testsuite");
1869 netio->close = netio_close_cb;
1870
1871 /* open/abort/close CTRL stream */
1872 res = pr_register_netio(netio, PR_NETIO_STRM_CTRL);
1873 fail_unless(res == 0, "Failed to register custom ctrl NetIO: %s",
1874 strerror(errno));
1875
1876 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
1877 fail_unless(nstrm != NULL, "Failed to open ctrl stream on fd %d: %s", fd,
1878 strerror(errno));
1879
1880 res = pr_netio_lingering_abort(nstrm, linger);
1881 fail_unless(res == 0, "Failed to set lingering abort on ctrl stream: %s",
1882 strerror(errno));
1883
1884 fail_unless(nstrm->strm_flags & PR_NETIO_SESS_ABORT,
1885 "Failed to set PR_NETIO_SESS_ABORT flags on ctrl stream");
1886
1887 pr_netio_close(nstrm);
1888 pr_unregister_netio(PR_NETIO_STRM_CTRL);
1889
1890 /* open/abort/close DATA stream */
1891 res = pr_register_netio(netio, PR_NETIO_STRM_DATA);
1892 fail_unless(res == 0, "Failed to register custom data NetIO: %s",
1893 strerror(errno));
1894
1895 nstrm = pr_netio_open(p, PR_NETIO_STRM_DATA, fd, PR_NETIO_IO_RD);
1896 fail_unless(nstrm != NULL, "Failed to open data stream on fd %d: %s", fd,
1897 strerror(errno));
1898
1899 res = pr_netio_lingering_abort(nstrm, linger);
1900 fail_unless(res == 0, "Failed to set lingering abort on data stream: %s",
1901 strerror(errno));
1902
1903 fail_unless(nstrm->strm_flags & PR_NETIO_SESS_ABORT,
1904 "Failed to set PR_NETIO_SESS_ABORT flags on data stream");
1905
1906 pr_netio_close(nstrm);
1907 pr_unregister_netio(PR_NETIO_STRM_DATA);
1908
1909 /* open/abort/close OTHR stream */
1910 res = pr_register_netio(netio, PR_NETIO_STRM_OTHR);
1911 fail_unless(res == 0, "Failed to register custom othr NetIO: %s",
1912 strerror(errno));
1913
1914 nstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, fd, PR_NETIO_IO_RD);
1915 fail_unless(nstrm != NULL, "Failed to open othr stream on fd %d: %s", fd,
1916 strerror(errno));
1917
1918 res = pr_netio_lingering_abort(nstrm, linger);
1919 fail_unless(res == 0, "Failed to set lingering abort on othr stream: %s",
1920 strerror(errno));
1921
1922 fail_unless(nstrm->strm_flags & PR_NETIO_SESS_ABORT,
1923 "Failed to set PR_NETIO_SESS_ABORT flags on othr stream");
1924
1925 pr_netio_close(nstrm);
1926 pr_unregister_netio(PR_NETIO_STRM_OTHR);
1927 }
1928 END_TEST
1929
START_TEST(netio_poll_interval_test)1930 START_TEST (netio_poll_interval_test) {
1931 pr_netio_stream_t *nstrm;
1932 int fd = -1;
1933 unsigned int interval = 3;
1934
1935 mark_point();
1936 pr_netio_set_poll_interval(NULL, 0);
1937
1938 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
1939 fail_unless(nstrm != NULL, "Failed to open ctrl stream on fd %d: %s", fd,
1940 strerror(errno));
1941
1942 pr_netio_set_poll_interval(nstrm, interval);
1943 fail_unless(nstrm->strm_interval == interval,
1944 "Expected stream interval %u, got %u", interval, nstrm->strm_interval);
1945 fail_unless(nstrm->strm_flags & PR_NETIO_SESS_INTR,
1946 "Failed to set PR_NETIO_SESS_INTR stream flag");
1947
1948 mark_point();
1949 pr_netio_reset_poll_interval(NULL);
1950
1951 pr_netio_reset_poll_interval(nstrm);
1952 fail_if(nstrm->strm_flags & PR_NETIO_SESS_INTR,
1953 "Failed to clear PR_NETIO_SESS_INTR stream flag");
1954
1955 (void) pr_netio_close(nstrm);
1956 }
1957 END_TEST
1958
netio_shutdown_cb(pr_netio_stream_t * nstrm,int how)1959 static int netio_shutdown_cb(pr_netio_stream_t *nstrm, int how) {
1960 return 0;
1961 }
1962
START_TEST(netio_shutdown_test)1963 START_TEST (netio_shutdown_test) {
1964 pr_netio_t *netio;
1965 pr_netio_stream_t *nstrm;
1966 int fd = 0, how = SHUT_RD, res;
1967
1968 mark_point();
1969 res = pr_netio_shutdown(NULL, how);
1970 fail_unless(res < 0, "Failed to handle null arguments");
1971 fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1972 strerror(errno), errno);
1973
1974 netio = pr_alloc_netio2(p, NULL, "testsuite");
1975 netio->close = netio_close_cb;
1976 netio->shutdown = netio_shutdown_cb;
1977
1978 /* open/shutdown/close CTRL stream */
1979 res = pr_register_netio(netio, PR_NETIO_STRM_CTRL);
1980 fail_unless(res == 0, "Failed to register custom ctrl NetIO: %s",
1981 strerror(errno));
1982
1983 nstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
1984 fail_unless(nstrm != NULL, "Failed to open ctrl stream on fd %d: %s", fd,
1985 strerror(errno));
1986
1987 res = pr_netio_shutdown(nstrm, how);
1988 fail_unless(res == 0, "Failed to shutdown ctrl stream: %s", strerror(errno));
1989
1990 pr_netio_close(nstrm);
1991 pr_unregister_netio(PR_NETIO_STRM_CTRL);
1992
1993 /* open/shutdown/close DATA stream */
1994 res = pr_register_netio(netio, PR_NETIO_STRM_DATA);
1995 fail_unless(res == 0, "Failed to register custom data NetIO: %s",
1996 strerror(errno));
1997
1998 nstrm = pr_netio_open(p, PR_NETIO_STRM_DATA, fd, PR_NETIO_IO_RD);
1999 fail_unless(nstrm != NULL, "Failed to open data stream on fd %d: %s", fd,
2000 strerror(errno));
2001
2002 res = pr_netio_shutdown(nstrm, how);
2003 fail_unless(res == 0, "Failed to shutdown ctrl stream: %s", strerror(errno));
2004
2005 pr_netio_close(nstrm);
2006 pr_unregister_netio(PR_NETIO_STRM_DATA);
2007
2008 /* open/shutdown/close OTHR stream */
2009 res = pr_register_netio(netio, PR_NETIO_STRM_OTHR);
2010 fail_unless(res == 0, "Failed to register custom othr NetIO: %s",
2011 strerror(errno));
2012
2013 nstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, fd, PR_NETIO_IO_RD);
2014 fail_unless(nstrm != NULL, "Failed to open othr stream on fd %d: %s", fd,
2015 strerror(errno));
2016
2017 res = pr_netio_shutdown(nstrm, how);
2018 fail_unless(res == 0, "Failed to shutdown ctrl stream: %s", strerror(errno));
2019
2020 pr_netio_close(nstrm);
2021 pr_unregister_netio(PR_NETIO_STRM_OTHR);
2022 }
2023 END_TEST
2024
tests_get_netio_suite(void)2025 Suite *tests_get_netio_suite(void) {
2026 Suite *suite;
2027 TCase *testcase;
2028
2029 suite = suite_create("netio");
2030
2031 testcase = tcase_create("base");
2032 tcase_add_checked_fixture(testcase, set_up, tear_down);
2033
2034 tcase_add_test(testcase, netio_open_test);
2035 tcase_add_test(testcase, netio_postopen_test);
2036 tcase_add_test(testcase, netio_close_test);
2037 tcase_add_test(testcase, netio_lingering_close_test);
2038 tcase_add_test(testcase, netio_reopen_test);
2039 tcase_add_test(testcase, netio_buffer_alloc_test);
2040
2041 tcase_add_test(testcase, netio_telnet_gets_args_test);
2042 tcase_add_test(testcase, netio_telnet_gets_single_line_test);
2043 tcase_add_test(testcase, netio_telnet_gets_multi_line_test);
2044 tcase_add_test(testcase, netio_telnet_gets_no_newline_test);
2045 tcase_add_test(testcase, netio_telnet_gets_telnet_will_test);
2046 tcase_add_test(testcase, netio_telnet_gets_telnet_bare_will_test);
2047 tcase_add_test(testcase, netio_telnet_gets_telnet_will_multi_read_test);
2048 tcase_add_test(testcase, netio_telnet_gets_telnet_wont_test);
2049 tcase_add_test(testcase, netio_telnet_gets_telnet_bare_wont_test);
2050 tcase_add_test(testcase, netio_telnet_gets_telnet_do_test);
2051 tcase_add_test(testcase, netio_telnet_gets_telnet_bare_do_test);
2052 tcase_add_test(testcase, netio_telnet_gets_telnet_dont_test);
2053 tcase_add_test(testcase, netio_telnet_gets_telnet_bare_dont_test);
2054 tcase_add_test(testcase, netio_telnet_gets_telnet_ip_test);
2055 tcase_add_test(testcase, netio_telnet_gets_telnet_bare_ip_test);
2056 tcase_add_test(testcase, netio_telnet_gets_telnet_dm_test);
2057 tcase_add_test(testcase, netio_telnet_gets_telnet_bare_dm_test);
2058 tcase_add_test(testcase, netio_telnet_gets_telnet_single_iac_test);
2059 tcase_add_test(testcase, netio_telnet_gets_bug3521_test);
2060 tcase_add_test(testcase, netio_telnet_gets_bug3697_test);
2061 tcase_add_test(testcase, netio_telnet_gets_eof_test);
2062
2063 tcase_add_test(testcase, netio_telnet_gets2_single_line_test);
2064 tcase_add_test(testcase, netio_telnet_gets2_single_line_crnul_test);
2065 tcase_add_test(testcase, netio_telnet_gets2_single_line_lf_test);
2066
2067 tcase_add_test(testcase, netio_read_test);
2068 tcase_add_test(testcase, netio_gets_test);
2069 tcase_add_test(testcase, netio_write_test);
2070 tcase_add_test(testcase, netio_write_async_test);
2071 tcase_add_test(testcase, netio_printf_test);
2072 tcase_add_test(testcase, netio_printf_async_test);
2073 tcase_add_test(testcase, netio_abort_test);
2074 tcase_add_test(testcase, netio_lingering_abort_test);
2075 tcase_add_test(testcase, netio_poll_interval_test);
2076 tcase_add_test(testcase, netio_shutdown_test);
2077
2078 suite_add_tcase(suite, testcase);
2079 return suite;
2080 }
2081