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