1 /*
2 * ProFTPD - FTP server daemon
3 * Copyright (c) 2001-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 routines */
26
27 #include "conf.h"
28
29 /* See RFC 854 for the definition of these Telnet values */
30
31 /* Telnet "Interpret As Command" indicator */
32 #ifndef TELNET_IAC
33 # define TELNET_IAC 255
34 #endif
35
36 #ifndef TELNET_DONT
37 # define TELNET_DONT 254
38 #endif
39
40 #ifndef TELNET_DO
41 # define TELNET_DO 253
42 #endif
43
44 #ifndef TELNET_WONT
45 # define TELNET_WONT 252
46 #endif
47
48 #ifndef TELNET_WILL
49 # define TELNET_WILL 251
50 #endif
51
52 /* Telnet "Interrupt Process" code */
53 #ifndef TELNET_IP
54 # define TELNET_IP 244
55 #endif
56
57 /* Telnet "Data Mark" code */
58 #ifndef TELNET_DM
59 # define TELNET_DM 242
60 #endif
61
62 static const char *trace_channel = "netio";
63
64 static pr_netio_t *default_ctrl_netio = NULL, *ctrl_netio = NULL;
65 static pr_netio_t *default_data_netio = NULL, *data_netio = NULL;
66 static pr_netio_t *default_othr_netio = NULL, *othr_netio = NULL;
67
68 /* Used to track whether the previous text read from the client's control
69 * connection was a properly-terminated command. If so, then read in the
70 * next/current text as per normal. If NOT (e.g. the client sent a too-long
71 * command), then read in the next/current text, but ignore it. Only clear
72 * this flag if the next/current command can be read as per normal.
73 *
74 * The pr_netio_telnet_gets() uses this variable, in conjunction with its
75 * saw_newline flag, for handling too-long commands from clients.
76 */
77 static int properly_terminated_prev_command = TRUE;
78
netio_stream_alloc(pool * parent_pool)79 static pr_netio_stream_t *netio_stream_alloc(pool *parent_pool) {
80 pool *netio_pool = NULL;
81 pr_netio_stream_t *nstrm = NULL;
82
83 if (!parent_pool) {
84 errno = EINVAL;
85 return NULL;
86 }
87
88 netio_pool = make_sub_pool(parent_pool);
89 pr_pool_tag(netio_pool, "netio stream pool");
90 nstrm = pcalloc(netio_pool, sizeof(pr_netio_stream_t));
91
92 nstrm->strm_pool = netio_pool;
93 nstrm->strm_fd = -1;
94 nstrm->strm_mode = 0;
95 nstrm->strm_flags = 0;
96 nstrm->strm_buf = NULL;
97 nstrm->strm_data = NULL;
98 nstrm->strm_errno = 0;
99
100 /* This table will not contain that many entries, so a low number
101 * of chains should suffice.
102 */
103 nstrm->notes = pr_table_nalloc(nstrm->strm_pool, 0, 4);
104
105 return nstrm;
106 }
107
pr_netio_buffer_alloc(pr_netio_stream_t * nstrm)108 pr_buffer_t *pr_netio_buffer_alloc(pr_netio_stream_t *nstrm) {
109 size_t bufsz;
110 pr_buffer_t *pbuf = NULL;
111
112 if (nstrm == NULL) {
113 errno = EINVAL;
114 return NULL;
115 }
116
117 pbuf = pcalloc(nstrm->strm_pool, sizeof(pr_buffer_t));
118
119 /* Allocate a buffer. */
120 bufsz = pr_config_get_server_xfer_bufsz(nstrm->strm_mode);
121 pbuf->buf = pcalloc(nstrm->strm_pool, bufsz);
122 pbuf->buflen = bufsz;
123
124 /* Position the offset at the start of the buffer, and set the
125 * remaining bytes value accordingly.
126 */
127 pbuf->current = pbuf->buf;
128 pbuf->remaining = bufsz;
129
130 /* Add this buffer to the given stream. */
131 nstrm->strm_buf = pbuf;
132
133 return pbuf;
134 }
135
136 /* Default core NetIO handlers
137 */
138
core_netio_abort_cb(pr_netio_stream_t * nstrm)139 static void core_netio_abort_cb(pr_netio_stream_t *nstrm) {
140 nstrm->strm_flags |= PR_NETIO_SESS_ABORT;
141 }
142
core_netio_close_cb(pr_netio_stream_t * nstrm)143 static int core_netio_close_cb(pr_netio_stream_t *nstrm) {
144 int res = 0;
145
146 if (nstrm->strm_fd != -1) {
147 res = close(nstrm->strm_fd);
148 nstrm->strm_fd = -1;
149
150 } else {
151 errno = EBADF;
152 res = -1;
153 }
154
155 return res;
156 }
157
core_netio_open_cb(pr_netio_stream_t * nstrm,int fd,int mode)158 static pr_netio_stream_t *core_netio_open_cb(pr_netio_stream_t *nstrm, int fd,
159 int mode) {
160
161 nstrm->strm_fd = fd;
162
163 /* The stream's strm_mode field does not need to be set, as it is set
164 * by the NetIO layer's open() wrapper function.
165 */
166
167 return nstrm;
168 }
169
core_netio_poll_cb(pr_netio_stream_t * nstrm)170 static int core_netio_poll_cb(pr_netio_stream_t *nstrm) {
171 int res;
172 fd_set rfds, *rfdsp, wfds, *wfdsp;
173 struct timeval tval;
174
175 FD_ZERO(&rfds);
176 rfdsp = NULL;
177 FD_ZERO(&wfds);
178 wfdsp = NULL;
179
180 if (nstrm->strm_mode == PR_NETIO_IO_RD) {
181 if (nstrm->strm_fd >= 0) {
182 FD_SET(nstrm->strm_fd, &rfds);
183 rfdsp = &rfds;
184 }
185
186 } else {
187 if (nstrm->strm_fd >= 0) {
188 FD_SET(nstrm->strm_fd, &wfds);
189 wfdsp = &wfds;
190 }
191 }
192
193 tval.tv_sec = ((nstrm->strm_flags & PR_NETIO_SESS_INTR) ?
194 nstrm->strm_interval: 60);
195 tval.tv_usec = 0;
196
197 res = select(nstrm->strm_fd + 1, rfdsp, wfdsp, NULL, &tval);
198 while (res < 0) {
199 int xerrno = errno;
200
201 if (!(nstrm->strm_flags & PR_NETIO_SESS_INTR)) {
202 /* Watch for EAGAIN, and handle it by delaying temporarily. */
203 if (xerrno == EAGAIN) {
204 errno = EINTR;
205 pr_signals_handle();
206 continue;
207 }
208 }
209
210 errno = nstrm->strm_errno = xerrno;
211 break;
212 }
213
214 return res;
215 }
216
core_netio_postopen_cb(pr_netio_stream_t * nstrm)217 static int core_netio_postopen_cb(pr_netio_stream_t *nstrm) {
218 return 0;
219 }
220
core_netio_read_cb(pr_netio_stream_t * nstrm,char * buf,size_t buflen)221 static int core_netio_read_cb(pr_netio_stream_t *nstrm, char *buf,
222 size_t buflen) {
223 return read(nstrm->strm_fd, buf, buflen);
224 }
225
core_netio_reopen_cb(pr_netio_stream_t * nstrm,int fd,int mode)226 static pr_netio_stream_t *core_netio_reopen_cb(pr_netio_stream_t *nstrm, int fd,
227 int mode) {
228
229 if (nstrm->strm_fd != -1) {
230 close(nstrm->strm_fd);
231 }
232
233 nstrm->strm_fd = fd;
234 nstrm->strm_mode = mode;
235
236 return nstrm;
237 }
238
core_netio_shutdown_cb(pr_netio_stream_t * nstrm,int how)239 static int core_netio_shutdown_cb(pr_netio_stream_t *nstrm, int how) {
240 return shutdown(nstrm->strm_fd, how);
241 }
242
core_netio_write_cb(pr_netio_stream_t * nstrm,char * buf,size_t buflen)243 static int core_netio_write_cb(pr_netio_stream_t *nstrm, char *buf,
244 size_t buflen) {
245 return write(nstrm->strm_fd, buf, buflen);
246 }
247
netio_stream_mode(int strm_mode)248 static const char *netio_stream_mode(int strm_mode) {
249 const char *modestr = "(unknown)";
250
251 switch (strm_mode) {
252 case PR_NETIO_IO_RD:
253 modestr = "reading";
254 break;
255
256 case PR_NETIO_IO_WR:
257 modestr = "writing";
258 break;
259
260 default:
261 break;
262 }
263
264 return modestr;
265 }
266
267 /* NetIO API wrapper functions. */
268
pr_netio_abort(pr_netio_stream_t * nstrm)269 void pr_netio_abort(pr_netio_stream_t *nstrm) {
270 const char *nstrm_mode;
271
272 if (nstrm == NULL) {
273 errno = EINVAL;
274 return;
275 }
276
277 nstrm_mode = netio_stream_mode(nstrm->strm_mode);
278
279 switch (nstrm->strm_type) {
280 case PR_NETIO_STRM_CTRL:
281 if (ctrl_netio != NULL) {
282 pr_trace_msg(trace_channel, 19,
283 "using %s abort() for control %s stream",
284 ctrl_netio->owner_name, nstrm_mode);
285 (ctrl_netio->abort)(nstrm);
286
287 } else {
288 pr_trace_msg(trace_channel, 19,
289 "using %s abort() for control %s stream",
290 default_ctrl_netio->owner_name, nstrm_mode);
291 (default_ctrl_netio->abort)(nstrm);
292 }
293
294 break;
295
296 case PR_NETIO_STRM_DATA:
297 if (data_netio != NULL) {
298 pr_trace_msg(trace_channel, 19, "using %s abort() for data %s stream",
299 data_netio->owner_name, nstrm_mode);
300 (data_netio->abort)(nstrm);
301
302 } else {
303 pr_trace_msg(trace_channel, 19, "using %s abort() for data %s stream",
304 default_data_netio->owner_name, nstrm_mode);
305 (default_data_netio->abort)(nstrm);
306 }
307 break;
308
309 case PR_NETIO_STRM_OTHR:
310 if (othr_netio != NULL) {
311 pr_trace_msg(trace_channel, 19, "using %s abort() for other %s stream",
312 othr_netio->owner_name, nstrm_mode);
313 (othr_netio->abort)(nstrm);
314
315 } else {
316 pr_trace_msg(trace_channel, 19, "using %s abort() for other %s stream",
317 default_othr_netio->owner_name, nstrm_mode);
318 (default_othr_netio->abort)(nstrm);
319 }
320 break;
321
322 default:
323 errno = EINVAL;
324 return;
325 }
326
327 return;
328 }
329
pr_netio_close(pr_netio_stream_t * nstrm)330 int pr_netio_close(pr_netio_stream_t *nstrm) {
331 int res = -1, xerrno = 0;
332 const char *nstrm_mode;
333
334 if (nstrm == NULL) {
335 errno = EINVAL;
336 return -1;
337 }
338
339 nstrm_mode = netio_stream_mode(nstrm->strm_mode);
340
341 switch (nstrm->strm_type) {
342 case PR_NETIO_STRM_CTRL:
343 if (ctrl_netio != NULL) {
344 pr_trace_msg(trace_channel, 19,
345 "using %s close() for control %s stream", ctrl_netio->owner_name,
346 nstrm_mode);
347 res = (ctrl_netio->close)(nstrm);
348
349 } else {
350 pr_trace_msg(trace_channel, 19,
351 "using %s close() for control %s stream",
352 default_ctrl_netio->owner_name, nstrm_mode);
353 res = (default_ctrl_netio->close)(nstrm);
354 }
355 xerrno = errno;
356 break;
357
358 case PR_NETIO_STRM_DATA:
359 if (data_netio != NULL) {
360 pr_trace_msg(trace_channel, 19, "using %s close() for data %s stream",
361 data_netio->owner_name, nstrm_mode);
362 res = (data_netio->close)(nstrm);
363
364 } else {
365 pr_trace_msg(trace_channel, 19, "using %s close() for data %s stream",
366 default_data_netio->owner_name, nstrm_mode);
367 res = (default_data_netio->close)(nstrm);
368 }
369 xerrno = errno;
370 break;
371
372 case PR_NETIO_STRM_OTHR:
373 if (othr_netio != NULL) {
374 pr_trace_msg(trace_channel, 19, "using %s close() for other %s stream",
375 othr_netio->owner_name, nstrm_mode);
376 res = (othr_netio->close)(nstrm);
377
378 } else {
379 pr_trace_msg(trace_channel, 19, "using %s close() for other %s stream",
380 default_othr_netio->owner_name, nstrm_mode);
381 res = (default_othr_netio->close)(nstrm);
382 }
383 xerrno = errno;
384 break;
385
386 default:
387 errno = EPERM;
388 return -1;
389 }
390
391 /* Make sure to scrub any buffered memory, too. */
392 if (nstrm->strm_buf != NULL) {
393 pr_buffer_t *pbuf;
394
395 pbuf = nstrm->strm_buf;
396 pr_memscrub(pbuf->buf, pbuf->buflen);
397 }
398
399 destroy_pool(nstrm->strm_pool);
400 errno = xerrno;
401 return res;
402 }
403
netio_lingering_close(pr_netio_stream_t * nstrm,long linger,int flags)404 static int netio_lingering_close(pr_netio_stream_t *nstrm, long linger,
405 int flags) {
406 int res;
407 const char *nstrm_mode;
408
409 if (nstrm == NULL) {
410 errno = EINVAL;
411 return -1;
412 }
413
414 switch (nstrm->strm_type) {
415 case PR_NETIO_STRM_CTRL:
416 case PR_NETIO_STRM_DATA:
417 case PR_NETIO_STRM_OTHR:
418 break;
419
420 default:
421 errno = EPERM;
422 return -1;
423 }
424
425 if (nstrm->strm_fd < 0) {
426 /* Already closed. */
427 return 0;
428 }
429
430 nstrm_mode = netio_stream_mode(nstrm->strm_mode);
431
432 if (!(flags & NETIO_LINGERING_CLOSE_FL_NO_SHUTDOWN)) {
433 pr_netio_shutdown(nstrm, 1);
434 }
435
436 if (nstrm->strm_fd >= 0) {
437 struct timeval tv;
438 fd_set rfds;
439 time_t when = time(NULL) + linger;
440
441 tv.tv_sec = linger;
442 tv.tv_usec = 0L;
443
444 /* Handle timers during reading, once selected for read this
445 * should mean all buffers have been flushed and the receiving end
446 * has closed.
447 */
448 while (TRUE) {
449 run_schedule();
450
451 FD_ZERO(&rfds);
452 FD_SET(nstrm->strm_fd, &rfds);
453
454 pr_trace_msg(trace_channel, 8,
455 "lingering %lu %s before closing fd %d",
456 (unsigned long) tv.tv_sec, tv.tv_sec != 1 ? "secs" : "sec",
457 nstrm->strm_fd);
458
459 res = select(nstrm->strm_fd+1, &rfds, NULL, NULL, &tv);
460 if (res == -1) {
461 if (errno == EINTR) {
462 time_t now = time(NULL);
463 pr_signals_handle();
464
465 /* Still here? If the requested lingering interval hasn't passed,
466 * continue lingering. Reset the timeval struct's fields to
467 * linger for the interval remaining in the given period of time.
468 */
469 if (now < when) {
470 tv.tv_sec = when - now;
471 tv.tv_usec = 0L;
472 continue;
473 }
474
475 } else {
476 nstrm->strm_errno = errno;
477 return -1;
478 }
479
480 } else {
481 if (FD_ISSET(nstrm->strm_fd, &rfds)) {
482 pr_trace_msg(trace_channel, 8,
483 "received data for reading on fd %d, ignoring", nstrm->strm_fd);
484 }
485 }
486
487 break;
488 }
489 }
490
491 pr_trace_msg(trace_channel, 8, "done lingering, closing fd %d",
492 nstrm->strm_fd);
493
494 switch (nstrm->strm_type) {
495 case PR_NETIO_STRM_CTRL:
496 if (ctrl_netio != NULL) {
497 pr_trace_msg(trace_channel, 19,
498 "using %s close() for control %s stream", ctrl_netio->owner_name,
499 nstrm_mode);
500 res = (ctrl_netio->close)(nstrm);
501
502 } else {
503 pr_trace_msg(trace_channel, 19,
504 "using %s close() for control %s stream",
505 default_ctrl_netio->owner_name, nstrm_mode);
506 res = (default_ctrl_netio->close)(nstrm);
507 }
508 return res;
509
510 case PR_NETIO_STRM_DATA:
511 if (data_netio != NULL) {
512 pr_trace_msg(trace_channel, 19, "using %s close() for data %s stream",
513 data_netio->owner_name, nstrm_mode);
514 res = (data_netio->close)(nstrm);
515
516 } else {
517 pr_trace_msg(trace_channel, 19, "using %s close() for data %s stream",
518 default_data_netio->owner_name, nstrm_mode);
519 res = (default_data_netio->close)(nstrm);
520 }
521 return res;
522
523 case PR_NETIO_STRM_OTHR:
524 if (othr_netio != NULL) {
525 pr_trace_msg(trace_channel, 19, "using %s close() for other %s stream",
526 othr_netio->owner_name, nstrm_mode);
527 res = (othr_netio->close)(nstrm);
528
529 } else {
530 pr_trace_msg(trace_channel, 19, "using %s close() for other %s stream",
531 default_othr_netio->owner_name, nstrm_mode);
532 res = (default_othr_netio->close)(nstrm);
533 }
534 return res;
535 }
536
537 errno = EPERM;
538 return -1;
539 }
540
pr_netio_lingering_abort(pr_netio_stream_t * nstrm,long linger)541 int pr_netio_lingering_abort(pr_netio_stream_t *nstrm, long linger) {
542 int res;
543
544 if (nstrm == NULL) {
545 errno = EINVAL;
546 return -1;
547 }
548
549 switch (nstrm->strm_type) {
550 case PR_NETIO_STRM_CTRL:
551 case PR_NETIO_STRM_DATA:
552 case PR_NETIO_STRM_OTHR:
553 break;
554
555 default:
556 errno = EPERM;
557 return -1;
558 }
559
560 /* Send an appropriate response code down the stream asynchronously. */
561 pr_response_send_async(R_426, _("Transfer aborted. Data connection closed."));
562
563 pr_netio_shutdown(nstrm, 1);
564
565 if (nstrm->strm_fd >= 0) {
566 fd_set rs;
567 struct timeval tv;
568
569 /* Wait for just a little while for the shutdown to take effect. */
570 tv.tv_sec = 0L;
571 tv.tv_usec = 300000L;
572
573 while (TRUE) {
574 run_schedule();
575
576 FD_ZERO(&rs);
577 FD_SET(nstrm->strm_fd, &rs);
578
579 res = select(nstrm->strm_fd+1, &rs, NULL, NULL, &tv);
580 if (res == -1) {
581 if (errno == EINTR) {
582 pr_signals_handle();
583
584 /* Linger some more. */
585 tv.tv_sec = 0L;
586 tv.tv_usec = 300000L;
587 continue;
588
589 } else {
590 nstrm->strm_errno = errno;
591 return -1;
592 }
593 }
594
595 break;
596 }
597 }
598
599 nstrm->strm_flags |= PR_NETIO_SESS_ABORT;
600
601 /* Now continue with a normal lingering close. */
602 return netio_lingering_close(nstrm, linger,
603 NETIO_LINGERING_CLOSE_FL_NO_SHUTDOWN);
604 }
605
pr_netio_lingering_close(pr_netio_stream_t * nstrm,long linger)606 int pr_netio_lingering_close(pr_netio_stream_t *nstrm, long linger) {
607 return netio_lingering_close(nstrm, linger, 0);
608 }
609
pr_netio_open(pool * parent_pool,int strm_type,int fd,int mode)610 pr_netio_stream_t *pr_netio_open(pool *parent_pool, int strm_type, int fd,
611 int mode) {
612 pr_netio_stream_t *nstrm = NULL, *res = NULL;
613 const char *nstrm_mode;
614
615 if (parent_pool == NULL) {
616 errno = EINVAL;
617 return NULL;
618 }
619
620 /* Create a new stream object, then pass that the NetIO open handler. */
621 nstrm = netio_stream_alloc(parent_pool);
622 nstrm_mode = netio_stream_mode(mode);
623
624 switch (strm_type) {
625 case PR_NETIO_STRM_CTRL:
626 nstrm->strm_type = PR_NETIO_STRM_CTRL;
627 nstrm->strm_mode = mode;
628
629 if (ctrl_netio != NULL) {
630 if (pr_table_add(nstrm->notes, pstrdup(nstrm->strm_pool, "core.netio"),
631 ctrl_netio, sizeof(pr_netio_t *)) < 0) {
632 pr_trace_msg(trace_channel, 9,
633 "error stashing 'core.netio' note for ctrl stream: %s",
634 strerror(errno));
635 }
636 pr_trace_msg(trace_channel, 19, "using %s open() for control %s stream",
637 ctrl_netio->owner_name, nstrm_mode);
638 res = (ctrl_netio->open)(nstrm, fd, mode);
639 if (res != NULL) {
640 res->strm_netio = ctrl_netio;
641 }
642
643 } else {
644 if (pr_table_add(nstrm->notes, pstrdup(nstrm->strm_pool, "core.netio"),
645 default_ctrl_netio, sizeof(pr_netio_t *)) < 0) {
646 pr_trace_msg(trace_channel, 9,
647 "error stashing 'core.netio' note for ctrl stream: %s",
648 strerror(errno));
649 }
650 pr_trace_msg(trace_channel, 19, "using %s open() for control %s stream",
651 default_ctrl_netio->owner_name, nstrm_mode);
652 res = (default_ctrl_netio->open)(nstrm, fd, mode);
653 if (res != NULL) {
654 res->strm_netio = default_ctrl_netio;
655 }
656 }
657 break;
658
659 case PR_NETIO_STRM_DATA:
660 nstrm->strm_type = PR_NETIO_STRM_DATA;
661 nstrm->strm_mode = mode;
662
663 if (data_netio != NULL) {
664 if (pr_table_add(nstrm->notes, pstrdup(nstrm->strm_pool, "core.netio"),
665 data_netio, sizeof(pr_netio_t *)) < 0) {
666 pr_trace_msg(trace_channel, 9,
667 "error stashing 'core.netio' note for data stream: %s",
668 strerror(errno));
669 }
670 pr_trace_msg(trace_channel, 19, "using %s open() for data %s stream",
671 data_netio->owner_name, nstrm_mode);
672 res = (data_netio->open)(nstrm, fd, mode);
673 if (res != NULL) {
674 res->strm_netio = data_netio;
675 }
676
677 } else {
678 if (pr_table_add(nstrm->notes, pstrdup(nstrm->strm_pool, "core.netio"),
679 default_data_netio, sizeof(pr_netio_t *)) < 0) {
680 pr_trace_msg(trace_channel, 9,
681 "error stashing 'core.netio' note for data stream: %s",
682 strerror(errno));
683 }
684 pr_trace_msg(trace_channel, 19, "using %s open() for data %s stream",
685 default_data_netio->owner_name, nstrm_mode);
686 res = (default_data_netio->open)(nstrm, fd, mode);
687 if (res != NULL) {
688 res->strm_netio = default_data_netio;
689 }
690 }
691 break;
692
693 case PR_NETIO_STRM_OTHR:
694 nstrm->strm_type = PR_NETIO_STRM_OTHR;
695 nstrm->strm_mode = mode;
696
697 if (othr_netio != NULL) {
698 if (pr_table_add(nstrm->notes, pstrdup(nstrm->strm_pool, "core.netio"),
699 othr_netio, sizeof(pr_netio_t *)) < 0) {
700 pr_trace_msg(trace_channel, 9,
701 "error stashing 'core.netio' note for othr stream: %s",
702 strerror(errno));
703 }
704 pr_trace_msg(trace_channel, 19, "using %s open() for other %s stream",
705 othr_netio->owner_name, nstrm_mode);
706 res = (othr_netio->open)(nstrm, fd, mode);
707 if (res != NULL) {
708 res->strm_netio = othr_netio;
709 }
710
711 } else {
712 if (pr_table_add(nstrm->notes, pstrdup(nstrm->strm_pool, "core.netio"),
713 default_othr_netio, sizeof(pr_netio_t *)) < 0) {
714 pr_trace_msg(trace_channel, 9,
715 "error stashing 'core.netio' note for othr stream: %s",
716 strerror(errno));
717 }
718 pr_trace_msg(trace_channel, 19, "using %s open() for other %s stream",
719 default_othr_netio->owner_name, nstrm_mode);
720 res = (default_othr_netio->open)(nstrm, fd, mode);
721 if (res != NULL) {
722 res->strm_netio = default_othr_netio;
723 }
724 }
725 break;
726
727 default:
728 destroy_pool(nstrm->strm_pool);
729 nstrm->strm_pool = NULL;
730 errno = EINVAL;
731 res = NULL;
732 }
733
734 return res;
735 }
736
pr_netio_reopen(pr_netio_stream_t * nstrm,int fd,int mode)737 pr_netio_stream_t *pr_netio_reopen(pr_netio_stream_t *nstrm, int fd, int mode) {
738 pr_netio_stream_t *res;
739 const char *nstrm_mode;
740
741 if (nstrm == NULL) {
742 errno = EINVAL;
743 return NULL;
744 }
745
746 nstrm_mode = netio_stream_mode(mode);
747
748 switch (nstrm->strm_type) {
749 case PR_NETIO_STRM_CTRL:
750 if (ctrl_netio != NULL) {
751 pr_trace_msg(trace_channel, 19,
752 "using %s reopen() for control %s stream", ctrl_netio->owner_name,
753 nstrm_mode);
754 res = (ctrl_netio->reopen)(nstrm, fd, mode);
755
756 } else {
757 pr_trace_msg(trace_channel, 19,
758 "using %s reopen() for control %s stream",
759 default_ctrl_netio->owner_name, nstrm_mode);
760 res = (default_ctrl_netio->reopen)(nstrm, fd, mode);
761 }
762 return res;
763
764 case PR_NETIO_STRM_DATA:
765 if (data_netio != NULL) {
766 pr_trace_msg(trace_channel, 19, "using %s reopen() for data %s stream",
767 data_netio->owner_name, nstrm_mode);
768 res = (data_netio->reopen)(nstrm, fd, mode);
769
770 } else {
771 pr_trace_msg(trace_channel, 19, "using %s reopen() for data %s stream",
772 default_data_netio->owner_name, nstrm_mode);
773 res = (default_data_netio->reopen)(nstrm, fd, mode);
774 }
775 return res;
776
777 case PR_NETIO_STRM_OTHR:
778 if (othr_netio != NULL) {
779 pr_trace_msg(trace_channel, 19, "using %s reopen() for other %s stream",
780 othr_netio->owner_name, nstrm_mode);
781 res = (othr_netio->reopen)(nstrm, fd, mode);
782
783 } else {
784 pr_trace_msg(trace_channel, 19, "using %s reopen() for other %s stream",
785 default_othr_netio->owner_name, nstrm_mode);
786 res = (default_othr_netio->reopen)(nstrm, fd, mode);
787 }
788 return res;
789 }
790
791 errno = EPERM;
792 return NULL;
793 }
794
pr_netio_reset_poll_interval(pr_netio_stream_t * nstrm)795 void pr_netio_reset_poll_interval(pr_netio_stream_t *nstrm) {
796 if (nstrm == NULL) {
797 errno = EINVAL;
798 return;
799 }
800
801 /* Simply clear the "interruptible" flag. */
802 nstrm->strm_flags &= ~PR_NETIO_SESS_INTR;
803 }
804
pr_netio_set_poll_interval(pr_netio_stream_t * nstrm,unsigned int secs)805 void pr_netio_set_poll_interval(pr_netio_stream_t *nstrm, unsigned int secs) {
806 if (nstrm == NULL) {
807 return;
808 }
809
810 nstrm->strm_flags |= PR_NETIO_SESS_INTR;
811 nstrm->strm_interval = secs;
812 }
813
pr_netio_poll(pr_netio_stream_t * nstrm)814 int pr_netio_poll(pr_netio_stream_t *nstrm) {
815 int res = 0, xerrno = 0;
816 const char *nstrm_mode;
817
818 /* Sanity checks. */
819 if (nstrm == NULL) {
820 errno = EINVAL;
821 return -1;
822 }
823
824 if (nstrm->strm_fd == -1) {
825 errno = EBADF;
826 return -1;
827 }
828
829 /* Has this stream been aborted? */
830 if (nstrm->strm_flags & PR_NETIO_SESS_ABORT) {
831 nstrm->strm_flags &= ~PR_NETIO_SESS_ABORT;
832 return 1;
833 }
834
835 nstrm_mode = netio_stream_mode(nstrm->strm_mode);
836
837 while (TRUE) {
838 run_schedule();
839 pr_signals_handle();
840
841 switch (nstrm->strm_type) {
842 case PR_NETIO_STRM_CTRL:
843 if (ctrl_netio != NULL) {
844 pr_trace_msg(trace_channel, 19,
845 "using %s poll() for control %s stream", ctrl_netio->owner_name,
846 nstrm_mode);
847 res = (ctrl_netio->poll)(nstrm);
848
849 } else {
850 pr_trace_msg(trace_channel, 19,
851 "using %s poll() for control %s stream",
852 default_ctrl_netio->owner_name, nstrm_mode);
853 res = (default_ctrl_netio->poll)(nstrm);
854 }
855 break;
856
857 case PR_NETIO_STRM_DATA:
858 if (data_netio != NULL) {
859 pr_trace_msg(trace_channel, 19,
860 "using %s poll() for data %s stream", data_netio->owner_name,
861 nstrm_mode);
862 res = (data_netio->poll)(nstrm);
863
864 } else {
865 pr_trace_msg(trace_channel, 19,
866 "using %s poll() for data %s stream",
867 default_data_netio->owner_name, nstrm_mode);
868 res = (default_data_netio->poll)(nstrm);
869 }
870 break;
871
872 case PR_NETIO_STRM_OTHR:
873 if (othr_netio != NULL) {
874 pr_trace_msg(trace_channel, 19,
875 "using %s poll() for other %s stream", othr_netio->owner_name,
876 nstrm_mode);
877 res = (othr_netio->poll)(nstrm);
878
879 } else {
880 pr_trace_msg(trace_channel, 19,
881 "using %s poll() for other %s stream",
882 default_othr_netio->owner_name, nstrm_mode);
883 res = (default_othr_netio->poll)(nstrm);
884 }
885 break;
886 }
887
888 if (res == -1) {
889 xerrno = errno;
890 if (xerrno == EINTR) {
891 if (nstrm->strm_flags & PR_NETIO_SESS_ABORT) {
892 nstrm->strm_flags &= ~PR_NETIO_SESS_ABORT;
893 return 1;
894 }
895
896 if (nstrm->strm_flags & PR_NETIO_SESS_INTR) {
897 errno = nstrm->strm_errno = xerrno;
898 return -1;
899 }
900
901 /* Otherwise, restart the call */
902 pr_signals_handle();
903 continue;
904 }
905
906 /* Some other error occurred */
907 nstrm->strm_errno = xerrno;
908
909 /* If this is the control stream, and the error indicates a
910 * broken pipe (i.e. the client went away), AND there is a data
911 * transfer is progress, abort the transfer.
912 */
913 if (xerrno == EPIPE &&
914 nstrm->strm_type == PR_NETIO_STRM_CTRL &&
915 (session.sf_flags & SF_XFER)) {
916 pr_trace_msg(trace_channel, 5,
917 "received EPIPE on control connection, setting 'aborted' "
918 "session flag");
919 session.sf_flags |= SF_ABORT;
920 }
921
922 errno = nstrm->strm_errno;
923 return -1;
924 }
925
926 if (res == 0) {
927 /* In case the kernel doesn't support interrupted syscalls. */
928 if (nstrm->strm_flags & PR_NETIO_SESS_ABORT) {
929 nstrm->strm_flags &= ~PR_NETIO_SESS_ABORT;
930 return 1;
931 }
932
933 /* If the stream has been marked as "interruptible", AND the
934 * poll interval is zero seconds (meaning a true poll, not blocking),
935 * then return here.
936 */
937 if ((nstrm->strm_flags & PR_NETIO_SESS_INTR) &&
938 nstrm->strm_interval == 0) {
939 errno = EOF;
940 return -1;
941 }
942
943 continue;
944 }
945
946 break;
947 }
948
949 return 0;
950 }
951
pr_netio_postopen(pr_netio_stream_t * nstrm)952 int pr_netio_postopen(pr_netio_stream_t *nstrm) {
953 int res;
954 const char *nstrm_mode;
955
956 if (nstrm == NULL) {
957 errno = EINVAL;
958 return -1;
959 }
960
961 nstrm_mode = netio_stream_mode(nstrm->strm_mode);
962
963 switch (nstrm->strm_type) {
964 case PR_NETIO_STRM_CTRL:
965 if (ctrl_netio != NULL) {
966 pr_trace_msg(trace_channel, 19,
967 "using %s postopen() for control %s stream", ctrl_netio->owner_name,
968 nstrm_mode);
969 res = (ctrl_netio->postopen)(nstrm);
970
971 } else {
972 pr_trace_msg(trace_channel, 19,
973 "using %s postopen() for control %s stream",
974 default_ctrl_netio->owner_name, nstrm_mode);
975 res = (default_ctrl_netio->postopen)(nstrm);
976 }
977 return res;
978
979 case PR_NETIO_STRM_DATA:
980 if (data_netio != NULL) {
981 pr_trace_msg(trace_channel, 19,
982 "using %s postopen() for data %s stream", data_netio->owner_name,
983 nstrm_mode);
984 res = (data_netio->postopen)(nstrm);
985
986 } else {
987 pr_trace_msg(trace_channel, 19,
988 "using %s postopen() for data %s stream",
989 default_data_netio->owner_name, nstrm_mode);
990 res = (default_data_netio->postopen)(nstrm);
991 }
992 return res;
993
994 case PR_NETIO_STRM_OTHR:
995 if (othr_netio != NULL) {
996 pr_trace_msg(trace_channel, 19,
997 "using %s postopen() for other %s stream", othr_netio->owner_name,
998 nstrm_mode);
999 res = (othr_netio->postopen)(nstrm);
1000
1001 } else {
1002 pr_trace_msg(trace_channel, 19,
1003 "using %s postopen() for other %s stream",
1004 default_othr_netio->owner_name, nstrm_mode);
1005 res = (default_othr_netio->postopen)(nstrm);
1006 }
1007 return res;
1008 }
1009
1010 errno = EPERM;
1011 return -1;
1012 }
1013
pr_netio_vprintf(pr_netio_stream_t * nstrm,const char * fmt,va_list msg)1014 int pr_netio_vprintf(pr_netio_stream_t *nstrm, const char *fmt, va_list msg) {
1015 char buf[PR_RESPONSE_BUFFER_SIZE] = {'\0'};
1016
1017 pr_vsnprintf(buf, sizeof(buf), fmt, msg);
1018 buf[sizeof(buf)-1] = '\0';
1019
1020 return pr_netio_write(nstrm, buf, strlen(buf));
1021 }
1022
pr_netio_printf(pr_netio_stream_t * nstrm,const char * fmt,...)1023 int pr_netio_printf(pr_netio_stream_t *nstrm, const char *fmt, ...) {
1024 int res;
1025 va_list msg;
1026
1027 if (!nstrm) {
1028 errno = EINVAL;
1029 return -1;
1030 }
1031
1032 va_start(msg, fmt);
1033 res = pr_netio_vprintf(nstrm, fmt, msg);
1034 va_end(msg);
1035
1036 return res;
1037 }
1038
pr_netio_printf_async(pr_netio_stream_t * nstrm,char * fmt,...)1039 int pr_netio_printf_async(pr_netio_stream_t *nstrm, char *fmt, ...) {
1040 va_list msg;
1041 char buf[PR_RESPONSE_BUFFER_SIZE] = {'\0'};
1042
1043 if (!nstrm) {
1044 errno = EINVAL;
1045 return -1;
1046 }
1047
1048 va_start(msg, fmt);
1049 pr_vsnprintf(buf, sizeof(buf), fmt, msg);
1050 va_end(msg);
1051 buf[sizeof(buf)-1] = '\0';
1052
1053 return pr_netio_write_async(nstrm, buf, strlen(buf));
1054 }
1055
pr_netio_write(pr_netio_stream_t * nstrm,char * buf,size_t buflen)1056 int pr_netio_write(pr_netio_stream_t *nstrm, char *buf, size_t buflen) {
1057 int bwritten = 0, total = 0;
1058 const char *nstrm_mode;
1059 pr_buffer_t *pbuf;
1060 pool *tmp_pool;
1061
1062 /* Sanity check */
1063 if (nstrm == NULL ||
1064 buf == NULL ||
1065 buflen == 0) {
1066 errno = EINVAL;
1067 return -1;
1068 }
1069
1070 if (nstrm->strm_fd == -1) {
1071 errno = (nstrm->strm_errno ? nstrm->strm_errno : EBADF);
1072 return -1;
1073 }
1074
1075 nstrm_mode = netio_stream_mode(nstrm->strm_mode);
1076
1077 /* Before we send out the data to the client, generate an event
1078 * for any listeners which may want to examine this data. To do this, we
1079 * need to allocate a pr_buffer_t for sending the buffer data to the
1080 * listeners.
1081 *
1082 * We could just use nstrm->strm_pool, but for a long-lived control
1083 * connection, this would amount to a slow memory increase. So instead,
1084 * we create a subpool from the stream's pool, and allocate the
1085 * pr_buffer_t out of that. Then simply destroy the subpool when done.
1086 */
1087
1088 tmp_pool = make_sub_pool(nstrm->strm_pool);
1089 pbuf = pcalloc(tmp_pool, sizeof(pr_buffer_t));
1090 pbuf->buf = buf;
1091 pbuf->buflen = buflen;
1092 pbuf->current = pbuf->buf;
1093 pbuf->remaining = 0;
1094
1095 switch (nstrm->strm_type) {
1096 case PR_NETIO_STRM_CTRL:
1097 pr_event_generate("core.ctrl-write", pbuf);
1098 break;
1099
1100 case PR_NETIO_STRM_DATA:
1101 pr_event_generate("core.data-write", pbuf);
1102 break;
1103
1104 case PR_NETIO_STRM_OTHR:
1105 pr_event_generate("core.othr-write", pbuf);
1106 break;
1107 }
1108
1109 /* The event listeners may have changed the data to write out. */
1110 buf = pbuf->buf;
1111 buflen = pbuf->buflen - pbuf->remaining;
1112 destroy_pool(tmp_pool);
1113
1114 while (buflen) {
1115
1116 switch (pr_netio_poll(nstrm)) {
1117 case 1:
1118 /* pr_netio_poll() returns 1 only if the stream has been aborted. */
1119 errno = ECONNABORTED;
1120 return -2;
1121
1122 case -1:
1123 return -1;
1124
1125 default:
1126 /* We have to potentially restart here as well, in case we get EINTR. */
1127 do {
1128 pr_signals_handle();
1129 run_schedule();
1130
1131 switch (nstrm->strm_type) {
1132 case PR_NETIO_STRM_CTRL:
1133 if (ctrl_netio != NULL) {
1134 pr_trace_msg(trace_channel, 19,
1135 "using %s write() for control %s stream",
1136 ctrl_netio->owner_name, nstrm_mode);
1137 bwritten = (ctrl_netio->write)(nstrm, buf, buflen);
1138
1139 } else {
1140 pr_trace_msg(trace_channel, 19,
1141 "using %s write() for control %s stream",
1142 default_ctrl_netio->owner_name, nstrm_mode);
1143 bwritten = (default_ctrl_netio->write)(nstrm, buf, buflen);
1144 }
1145 break;
1146
1147 case PR_NETIO_STRM_DATA:
1148 if (XFER_ABORTED) {
1149 break;
1150 }
1151
1152 if (data_netio != NULL) {
1153 pr_trace_msg(trace_channel, 19,
1154 "using %s write() for data %s stream", data_netio->owner_name,
1155 nstrm_mode);
1156 bwritten = (data_netio->write)(nstrm, buf, buflen);
1157
1158 } else {
1159 pr_trace_msg(trace_channel, 19,
1160 "using %s write() for data %s stream",
1161 default_data_netio->owner_name, nstrm_mode);
1162 bwritten = (default_data_netio->write)(nstrm, buf, buflen);
1163 }
1164 break;
1165
1166 case PR_NETIO_STRM_OTHR:
1167 if (othr_netio != NULL) {
1168 pr_trace_msg(trace_channel, 19,
1169 "using %s write() for other %s stream",
1170 othr_netio->owner_name, nstrm_mode);
1171 bwritten = (othr_netio->write)(nstrm, buf, buflen);
1172
1173 } else {
1174 pr_trace_msg(trace_channel, 19,
1175 "using %s write() for other %s stream",
1176 default_othr_netio->owner_name, nstrm_mode);
1177 bwritten = (default_othr_netio->write)(nstrm, buf, buflen);
1178 }
1179 break;
1180 }
1181
1182 } while (bwritten == -1 && errno == EINTR);
1183 break;
1184 }
1185
1186 if (bwritten == -1) {
1187 nstrm->strm_errno = errno;
1188 return -1;
1189 }
1190
1191 buf += bwritten;
1192 total += bwritten;
1193 buflen -= bwritten;
1194 }
1195
1196 session.total_raw_out += total;
1197 return total;
1198 }
1199
pr_netio_write_async(pr_netio_stream_t * nstrm,char * buf,size_t buflen)1200 int pr_netio_write_async(pr_netio_stream_t *nstrm, char *buf, size_t buflen) {
1201 int bwritten = 0, flags = 0, total = 0;
1202 const char *nstrm_mode;
1203 pr_buffer_t *pbuf;
1204 pool *tmp_pool;
1205
1206 /* Sanity check */
1207 if (nstrm == NULL) {
1208 errno = EINVAL;
1209 return -1;
1210 }
1211
1212 if (nstrm->strm_fd == -1) {
1213 errno = (nstrm->strm_errno ? nstrm->strm_errno : EBADF);
1214 return -1;
1215 }
1216
1217 /* Prepare the descriptor for nonblocking IO. */
1218 flags = fcntl(nstrm->strm_fd, F_GETFL);
1219 if (flags < 0) {
1220 return -1;
1221 }
1222
1223 if (fcntl(nstrm->strm_fd, F_SETFL, flags|O_NONBLOCK) < 0) {
1224 return -1;
1225 }
1226
1227 nstrm_mode = netio_stream_mode(nstrm->strm_mode);
1228
1229 /* Before we send out the data to the client, generate an event
1230 * for any listeners which may want to examine this data.
1231 */
1232
1233 tmp_pool = make_sub_pool(nstrm->strm_pool);
1234 pbuf = pcalloc(tmp_pool, sizeof(pr_buffer_t));
1235 pbuf->buf = buf;
1236 pbuf->buflen = buflen;
1237 pbuf->current = pbuf->buf;
1238 pbuf->remaining = 0;
1239
1240 switch (nstrm->strm_type) {
1241 case PR_NETIO_STRM_CTRL:
1242 pr_event_generate("core.ctrl-write", pbuf);
1243 break;
1244
1245 case PR_NETIO_STRM_DATA:
1246 pr_event_generate("core.data-write", pbuf);
1247 break;
1248
1249 case PR_NETIO_STRM_OTHR:
1250 pr_event_generate("core.othr-write", pbuf);
1251 break;
1252 }
1253
1254 /* The event listeners may have changed the data to write out. */
1255 buf = pbuf->buf;
1256 buflen = pbuf->buflen - pbuf->remaining;
1257 destroy_pool(tmp_pool);
1258
1259 while (buflen) {
1260 do {
1261
1262 /* Do NOT check for XFER_ABORTED here. After a client aborts a
1263 * transfer, proftpd still needs to send the 426 response code back
1264 * to the client via the control connection; checking for XFER_ABORTED
1265 * here would block that response code sending, which in turn causes
1266 * problems for clients waiting for that response code.
1267 */
1268
1269 pr_signals_handle();
1270
1271 switch (nstrm->strm_type) {
1272 case PR_NETIO_STRM_CTRL:
1273 if (ctrl_netio != NULL) {
1274 pr_trace_msg(trace_channel, 19,
1275 "using %s write() for control %s stream", ctrl_netio->owner_name,
1276 nstrm_mode);
1277 bwritten = (ctrl_netio->write)(nstrm, buf, buflen);
1278
1279 } else {
1280 pr_trace_msg(trace_channel, 19,
1281 "using %s write() for control %s stream",
1282 default_ctrl_netio->owner_name, nstrm_mode);
1283 bwritten = (default_ctrl_netio->write)(nstrm, buf, buflen);
1284 }
1285 break;
1286
1287 case PR_NETIO_STRM_DATA:
1288 if (data_netio != NULL) {
1289 pr_trace_msg(trace_channel, 19,
1290 "using %s write() for data %s stream", data_netio->owner_name,
1291 nstrm_mode);
1292 bwritten = (data_netio->write)(nstrm, buf, buflen);
1293
1294 } else {
1295 pr_trace_msg(trace_channel, 19,
1296 "using %s write() for data %s stream",
1297 default_data_netio->owner_name, nstrm_mode);
1298 bwritten = (default_data_netio->write)(nstrm, buf, buflen);
1299 }
1300 break;
1301
1302 case PR_NETIO_STRM_OTHR:
1303 if (othr_netio != NULL) {
1304 pr_trace_msg(trace_channel, 19,
1305 "using %s write() for other %s stream", othr_netio->owner_name,
1306 nstrm_mode);
1307 bwritten = (othr_netio->write)(nstrm, buf, buflen);
1308
1309 } else {
1310 pr_trace_msg(trace_channel, 19,
1311 "using %s write() for other %s stream",
1312 default_othr_netio->owner_name, nstrm_mode);
1313 bwritten = (default_othr_netio->write)(nstrm, buf, buflen);
1314 }
1315 break;
1316 }
1317
1318 } while (bwritten == -1 && errno == EINTR);
1319
1320 if (bwritten < 0) {
1321 nstrm->strm_errno = errno;
1322 (void) fcntl(nstrm->strm_fd, F_SETFL, flags);
1323
1324 if (nstrm->strm_errno == EWOULDBLOCK) {
1325 /* Give up ... */
1326 return total;
1327 }
1328
1329 return -1;
1330 }
1331
1332 buf += bwritten;
1333 total += bwritten;
1334 buflen -= bwritten;
1335 }
1336
1337 (void) fcntl(nstrm->strm_fd, F_SETFL, flags);
1338 return total;
1339 }
1340
pr_netio_read(pr_netio_stream_t * nstrm,char * buf,size_t buflen,int bufmin)1341 int pr_netio_read(pr_netio_stream_t *nstrm, char *buf, size_t buflen,
1342 int bufmin) {
1343 int bread = 0, total = 0;
1344 const char *nstrm_mode;
1345 pr_buffer_t *pbuf;
1346 pool *tmp_pool;
1347
1348 /* Sanity check. */
1349 if (nstrm == NULL ||
1350 buf == NULL ||
1351 buflen == 0) {
1352 errno = EINVAL;
1353 return -1;
1354 }
1355
1356 if (nstrm->strm_fd == -1) {
1357 errno = (nstrm->strm_errno ? nstrm->strm_errno : EBADF);
1358 return -1;
1359 }
1360
1361 if (bufmin < 1) {
1362 bufmin = 1;
1363 }
1364
1365 if ((size_t) bufmin > buflen) {
1366 bufmin = buflen;
1367 }
1368
1369 nstrm_mode = netio_stream_mode(nstrm->strm_mode);
1370
1371 while (bufmin > 0) {
1372 polling:
1373
1374 switch (pr_netio_poll(nstrm)) {
1375 case 1:
1376 return -2;
1377
1378 case -1:
1379 return -1;
1380
1381 default:
1382 do {
1383 pr_signals_handle();
1384
1385 run_schedule();
1386
1387 switch (nstrm->strm_type) {
1388 case PR_NETIO_STRM_CTRL:
1389 if (ctrl_netio != NULL) {
1390 pr_trace_msg(trace_channel, 19,
1391 "using %s read() for control %s stream",
1392 ctrl_netio->owner_name, nstrm_mode);
1393 bread = (ctrl_netio->read)(nstrm, buf, buflen);
1394
1395 } else {
1396 pr_trace_msg(trace_channel, 19,
1397 "using %s read() for control %s stream",
1398 default_ctrl_netio->owner_name, nstrm_mode);
1399 bread = (default_ctrl_netio->read)(nstrm, buf, buflen);
1400 }
1401 break;
1402
1403 case PR_NETIO_STRM_DATA:
1404 if (XFER_ABORTED) {
1405 break;
1406 }
1407
1408 if (data_netio != NULL) {
1409 pr_trace_msg(trace_channel, 19,
1410 "using %s read() for data %s stream", data_netio->owner_name,
1411 nstrm_mode);
1412 bread = (data_netio->read)(nstrm, buf, buflen);
1413
1414 } else {
1415 pr_trace_msg(trace_channel, 19,
1416 "using %s read() for data %s stream",
1417 default_data_netio->owner_name, nstrm_mode);
1418 bread = (default_data_netio->read)(nstrm, buf, buflen);
1419 }
1420 break;
1421
1422 case PR_NETIO_STRM_OTHR:
1423 if (othr_netio != NULL) {
1424 pr_trace_msg(trace_channel, 19,
1425 "using %s read() for other %s stream",
1426 othr_netio->owner_name, nstrm_mode);
1427 bread = (othr_netio->read)(nstrm, buf, buflen);
1428
1429 } else {
1430 pr_trace_msg(trace_channel, 19,
1431 "using %s read() for other %s stream",
1432 default_othr_netio->owner_name, nstrm_mode);
1433 bread = (default_othr_netio->read)(nstrm, buf, buflen);
1434 }
1435 break;
1436 }
1437
1438 #ifdef EAGAIN
1439 if (bread == -1 &&
1440 errno == EAGAIN) {
1441 int xerrno = EAGAIN;
1442
1443 /* Treat this as an interrupted call, call pr_signals_handle()
1444 * (which will delay for a few msecs because of EINTR), and try
1445 * again.
1446 *
1447 * This should avoid a tightly spinning loop if read(2) returns
1448 * EAGAIN, as on a data transfer (Bug#3639).
1449 */
1450
1451 errno = EINTR;
1452 pr_signals_handle();
1453
1454 errno = xerrno;
1455 goto polling;
1456 }
1457 #endif
1458
1459 } while (bread == -1 && errno == EINTR);
1460 break;
1461 }
1462
1463 if (bread == -1) {
1464 nstrm->strm_errno = errno;
1465 return -1;
1466 }
1467
1468 /* EOF? */
1469 if (bread == 0) {
1470 if (nstrm->strm_type == PR_NETIO_STRM_CTRL) {
1471 pr_trace_msg(trace_channel, 7,
1472 "read %d bytes from control stream fd %d, handling as EOF", bread,
1473 nstrm->strm_fd);
1474 }
1475
1476 nstrm->strm_errno = 0;
1477 errno = EOF;
1478 break;
1479 }
1480
1481 /* Before we provide the data from the client, generate an event
1482 * for any listeners which may want to examine this data. To do this, we
1483 * need to allocate a pr_buffer_t for sending the buffer data to the
1484 * listeners.
1485 *
1486 * We could just use nstrm->strm_pool, but for a long-lived control
1487 * connection, this would amount to a slow memory increase. So instead,
1488 * we create a subpool from the stream's pool, and allocate the
1489 * pr_buffer_t out of that. Then simply destroy the subpool when done.
1490 */
1491
1492 tmp_pool = make_sub_pool(nstrm->strm_pool);
1493 pbuf = pcalloc(tmp_pool, sizeof(pr_buffer_t));
1494 pbuf->buf = buf;
1495 pbuf->buflen = bread;
1496 pbuf->current = pbuf->buf;
1497 pbuf->remaining = 0;
1498
1499 switch (nstrm->strm_type) {
1500 case PR_NETIO_STRM_CTRL:
1501 pr_event_generate("core.ctrl-read", pbuf);
1502 break;
1503
1504 case PR_NETIO_STRM_DATA:
1505 pr_event_generate("core.data-read", pbuf);
1506 break;
1507
1508 case PR_NETIO_STRM_OTHR:
1509 pr_event_generate("core.othr-read", pbuf);
1510 break;
1511 }
1512
1513 /* The event listeners may have changed the data read in out. */
1514 buf = pbuf->buf;
1515 bread = pbuf->buflen - pbuf->remaining;
1516 destroy_pool(tmp_pool);
1517
1518 buf += bread;
1519 total += bread;
1520 bufmin -= bread;
1521 buflen -= bread;
1522 }
1523
1524 session.total_raw_in += total;
1525 return total;
1526 }
1527
pr_netio_shutdown(pr_netio_stream_t * nstrm,int how)1528 int pr_netio_shutdown(pr_netio_stream_t *nstrm, int how) {
1529 int res = -1;
1530 const char *nstrm_mode;
1531
1532 if (nstrm == NULL) {
1533 errno = EINVAL;
1534 return -1;
1535 }
1536
1537 nstrm_mode = netio_stream_mode(nstrm->strm_mode);
1538
1539 switch (nstrm->strm_type) {
1540 case PR_NETIO_STRM_CTRL:
1541 if (ctrl_netio != NULL) {
1542 pr_trace_msg(trace_channel, 19,
1543 "using %s shutdown() for control %s stream", ctrl_netio->owner_name,
1544 nstrm_mode);
1545 res = (ctrl_netio->shutdown)(nstrm, how);
1546
1547 } else {
1548 pr_trace_msg(trace_channel, 19,
1549 "using %s shutdown() for control %s stream",
1550 default_ctrl_netio->owner_name, nstrm_mode);
1551 res = (default_ctrl_netio->shutdown)(nstrm, how);
1552 }
1553 return res;
1554
1555 case PR_NETIO_STRM_DATA:
1556 if (data_netio != NULL) {
1557 pr_trace_msg(trace_channel, 19,
1558 "using %s shutdown() for data %s stream", data_netio->owner_name,
1559 nstrm_mode);
1560 res = (data_netio->shutdown)(nstrm, how);
1561
1562 } else {
1563 pr_trace_msg(trace_channel, 19,
1564 "using %s shutdown() for data %s stream",
1565 default_data_netio->owner_name, nstrm_mode);
1566 res = (default_data_netio->shutdown)(nstrm, how);
1567 }
1568 return res;
1569
1570 case PR_NETIO_STRM_OTHR:
1571 if (othr_netio != NULL) {
1572 pr_trace_msg(trace_channel, 19,
1573 "using %s shutdown() for other %s stream", othr_netio->owner_name,
1574 nstrm_mode);
1575 res = (othr_netio->shutdown)(nstrm, how);
1576
1577 } else {
1578 pr_trace_msg(trace_channel, 19,
1579 "using %s shutdown() for other %s stream",
1580 default_othr_netio->owner_name, nstrm_mode);
1581 res = (default_othr_netio->shutdown)(nstrm, how);
1582 }
1583 return res;
1584 }
1585
1586 errno = EPERM;
1587 return res;
1588 }
1589
pr_netio_gets(char * buf,size_t buflen,pr_netio_stream_t * nstrm)1590 char *pr_netio_gets(char *buf, size_t buflen, pr_netio_stream_t *nstrm) {
1591 char *bp = buf;
1592 int toread;
1593 pr_buffer_t *pbuf = NULL;
1594
1595 if (nstrm == NULL ||
1596 buf == NULL ||
1597 buflen == 0) {
1598 errno = EINVAL;
1599 return NULL;
1600 }
1601
1602 buflen--;
1603
1604 if (nstrm->strm_buf) {
1605 pbuf = nstrm->strm_buf;
1606
1607 } else {
1608 pbuf = pr_netio_buffer_alloc(nstrm);
1609 }
1610
1611 while (buflen) {
1612
1613 /* Is the buffer empty? */
1614 if (!pbuf->current ||
1615 pbuf->remaining == pbuf->buflen) {
1616
1617 toread = pr_netio_read(nstrm, pbuf->buf,
1618 (buflen < pbuf->buflen ? buflen : pbuf->buflen), 1);
1619
1620 if (toread <= 0) {
1621 if (bp != buf) {
1622 *bp = '\0';
1623 return buf;
1624 }
1625
1626 return NULL;
1627 }
1628
1629 pbuf->remaining = pbuf->buflen - toread;
1630 pbuf->current = pbuf->buf;
1631
1632 pbuf->remaining = pbuf->buflen - toread;
1633 pbuf->current = pbuf->buf;
1634
1635 /* Before we begin iterating through the data read in from the
1636 * network, generate an event for any listeners which may want to
1637 * examine this data as well.
1638 */
1639 pr_event_generate("core.othr-read", pbuf);
1640 }
1641
1642 toread = pbuf->buflen - pbuf->remaining;
1643
1644 while (buflen && *pbuf->current != '\n' && toread--) {
1645 if (*pbuf->current & 0x80) {
1646 pbuf->current++;
1647
1648 } else {
1649 *bp++ = *pbuf->current++;
1650 buflen--;
1651 }
1652 pbuf->remaining++;
1653 }
1654
1655 if (buflen && toread && *pbuf->current == '\n') {
1656 buflen--;
1657 toread--;
1658 *bp++ = *pbuf->current++;
1659 pbuf->remaining++;
1660 break;
1661 }
1662
1663 if (!toread) {
1664 pbuf->current = NULL;
1665 }
1666 }
1667
1668 *bp = '\0';
1669 return buf;
1670 }
1671
1672 static int telnet_mode = 0;
1673
pr_netio_telnet_gets2(char * buf,size_t bufsz,pr_netio_stream_t * in_nstrm,pr_netio_stream_t * out_nstrm)1674 int pr_netio_telnet_gets2(char *buf, size_t bufsz,
1675 pr_netio_stream_t *in_nstrm, pr_netio_stream_t *out_nstrm) {
1676 char *bp = buf;
1677 unsigned char cp;
1678 int toread, handle_iac = TRUE, saw_newline = FALSE;
1679 pr_buffer_t *pbuf = NULL;
1680 size_t buflen = bufsz;
1681
1682 if (buflen == 0 ||
1683 in_nstrm == NULL ||
1684 out_nstrm == NULL) {
1685 errno = EINVAL;
1686 return -1;
1687 }
1688
1689 #ifdef PR_USE_NLS
1690 handle_iac = pr_encode_supports_telnet_iac();
1691 #endif /* PR_USE_NLS */
1692
1693 buflen--;
1694
1695 if (in_nstrm->strm_buf) {
1696 pbuf = in_nstrm->strm_buf;
1697
1698 } else {
1699 pbuf = pr_netio_buffer_alloc(in_nstrm);
1700 }
1701
1702 while (buflen > 0) {
1703 pr_signals_handle();
1704
1705 /* Is the buffer empty? */
1706 if (pbuf->current == NULL ||
1707 pbuf->remaining == pbuf->buflen) {
1708
1709 toread = pr_netio_read(in_nstrm, pbuf->buf,
1710 (buflen < pbuf->buflen ? buflen : pbuf->buflen), 1);
1711
1712 if (toread <= 0) {
1713 if (bp != buf) {
1714 *bp = '\0';
1715 return (bufsz - buflen - 1);
1716 }
1717
1718 return -1;
1719 }
1720
1721 pbuf->remaining = pbuf->buflen - toread;
1722 pbuf->current = pbuf->buf;
1723
1724 /* Before we begin iterating through the data read in from the
1725 * network, handing any Telnet characters and such, generate an event
1726 * for any listeners which may want to examine this data as well.
1727 */
1728 pr_event_generate("core.ctrl-read", pbuf);
1729 }
1730
1731 toread = pbuf->buflen - pbuf->remaining;
1732
1733 while (buflen > 0 &&
1734 toread > 0 &&
1735 (*pbuf->current != '\n' ||
1736 (*pbuf->current == '\n' && *(pbuf->current - 1) != '\r')) &&
1737 toread--) {
1738 pr_signals_handle();
1739
1740 cp = *pbuf->current++;
1741 pbuf->remaining++;
1742
1743 if (handle_iac == TRUE) {
1744 switch (telnet_mode) {
1745 case TELNET_IAC:
1746 switch (cp) {
1747 case TELNET_WILL:
1748 case TELNET_WONT:
1749 case TELNET_DO:
1750 case TELNET_DONT:
1751 case TELNET_IP:
1752 case TELNET_DM:
1753 /* Why do we do this crazy thing where we set the "telnet mode"
1754 * to be the action, and let the while loop, on the next pass,
1755 * handle that action? It's because we don't know, right now,
1756 * whether there actually a "next byte" in the input buffer.
1757 * There _should_ be -- but we can't be sure. And that next
1758 * byte is needed for properly responding with WONT/DONT
1759 * responses.
1760 */
1761 telnet_mode = cp;
1762 continue;
1763
1764 case TELNET_IAC:
1765 /* In this case, we know that the previous byte was TELNET_IAC,
1766 * and that the current byte is another TELNET_IAC. The
1767 * first TELNET_IAC thus "escapes" the second, telling us
1768 * that the current byte (TELNET_IAC) should be written out
1769 * as is (Bug#3697).
1770 */
1771 telnet_mode = 0;
1772 break;
1773
1774 default:
1775 /* In this case, we know that the previous byte was TELNET_IAC,
1776 * but the current byte is not a value we care about. So
1777 * write the TELNET_IAC into the output buffer, break out of
1778 * of the switch, and let that handle the writing of the
1779 * current byte into the output buffer.
1780 */
1781 *bp++ = TELNET_IAC;
1782 buflen--;
1783
1784 telnet_mode = 0;
1785 break;
1786 }
1787 break;
1788
1789 case TELNET_WILL:
1790 case TELNET_WONT:
1791 pr_netio_printf(out_nstrm, "%c%c%c", TELNET_IAC, TELNET_DONT, cp);
1792 telnet_mode = 0;
1793 continue;
1794
1795 case TELNET_DO:
1796 case TELNET_DONT:
1797 pr_netio_printf(out_nstrm, "%c%c%c", TELNET_IAC, TELNET_WONT, cp);
1798 telnet_mode = 0;
1799 continue;
1800
1801 case TELNET_IP:
1802 case TELNET_DM:
1803 default:
1804 if (cp == TELNET_IAC) {
1805 telnet_mode = cp;
1806 continue;
1807 }
1808 break;
1809 }
1810 }
1811
1812 /* In the situation where the previous byte was an IAC, we wrote IAC
1813 * into the output buffer, and decremented buflen (size of the output
1814 * buffer remaining). Thus we need to check here if buflen is zero,
1815 * before trying to decrement buflen again (and possibly underflowing
1816 * the buflen size_t data type).
1817 */
1818 if (buflen == 0) {
1819 break;
1820 }
1821
1822 *bp++ = cp;
1823 buflen--;
1824 }
1825
1826 if (buflen > 0 &&
1827 toread > 0 &&
1828 *pbuf->current == '\n') {
1829
1830 /* If the current character is LF, and the previous character we
1831 * copied was a CR, then strip the CR by overwriting it with the LF,
1832 * turning the copied data from Telnet CRLF line termination to
1833 * Unix LF line termination.
1834 */
1835 if (*(bp-1) == '\r') {
1836 /* We already decrement the buffer length for the CR; no need to
1837 * do it again since we are overwriting that CR.
1838 */
1839 *(bp-1) = *pbuf->current++;
1840
1841 } else {
1842 *bp++ = *pbuf->current++;
1843 buflen--;
1844 }
1845
1846 pbuf->remaining++;
1847 toread--;
1848 saw_newline = TRUE;
1849 break;
1850 }
1851
1852 if (toread == 0) {
1853 /* No more input? Set pbuf->current to null, so that at the top of
1854 * the loop, we read more.
1855 */
1856 pbuf->current = NULL;
1857 }
1858 }
1859
1860 if (!saw_newline) {
1861 /* If we haven't seen a newline, then assume the client is deliberately
1862 * sending a too-long command, trying to exploit buffer sizes and make
1863 * the server make some possibly bad assumptions.
1864 */
1865
1866 properly_terminated_prev_command = FALSE;
1867 errno = E2BIG;
1868 return -1;
1869 }
1870
1871 if (!properly_terminated_prev_command) {
1872 properly_terminated_prev_command = TRUE;
1873 pr_log_pri(PR_LOG_NOTICE, "client sent too-long command, ignoring");
1874 errno = E2BIG;
1875 return -1;
1876 }
1877
1878 properly_terminated_prev_command = TRUE;
1879 *bp = '\0';
1880 return (bufsz - buflen - 1);
1881 }
1882
pr_netio_telnet_gets(char * buf,size_t bufsz,pr_netio_stream_t * in_nstrm,pr_netio_stream_t * out_nstrm)1883 char *pr_netio_telnet_gets(char *buf, size_t bufsz,
1884 pr_netio_stream_t *in_nstrm, pr_netio_stream_t *out_nstrm) {
1885 int res;
1886
1887 res = pr_netio_telnet_gets2(buf, bufsz, in_nstrm, out_nstrm);
1888 if (res < 0) {
1889 return NULL;
1890 }
1891
1892 return buf;
1893 }
1894
pr_register_netio(pr_netio_t * netio,int strm_types)1895 int pr_register_netio(pr_netio_t *netio, int strm_types) {
1896
1897 if (netio == NULL) {
1898 pr_netio_t *default_netio = NULL;
1899
1900 /* Only instantiate the default NetIO objects once, reusing the same
1901 * pointer.
1902 */
1903 if (default_ctrl_netio == NULL) {
1904 default_ctrl_netio = default_netio = pr_alloc_netio2(permanent_pool,
1905 NULL, NULL);
1906 }
1907
1908 if (default_data_netio == NULL) {
1909 default_data_netio = default_netio ? default_netio :
1910 (default_netio = pr_alloc_netio2(permanent_pool, NULL, NULL));
1911 }
1912
1913 if (default_othr_netio == NULL) {
1914 default_othr_netio = default_netio ? default_netio :
1915 (default_netio = pr_alloc_netio2(permanent_pool, NULL, NULL));
1916 }
1917
1918 return 0;
1919 }
1920
1921 if (!netio->abort || !netio->close || !netio->open || !netio->poll ||
1922 !netio->postopen || !netio->read || !netio->reopen ||
1923 !netio->shutdown || !netio->write) {
1924 errno = EINVAL;
1925 return -1;
1926 }
1927
1928 if (strm_types & PR_NETIO_STRM_CTRL) {
1929 ctrl_netio = netio;
1930 }
1931
1932 if (strm_types & PR_NETIO_STRM_DATA) {
1933 data_netio = netio;
1934 }
1935
1936 if (strm_types & PR_NETIO_STRM_OTHR) {
1937 othr_netio = netio;
1938 }
1939
1940 return 0;
1941 }
1942
pr_unregister_netio(int strm_types)1943 int pr_unregister_netio(int strm_types) {
1944 if (!strm_types) {
1945 errno = EINVAL;
1946 return -1;
1947 }
1948
1949 /* NOTE: consider using cleanups here in the future? */
1950
1951 if (strm_types & PR_NETIO_STRM_CTRL) {
1952 ctrl_netio = NULL;
1953 }
1954
1955 if (strm_types & PR_NETIO_STRM_DATA) {
1956 data_netio = NULL;
1957 }
1958
1959 if (strm_types & PR_NETIO_STRM_OTHR) {
1960 othr_netio = NULL;
1961 }
1962
1963 return 0;
1964 }
1965
pr_get_netio(int strm_type)1966 pr_netio_t *pr_get_netio(int strm_type) {
1967 pr_netio_t *netio = NULL;
1968
1969 if (strm_type == 0) {
1970 errno = EINVAL;
1971 return NULL;
1972 }
1973
1974 switch (strm_type) {
1975 case PR_NETIO_STRM_CTRL:
1976 netio = ctrl_netio;
1977 break;
1978
1979 case PR_NETIO_STRM_DATA:
1980 netio = data_netio;
1981 break;
1982
1983 case PR_NETIO_STRM_OTHR:
1984 netio = othr_netio;
1985 break;
1986
1987 default:
1988 errno = ENOENT;
1989 }
1990
1991 return netio;
1992 }
1993
1994 extern pid_t mpid;
1995
pr_alloc_netio2(pool * parent_pool,module * owner,const char * owner_name)1996 pr_netio_t *pr_alloc_netio2(pool *parent_pool, module *owner,
1997 const char *owner_name) {
1998 pr_netio_t *netio = NULL;
1999 pool *netio_pool = NULL;
2000
2001 if (parent_pool == NULL) {
2002 errno = EINVAL;
2003 return NULL;
2004 }
2005
2006 netio_pool = make_sub_pool(parent_pool);
2007
2008 /* If this is the daemon process, we are allocating a sub-pool from the
2009 * permanent_pool. You might wonder why the daemon process needs netio
2010 * objects. It doesn't, really -- but it's for use by all of the session
2011 * processes that will be forked. They will be able to reuse the memory
2012 * already allocated for the main ctrl/data/other netios, as is.
2013 *
2014 * This being the case, we should label the sub-pool accordingly.
2015 */
2016 if (mpid == getpid()) {
2017 pr_pool_tag(netio_pool, "Shared Netio Pool");
2018
2019 } else {
2020 pr_pool_tag(netio_pool, "netio pool");
2021 }
2022
2023 netio = pcalloc(netio_pool, sizeof(pr_netio_t));
2024 netio->pool = netio_pool;
2025 netio->owner = owner;
2026
2027 if (owner != NULL) {
2028 if (owner_name != NULL) {
2029 netio->owner_name = pstrdup(netio_pool, owner_name);
2030
2031 } else {
2032 netio->owner_name = pstrdup(netio_pool, owner->name);
2033 }
2034
2035 } else {
2036 if (owner_name != NULL) {
2037 netio->owner_name = owner_name;
2038
2039 } else {
2040 netio->owner_name = "default";
2041 }
2042 }
2043
2044 /* Set the default NetIO handlers to the core handlers. */
2045 netio->abort = core_netio_abort_cb;
2046 netio->close = core_netio_close_cb;
2047 netio->open = core_netio_open_cb;
2048 netio->poll = core_netio_poll_cb;
2049 netio->postopen = core_netio_postopen_cb;
2050 netio->read = core_netio_read_cb;
2051 netio->reopen = core_netio_reopen_cb;
2052 netio->shutdown = core_netio_shutdown_cb;
2053 netio->write = core_netio_write_cb;
2054
2055 return netio;
2056 }
2057
pr_alloc_netio(pool * parent_pool)2058 pr_netio_t *pr_alloc_netio(pool *parent_pool) {
2059 return pr_alloc_netio2(parent_pool, NULL, NULL);
2060 }
2061
init_netio(void)2062 void init_netio(void) {
2063 signal(SIGPIPE, SIG_IGN);
2064 signal(SIGURG, SIG_IGN);
2065
2066 pr_register_netio(NULL, 0);
2067 }
2068