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