1 /*
2  * ProFTPD - mod_sftp channels
3  * Copyright (c) 2008-2017 TJ Saunders
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, TJ Saunders and other respective copyright holders
20  * give permission to link this program with OpenSSL, and distribute the
21  * resulting executable, without including the source code for OpenSSL in the
22  * source distribution.
23  */
24 
25 #include "mod_sftp.h"
26 #include "ssh2.h"
27 #include "msg.h"
28 #include "packet.h"
29 #include "channel.h"
30 #include "disconnect.h"
31 #include "interop.h"
32 #include "fxp.h"
33 #include "scp.h"
34 #include "date.h"
35 
36 extern module sftp_module;
37 
38 /* Used for maintaining our list of 'exec' channel handlers. */
39 struct ssh2_channel_exec_handler {
40   /* The module which registered this handler (err, collection of
41    * callbacks).
42    */
43   module *m;
44 
45   /* The 'exec' command for which these handlers should be used. */
46   const char *command;
47 
48   int (*set_params)(pool *, uint32_t, array_header *);
49   int (*prepare)(uint32_t);
50   int (*postopen)(uint32_t);
51   int (*handle_packet)(pool *, void *, uint32_t, unsigned char *, uint32_t);
52   int (*finish)(uint32_t);
53 };
54 
55 static array_header *channel_exec_handlers = NULL;
56 
57 /* Used for buffering up incoming/outgoing packets until the channel windows
58  * open.
59  */
60 struct ssh2_channel_databuf {
61   pool *pool;
62 
63   struct ssh2_channel_databuf *next;
64 
65   /* Points to the start of the buffer. */
66   char *ptr;
67 
68   /* Points to the start of the data which needs to be sent.  Usually, but
69    * not always, this is the same as ptr.
70    */
71   char *buf;
72 
73   uint32_t buflen;
74   uint32_t bufsz;
75 };
76 
77 static pool *channel_pool = NULL;
78 static uint32_t channelno = 0;
79 
80 static unsigned int channel_max = SFTP_SSH2_CHANNEL_MAX_COUNT;
81 static unsigned int channel_count = 0;
82 
83 static pool *channel_databuf_pool = NULL;
84 
85 /* XXX Use a table, rather than a list, for tracking channels? */
86 static array_header *channel_list = NULL;
87 
88 static uint32_t chan_window_size = SFTP_SSH2_CHANNEL_WINDOW_SIZE;
89 static uint32_t chan_packet_size = SFTP_SSH2_CHANNEL_MAX_PACKET_SIZE;
90 
91 static array_header *accepted_envs = NULL;
92 
93 static const char *trace_channel = "ssh2";
94 
95 static int send_channel_done(pool *, uint32_t);
96 
alloc_channel(const char * type,uint32_t remote_channel_id,uint32_t remote_windowsz,uint32_t remote_max_packetsz)97 static struct ssh2_channel *alloc_channel(const char *type,
98     uint32_t remote_channel_id, uint32_t remote_windowsz,
99     uint32_t remote_max_packetsz) {
100   struct ssh2_channel *chan = NULL;
101   pool *sub_pool = NULL;
102 
103   sub_pool = make_sub_pool(channel_pool);
104   pr_pool_tag(sub_pool, "SSH2 channel pool");
105 
106   chan = pcalloc(sub_pool, sizeof(struct ssh2_channel));
107   chan->pool = sub_pool;
108   chan->type = pstrdup(sub_pool, type);
109 
110   chan->local_channel_id = channelno++;
111 
112   chan->local_windowsz = chan_window_size;
113   chan->local_max_packetsz = chan_packet_size;
114 
115   chan->remote_channel_id = remote_channel_id;
116   chan->remote_windowsz = remote_windowsz;
117   chan->remote_max_packetsz = remote_max_packetsz;
118 
119   if (channel_list == NULL) {
120     channel_list = make_array(channel_pool, 1, sizeof(struct ssh2_channel *));
121   }
122 
123   *((struct ssh2_channel **) push_array(channel_list)) = chan;
124 
125   channel_count++;
126   return chan;
127 }
128 
destroy_channel(uint32_t channel_id)129 static void destroy_channel(uint32_t channel_id) {
130   register unsigned int i;
131   struct ssh2_channel **chans;
132 
133   if (channel_list == NULL)
134     return;
135 
136   chans = channel_list->elts;
137   for (i = 0; i < channel_list->nelts; i++) {
138     if (chans[i] != NULL &&
139         chans[i]->local_channel_id == channel_id) {
140 
141       /* If both parties have said that this channel is closed, we can
142        * close it.
143        */
144       if (chans[i]->recvd_close &&
145           chans[i]->sent_close) {
146         if (chans[i]->finish != NULL) {
147           pr_trace_msg(trace_channel, 15,
148             "calling finish handler for channel ID %lu",
149             (unsigned long) channel_id);
150           (chans[i]->finish)(channel_id);
151         }
152 
153         chans[i] = NULL;
154         channel_count--;
155         break;
156       }
157     }
158   }
159 
160   return;
161 }
162 
get_channel(uint32_t channel_id)163 static struct ssh2_channel *get_channel(uint32_t channel_id) {
164   register unsigned int i;
165   struct ssh2_channel **chans;
166 
167   if (channel_list == NULL) {
168     errno = EACCES;
169     return NULL;
170   }
171 
172   chans = channel_list->elts;
173   for (i = 0; i < channel_list->nelts; i++) {
174     if (chans[i] != NULL &&
175         chans[i]->local_channel_id == channel_id) {
176       return chans[i];
177     }
178   }
179 
180   errno = ENOENT;
181   return NULL;
182 }
183 
get_channel_pending_size(struct ssh2_channel * chan)184 static uint32_t get_channel_pending_size(struct ssh2_channel *chan) {
185   struct ssh2_channel_databuf *db;
186   uint32_t pending_datalen = 0;
187 
188   db = chan->outgoing;
189   while (db &&
190          db->buflen > 0) {
191     pr_signals_handle();
192 
193     pending_datalen += db->buflen;
194     db = db->next;
195   }
196 
197   return pending_datalen;
198 }
199 
drain_pending_channel_data(uint32_t channel_id)200 static void drain_pending_channel_data(uint32_t channel_id) {
201   struct ssh2_channel *chan;
202 
203   chan = get_channel(channel_id);
204   if (chan == NULL) {
205     return;
206   }
207 
208   if (chan->outgoing) {
209     pool *tmp_pool;
210     struct ssh2_channel_databuf *db;
211 
212     tmp_pool = make_sub_pool(channel_pool);
213 
214     pr_trace_msg(trace_channel, 15, "draining pending data for channel ID %lu "
215       "(%lu bytes)", (unsigned long) channel_id,
216       (unsigned long) get_channel_pending_size(chan));
217 
218     db = chan->outgoing;
219 
220     /* While we have room remaining in the remote window (and we are not
221      * rekeying), and while there are still pending outgoing messages,
222      * send them.
223      */
224 
225     while (!(sftp_sess_state & SFTP_SESS_STATE_REKEYING) &&
226            db &&
227            db->buflen > 0 &&
228            chan->remote_windowsz > 0) {
229       struct ssh2_packet *pkt;
230       unsigned char *buf, *ptr;
231       uint32_t bufsz, buflen, payload_len;
232       int res;
233 
234       pr_signals_handle();
235 
236       /* If the remote window size or remote max packet size changes the
237        * length we can send, then payload_len is NOT the same as buflen.  Hence
238        * the separate variable.
239        */
240       payload_len = db->buflen;
241 
242       /* The maximum size of the CHANNEL_DATA payload we can send to the client
243        * is the smaller of the remote window size and the remote packet size.
244        */
245 
246       if (payload_len > chan->remote_max_packetsz)
247         payload_len = chan->remote_max_packetsz;
248 
249       if (payload_len > chan->remote_windowsz)
250         payload_len = chan->remote_windowsz;
251 
252       pkt = sftp_ssh2_packet_create(tmp_pool);
253 
254       /* In addition to the data itself, we need to allocate room in the
255        * outgoing packet for the type (1 byte), the channel ID (4 bytes),
256        * and for the data length (4 bytes).
257        */
258       bufsz = buflen = payload_len + 9;
259       ptr = buf = palloc(pkt->pool, bufsz);
260 
261       sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_CHANNEL_DATA);
262       sftp_msg_write_int(&buf, &buflen, chan->remote_channel_id);
263       sftp_msg_write_int(&buf, &buflen, payload_len);
264       memcpy(buf, db->buf, payload_len);
265       buflen -= payload_len;
266 
267       pkt->payload = ptr;
268       pkt->payload_len = (bufsz - buflen);
269 
270       pr_trace_msg(trace_channel, 9, "sending CHANNEL_DATA (remote channel "
271         "ID %lu, %lu data bytes)", (unsigned long) chan->remote_channel_id,
272         (unsigned long) payload_len);
273 
274       res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
275       if (res < 0) {
276         (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
277           "error draining pending CHANNEL_DATA for channel ID %lu: %s",
278           (unsigned long) channel_id, strerror(errno));
279         destroy_pool(tmp_pool);
280         return;
281       }
282 
283       chan->remote_windowsz -= payload_len;
284 
285       pr_trace_msg(trace_channel, 11,
286         "channel ID %lu remote window size currently at %lu bytes",
287         (unsigned long) chan->remote_channel_id,
288         (unsigned long) chan->remote_windowsz);
289 
290       /* If we sent this entire databuf, then we can dispose of it, and
291        * advance to the next one on the list.  However, we may have only
292        * sent a portion of it, in which case it needs to stay where it is;
293        * we only need to update buf and buflen.
294        */
295 
296       if (payload_len == db->buflen) {
297         struct ssh2_channel_databuf *next;
298 
299         next = db->next;
300         destroy_pool(db->pool);
301         chan->outgoing = db = next;
302 
303       } else {
304         db->buf += payload_len;
305         db->buflen -= payload_len;
306       }
307     }
308 
309     /* If we still have pending data at this point, it is probably because
310      * the window wasn't big enough; we need to wait for another
311      * CHANNEL_WINDOW_ADJUST.
312      */
313     if (chan->outgoing) {
314       pr_trace_msg(trace_channel, 15, "still have pending channel data "
315         "(%lu bytes) for channel ID %lu (window at %lu bytes)",
316         (unsigned long) get_channel_pending_size(chan),
317         (unsigned long) channel_id, (unsigned long) chan->remote_windowsz);
318     }
319 
320     destroy_pool(tmp_pool);
321   }
322 
323   return;
324 }
325 
get_databuf(uint32_t channel_id,uint32_t buflen)326 static struct ssh2_channel_databuf *get_databuf(uint32_t channel_id,
327     uint32_t buflen) {
328   struct ssh2_channel *chan;
329   struct ssh2_channel_databuf *db;
330   pool *sub_pool;
331 
332   chan = get_channel(channel_id);
333   if (chan == NULL) {
334     errno = EPERM;
335     return NULL;
336   }
337 
338   if (!channel_databuf_pool) {
339     channel_databuf_pool = make_sub_pool(channel_pool);
340     pr_pool_tag(channel_databuf_pool, "SSH2 Channel data buffer pool");
341   }
342 
343   sub_pool = pr_pool_create_sz(channel_databuf_pool, 128);
344   pr_pool_tag(sub_pool, "channel databuf pool");
345 
346   db = pcalloc(sub_pool, sizeof(struct ssh2_channel_databuf));
347   db->pool = sub_pool;
348   db->bufsz = buflen;
349   db->ptr = db->buf = palloc(db->pool, db->bufsz);
350 
351   db->buflen = 0;
352   db->next = NULL;
353 
354   /* Make sure the returned outbuf is already in place at the end of
355    * the pending outgoing list.
356    */
357   if (chan->outgoing) {
358     struct ssh2_channel_databuf *iter;
359 
360     iter = chan->outgoing;
361     while (iter->next) {
362       pr_signals_handle();
363       iter = iter->next;
364     }
365 
366     iter->next = db;
367 
368   } else {
369     chan->outgoing = db;
370   }
371 
372   return db;
373 }
374 
read_channel_open(struct ssh2_packet * pkt,uint32_t * channel_id)375 static int read_channel_open(struct ssh2_packet *pkt, uint32_t *channel_id) {
376   unsigned char *buf;
377   char *channel_type;
378   uint32_t buflen, initial_windowsz, max_packetsz;
379   cmd_rec *cmd;
380 
381   buf = pkt->payload;
382   buflen = pkt->payload_len;
383 
384   channel_type = sftp_msg_read_string(pkt->pool, &buf, &buflen);
385   *channel_id = sftp_msg_read_int(pkt->pool, &buf, &buflen);
386 
387   /* First check if this would cause the client to exceed its count of
388    * open channels.
389    */
390   if (channel_count + 1 > channel_max) {
391     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
392       "maximum number of channels (%u) open, denying request to "
393       "open '%s' channel", channel_count, channel_type);
394     return -1;
395   }
396 
397   initial_windowsz = sftp_msg_read_int(pkt->pool, &buf, &buflen);
398   max_packetsz = sftp_msg_read_int(pkt->pool, &buf, &buflen);
399 
400   pr_trace_msg(trace_channel, 8, "open of '%s' channel using remote "
401     "ID %lu requested: initial client window len = %lu bytes, client max "
402     "packet size = %lu bytes", channel_type, (unsigned long) *channel_id,
403     (unsigned long) initial_windowsz, (unsigned long) max_packetsz);
404 
405   cmd = pr_cmd_alloc(pkt->pool, 2, pstrdup(pkt->pool, "CHANNEL_OPEN"),
406     pstrdup(pkt->pool, channel_type));
407   cmd->arg = channel_type;
408   cmd->cmd_class = CL_MISC|CL_SSH;
409 
410   if (strncmp(channel_type, "session", 8) != 0) {
411     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
412       "unsupported channel type '%s' requested, denying", channel_type);
413     pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
414     return -1;
415   }
416 
417   if (alloc_channel(channel_type, *channel_id, initial_windowsz,
418       max_packetsz) == NULL) {
419     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
420       "error allocating channel");
421     pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
422     return -1;
423   }
424 
425   pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
426   return 0;
427 }
428 
handle_channel_close(struct ssh2_packet * pkt)429 static int handle_channel_close(struct ssh2_packet *pkt) {
430   char chan_str[16];
431   unsigned char *buf;
432   uint32_t buflen, channel_id;
433   struct ssh2_channel *chan;
434   cmd_rec *cmd;
435 
436   buf = pkt->payload;
437   buflen = pkt->payload_len;
438 
439   channel_id = sftp_msg_read_int(pkt->pool, &buf, &buflen);
440 
441   memset(chan_str, '\0', sizeof(chan_str));
442   pr_snprintf(chan_str, sizeof(chan_str)-1, "%lu", (unsigned long) channel_id);
443 
444   cmd = pr_cmd_alloc(pkt->pool, 1, pstrdup(pkt->pool, "CHANNEL_CLOSE"));
445   cmd->arg = pstrdup(pkt->pool, chan_str);
446   cmd->cmd_class = CL_MISC|CL_SSH;
447 
448   chan = get_channel(channel_id);
449   if (chan == NULL) {
450     pr_trace_msg(trace_channel, 8, "unable to close channel ID %lu: %s",
451       (unsigned long) channel_id, strerror(errno));
452 
453     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
454       "no open channel for channel ID %lu", (unsigned long) channel_id);
455     pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
456     return -1;
457   }
458 
459   /* The order of these calls, and the setting of recvd_close, is important.
460    * Do not set recvd_close to true before calling send_channel_done,
461    * otherwise the client will receive an EOF prematurely.
462    */
463 
464   if (!chan->sent_close) {
465     send_channel_done(pkt->pool, channel_id);
466   }
467 
468   chan->recvd_close = TRUE;
469   destroy_channel(channel_id);
470 
471   pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
472   return 0;
473 }
474 
process_channel_data(struct ssh2_channel * chan,struct ssh2_packet * pkt,unsigned char * data,uint32_t datalen)475 static int process_channel_data(struct ssh2_channel *chan,
476     struct ssh2_packet *pkt, unsigned char *data, uint32_t datalen) {
477   int res;
478 
479   if (chan->handle_packet == NULL) {
480     pr_trace_msg(trace_channel, 3, "no handler registered for data on "
481       "channel ID %lu, rejecting packet",
482       (unsigned long) chan->local_channel_id);
483     errno = EACCES;
484     return -1;
485   }
486 
487   res = chan->handle_packet(pkt->pool, pkt, chan->local_channel_id, data,
488     datalen);
489 
490   chan->local_windowsz -= datalen;
491 
492   if (chan->local_windowsz < (chan->local_max_packetsz * 3)) {
493     unsigned char *buf, *ptr;
494     uint32_t buflen, bufsz, window_adjlen;
495     struct ssh2_packet *resp;
496 
497     /* Need to send a CHANNEL_WINDOW_ADJUST message to the client, so that
498      * they know to send more data.
499      */
500     buflen = bufsz = 128;
501     ptr = buf = palloc(pkt->pool, bufsz);
502 
503     window_adjlen = chan_window_size - chan->local_windowsz;
504 
505     sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_CHANNEL_WINDOW_ADJUST);
506     sftp_msg_write_int(&buf, &buflen, chan->remote_channel_id);
507     sftp_msg_write_int(&buf, &buflen, window_adjlen);
508 
509     pr_trace_msg(trace_channel, 15, "sending CHANNEL_WINDOW_ADJUST message "
510       "for channel ID %lu, adding %lu bytes to the window size (currently %lu "
511       "bytes)", (unsigned long) chan->local_channel_id,
512       (unsigned long) window_adjlen, (unsigned long) chan->local_windowsz);
513 
514     resp = sftp_ssh2_packet_create(pkt->pool);
515     resp->payload = ptr;
516     resp->payload_len = (bufsz - buflen);
517 
518     if (sftp_ssh2_packet_write(sftp_conn->wfd, resp) < 0) {
519       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
520         "error sending CHANNEL_WINDOW_ADJUST request to client: %s",
521         strerror(errno));
522     }
523 
524     destroy_pool(resp->pool);
525     chan->local_windowsz += window_adjlen;
526   }
527 
528   return res;
529 }
530 
handle_channel_data(struct ssh2_packet * pkt,uint32_t * channel_id)531 static int handle_channel_data(struct ssh2_packet *pkt, uint32_t *channel_id) {
532   unsigned char *buf, *data;
533   uint32_t buflen, datalen;
534   struct ssh2_channel *chan;
535 
536   buf = pkt->payload;
537   buflen = pkt->payload_len;
538 
539   *channel_id = sftp_msg_read_int(pkt->pool, &buf, &buflen);
540 
541   chan = get_channel(*channel_id);
542   if (chan == NULL) {
543     pr_trace_msg(trace_channel, 8, "unable to handle data for "
544       "channel ID %lu: %s", (unsigned long) *channel_id, strerror(errno));
545 
546     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
547       "no open channel for remote channel ID %lu", (unsigned long) *channel_id);
548     return -1;
549   }
550 
551   if (chan->recvd_eof) {
552     pr_trace_msg(trace_channel, 3, "received data on channel ID %lu after "
553       "client had sent CHANNEL_EOF", (unsigned long) *channel_id);
554   }
555 
556   datalen = sftp_msg_read_int(pkt->pool, &buf, &buflen);
557 
558   if (datalen > chan->local_windowsz) {
559     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
560       "received too much data (%lu bytes) for local window size (%lu bytes) "
561       "for channel ID %lu, ignoring CHANNEL_DATA message",
562       (unsigned long) datalen, (unsigned long) chan->local_windowsz,
563       (unsigned long) *channel_id);
564     return 0;
565   }
566 
567   pr_trace_msg(trace_channel, 17,
568     "processing %lu %s of data for channel ID %lu", (unsigned long) datalen,
569     datalen != 1 ? "bytes" : "byte", (unsigned long) *channel_id);
570   data = sftp_msg_read_data(pkt->pool, &buf, &buflen, datalen);
571 
572   return process_channel_data(chan, pkt, data, datalen);
573 }
574 
575 /* Sends an "exit-status" message, followed by CHANNEL_EOF, and
576  * finishes with CHANNEL_CLOSE.
577  */
send_channel_done(pool * p,uint32_t channel_id)578 static int send_channel_done(pool *p, uint32_t channel_id) {
579   int res;
580   unsigned char *buf, *ptr;
581   uint32_t buflen, bufsz;
582   struct ssh2_channel *chan;
583   struct ssh2_packet *pkt;
584 
585   chan = get_channel(channel_id);
586   if (chan == NULL) {
587     return 0;
588   }
589 
590   buflen = bufsz = 128;
591   ptr = buf = palloc(p, bufsz);
592 
593   sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_CHANNEL_REQUEST);
594   sftp_msg_write_int(&buf, &buflen, chan->remote_channel_id);
595   sftp_msg_write_string(&buf, &buflen, "exit-status");
596   sftp_msg_write_bool(&buf, &buflen, FALSE);
597   sftp_msg_write_int(&buf, &buflen, 0);
598 
599   pkt = sftp_ssh2_packet_create(p);
600   pkt->payload = ptr;
601   pkt->payload_len = (bufsz - buflen);
602 
603   pr_trace_msg(trace_channel, 9,
604     "sending CHANNEL_REQUEST (remote channel ID %lu, exit status 0)",
605     (unsigned long) chan->remote_channel_id);
606 
607   res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
608   if (res < 0) {
609     destroy_pool(pkt->pool);
610     return res;
611   }
612 
613   if (!chan->sent_eof) {
614     buf = ptr;
615     buflen = bufsz;
616 
617     sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_CHANNEL_EOF);
618     sftp_msg_write_int(&buf, &buflen, chan->remote_channel_id);
619 
620     pkt = sftp_ssh2_packet_create(p);
621     pkt->payload = ptr;
622     pkt->payload_len = (bufsz - buflen);
623 
624     pr_trace_msg(trace_channel, 9,
625       "sending CHANNEL_EOF (remote channel ID %lu)",
626       (unsigned long) chan->remote_channel_id);
627 
628     res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
629     if (res < 0) {
630       destroy_pool(pkt->pool);
631       return res;
632     }
633 
634     chan->sent_eof = TRUE;
635   }
636 
637   if (!chan->sent_close) {
638     buf = ptr;
639     buflen = bufsz;
640 
641     sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_CHANNEL_CLOSE);
642     sftp_msg_write_int(&buf, &buflen, chan->remote_channel_id);
643 
644     pkt->payload = ptr;
645     pkt->payload_len = (bufsz - buflen);
646 
647     pr_trace_msg(trace_channel, 9,
648       "sending CHANNEL_CLOSE (remote channel ID %lu)",
649       (unsigned long) chan->remote_channel_id);
650 
651     res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
652     if (res < 0) {
653       destroy_pool(pkt->pool);
654       return res;
655     }
656 
657     destroy_pool(pkt->pool);
658     chan->sent_close = TRUE;
659   }
660 
661   destroy_channel(channel_id);
662   return res;
663 }
664 
handle_channel_eof(struct ssh2_packet * pkt)665 static int handle_channel_eof(struct ssh2_packet *pkt) {
666   char chan_str[16];
667   unsigned char *buf;
668   uint32_t buflen, channel_id;
669   struct ssh2_channel *chan;
670   cmd_rec *cmd;
671 
672   buf = pkt->payload;
673   buflen = pkt->payload_len;
674 
675   channel_id = sftp_msg_read_int(pkt->pool, &buf, &buflen);
676 
677   memset(chan_str, '\0', sizeof(chan_str));
678   pr_snprintf(chan_str, sizeof(chan_str)-1, "%lu", (unsigned long) channel_id);
679 
680   cmd = pr_cmd_alloc(pkt->pool, 1, pstrdup(pkt->pool, "CHANNEL_EOF"));
681   cmd->arg = pstrdup(pkt->pool, chan_str);
682   cmd->cmd_class = CL_MISC|CL_SSH;
683 
684   chan = get_channel(channel_id);
685   if (chan == NULL) {
686     pr_trace_msg(trace_channel, 8, "unable to handle EOF for "
687       "channel ID %lu: %s", (unsigned long) channel_id, strerror(errno));
688 
689     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
690       "no open channel for remote channel ID %lu", (unsigned long) channel_id);
691     pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
692     return -1;
693   }
694 
695   /* The client is telling us it will not send any more data on this channel.*/
696   chan->recvd_eof = TRUE;
697 
698   /* First, though, drain any pending data for the channel. */
699   drain_pending_channel_data(channel_id);
700 
701   if (!chan->sent_eof) {
702     send_channel_done(pkt->pool, channel_id);
703   }
704 
705   pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
706   return 0;
707 }
708 
allow_env(const char * key)709 static int allow_env(const char *key) {
710   register unsigned int i;
711   char **elts;
712 
713   /* The following is a hardcoded list of environment variables set by
714    * mod_sftp itself.  These are not allowed to be changed by the client.
715    *
716    * XXX At some point, this should be changed to use a table; lookups of
717    * barred keys will be much faster, especially as the list of barred
718    * keys grows.
719    */
720 
721   const char *prohibited_envs[] = {
722     "DYLD_LIBRARY_PATH", /* Mac OSX */
723     "HOME",
724     "LD_CONFIG",         /* Solaris */
725     "LD_CONFIG_32",      /* Solaris */
726     "LD_CONFIG_64",      /* Solaris */
727     "LD_LIBMAP",         /* FreeBSD */
728     "LD_LIBRARY_PATH",
729     "LD_NOCONFIG",       /* Solaris */
730     "LD_NOCONFIG_32",    /* Solaris */
731     "LD_NOCONFIG_64",    /* Solaris */
732     "LD_PRELOAD",
733     "LD_RUN_PATH",
734     "LIBPATH",           /* AIX */
735     "PATH",
736     "SFTP",
737     "SFTP_LIBRARY_VERSION",
738     "SFTP_CLIENT_CIPHER_ALGO",
739     "SFTP_CLIENT_MAC_ALGO",
740     "SFTP_CLIENT_COMPRESSION_ALGO",
741     "SFTP_KEX_ALGO",
742     "SFTP_SERVER_CIPHER_ALGO",
743     "SFTP_SERVER_MAC_ALGO",
744     "SFTP_SERVER_COMPRESSION_ALGO",
745     "SHLIB_PATH",        /* HP-UX */
746     "TMP",
747     "TMPDIR",
748     "TZ",
749     "USER",
750     NULL
751   };
752 
753   for (i = 0; prohibited_envs[i]; i++) {
754     if (strcasecmp(key, prohibited_envs[i]) == 0) {
755       return FALSE;
756     }
757   }
758 
759   elts = accepted_envs->elts;
760   for (i = 0; i < accepted_envs->nelts; i++) {
761     if (pr_fnmatch(elts[i], key, 0) == 0) {
762       return TRUE;
763     }
764   }
765 
766   /* Bar all environment variables by default. */
767   return FALSE;
768 }
769 
handle_exec_channel(struct ssh2_channel * chan,struct ssh2_packet * pkt,unsigned char ** buf,uint32_t * buflen)770 static int handle_exec_channel(struct ssh2_channel *chan,
771     struct ssh2_packet *pkt, unsigned char **buf, uint32_t *buflen) {
772   register unsigned int i;
773   int flags = PR_STR_FL_PRESERVE_WHITESPACE, have_handler = FALSE;
774   char *command, *ptr, *word;
775   array_header *req;
776   struct ssh2_channel_exec_handler **handlers;
777 
778   command = sftp_msg_read_string(pkt->pool, buf, buflen);
779 
780   (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
781     "'exec' channel request: command = '%s'", command);
782 
783   req = make_array(pkt->pool, 2, sizeof(char *));
784   ptr = command;
785 
786   while ((word = pr_str_get_word(&ptr, flags)) != NULL) {
787     pr_signals_handle();
788     *((char **) push_array(req)) = pstrdup(pkt->pool, word);
789   }
790 
791   *((char **) push_array(req)) = NULL;
792 
793   handlers = channel_exec_handlers->elts;
794   for (i = 0; i < channel_exec_handlers->nelts; i++) {
795     struct ssh2_channel_exec_handler *handler;
796 
797     handler = handlers[i];
798 
799     pr_trace_msg(trace_channel, 18,
800       "checking exec command '%s' against handler registered by 'mod_%s.c'",
801       command, handler->m->name);
802 
803     if (strcmp(command, handler->command) == 0) {
804       int res;
805 
806       pr_trace_msg(trace_channel, 18,
807         "found '%s' exec handler registered by 'mod_%s.c'",
808         command, handler->m->name);
809 
810       res = (handler->set_params)(pkt->pool, chan->local_channel_id, req);
811       if (res < 0) {
812         int xerrno = errno;
813 
814         pr_trace_msg(trace_channel, 18, "'set_params' callback error: %s",
815           strerror(xerrno));
816 
817         errno = xerrno;
818         return -1;
819       }
820 
821       chan->prepare = handler->prepare;
822       chan->postopen = handler->postopen;
823       chan->handle_packet = handler->handle_packet;
824       chan->finish = handler->finish;
825 
826       have_handler = TRUE;
827       break;
828     }
829   }
830 
831   if (!have_handler) {
832     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
833       "unsupported exec command '%s'", command);
834     return -1;
835   }
836 
837   return 0;
838 }
839 
handle_env_channel(struct ssh2_channel * chan,struct ssh2_packet * pkt,unsigned char ** buf,uint32_t * buflen)840 static int handle_env_channel(struct ssh2_channel *chan,
841     struct ssh2_packet *pkt, unsigned char **buf, uint32_t *buflen) {
842   int res;
843   char *key, *value;
844 
845   key = sftp_msg_read_string(pkt->pool, buf, buflen);
846   value = sftp_msg_read_string(pkt->pool, buf, buflen);
847 
848   (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
849     "'env' channel request: '%s' = '%s'", key, value);
850 
851   if (allow_env(key) == TRUE) {
852     res = pr_env_set(sftp_pool, pstrdup(session.pool, key),
853       pstrdup(session.pool, value));
854     if (res < 0) {
855       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
856         "error setting environment variable '%s' with value '%s': %s",
857         key, value, strerror(errno));
858     }
859 
860   } else {
861     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
862       "environment variable '%s' prohibited by policy", key);
863     res = -1;
864   }
865 
866   return res;
867 }
868 
handle_signal_channel(struct ssh2_channel * chan,struct ssh2_packet * pkt,unsigned char ** buf,uint32_t * buflen)869 static int handle_signal_channel(struct ssh2_channel *chan,
870     struct ssh2_packet *pkt, unsigned char **buf, uint32_t *buflen) {
871   int res;
872   char bool, *sig_name;
873 
874   bool = sftp_msg_read_bool(pkt->pool, buf, buflen);
875   if (bool != FALSE) {
876     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
877       "malformed 'signal' request (bool must be FALSE)");
878   }
879 
880   sig_name = sftp_msg_read_string(pkt->pool, buf, buflen);
881 
882   (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
883     "'signal' channel request: SIG%s", sig_name);
884 
885   if (strncmp(sig_name, "ABRT", 5) == 0) {
886     res = raise(SIGABRT);
887 
888   } else if (strncmp(sig_name, "ALRM", 5) == 0) {
889     res = raise(SIGALRM);
890 
891 #ifdef SIGFPE
892   } else if (strncmp(sig_name, "FPE", 4) == 0) {
893     res = raise(SIGFPE);
894 
895 #endif
896   } else if (strncmp(sig_name, "HUP", 4) == 0) {
897     /* Sending SIGHUP to this process is not a good idea, but we'll act
898      * like it succeeded anyway.
899      */
900     res = 0;
901 
902 #ifdef SIGILL
903   } else if (strncmp(sig_name, "ILL", 4) == 0) {
904     res = raise(SIGILL);
905 
906 #endif
907   } else if (strncmp(sig_name, "INT", 4) == 0) {
908     res = raise(SIGINT);
909 
910   } else if (strncmp(sig_name, "KILL", 5) == 0) {
911     res = raise(SIGKILL);
912 
913   } else if (strncmp(sig_name, "PIPE", 5) == 0) {
914     /* Ignore SIGPIPE, since we told the kernel we would ignore it. */
915     res = 0;
916 
917   } else if (strncmp(sig_name, "QUIT", 5) == 0) {
918     res = raise(SIGQUIT);
919 
920   } else if (strncmp(sig_name, "SEGV", 5) == 0) {
921     res = raise(SIGSEGV);
922 
923   } else if (strncmp(sig_name, "TERM", 5) == 0) {
924     res = raise(SIGTERM);
925 
926   } else if (strncmp(sig_name, "USR1", 5) == 0 ||
927              strncmp(sig_name, "USR2", 5) == 0) {
928     /* We already use these for very specific uses. */
929     res = 0;
930 
931   } else {
932     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
933       "unknown signal name 'SIG%s'", sig_name);
934     res = -1;
935   }
936 
937   return res;
938 }
939 
handle_subsystem_channel(struct ssh2_channel * chan,struct ssh2_packet * pkt,unsigned char ** buf,uint32_t * buflen)940 static int handle_subsystem_channel(struct ssh2_channel *chan,
941     struct ssh2_packet *pkt, unsigned char **buf, uint32_t *buflen) {
942   char *subsystem;
943 
944   subsystem = sftp_msg_read_string(pkt->pool, buf, buflen);
945 
946   (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
947     "'subsystem' channel request for '%s' subsystem", subsystem);
948 
949   if (strncmp(subsystem, "sftp", 5) == 0) {
950 
951     if (sftp_services & SFTP_SERVICE_FL_SFTP) {
952       chan->prepare = sftp_fxp_open_session;
953       chan->postopen = NULL;
954       chan->handle_packet = sftp_fxp_handle_packet;
955       chan->finish = sftp_fxp_close_session;
956 
957     } else {
958       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
959         "'%s' subsystem denied by Protocols config", subsystem);
960       return -1;
961     }
962 
963   } else {
964     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
965       "subsystem '%s' unsupported", subsystem);
966     return -1;
967   }
968 
969   return 0;
970 }
971 
handle_channel_req(struct ssh2_packet * pkt)972 static int handle_channel_req(struct ssh2_packet *pkt) {
973   unsigned char *buf;
974   char *channel_request;
975   uint32_t buflen, channel_id;
976   int res, unsupported = FALSE, want_reply;
977   struct ssh2_channel *chan;
978   cmd_rec *cmd;
979 
980   buf = pkt->payload;
981   buflen = pkt->payload_len;
982 
983   channel_id = sftp_msg_read_int(pkt->pool, &buf, &buflen);
984   channel_request = sftp_msg_read_string(pkt->pool, &buf, &buflen);
985   want_reply = sftp_msg_read_bool(pkt->pool, &buf, &buflen);
986 
987   pr_trace_msg(trace_channel, 7,
988     "received '%s' request for channel ID %lu, want reply = %s",
989     channel_request, (unsigned long) channel_id,
990     want_reply ? "true" : "false");
991 
992   cmd = pr_cmd_alloc(pkt->pool, 2, pstrdup(pkt->pool, "CHANNEL_REQUEST"),
993     pstrdup(pkt->pool, channel_request));
994   cmd->arg = channel_request;
995   cmd->cmd_class = CL_MISC|CL_SSH;
996 
997   chan = get_channel(channel_id);
998   if (chan == NULL) {
999     pr_trace_msg(trace_channel, 8, "unable to handle request for "
1000       "channel ID %lu: %s", (unsigned long) channel_id, strerror(errno));
1001 
1002     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1003       "no open channel for remote channel ID %lu", (unsigned long) channel_id);
1004     pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1005     return -1;
1006   }
1007 
1008   if (strncmp(channel_request, "subsystem", 10) == 0) {
1009     res = handle_subsystem_channel(chan, pkt, &buf, &buflen);
1010 
1011   } else if (strncmp(channel_request, "exec", 5) == 0) {
1012     res = handle_exec_channel(chan, pkt, &buf, &buflen);
1013 
1014   } else if (strncmp(channel_request, "env", 4) == 0) {
1015     res = handle_env_channel(chan, pkt, &buf, &buflen);
1016 
1017   } else if (strncmp(channel_request, "signal", 7) == 0) {
1018     res = handle_signal_channel(chan, pkt, &buf, &buflen);
1019 
1020   } else if (strncmp(channel_request, "break", 6) == 0) {
1021     uint32_t breaklen;
1022 
1023     /* Handle RFC4335 messages.  We will still return CHANNEL_FAILURE for
1024      * them, but at least we can log that we understood the request.
1025      */
1026 
1027     breaklen = sftp_msg_read_int(pkt->pool, &buf, &buflen);
1028 
1029     pr_trace_msg(trace_channel, 10,
1030       "received '%s' request for %lu millisecs, ignoring", channel_request,
1031       (unsigned long) breaklen);
1032 
1033     res = -1;
1034 
1035   } else {
1036     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1037       "unsupported '%s' channel requested, ignoring", channel_request);
1038     res = -1;
1039     unsupported = TRUE;
1040   }
1041 
1042   if (res == 0 &&
1043       chan->prepare) {
1044     if ((chan->prepare)(chan->local_channel_id) < 0) {
1045       int xerrno = errno;
1046 
1047       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1048         "unable to prepare channel ID %lu: %s",
1049         (unsigned long) chan->local_channel_id, strerror(xerrno));
1050 
1051       errno = xerrno;
1052       res = -1;
1053     }
1054   }
1055 
1056   if (want_reply) {
1057     struct ssh2_packet *pkt2;
1058     unsigned char *buf2, *ptr2;
1059     uint32_t buflen2, bufsz2;
1060 
1061     buflen2 = bufsz2 = 128;
1062     buf2 = ptr2 = palloc(pkt->pool, bufsz2);
1063 
1064     if (res < 0) {
1065       sftp_msg_write_byte(&buf2, &buflen2, SFTP_SSH2_MSG_CHANNEL_FAILURE);
1066 
1067     } else {
1068       sftp_msg_write_byte(&buf2, &buflen2, SFTP_SSH2_MSG_CHANNEL_SUCCESS);
1069     }
1070 
1071     sftp_msg_write_int(&buf2, &buflen2, chan->remote_channel_id);
1072 
1073     pkt2 = sftp_ssh2_packet_create(pkt->pool);
1074     pkt2->payload = ptr2;
1075     pkt2->payload_len = (bufsz2 - buflen2);
1076 
1077     if (sftp_ssh2_packet_write(sftp_conn->wfd, pkt2) < 0) {
1078       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1079         "error sending reply to CHANNEL_REQUEST: %s", strerror(errno));
1080     }
1081 
1082     destroy_pool(pkt2->pool);
1083   }
1084 
1085   /* If the handler has a postopen callback, invoke that. */
1086   if (res == 0 &&
1087       chan->postopen) {
1088     int pres;
1089 
1090     pr_trace_msg(trace_channel, 18,
1091       "calling '%s' handler postopen callback", channel_request);
1092 
1093     pres = (chan->postopen)(chan->local_channel_id);
1094     if (pres < 0) {
1095       int xerrno = errno;
1096 
1097       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1098         "postopen error on channel ID %lu: %s",
1099         (unsigned long) chan->local_channel_id, strerror(xerrno));
1100 
1101     } else if (pres == 1) {
1102       /* Special case: if the postopen callback returns 1, the handler
1103        * is indicating that it has already handled the requests and requires
1104        * no further data from the client.
1105        *
1106        * This means that we can call send_channel_done() for this channel.
1107        */
1108       pr_trace_msg(trace_channel, 18,
1109         "sending CHANNEL_CLOSE for '%s', due to postopen return value",
1110         channel_request);
1111       send_channel_done(pkt->pool, chan->local_channel_id);
1112     }
1113   }
1114 
1115   /* Make a special case for failed, but unsupported, channel requests.
1116    * For these, we essentially treat them as "succeeded", but ignore them.
1117    * Clients like PuTTY send some strange requests, and there's no reason to
1118    * support such requests unnecessarily.
1119    */
1120 
1121   if (!unsupported &&
1122       res < 0) {
1123     pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1124     return 0;
1125   }
1126 
1127   pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
1128   return 0;
1129 }
1130 
handle_channel_window_adjust(struct ssh2_packet * pkt)1131 static int handle_channel_window_adjust(struct ssh2_packet *pkt) {
1132   char adjust_str[32];
1133   unsigned char *buf;
1134   uint32_t buflen, channel_id, adjust_len, max_adjust_len;
1135   struct ssh2_channel *chan;
1136   cmd_rec *cmd;
1137 
1138   buf = pkt->payload;
1139   buflen = pkt->payload_len;
1140 
1141   channel_id = sftp_msg_read_int(pkt->pool, &buf, &buflen);
1142   adjust_len = sftp_msg_read_int(pkt->pool, &buf, &buflen);
1143 
1144   memset(adjust_str, '\0', sizeof(adjust_str));
1145   pr_snprintf(adjust_str, sizeof(adjust_str)-1, "%lu %lu",
1146     (unsigned long) channel_id, (unsigned long) adjust_len);
1147 
1148   cmd = pr_cmd_alloc(pkt->pool, 1, pstrdup(pkt->pool, "CHANNEL_WINDOW_ADJUST"));
1149   cmd->arg = pstrdup(pkt->pool, adjust_str);
1150   cmd->cmd_class = CL_MISC|CL_SSH;
1151 
1152   chan = get_channel(channel_id);
1153   if (chan == NULL) {
1154     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1155       "no open channel for channel ID %lu", (unsigned long) channel_id);
1156     pr_cmd_dispatch_phase(cmd, LOG_CMD_ERR, 0);
1157     return -1;
1158   }
1159 
1160   /* As per RFC4254, Section 5.2, we MUST NOT allow the window size to be
1161    * increased above 2^32-1 bytes.
1162    *
1163    * To check this, we cannot simply add the given increment to our current
1164    * size; if the given increment is large, it could overflow our data
1165    * type.  So instead, we check whether the difference between the max
1166    * possible window size and the current window size is larger than the
1167    * given increment.  If not, we will only increment the window up to the
1168    * max possible window size.
1169    */
1170   max_adjust_len = SFTP_SSH2_CHANNEL_WINDOW_SIZE - chan->remote_windowsz;
1171 
1172   if (adjust_len > max_adjust_len) {
1173     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1174       "received WINDOW_ADJUST message whose window size adjustment (%lu bytes) "
1175       "exceeds max possible adjustment (%lu bytes), trimming",
1176       (unsigned long) adjust_len, (unsigned long) max_adjust_len);
1177     adjust_len = max_adjust_len;
1178   }
1179 
1180   pr_trace_msg(trace_channel, 15, "adjusting remote window size "
1181     "for local channel ID %lu, adding %lu bytes to current window size "
1182     "(%lu bytes)", (unsigned long) channel_id, (unsigned long) adjust_len,
1183     (unsigned long) chan->remote_windowsz);
1184 
1185   chan->remote_windowsz += adjust_len;
1186 
1187   drain_pending_channel_data(channel_id);
1188 
1189   pr_cmd_dispatch_phase(cmd, LOG_CMD, 0);
1190   return 0;
1191 }
1192 
write_channel_open_confirm(struct ssh2_packet * pkt,uint32_t channel_id)1193 static int write_channel_open_confirm(struct ssh2_packet *pkt,
1194     uint32_t channel_id) {
1195   register unsigned int i;
1196   unsigned char *buf, *ptr;
1197   uint32_t buflen, bufsz;
1198   struct ssh2_channel *chan = NULL, **chans;
1199 
1200   chans = channel_list->elts;
1201   for (i = 0; i < channel_list->nelts; i++) {
1202     if (chans[i] != NULL &&
1203         chans[i]->remote_channel_id == channel_id) {
1204       chan = chans[i];
1205       break;
1206     }
1207   }
1208 
1209   if (chan == NULL) {
1210     pr_trace_msg(trace_channel, 8, "unable to confirm open channel ID %lu: %s",
1211       (unsigned long) channel_id, strerror(errno));
1212 
1213     return -1;
1214   }
1215 
1216   buflen = bufsz = 1024;
1217   ptr = buf = palloc(pkt->pool, bufsz);
1218 
1219   sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
1220   sftp_msg_write_int(&buf, &buflen, chan->remote_channel_id);
1221   sftp_msg_write_int(&buf, &buflen, chan->local_channel_id);
1222   sftp_msg_write_int(&buf, &buflen, chan->local_windowsz);
1223   sftp_msg_write_int(&buf, &buflen, chan->local_max_packetsz);
1224 
1225   pr_trace_msg(trace_channel, 8, "confirm open channel remote ID %lu, "
1226     "local ID %lu: initial server window len = %lu bytes, server max "
1227     "packet size = %lu bytes", (unsigned long) chan->remote_channel_id,
1228     (unsigned long) chan->local_channel_id, (unsigned long)
1229     chan->local_windowsz, (unsigned long) chan->local_max_packetsz);
1230 
1231   pkt->payload = ptr;
1232   pkt->payload_len = (bufsz - buflen);
1233 
1234   return 0;
1235 }
1236 
write_channel_open_failed(struct ssh2_packet * pkt,uint32_t channel_id)1237 static int write_channel_open_failed(struct ssh2_packet *pkt,
1238     uint32_t channel_id) {
1239   unsigned char *buf, *ptr;
1240   uint32_t buflen, bufsz;
1241 
1242   buflen = bufsz = 1024;
1243   ptr = buf = palloc(pkt->pool, bufsz);
1244 
1245   sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_CHANNEL_OPEN_FAILURE);
1246   sftp_msg_write_int(&buf, &buflen, channel_id);
1247   sftp_msg_write_int(&buf, &buflen,
1248     SFTP_SSH2_CHANNEL_OPEN_UNKNOWN_CHANNEL_TYPE);
1249   sftp_msg_write_string(&buf, &buflen, "Unsupported channel type requested");
1250   sftp_msg_write_string(&buf, &buflen, "en-US");
1251 
1252   pkt->payload = ptr;
1253   pkt->payload_len = (bufsz - buflen);
1254 
1255   return 0;
1256 }
1257 
sftp_channel_get_windowsz(uint32_t channel_id)1258 uint32_t sftp_channel_get_windowsz(uint32_t channel_id) {
1259   struct ssh2_channel *chan;
1260 
1261   chan = get_channel(channel_id);
1262   if (chan == NULL) {
1263     pr_trace_msg(trace_channel, 1, "cannot return window size for unknown "
1264       "channel ID %lu", (unsigned long) channel_id);
1265     return 0;
1266   }
1267 
1268   return chan->remote_windowsz;
1269 }
1270 
sftp_channel_set_max_count(unsigned int max)1271 unsigned int sftp_channel_set_max_count(unsigned int max) {
1272   unsigned int prev_max;
1273 
1274   prev_max = channel_max;
1275   channel_max = max;
1276 
1277   return prev_max;
1278 }
1279 
sftp_channel_get_max_packetsz(void)1280 uint32_t sftp_channel_get_max_packetsz(void) {
1281   return chan_packet_size;
1282 }
1283 
sftp_channel_set_max_packetsz(uint32_t packetsz)1284 uint32_t sftp_channel_set_max_packetsz(uint32_t packetsz) {
1285   uint32_t prev_packetsz;
1286 
1287   prev_packetsz = chan_packet_size;
1288   chan_packet_size = packetsz;
1289 
1290   return prev_packetsz;
1291 }
1292 
sftp_channel_set_max_windowsz(uint32_t windowsz)1293 uint32_t sftp_channel_set_max_windowsz(uint32_t windowsz) {
1294   uint32_t prev_windowsz;
1295 
1296   prev_windowsz = chan_window_size;
1297   chan_window_size = windowsz;
1298 
1299   return prev_windowsz;
1300 }
1301 
sftp_channel_handle(struct ssh2_packet * pkt,char mesg_type)1302 int sftp_channel_handle(struct ssh2_packet *pkt, char mesg_type) {
1303   int res;
1304   uint32_t channel_id;
1305 
1306   switch (mesg_type) {
1307     case SFTP_SSH2_MSG_CHANNEL_OPEN: {
1308       res = read_channel_open(pkt, &channel_id);
1309       if (res < 0) {
1310         struct ssh2_packet *pkt2;
1311         pkt2 = sftp_ssh2_packet_create(channel_pool);
1312 
1313         if (write_channel_open_failed(pkt2, channel_id) == 0) {
1314           (void) sftp_ssh2_packet_write(sftp_conn->wfd, pkt2);
1315         }
1316 
1317         destroy_pool(pkt2->pool);
1318         destroy_pool(pkt->pool);
1319 
1320         return -1;
1321       }
1322 
1323       destroy_pool(pkt->pool);
1324 
1325       pkt = sftp_ssh2_packet_create(channel_pool);
1326       res = write_channel_open_confirm(pkt, channel_id);
1327       if (res < 0) {
1328         destroy_pool(pkt->pool);
1329         return -1;
1330       }
1331 
1332       res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
1333       if (res < 0) {
1334         destroy_pool(pkt->pool);
1335         return -1;
1336       }
1337 
1338       destroy_pool(pkt->pool);
1339       return 0;
1340     }
1341 
1342     case SFTP_SSH2_MSG_CHANNEL_REQUEST:
1343       res = handle_channel_req(pkt);
1344       destroy_pool(pkt->pool);
1345       return res;
1346 
1347     case SFTP_SSH2_MSG_CHANNEL_CLOSE:
1348       res = handle_channel_close(pkt);
1349       destroy_pool(pkt->pool);
1350       return res;
1351 
1352     case SFTP_SSH2_MSG_CHANNEL_DATA:
1353       res = handle_channel_data(pkt, &channel_id);
1354       if (res == 1) {
1355         /* Send an EOF, since the channel has indicated it has finished
1356          * gracefully.
1357          */
1358         res = send_channel_done(pkt->pool, channel_id);
1359       }
1360 
1361       destroy_pool(pkt->pool);
1362       return res;
1363 
1364     case SFTP_SSH2_MSG_CHANNEL_EOF:
1365       res = handle_channel_eof(pkt);
1366       destroy_pool(pkt->pool);
1367       return res;
1368 
1369     case SFTP_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
1370       res = handle_channel_window_adjust(pkt);
1371       destroy_pool(pkt->pool);
1372       return res;
1373 
1374     default:
1375       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1376         "expecting CHANNEL message, received %s (%d), disconnecting",
1377         sftp_ssh2_packet_get_mesg_type_desc(mesg_type), mesg_type);
1378       destroy_pool(pkt->pool);
1379       SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_PROTOCOL_ERROR, NULL);
1380   }
1381 
1382   errno = EINVAL;
1383   return -1;
1384 }
1385 
sftp_channel_free(void)1386 int sftp_channel_free(void) {
1387   register unsigned int i;
1388   struct ssh2_channel **chans;
1389 
1390   if (channel_count == 0 ||
1391       channel_list == NULL) {
1392     return 0;
1393   }
1394 
1395   /* Iterate through all the open channels, destroying each one. */
1396   chans = channel_list->elts;
1397   for (i = 0; i < channel_list->nelts; i++) {
1398     if (chans[i] != NULL) {
1399       uint32_t pending_len;
1400 
1401       pending_len = get_channel_pending_size(chans[i]);
1402       pr_trace_msg(trace_channel, 15,
1403         "destroying unclosed channel ID %lu (%lu bytes pending)",
1404         (unsigned long) chans[i]->local_channel_id,
1405         (unsigned long) pending_len);
1406 
1407       if (chans[i]->finish != NULL) {
1408         (chans[i]->finish)(chans[i]->local_channel_id);
1409       }
1410 
1411       chans[i] = NULL;
1412       channel_count--;
1413     }
1414   }
1415 
1416   return 0;
1417 }
1418 
sftp_channel_init(void)1419 int sftp_channel_init(void) {
1420   struct ssh2_channel_exec_handler *handler;
1421   config_rec *c;
1422 
1423   if (channel_pool == NULL) {
1424     channel_pool = make_sub_pool(sftp_pool);
1425     pr_pool_tag(channel_pool, "SSH2 Channel Pool");
1426   }
1427 
1428   if (channel_exec_handlers == NULL) {
1429     /* Initialize our list of 'exec' channel handlers. */
1430     channel_exec_handlers = make_array(channel_pool, 1,
1431       sizeof(struct ssh2_channel_exec_handler *));
1432   }
1433 
1434   /* Allocate the 'scp' handler */
1435 
1436   handler = pcalloc(channel_pool, sizeof(struct ssh2_channel_exec_handler));
1437   handler->m = &sftp_module;
1438 
1439   /* XXX In the future, we should be able to handle clients which request
1440    * something like "/usr/bin/scp", in addition to just "scp".
1441    */
1442   handler->command = pstrdup(channel_pool, "scp");
1443   handler->set_params = sftp_scp_set_params;
1444   handler->prepare = sftp_scp_open_session;
1445   handler->postopen = NULL;
1446   handler->handle_packet = sftp_scp_handle_packet;
1447   handler->finish = sftp_scp_close_session;
1448 
1449   *((struct ssh2_channel_exec_handler **) push_array(channel_exec_handlers)) =
1450     handler;
1451 
1452   /* Allocate the 'date' handler */
1453 
1454   handler = pcalloc(channel_pool, sizeof(struct ssh2_channel_exec_handler));
1455   handler->m = &sftp_module;
1456 
1457   /* XXX In the future, we should be able to handle clients which request
1458    * something like "/bin/date", in addition to just "date".
1459    */
1460   handler->command = pstrdup(channel_pool, "date");
1461   handler->set_params = sftp_date_set_params;
1462   handler->prepare = sftp_date_open_session;
1463   handler->postopen = sftp_date_postopen_session;
1464   handler->handle_packet = sftp_date_handle_packet;
1465   handler->finish = sftp_date_close_session;
1466 
1467   *((struct ssh2_channel_exec_handler **) push_array(channel_exec_handlers)) =
1468     handler;
1469 
1470   accepted_envs = make_array(channel_pool, 0, sizeof(char *));
1471 
1472   c = find_config(main_server->conf, CONF_PARAM, "SFTPAcceptEnv", FALSE);
1473   if (c) {
1474     while (c) {
1475       register unsigned int i;
1476       array_header *envs;
1477       char **elts;
1478 
1479       pr_signals_handle();
1480 
1481       envs = c->argv[0];
1482       elts = envs->elts;
1483       for (i = 0; i < envs->nelts; i++) {
1484         *((char **) push_array(accepted_envs)) = pstrdup(channel_pool, elts[i]);
1485       }
1486 
1487       c = find_config_next(c, c->next, CONF_PARAM, "SFTPAcceptEnv", FALSE);
1488     }
1489 
1490   } else {
1491     /* Allow the LANG environment variable by default. */
1492     *((char **) push_array(accepted_envs)) = pstrdup(channel_pool, "LANG");
1493   }
1494 
1495   return 0;
1496 }
1497 
sftp_channel_drain_data(void)1498 int sftp_channel_drain_data(void) {
1499   register unsigned int i;
1500   struct ssh2_channel **chans;
1501 
1502   if (channel_list == NULL) {
1503     errno = EACCES;
1504     return -1;
1505   }
1506 
1507   /* Iterate through all the open channels, draining any pending data they
1508    * might have.
1509    */
1510   chans = channel_list->elts;
1511   for (i = 0; i < channel_list->nelts; i++) {
1512     if (chans[i] != NULL) {
1513       pr_trace_msg(trace_channel, 15, "draining pending data for local "
1514         "channel ID %lu", (unsigned long) chans[i]->local_channel_id);
1515 
1516       drain_pending_channel_data(chans[i]->local_channel_id);
1517     }
1518   }
1519 
1520   return 0;
1521 }
1522 
channel_write_data(pool * p,uint32_t channel_id,unsigned char * buf,uint32_t buflen,char msg_type,uint32_t data_type)1523 static int channel_write_data(pool *p, uint32_t channel_id,
1524     unsigned char *buf, uint32_t buflen, char msg_type, uint32_t data_type) {
1525   struct ssh2_channel *chan;
1526   int res;
1527 
1528   chan = get_channel(channel_id);
1529   if (chan == NULL) {
1530     errno = EACCES;
1531     return -1;
1532   }
1533 
1534   /* We may need to send the given buffer in multiple CHANNEL_DATA packets,
1535    * for example of the remote window size is large but the remote max
1536    * packet size is small.  Hence the loop.
1537    */
1538 
1539   while (!(sftp_sess_state & SFTP_SESS_STATE_REKEYING) &&
1540          chan->remote_windowsz > 0 &&
1541          buflen > 0) {
1542     uint32_t payload_len;
1543 
1544     pr_signals_handle();
1545 
1546     /* First try to drain any pending data for this channel. */
1547     drain_pending_channel_data(channel_id);
1548     if (chan->remote_windowsz == 0)
1549       break;
1550 
1551     /* If the remote window size or remote max packet size changes the
1552      * length we can send, then payload_len is NOT the same as buflen.  Hence
1553      * the separate variable.
1554      */
1555     payload_len = buflen;
1556 
1557     /* The maximum size of the CHANNEL_DATA payload we can send to the client
1558      * is the smaller of the remote window size and the remote packet size.
1559      */
1560 
1561     if (payload_len > chan->remote_max_packetsz)
1562       payload_len = chan->remote_max_packetsz;
1563 
1564     if (payload_len > chan->remote_windowsz)
1565       payload_len = chan->remote_windowsz;
1566 
1567     if (payload_len > 0) {
1568       struct ssh2_packet *pkt;
1569       unsigned char *buf2, *ptr2;
1570       uint32_t bufsz2, buflen2;
1571 
1572       /* In addition to the data itself, we need to allocate room in the
1573        * outgoing packet for the type (1 byte), the channel ID (4 bytes),
1574        * a possible data type ID (4 bytes),  and for the data length (4 bytes).
1575        */
1576       bufsz2 = buflen2 = payload_len + 13;
1577 
1578       pkt = sftp_ssh2_packet_create(p);
1579       ptr2 = buf2 = palloc(pkt->pool, bufsz2);
1580 
1581       sftp_msg_write_byte(&buf2, &buflen2, msg_type);
1582       sftp_msg_write_int(&buf2, &buflen2, chan->remote_channel_id);
1583 
1584       if (data_type != 0) {
1585         /* Right now, this is only used for EXTENDED_DATA messages of type
1586          * STDERR.
1587          */
1588         sftp_msg_write_int(&buf2, &buflen2, data_type);
1589       }
1590 
1591       sftp_msg_write_int(&buf2, &buflen2, payload_len);
1592       memcpy(buf2, buf, payload_len);
1593       buflen2 -= payload_len;
1594 
1595       pkt->payload = ptr2;
1596       pkt->payload_len = (bufsz2 - buflen2);
1597 
1598       pr_trace_msg(trace_channel, 9, "sending %s (remote channel ID %lu, "
1599         "%lu data bytes)",
1600         msg_type == SFTP_SSH2_MSG_CHANNEL_DATA ? "CHANNEL_DATA" :
1601           "CHANNEL_EXTENDED_DATA", (unsigned long) chan->remote_channel_id,
1602         (unsigned long) payload_len);
1603 
1604       res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
1605       if (res == 0) {
1606         chan->remote_windowsz -= payload_len;
1607 
1608         pr_trace_msg(trace_channel, 11,
1609           "channel ID %lu remote window size currently at %lu bytes",
1610           (unsigned long) chan->remote_channel_id,
1611           (unsigned long) chan->remote_windowsz);
1612       }
1613 
1614       destroy_pool(pkt->pool);
1615 
1616       /* If that was the entire payload, we can be done now. */
1617       if (payload_len == buflen) {
1618         return res;
1619       }
1620 
1621       buf += payload_len;
1622       buflen -= payload_len;
1623 
1624       /* Otherwise try sending another packet.  If the window closes, the loop
1625        * will end.
1626        */
1627 
1628     } else {
1629       pr_trace_msg(trace_channel, 6, "allowed payload size of %lu bytes is too "
1630         "small for data (%lu bytes)", (unsigned long) payload_len,
1631         (unsigned long) buflen);
1632 
1633       /* For now, leave this case as is, and break out of the while loop. */
1634       break;
1635     }
1636   }
1637 
1638   /* We have to buffer up the remaining payload, and wait for a
1639    * CHANNEL_WINDOW_ADJUST from the client before we can send more.
1640    */
1641 
1642   if (buflen > 0) {
1643     struct ssh2_channel_databuf *db;
1644     const char *reason;
1645 
1646     db = get_databuf(channel_id, buflen);
1647 
1648     db->buflen = buflen;
1649     memcpy(db->buf, buf, buflen);
1650 
1651     /* Why are we buffering these bytes? */
1652     reason = "remote window size too small";
1653     if (sftp_sess_state & SFTP_SESS_STATE_REKEYING) {
1654       reason = "rekeying";
1655     }
1656 
1657     pr_trace_msg(trace_channel, 8, "buffering %lu remaining bytes of "
1658       "outgoing data (%s)", (unsigned long) buflen, reason);
1659   }
1660 
1661   return 0;
1662 }
1663 
sftp_channel_write_data(pool * p,uint32_t channel_id,unsigned char * buf,uint32_t buflen)1664 int sftp_channel_write_data(pool *p, uint32_t channel_id,
1665     unsigned char *buf, uint32_t buflen) {
1666   return channel_write_data(p, channel_id, buf, buflen,
1667     SFTP_SSH2_MSG_CHANNEL_DATA, 0);
1668 }
1669 
sftp_channel_write_ext_data_stderr(pool * p,uint32_t channel_id,unsigned char * buf,uint32_t buflen)1670 int sftp_channel_write_ext_data_stderr(pool *p, uint32_t channel_id,
1671     unsigned char *buf, uint32_t buflen) {
1672   return channel_write_data(p, channel_id, buf, buflen,
1673     SFTP_SSH2_MSG_CHANNEL_EXTENDED_DATA,
1674     SFTP_SSH2_MSG_CHANNEL_EXTENDED_DATA_TYPE_STDERR);
1675 }
1676 
1677 /* Return the number of open channels, if any. */
sftp_channel_opened(uint32_t * remote_channel_id)1678 unsigned int sftp_channel_opened(uint32_t *remote_channel_id) {
1679   register unsigned int i;
1680   struct ssh2_channel **chans;
1681 
1682   if (channel_count == 0 ||
1683       channel_list == NULL) {
1684     return 0;
1685   }
1686 
1687   if (channel_list == NULL) {
1688     errno = EACCES;
1689     return 0;
1690   }
1691 
1692   chans = channel_list->elts;
1693   for (i = 0; i < channel_list->nelts; i++) {
1694     if (chans[i] != NULL) {
1695       if (remote_channel_id != NULL) {
1696         *remote_channel_id = chans[i]->remote_channel_id;
1697       }
1698     }
1699   }
1700 
1701   return channel_count;
1702 }
1703 
sftp_channel_register_exec_handler(module * m,const char * command,int (* set_params)(pool *,uint32_t,array_header *),int (* prepare)(uint32_t),int (* postopen)(uint32_t),int (* handle_packet)(pool *,void *,uint32_t,unsigned char *,uint32_t),int (* finish)(uint32_t),int (** write_data)(pool *,uint32_t,unsigned char *,uint32_t))1704 int sftp_channel_register_exec_handler(module *m, const char *command,
1705     int (*set_params)(pool *, uint32_t, array_header *),
1706     int (*prepare)(uint32_t),
1707     int (*postopen)(uint32_t),
1708     int (*handle_packet)(pool *, void *, uint32_t, unsigned char *, uint32_t),
1709     int (*finish)(uint32_t),
1710     int (**write_data)(pool *, uint32_t, unsigned char *, uint32_t)) {
1711   struct ssh2_channel_exec_handler *handler;
1712 
1713   if (m == NULL ||
1714       command == NULL ||
1715       set_params == NULL ||
1716       prepare == NULL ||
1717       handle_packet == NULL ||
1718       finish == NULL ||
1719       write_data == NULL) {
1720     errno = EINVAL;
1721     return -1;
1722   }
1723 
1724   if (channel_pool == NULL) {
1725     channel_pool = make_sub_pool(sftp_pool);
1726     pr_pool_tag(channel_pool, "SSH2 Channel Pool");
1727   }
1728 
1729   if (channel_exec_handlers == NULL) {
1730     /* Initialize our list of 'exec' channel handlers. */
1731     channel_exec_handlers = make_array(channel_pool, 1,
1732       sizeof(struct ssh2_channel_exec_handler *));
1733 
1734   } else {
1735     register unsigned int i;
1736     struct ssh2_channel_exec_handler **handlers;
1737 
1738     /* Make sure that another handler for this command hasn't already been
1739      * registered.
1740      */
1741     handlers = channel_exec_handlers->elts;
1742     for (i = 0; i < channel_exec_handlers->nelts; i++) {
1743       handler = handlers[i];
1744 
1745       if (strcmp(handler->command, command) == 0) {
1746         errno = EEXIST;
1747         return -1;
1748       }
1749     }
1750   }
1751 
1752   handler = pcalloc(channel_pool, sizeof(struct ssh2_channel_exec_handler));
1753 
1754   handler->m = m;
1755   handler->command = pstrdup(channel_pool, command);
1756   handler->set_params = set_params;
1757   handler->prepare = prepare;
1758   handler->postopen = postopen;
1759   handler->handle_packet = handle_packet;
1760   handler->finish = finish;
1761 
1762   *((struct ssh2_channel_exec_handler **) push_array(channel_exec_handlers)) =
1763     handler;
1764 
1765   /* Send back to the caller, via the value-result argument, the address
1766    * of the function which the caller can use for writing data back to
1767    * the SSH2 channel.  This pointer trickery means that we don't have to
1768    * expose the sftp_channel_write_data() function via the public mod_sftp.h
1769    * header file.
1770    */
1771 
1772   *write_data = sftp_channel_write_data;
1773 
1774   return 0;
1775 }
1776