1 /* 2 * Dropbear SSH 3 * 4 * Copyright (c) 2002-2004 Matt Johnston 5 * All rights reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. */ 24 25 /* Handle the multiplexed channels, such as sessions, x11, agent connections */ 26 27 #include "includes.h" 28 #include "session.h" 29 #include "packet.h" 30 #include "ssh.h" 31 #include "buffer.h" 32 #include "circbuffer.h" 33 #include "dbutil.h" 34 #include "channel.h" 35 #include "ssh.h" 36 #include "listener.h" 37 38 static void send_msg_channel_open_failure(unsigned int remotechan, int reason, 39 const unsigned char *text, const unsigned char *lang); 40 static void send_msg_channel_open_confirmation(struct Channel* channel, 41 unsigned int recvwindow, 42 unsigned int recvmaxpacket); 43 static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf); 44 static void send_msg_channel_window_adjust(struct Channel *channel, 45 unsigned int incr); 46 static void send_msg_channel_data(struct Channel *channel, int isextended); 47 static void send_msg_channel_eof(struct Channel *channel); 48 static void send_msg_channel_close(struct Channel *channel); 49 static void remove_channel(struct Channel *channel); 50 static void delete_channel(struct Channel *channel); 51 static void check_in_progress(struct Channel *channel); 52 static unsigned int write_pending(struct Channel * channel); 53 static void check_close(struct Channel *channel); 54 static void close_chan_fd(struct Channel *channel, int fd, int how); 55 56 #define FD_UNINIT (-2) 57 #define FD_CLOSED (-1) 58 59 #define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL) 60 #define ERRFD_IS_WRITE(channel) (!ERRFD_IS_READ(channel)) 61 62 /* Initialise all the channels */ 63 void chaninitialise(const struct ChanType *chantypes[]) { 64 65 /* may as well create space for a single channel */ 66 ses.channels = (struct Channel**)m_malloc(sizeof(struct Channel*)); 67 ses.chansize = 1; 68 ses.channels[0] = NULL; 69 ses.chancount = 0; 70 71 ses.chantypes = chantypes; 72 73 #ifdef USING_LISTENERS 74 listeners_initialise(); 75 #endif 76 77 } 78 79 /* Clean up channels, freeing allocated memory */ 80 void chancleanup() { 81 82 unsigned int i; 83 84 TRACE(("enter chancleanup")) 85 for (i = 0; i < ses.chansize; i++) { 86 if (ses.channels[i] != NULL) { 87 TRACE(("channel %d closing", i)) 88 remove_channel(ses.channels[i]); 89 } 90 } 91 m_free(ses.channels); 92 TRACE(("leave chancleanup")) 93 } 94 95 /* Create a new channel entry, send a reply confirm or failure */ 96 /* If remotechan, transwindow and transmaxpacket are not know (for a new 97 * outgoing connection, with them to be filled on confirmation), they should 98 * all be set to 0 */ 99 struct Channel* newchannel(unsigned int remotechan, 100 const struct ChanType *type, 101 unsigned int transwindow, unsigned int transmaxpacket) { 102 103 struct Channel * newchan; 104 unsigned int i, j; 105 106 TRACE(("enter newchannel")) 107 108 /* first see if we can use existing channels */ 109 for (i = 0; i < ses.chansize; i++) { 110 if (ses.channels[i] == NULL) { 111 break; 112 } 113 } 114 115 /* otherwise extend the list */ 116 if (i == ses.chansize) { 117 if (ses.chansize >= MAX_CHANNELS) { 118 TRACE(("leave newchannel: max chans reached")) 119 return NULL; 120 } 121 122 /* extend the channels */ 123 ses.channels = (struct Channel**)m_realloc(ses.channels, 124 (ses.chansize+CHAN_EXTEND_SIZE)*sizeof(struct Channel*)); 125 126 ses.chansize += CHAN_EXTEND_SIZE; 127 128 /* set the new channels to null */ 129 for (j = i; j < ses.chansize; j++) { 130 ses.channels[j] = NULL; 131 } 132 133 } 134 135 newchan = (struct Channel*)m_malloc(sizeof(struct Channel)); 136 newchan->type = type; 137 newchan->index = i; 138 newchan->sent_close = newchan->recv_close = 0; 139 newchan->sent_eof = newchan->recv_eof = 0; 140 141 newchan->remotechan = remotechan; 142 newchan->transwindow = transwindow; 143 newchan->transmaxpacket = transmaxpacket; 144 145 newchan->typedata = NULL; 146 newchan->writefd = FD_UNINIT; 147 newchan->readfd = FD_UNINIT; 148 newchan->errfd = FD_CLOSED; /* this isn't always set to start with */ 149 newchan->initconn = 0; 150 newchan->await_open = 0; 151 newchan->flushing = 0; 152 153 newchan->writebuf = cbuf_new(RECV_MAXWINDOW); 154 newchan->extrabuf = NULL; /* The user code can set it up */ 155 newchan->recvwindow = RECV_MAXWINDOW; 156 newchan->recvdonelen = 0; 157 newchan->recvmaxpacket = RECV_MAXPACKET; 158 159 ses.channels[i] = newchan; 160 ses.chancount++; 161 162 TRACE(("leave newchannel")) 163 164 return newchan; 165 } 166 167 /* Returns the channel structure corresponding to the channel in the current 168 * data packet (ses.payload must be positioned appropriately). 169 * A valid channel is always returns, it will fail fatally with an unknown 170 * channel */ 171 static struct Channel* getchannel_msg(const char* kind) { 172 173 unsigned int chan; 174 175 chan = buf_getint(ses.payload); 176 if (chan >= ses.chansize || ses.channels[chan] == NULL) { 177 if (kind) { 178 dropbear_exit("%s for unknown channel %d", kind, chan); 179 } else { 180 dropbear_exit("Unknown channel %d", chan); 181 } 182 } 183 return ses.channels[chan]; 184 } 185 186 struct Channel* getchannel() { 187 return getchannel_msg(NULL); 188 } 189 190 /* Iterate through the channels, performing IO if available */ 191 void channelio(fd_set *readfds, fd_set *writefds) { 192 193 struct Channel *channel; 194 unsigned int i; 195 196 /* foreach channel */ 197 for (i = 0; i < ses.chansize; i++) { 198 199 channel = ses.channels[i]; 200 if (channel == NULL) { 201 /* only process in-use channels */ 202 continue; 203 } 204 205 /* read data and send it over the wire */ 206 if (channel->readfd >= 0 && FD_ISSET(channel->readfd, readfds)) { 207 TRACE(("send normal readfd")) 208 send_msg_channel_data(channel, 0); 209 } 210 211 /* read stderr data and send it over the wire */ 212 if (ERRFD_IS_READ(channel) && channel->errfd >= 0 213 && FD_ISSET(channel->errfd, readfds)) { 214 TRACE(("send normal errfd")) 215 send_msg_channel_data(channel, 1); 216 } 217 218 /* write to program/pipe stdin */ 219 if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) { 220 if (channel->initconn) { 221 /* XXX should this go somewhere cleaner? */ 222 check_in_progress(channel); 223 continue; /* Important not to use the channel after 224 check_in_progress(), as it may be NULL */ 225 } 226 writechannel(channel, channel->writefd, channel->writebuf); 227 } 228 229 /* stderr for client mode */ 230 if (ERRFD_IS_WRITE(channel) 231 && channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) { 232 writechannel(channel, channel->errfd, channel->extrabuf); 233 } 234 235 /* handle any channel closing etc */ 236 check_close(channel); 237 238 } 239 240 /* Listeners such as TCP, X11, agent-auth */ 241 #ifdef USING_LISTENERS 242 handle_listeners(readfds); 243 #endif 244 } 245 246 247 /* Returns true if there is data remaining to be written to stdin or 248 * stderr of a channel's endpoint. */ 249 static unsigned int write_pending(struct Channel * channel) { 250 251 if (channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0) { 252 return 1; 253 } else if (channel->errfd >= 0 && channel->extrabuf && 254 cbuf_getused(channel->extrabuf) > 0) { 255 return 1; 256 } 257 return 0; 258 } 259 260 261 /* EOF/close handling */ 262 static void check_close(struct Channel *channel) { 263 264 TRACE(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d", 265 channel->writefd, channel->readfd, 266 channel->errfd, channel->sent_close, channel->recv_close)) 267 TRACE(("writebuf size %d extrabuf size %d", 268 cbuf_getused(channel->writebuf), 269 channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0)) 270 271 if (!channel->flushing && channel->type->check_close 272 && channel->type->check_close(channel)) 273 { 274 channel->flushing = 1; 275 } 276 277 if (channel->recv_close && !write_pending(channel)) { 278 if (!channel->sent_close) { 279 TRACE(("Sending MSG_CHANNEL_CLOSE in response to same.")) 280 send_msg_channel_close(channel); 281 } 282 remove_channel(channel); 283 return; 284 } 285 286 if (channel->recv_eof && !write_pending(channel)) { 287 close_chan_fd(channel, channel->writefd, SHUT_WR); 288 } 289 290 /* Special handling for flushing read data after an exit. We 291 read regardless of whether the select FD was set, 292 and if there isn't data available, the channel will get closed. */ 293 if (channel->flushing) { 294 TRACE(("might send data, flushing")) 295 if (channel->readfd >= 0 && channel->transwindow > 0) { 296 TRACE(("send data readfd")) 297 send_msg_channel_data(channel, 0); 298 } 299 if (ERRFD_IS_READ(channel) && channel->errfd >= 0 300 && channel->transwindow > 0) { 301 TRACE(("send data errfd")) 302 send_msg_channel_data(channel, 1); 303 } 304 } 305 306 /* If we're not going to send any more data, send EOF */ 307 if (!channel->sent_eof 308 && channel->readfd == FD_CLOSED 309 && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)) { 310 send_msg_channel_eof(channel); 311 } 312 313 /* And if we can't receive any more data from them either, close up */ 314 if (!channel->sent_close 315 && channel->readfd == FD_CLOSED 316 && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED) 317 && !write_pending(channel)) { 318 TRACE(("sending close, readfd is closed")) 319 send_msg_channel_close(channel); 320 } 321 } 322 323 /* Check whether a deferred (EINPROGRESS) connect() was successful, and 324 * if so, set up the channel properly. Otherwise, the channel is cleaned up, so 325 * it is important that the channel reference isn't used after a call to this 326 * function */ 327 static void check_in_progress(struct Channel *channel) { 328 329 int val; 330 socklen_t vallen = sizeof(val); 331 332 TRACE(("enter check_in_progress")) 333 334 if (getsockopt(channel->writefd, SOL_SOCKET, SO_ERROR, &val, &vallen) 335 || val != 0) { 336 send_msg_channel_open_failure(channel->remotechan, 337 SSH_OPEN_CONNECT_FAILED, "", ""); 338 close(channel->writefd); 339 delete_channel(channel); 340 TRACE(("leave check_in_progress: fail")) 341 } else { 342 send_msg_channel_open_confirmation(channel, channel->recvwindow, 343 channel->recvmaxpacket); 344 channel->readfd = channel->writefd; 345 channel->initconn = 0; 346 TRACE(("leave check_in_progress: success")) 347 } 348 } 349 350 351 /* Send the close message and set the channel as closed */ 352 static void send_msg_channel_close(struct Channel *channel) { 353 354 TRACE(("enter send_msg_channel_close")) 355 if (channel->type->closehandler) { 356 channel->type->closehandler(channel); 357 } 358 359 CHECKCLEARTOWRITE(); 360 361 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE); 362 buf_putint(ses.writepayload, channel->remotechan); 363 364 encrypt_packet(); 365 366 channel->sent_eof = 1; 367 channel->sent_close = 1; 368 close_chan_fd(channel, channel->readfd, SHUT_RD); 369 close_chan_fd(channel, channel->errfd, SHUT_RDWR); 370 close_chan_fd(channel, channel->writefd, SHUT_WR); 371 TRACE(("leave send_msg_channel_close")) 372 } 373 374 /* call this when trans/eof channels are closed */ 375 static void send_msg_channel_eof(struct Channel *channel) { 376 377 TRACE(("enter send_msg_channel_eof")) 378 CHECKCLEARTOWRITE(); 379 380 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF); 381 buf_putint(ses.writepayload, channel->remotechan); 382 383 encrypt_packet(); 384 385 channel->sent_eof = 1; 386 387 TRACE(("leave send_msg_channel_eof")) 388 } 389 390 /* Called to write data out to the local side of the channel. 391 * Only called when we know we can write to a channel, writes as much as 392 * possible */ 393 static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) { 394 395 int len, maxlen; 396 397 TRACE(("enter writechannel fd %d", fd)) 398 399 maxlen = cbuf_readlen(cbuf); 400 401 /* Write the data out */ 402 len = write(fd, cbuf_readptr(cbuf, maxlen), maxlen); 403 if (len <= 0) { 404 TRACE(("errno %d len %d", errno, len)) 405 if (len < 0 && errno != EINTR) { 406 close_chan_fd(channel, fd, SHUT_WR); 407 } 408 TRACE(("leave writechannel: len <= 0")) 409 return; 410 } 411 TRACE(("writechannel wrote %d", len)) 412 413 cbuf_incrread(cbuf, len); 414 channel->recvdonelen += len; 415 416 /* Window adjust handling */ 417 if (channel->recvdonelen >= RECV_WINDOWEXTEND) { 418 /* Set it back to max window */ 419 send_msg_channel_window_adjust(channel, channel->recvdonelen); 420 channel->recvwindow += channel->recvdonelen; 421 channel->recvdonelen = 0; 422 } 423 424 dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW); 425 dropbear_assert(channel->recvwindow <= cbuf_getavail(channel->writebuf)); 426 dropbear_assert(channel->extrabuf == NULL || 427 channel->recvwindow <= cbuf_getavail(channel->extrabuf)); 428 429 TRACE(("leave writechannel")) 430 } 431 432 /* Set the file descriptors for the main select in session.c 433 * This avoid channels which don't have any window available, are closed, etc*/ 434 void setchannelfds(fd_set *readfds, fd_set *writefds) { 435 436 unsigned int i; 437 struct Channel * channel; 438 439 for (i = 0; i < ses.chansize; i++) { 440 441 channel = ses.channels[i]; 442 if (channel == NULL) { 443 continue; 444 } 445 446 /* Stuff to put over the wire */ 447 if (channel->transwindow > 0) { 448 449 if (channel->readfd >= 0) { 450 FD_SET(channel->readfd, readfds); 451 } 452 453 if (ERRFD_IS_READ(channel) && channel->errfd >= 0) { 454 FD_SET(channel->errfd, readfds); 455 } 456 } 457 458 /* Stuff from the wire */ 459 if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 ) 460 || channel->initconn) { 461 FD_SET(channel->writefd, writefds); 462 } 463 464 if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0 465 && cbuf_getused(channel->extrabuf) > 0 ) { 466 FD_SET(channel->errfd, writefds); 467 } 468 469 } /* foreach channel */ 470 471 #ifdef USING_LISTENERS 472 set_listener_fds(readfds); 473 #endif 474 475 } 476 477 /* handle the channel EOF event, by closing the channel filedescriptor. The 478 * channel isn't closed yet, it is left until the incoming (from the program 479 * etc) FD is also EOF */ 480 void recv_msg_channel_eof() { 481 482 struct Channel * channel; 483 484 TRACE(("enter recv_msg_channel_eof")) 485 486 channel = getchannel_msg("EOF"); 487 488 channel->recv_eof = 1; 489 490 check_close(channel); 491 TRACE(("leave recv_msg_channel_eof")) 492 } 493 494 495 /* Handle channel closure(), respond in kind and close the channels */ 496 void recv_msg_channel_close() { 497 498 struct Channel * channel; 499 500 TRACE(("enter recv_msg_channel_close")) 501 502 channel = getchannel_msg("Close"); 503 504 channel->recv_eof = 1; 505 channel->recv_close = 1; 506 507 check_close(channel); 508 TRACE(("leave recv_msg_channel_close")) 509 } 510 511 /* Remove a channel entry, this is only executed after both sides have sent 512 * channel close */ 513 static void remove_channel(struct Channel * channel) { 514 515 TRACE(("enter remove_channel")) 516 TRACE(("channel index is %d", channel->index)) 517 518 cbuf_free(channel->writebuf); 519 channel->writebuf = NULL; 520 521 if (channel->extrabuf) { 522 cbuf_free(channel->extrabuf); 523 channel->extrabuf = NULL; 524 } 525 526 527 /* close the FDs in case they haven't been done 528 * yet (they might have been shutdown etc) */ 529 TRACE(("CLOSE writefd %d", channel->writefd)) 530 close(channel->writefd); 531 TRACE(("CLOSE readfd %d", channel->readfd)) 532 close(channel->readfd); 533 TRACE(("CLOSE errfd %d", channel->errfd)) 534 close(channel->errfd); 535 536 channel->typedata = NULL; 537 538 delete_channel(channel); 539 540 TRACE(("leave remove_channel")) 541 } 542 543 /* Remove a channel entry */ 544 static void delete_channel(struct Channel *channel) { 545 546 ses.channels[channel->index] = NULL; 547 m_free(channel); 548 ses.chancount--; 549 550 } 551 552 553 /* Handle channel specific requests, passing off to corresponding handlers 554 * such as chansession or x11fwd */ 555 void recv_msg_channel_request() { 556 557 struct Channel *channel; 558 559 TRACE(("enter recv_msg_channel_request")) 560 561 channel = getchannel(); 562 563 if (channel->type->reqhandler) { 564 channel->type->reqhandler(channel); 565 } else { 566 send_msg_channel_failure(channel); 567 } 568 569 TRACE(("leave recv_msg_channel_request")) 570 571 } 572 573 /* Reads data from the server's program/shell/etc, and puts it in a 574 * channel_data packet to send. 575 * chan is the remote channel, isextended is 0 if it is normal data, 1 576 * if it is extended data. if it is extended, then the type is in 577 * exttype */ 578 static void send_msg_channel_data(struct Channel *channel, int isextended) { 579 580 int len; 581 size_t maxlen, size_pos; 582 int fd; 583 584 CHECKCLEARTOWRITE(); 585 586 TRACE(("enter send_msg_channel_data")) 587 dropbear_assert(!channel->sent_close); 588 589 if (isextended) { 590 fd = channel->errfd; 591 } else { 592 fd = channel->readfd; 593 } 594 TRACE(("enter send_msg_channel_data isextended %d fd %d", isextended, fd)) 595 dropbear_assert(fd >= 0); 596 597 maxlen = MIN(channel->transwindow, channel->transmaxpacket); 598 /* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and 599 * exttype if is extended */ 600 maxlen = MIN(maxlen, 601 ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0)); 602 TRACE(("maxlen %d", maxlen)) 603 if (maxlen == 0) { 604 TRACE(("leave send_msg_channel_data: no window")) 605 return; 606 } 607 608 buf_putbyte(ses.writepayload, 609 isextended ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA); 610 buf_putint(ses.writepayload, channel->remotechan); 611 if (isextended) { 612 buf_putint(ses.writepayload, SSH_EXTENDED_DATA_STDERR); 613 } 614 /* a dummy size first ...*/ 615 size_pos = ses.writepayload->pos; 616 buf_putint(ses.writepayload, 0); 617 618 /* read the data */ 619 len = read(fd, buf_getwriteptr(ses.writepayload, maxlen), maxlen); 620 if (len <= 0) { 621 if (len == 0 || errno != EINTR) { 622 /* This will also get hit in the case of EAGAIN. The only 623 time we expect to receive EAGAIN is when we're flushing a FD, 624 in which case it can be treated the same as EOF */ 625 close_chan_fd(channel, fd, SHUT_RD); 626 } 627 ses.writepayload->len = ses.writepayload->pos = 0; 628 TRACE(("leave send_msg_channel_data: len %d read err %d or EOF for fd %d", 629 len, errno, fd)) 630 return; 631 } 632 buf_incrwritepos(ses.writepayload, len); 633 /* ... real size here */ 634 buf_setpos(ses.writepayload, size_pos); 635 buf_putint(ses.writepayload, len); 636 637 channel->transwindow -= len; 638 639 encrypt_packet(); 640 641 /* If we receive less data than we requested when flushing, we've 642 reached the equivalent of EOF */ 643 if (channel->flushing && len < (ssize_t)maxlen) 644 { 645 TRACE(("closing from channel, flushing out.")) 646 close_chan_fd(channel, fd, SHUT_RD); 647 } 648 TRACE(("leave send_msg_channel_data")) 649 } 650 651 /* We receive channel data */ 652 void recv_msg_channel_data() { 653 654 struct Channel *channel; 655 656 channel = getchannel(); 657 658 common_recv_msg_channel_data(channel, channel->writefd, channel->writebuf); 659 } 660 661 /* Shared for data and stderr data - when we receive data, put it in a buffer 662 * for writing to the local file descriptor */ 663 void common_recv_msg_channel_data(struct Channel *channel, int fd, 664 circbuffer * cbuf) { 665 666 unsigned int datalen; 667 unsigned int maxdata; 668 unsigned int buflen; 669 unsigned int len; 670 671 TRACE(("enter recv_msg_channel_data")) 672 673 if (channel->recv_eof) { 674 dropbear_exit("received data after eof"); 675 } 676 677 if (fd < 0) { 678 /* If we have encountered failed write, the far side might still 679 * be sending data without having yet received our close notification. 680 * We just drop the data. */ 681 return; 682 } 683 684 datalen = buf_getint(ses.payload); 685 TRACE(("length %d", datalen)) 686 687 maxdata = cbuf_getavail(cbuf); 688 689 /* Whilst the spec says we "MAY ignore data past the end" this could 690 * lead to corrupted file transfers etc (chunks missed etc). It's better to 691 * just die horribly */ 692 if (datalen > maxdata) { 693 dropbear_exit("Oversized packet"); 694 } 695 696 /* We may have to run throught twice, if the buffer wraps around. Can't 697 * just "leave it for next time" like with writechannel, since this 698 * is payload data */ 699 len = datalen; 700 while (len > 0) { 701 buflen = cbuf_writelen(cbuf); 702 buflen = MIN(buflen, len); 703 704 memcpy(cbuf_writeptr(cbuf, buflen), 705 buf_getptr(ses.payload, buflen), buflen); 706 cbuf_incrwrite(cbuf, buflen); 707 buf_incrpos(ses.payload, buflen); 708 len -= buflen; 709 } 710 711 dropbear_assert(channel->recvwindow >= datalen); 712 channel->recvwindow -= datalen; 713 dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW); 714 715 TRACE(("leave recv_msg_channel_data")) 716 } 717 718 /* Increment the outgoing data window for a channel - the remote end limits 719 * the amount of data which may be transmitted, this window is decremented 720 * as data is sent, and incremented upon receiving window-adjust messages */ 721 void recv_msg_channel_window_adjust() { 722 723 struct Channel * channel; 724 unsigned int incr; 725 726 channel = getchannel(); 727 728 incr = buf_getint(ses.payload); 729 TRACE(("received window increment %d", incr)) 730 incr = MIN(incr, MAX_TRANS_WIN_INCR); 731 732 channel->transwindow += incr; 733 channel->transwindow = MIN(channel->transwindow, MAX_TRANS_WINDOW); 734 735 } 736 737 /* Increment the incoming data window for a channel, and let the remote 738 * end know */ 739 static void send_msg_channel_window_adjust(struct Channel* channel, 740 unsigned int incr) { 741 742 TRACE(("sending window adjust %d", incr)) 743 CHECKCLEARTOWRITE(); 744 745 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_WINDOW_ADJUST); 746 buf_putint(ses.writepayload, channel->remotechan); 747 buf_putint(ses.writepayload, incr); 748 749 encrypt_packet(); 750 } 751 752 /* Handle a new channel request, performing any channel-type-specific setup */ 753 void recv_msg_channel_open() { 754 755 unsigned char *type; 756 unsigned int typelen; 757 unsigned int remotechan, transwindow, transmaxpacket; 758 struct Channel *channel; 759 const struct ChanType **cp; 760 const struct ChanType *chantype; 761 unsigned int errtype = SSH_OPEN_UNKNOWN_CHANNEL_TYPE; 762 int ret; 763 764 765 TRACE(("enter recv_msg_channel_open")) 766 767 /* get the packet contents */ 768 type = buf_getstring(ses.payload, &typelen); 769 770 remotechan = buf_getint(ses.payload); 771 transwindow = buf_getint(ses.payload); 772 transwindow = MIN(transwindow, MAX_TRANS_WINDOW); 773 transmaxpacket = buf_getint(ses.payload); 774 transmaxpacket = MIN(transmaxpacket, MAX_TRANS_PAYLOAD_LEN); 775 776 /* figure what type of packet it is */ 777 if (typelen > MAX_NAME_LEN) { 778 goto failure; 779 } 780 781 /* Get the channel type. Client and server style invokation will set up a 782 * different list for ses.chantypes at startup. We just iterate through 783 * this list and find the matching name */ 784 for (cp = &ses.chantypes[0], chantype = (*cp); 785 chantype != NULL; 786 cp++, chantype = (*cp)) { 787 if (strcmp(type, chantype->name) == 0) { 788 break; 789 } 790 } 791 792 if (chantype == NULL) { 793 TRACE(("No matching type for '%s'", type)) 794 goto failure; 795 } 796 797 TRACE(("matched type '%s'", type)) 798 799 /* create the channel */ 800 channel = newchannel(remotechan, chantype, transwindow, transmaxpacket); 801 802 if (channel == NULL) { 803 TRACE(("newchannel returned NULL")) 804 goto failure; 805 } 806 807 if (channel->type->inithandler) { 808 ret = channel->type->inithandler(channel); 809 if (ret == SSH_OPEN_IN_PROGRESS) { 810 /* We'll send the confirmation later */ 811 goto cleanup; 812 } 813 if (ret > 0) { 814 errtype = ret; 815 delete_channel(channel); 816 TRACE(("inithandler returned failure %d", ret)) 817 goto failure; 818 } 819 } 820 821 /* success */ 822 send_msg_channel_open_confirmation(channel, channel->recvwindow, 823 channel->recvmaxpacket); 824 goto cleanup; 825 826 failure: 827 TRACE(("recv_msg_channel_open failure")) 828 send_msg_channel_open_failure(remotechan, errtype, "", ""); 829 830 cleanup: 831 m_free(type); 832 833 TRACE(("leave recv_msg_channel_open")) 834 } 835 836 /* Send a failure message */ 837 void send_msg_channel_failure(struct Channel *channel) { 838 839 TRACE(("enter send_msg_channel_failure")) 840 CHECKCLEARTOWRITE(); 841 842 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE); 843 buf_putint(ses.writepayload, channel->remotechan); 844 845 encrypt_packet(); 846 TRACE(("leave send_msg_channel_failure")) 847 } 848 849 /* Send a success message */ 850 void send_msg_channel_success(struct Channel *channel) { 851 852 TRACE(("enter send_msg_channel_success")) 853 CHECKCLEARTOWRITE(); 854 855 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS); 856 buf_putint(ses.writepayload, channel->remotechan); 857 858 encrypt_packet(); 859 TRACE(("leave send_msg_channel_success")) 860 } 861 862 /* Send a channel open failure message, with a corresponding reason 863 * code (usually resource shortage or unknown chan type) */ 864 static void send_msg_channel_open_failure(unsigned int remotechan, 865 int reason, const unsigned char *text, const unsigned char *lang) { 866 867 TRACE(("enter send_msg_channel_open_failure")) 868 CHECKCLEARTOWRITE(); 869 870 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE); 871 buf_putint(ses.writepayload, remotechan); 872 buf_putint(ses.writepayload, reason); 873 buf_putstring(ses.writepayload, text, strlen((char*)text)); 874 buf_putstring(ses.writepayload, lang, strlen((char*)lang)); 875 876 encrypt_packet(); 877 TRACE(("leave send_msg_channel_open_failure")) 878 } 879 880 /* Confirm a channel open, and let the remote end know what number we've 881 * allocated and the receive parameters */ 882 static void send_msg_channel_open_confirmation(struct Channel* channel, 883 unsigned int recvwindow, 884 unsigned int recvmaxpacket) { 885 886 TRACE(("enter send_msg_channel_open_confirmation")) 887 CHECKCLEARTOWRITE(); 888 889 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 890 buf_putint(ses.writepayload, channel->remotechan); 891 buf_putint(ses.writepayload, channel->index); 892 buf_putint(ses.writepayload, recvwindow); 893 buf_putint(ses.writepayload, recvmaxpacket); 894 895 encrypt_packet(); 896 TRACE(("leave send_msg_channel_open_confirmation")) 897 } 898 899 /* close a fd, how is SHUT_RD or SHUT_WR */ 900 static void close_chan_fd(struct Channel *channel, int fd, int how) { 901 902 int closein = 0, closeout = 0; 903 904 if (channel->type->sepfds) { 905 TRACE(("SHUTDOWN(%d, %d)", fd, how)) 906 shutdown(fd, how); 907 if (how == 0) { 908 closeout = 1; 909 } else { 910 closein = 1; 911 } 912 } else { 913 TRACE(("CLOSE some fd %d", fd)) 914 close(fd); 915 closein = closeout = 1; 916 } 917 918 if (closeout && (fd == channel->readfd)) { 919 channel->readfd = FD_CLOSED; 920 } 921 if (closeout && ERRFD_IS_READ(channel) && (fd == channel->errfd)) { 922 channel->errfd = FD_CLOSED; 923 } 924 925 if (closein && fd == channel->writefd) { 926 channel->writefd = FD_CLOSED; 927 } 928 if (closein && ERRFD_IS_WRITE(channel) && (fd == channel->errfd)) { 929 channel->errfd = FD_CLOSED; 930 } 931 932 /* if we called shutdown on it and all references are gone, then we 933 * need to close() it to stop it lingering */ 934 if (channel->type->sepfds && channel->readfd == FD_CLOSED 935 && channel->writefd == FD_CLOSED && channel->errfd == FD_CLOSED) { 936 TRACE(("CLOSE (finally) of %d", fd)) 937 close(fd); 938 } 939 } 940 941 942 #if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT) 943 /* Create a new channel, and start the open request. This is intended 944 * for X11, agent, tcp forwarding, and should be filled with channel-specific 945 * options, with the calling function calling encrypt_packet() after 946 * completion. It is mandatory for the caller to encrypt_packet() if 947 * DROPBEAR_SUCCESS is returned */ 948 int send_msg_channel_open_init(int fd, const struct ChanType *type) { 949 950 struct Channel* chan; 951 952 TRACE(("enter send_msg_channel_open_init()")) 953 chan = newchannel(0, type, 0, 0); 954 if (!chan) { 955 TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()")) 956 return DROPBEAR_FAILURE; 957 } 958 959 /* set fd non-blocking */ 960 setnonblocking(fd); 961 962 chan->writefd = chan->readfd = fd; 963 ses.maxfd = MAX(ses.maxfd, fd); 964 965 chan->await_open = 1; 966 967 /* now open the channel connection */ 968 CHECKCLEARTOWRITE(); 969 970 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN); 971 buf_putstring(ses.writepayload, type->name, strlen(type->name)); 972 buf_putint(ses.writepayload, chan->index); 973 buf_putint(ses.writepayload, RECV_MAXWINDOW); 974 buf_putint(ses.writepayload, RECV_MAXPACKET); 975 976 TRACE(("leave send_msg_channel_open_init()")) 977 return DROPBEAR_SUCCESS; 978 } 979 980 /* Confirmation that our channel open request (for forwardings) was 981 * successful*/ 982 void recv_msg_channel_open_confirmation() { 983 984 struct Channel * channel; 985 int ret; 986 987 TRACE(("enter recv_msg_channel_open_confirmation")) 988 989 channel = getchannel(); 990 991 if (!channel->await_open) { 992 dropbear_exit("unexpected channel reply"); 993 } 994 channel->await_open = 0; 995 996 channel->remotechan = buf_getint(ses.payload); 997 channel->transwindow = buf_getint(ses.payload); 998 channel->transmaxpacket = buf_getint(ses.payload); 999 1000 TRACE(("new chan remote %d local %d", 1001 channel->remotechan, channel->index)) 1002 1003 /* Run the inithandler callback */ 1004 if (channel->type->inithandler) { 1005 ret = channel->type->inithandler(channel); 1006 if (ret > 0) { 1007 remove_channel(channel); 1008 TRACE(("inithandler returned failure %d", ret)) 1009 } 1010 } 1011 1012 1013 TRACE(("leave recv_msg_channel_open_confirmation")) 1014 } 1015 1016 /* Notification that our channel open request failed */ 1017 void recv_msg_channel_open_failure() { 1018 1019 struct Channel * channel; 1020 1021 channel = getchannel(); 1022 1023 if (!channel->await_open) { 1024 dropbear_exit("unexpected channel reply"); 1025 } 1026 channel->await_open = 0; 1027 1028 remove_channel(channel); 1029 } 1030 #endif /* USING_LISTENERS */ 1031