1 2 package ch.ethz.ssh2.channel; 3 4 import java.io.IOException ; 5 import java.util.HashMap ; 6 import java.util.Vector ; 7 8 import ch.ethz.ssh2.ChannelCondition; 9 import ch.ethz.ssh2.log.Logger; 10 import ch.ethz.ssh2.packets.PacketChannelOpenConfirmation; 11 import ch.ethz.ssh2.packets.PacketChannelOpenFailure; 12 import ch.ethz.ssh2.packets.PacketGlobalCancelForwardRequest; 13 import ch.ethz.ssh2.packets.PacketGlobalForwardRequest; 14 import ch.ethz.ssh2.packets.PacketOpenDirectTCPIPChannel; 15 import ch.ethz.ssh2.packets.PacketOpenSessionChannel; 16 import ch.ethz.ssh2.packets.PacketSessionExecCommand; 17 import ch.ethz.ssh2.packets.PacketSessionPtyRequest; 18 import ch.ethz.ssh2.packets.PacketSessionStartShell; 19 import ch.ethz.ssh2.packets.PacketSessionSubsystemRequest; 20 import ch.ethz.ssh2.packets.PacketSessionX11Request; 21 import ch.ethz.ssh2.packets.Packets; 22 import ch.ethz.ssh2.packets.TypesReader; 23 import ch.ethz.ssh2.transport.MessageHandler; 24 import ch.ethz.ssh2.transport.TransportManager; 25 26 34 public class ChannelManager implements MessageHandler 35 { 36 private static final Logger log = Logger.getLogger(ChannelManager.class); 37 38 private HashMap x11_magic_cookies = new HashMap (); 39 40 private TransportManager tm; 41 42 private Vector channels = new Vector (); 43 private int nextLocalChannel = 100; 44 private boolean shutdown = false; 45 private int globalSuccessCounter = 0; 46 private int globalFailedCounter = 0; 47 48 private HashMap remoteForwardings = new HashMap (); 49 50 private Vector listenerThreads = new Vector (); 51 52 private boolean listenerThreadsAllowed = true; 53 54 public ChannelManager(TransportManager tm) 55 { 56 this.tm = tm; 57 tm.registerMessageHandler(this, 80, 100); 58 } 59 60 private Channel getChannel(int id) 61 { 62 synchronized (channels) 63 { 64 for (int i = 0; i < channels.size(); i++) 65 { 66 Channel c = (Channel) channels.elementAt(i); 67 if (c.localID == id) 68 return c; 69 } 70 } 71 return null; 72 } 73 74 private void removeChannel(int id) 75 { 76 synchronized (channels) 77 { 78 for (int i = 0; i < channels.size(); i++) 79 { 80 Channel c = (Channel) channels.elementAt(i); 81 if (c.localID == id) 82 { 83 channels.removeElementAt(i); 84 break; 85 } 86 } 87 } 88 } 89 90 private int addChannel(Channel c) 91 { 92 synchronized (channels) 93 { 94 channels.addElement(c); 95 return nextLocalChannel++; 96 } 97 } 98 99 private void waitUntilChannelOpen(Channel c) throws IOException  100 { 101 synchronized (c) 102 { 103 while (c.state == Channel.STATE_OPENING) 104 { 105 try 106 { 107 c.wait(); 108 } 109 catch (InterruptedException ignore) 110 { 111 } 112 } 113 114 if (c.state != Channel.STATE_OPEN) 115 { 116 removeChannel(c.localID); 117 118 String detail = c.getReasonClosed(); 119 120 if (detail == null) 121 detail = "state: " + c.state; 122 123 throw new IOException ("Could not open channel (" + detail + ")"); 124 } 125 } 126 } 127 128 private final void waitForGlobalSuccessOrFailure() throws IOException  129 { 130 synchronized (channels) 131 { 132 while ((globalSuccessCounter == 0) && (globalFailedCounter == 0)) 133 { 134 if (shutdown) 135 { 136 throw new IOException ("The connection is being shutdown"); 137 } 138 139 try 140 { 141 channels.wait(); 142 } 143 catch (InterruptedException ignore) 144 { 145 } 146 } 147 148 if (globalFailedCounter != 0) 149 { 150 throw new IOException ("The server denied the request (did you enable port forwarding?)"); 151 } 152 153 if (globalSuccessCounter == 0) 154 { 155 throw new IOException ("Illegal state."); 156 } 157 158 } 159 } 160 161 private final void waitForChannelSuccessOrFailure(Channel c) throws IOException  162 { 163 synchronized (c) 164 { 165 while ((c.successCounter == 0) && (c.failedCounter == 0)) 166 { 167 if (c.state != Channel.STATE_OPEN) 168 { 169 String detail = c.getReasonClosed(); 170 171 if (detail == null) 172 detail = "state: " + c.state; 173 174 throw new IOException ("This SSH2 channel is not open (" + detail + ")"); 175 } 176 177 try 178 { 179 c.wait(); 180 } 181 catch (InterruptedException ignore) 182 { 183 } 184 } 185 186 if (c.failedCounter != 0) 187 { 188 throw new IOException ("The server denied the request."); 189 } 190 } 191 } 192 193 public void registerX11Cookie(String hexFakeCookie, X11ServerData data) 194 { 195 synchronized (x11_magic_cookies) 196 { 197 x11_magic_cookies.put(hexFakeCookie, data); 198 } 199 } 200 201 public void unRegisterX11Cookie(String hexFakeCookie, boolean killChannels) 202 { 203 if (hexFakeCookie == null) 204 throw new IllegalStateException ("hexFakeCookie may not be null"); 205 206 synchronized (x11_magic_cookies) 207 { 208 x11_magic_cookies.remove(hexFakeCookie); 209 } 210 211 if (killChannels == false) 212 return; 213 214 if (log.isEnabled()) 215 log.log(50, "Closing all X11 channels for the given fake cookie"); 216 217 Vector channel_copy; 218 219 synchronized (channels) 220 { 221 channel_copy = (Vector ) channels.clone(); 222 } 223 224 for (int i = 0; i < channel_copy.size(); i++) 225 { 226 Channel c = (Channel) channel_copy.elementAt(i); 227 228 synchronized (c) 229 { 230 if (hexFakeCookie.equals(c.hexX11FakeCookie) == false) 231 continue; 232 } 233 234 try 235 { 236 closeChannel(c, "Closing X11 channel since the corresponding session is closing", true); 237 } 238 catch (IOException e) 239 { 240 } 241 } 242 } 243 244 public X11ServerData checkX11Cookie(String hexFakeCookie) 245 { 246 synchronized (x11_magic_cookies) 247 { 248 if (hexFakeCookie != null) 249 return (X11ServerData) x11_magic_cookies.get(hexFakeCookie); 250 } 251 return null; 252 } 253 254 public void closeAllChannels() 255 { 256 if (log.isEnabled()) 257 log.log(50, "Closing all channels"); 258 259 Vector channel_copy; 260 261 synchronized (channels) 262 { 263 channel_copy = (Vector ) channels.clone(); 264 } 265 266 for (int i = 0; i < channel_copy.size(); i++) 267 { 268 Channel c = (Channel) channel_copy.elementAt(i); 269 try 270 { 271 closeChannel(c, "Closing all channels", true); 272 } 273 catch (IOException e) 274 { 275 } 276 } 277 } 278 279 public void closeChannel(Channel c, String reason, boolean force) throws IOException  280 { 281 byte msg[] = new byte[5]; 282 283 synchronized (c) 284 { 285 if (force) 286 { 287 c.state = Channel.STATE_CLOSED; 288 c.EOF = true; 289 } 290 291 c.setReasonClosed(reason); 292 293 msg[0] = Packets.SSH_MSG_CHANNEL_CLOSE; 294 msg[1] = (byte) (c.remoteID >> 24); 295 msg[2] = (byte) (c.remoteID >> 16); 296 msg[3] = (byte) (c.remoteID >> 8); 297 msg[4] = (byte) (c.remoteID); 298 299 c.notifyAll(); 300 } 301 302 synchronized (c.channelSendLock) 303 { 304 if (c.closeMessageSent == true) 305 return; 306 tm.sendMessage(msg); 307 c.closeMessageSent = true; 308 } 309 310 if (log.isEnabled()) 311 log.log(50, "Sent SSH_MSG_CHANNEL_CLOSE (channel " + c.localID + ")"); 312 } 313 314 public void sendEOF(Channel c) throws IOException  315 { 316 byte[] msg = new byte[5]; 317 318 synchronized (c) 319 { 320 if (c.state != Channel.STATE_OPEN) 321 return; 322 323 msg[0] = Packets.SSH_MSG_CHANNEL_EOF; 324 msg[1] = (byte) (c.remoteID >> 24); 325 msg[2] = (byte) (c.remoteID >> 16); 326 msg[3] = (byte) (c.remoteID >> 8); 327 msg[4] = (byte) (c.remoteID); 328 } 329 330 synchronized (c.channelSendLock) 331 { 332 if (c.closeMessageSent == true) 333 return; 334 tm.sendMessage(msg); 335 } 336 337 if (log.isEnabled()) 338 log.log(50, "Sent EOF (Channel " + c.localID + "/" + c.remoteID + ")"); 339 } 340 341 public void sendOpenConfirmation(Channel c) throws IOException  342 { 343 PacketChannelOpenConfirmation pcoc = null; 344 345 synchronized (c) 346 { 347 if (c.state != Channel.STATE_OPENING) 348 return; 349 350 c.state = Channel.STATE_OPEN; 351 352 pcoc = new PacketChannelOpenConfirmation(c.remoteID, c.localID, c.localWindow, c.localMaxPacketSize); 353 } 354 355 synchronized (c.channelSendLock) 356 { 357 if (c.closeMessageSent == true) 358 return; 359 tm.sendMessage(pcoc.getPayload()); 360 } 361 } 362 363 public void sendData(Channel c, byte[] buffer, int pos, int len) throws IOException  364 { 365 while (len > 0) 366 { 367 int thislen = 0; 368 byte[] msg; 369 370 synchronized (c) 371 { 372 while (true) 373 { 374 if (c.state == Channel.STATE_CLOSED) 375 throw new IOException ("SSH channel is closed. (" + c.getReasonClosed() + ")"); 376 377 if (c.state != Channel.STATE_OPEN) 378 throw new IOException ("SSH channel in strange state. (" + c.state + ")"); 379 380 if (c.remoteWindow != 0) 381 break; 382 383 try 384 { 385 c.wait(); 386 } 387 catch (InterruptedException ignore) 388 { 389 } 390 } 391 392 393 394 thislen = (c.remoteWindow >= len) ? len : (int) c.remoteWindow; 395 396 int estimatedMaxDataLen = c.remoteMaxPacketSize - (tm.getPacketOverheadEstimate() + 9); 397 398 399 400 if (estimatedMaxDataLen <= 0) 401 { 402 estimatedMaxDataLen = 1; 403 } 404 405 if (thislen > estimatedMaxDataLen) 406 thislen = estimatedMaxDataLen; 407 408 c.remoteWindow -= thislen; 409 410 msg = new byte[1 + 8 + thislen]; 411 412 msg[0] = Packets.SSH_MSG_CHANNEL_DATA; 413 msg[1] = (byte) (c.remoteID >> 24); 414 msg[2] = (byte) (c.remoteID >> 16); 415 msg[3] = (byte) (c.remoteID >> 8); 416 msg[4] = (byte) (c.remoteID); 417 msg[5] = (byte) (thislen >> 24); 418 msg[6] = (byte) (thislen >> 16); 419 msg[7] = (byte) (thislen >> 8); 420 msg[8] = (byte) (thislen); 421 422 System.arraycopy(buffer, pos, msg, 9, thislen); 423 } 424 425 synchronized (c.channelSendLock) 426 { 427 if (c.closeMessageSent == true) 428 throw new IOException ("SSH channel is closed. (" + c.getReasonClosed() + ")"); 429 430 tm.sendMessage(msg); 431 } 432 433 pos += thislen; 434 len -= thislen; 435 } 436 } 437 438 public int requestGlobalForward(String bindAddress, int bindPort, String targetAddress, int targetPort) 439 throws IOException  440 { 441 RemoteForwardingData rfd = new RemoteForwardingData(); 442 443 rfd.bindAddress = bindAddress; 444 rfd.bindPort = bindPort; 445 rfd.targetAddress = targetAddress; 446 rfd.targetPort = targetPort; 447 448 synchronized (remoteForwardings) 449 { 450 Integer key = new Integer (bindPort); 451 452 if (remoteForwardings.get(key) != null) 453 { 454 throw new IOException ("There is already a forwarding for remote port " + bindPort); 455 } 456 457 remoteForwardings.put(key, rfd); 458 } 459 460 synchronized (channels) 461 { 462 globalSuccessCounter = globalFailedCounter = 0; 463 } 464 465 PacketGlobalForwardRequest pgf = new PacketGlobalForwardRequest(true, bindAddress, bindPort); 466 tm.sendMessage(pgf.getPayload()); 467 468 if (log.isEnabled()) 469 log.log(50, "Requesting a remote forwarding ('" + bindAddress + "', " + bindPort + ")"); 470 471 try 472 { 473 waitForGlobalSuccessOrFailure(); 474 } 475 catch (IOException e) 476 { 477 synchronized (remoteForwardings) 478 { 479 remoteForwardings.remove(rfd); 480 } 481 throw e; 482 } 483 484 return bindPort; 485 } 486 487 public void requestCancelGlobalForward(int bindPort) throws IOException  488 { 489 RemoteForwardingData rfd = null; 490 491 synchronized (remoteForwardings) 492 { 493 rfd = (RemoteForwardingData) remoteForwardings.get(new Integer (bindPort)); 494 495 if (rfd == null) 496 throw new IOException ("Sorry, there is no known remote forwarding for remote port " + bindPort); 497 } 498 499 synchronized (channels) 500 { 501 globalSuccessCounter = globalFailedCounter = 0; 502 } 503 504 PacketGlobalCancelForwardRequest pgcf = new PacketGlobalCancelForwardRequest(true, rfd.bindAddress, 505 rfd.bindPort); 506 tm.sendMessage(pgcf.getPayload()); 507 508 if (log.isEnabled()) 509 log.log(50, "Requesting cancelation of remote forward ('" + rfd.bindAddress + "', " + rfd.bindPort + ")"); 510 511 waitForGlobalSuccessOrFailure(); 512 513 514 515 synchronized (remoteForwardings) 516 { 517 remoteForwardings.remove(rfd); 518 } 519 } 520 521 public void registerThread(IChannelWorkerThread thr) throws IOException  522 { 523 synchronized (listenerThreads) 524 { 525 if (listenerThreadsAllowed == false) 526 throw new IOException ("Too late, this connection is closed."); 527 listenerThreads.addElement(thr); 528 } 529 } 530 531 public Channel openDirectTCPIPChannel(String host_to_connect, int port_to_connect, String originator_IP_address, 532 int originator_port) throws IOException  533 { 534 Channel c = new Channel(this); 535 536 synchronized (c) 537 { 538 c.localID = addChannel(c); 539 } 541 542 PacketOpenDirectTCPIPChannel dtc = new PacketOpenDirectTCPIPChannel(c.localID, c.localWindow, 543 c.localMaxPacketSize, host_to_connect, port_to_connect, originator_IP_address, originator_port); 544 545 tm.sendMessage(dtc.getPayload()); 546 547 waitUntilChannelOpen(c); 548 549 return c; 550 } 551 552 public Channel openSessionChannel() throws IOException  553 { 554 Channel c = new Channel(this); 555 556 synchronized (c) 557 { 558 c.localID = addChannel(c); 559 } 561 562 if (log.isEnabled()) 563 log.log(50, "Sending SSH_MSG_CHANNEL_OPEN (Channel " + c.localID + ")"); 564 565 PacketOpenSessionChannel smo = new PacketOpenSessionChannel(c.localID, c.localWindow, c.localMaxPacketSize); 566 tm.sendMessage(smo.getPayload()); 567 568 waitUntilChannelOpen(c); 569 570 return c; 571 } 572 573 public void requestPTY(Channel c, String term, int term_width_characters, int term_height_characters, 574 int term_width_pixels, int term_height_pixels, byte[] terminal_modes) throws IOException  575 { 576 PacketSessionPtyRequest spr; 577 578 synchronized (c) 579 { 580 if (c.state != Channel.STATE_OPEN) 581 throw new IOException ("Cannot request PTY on this channel (" + c.getReasonClosed() + ")"); 582 583 spr = new PacketSessionPtyRequest(c.remoteID, true, term, term_width_characters, term_height_characters, 584 term_width_pixels, term_height_pixels, terminal_modes); 585 586 c.successCounter = c.failedCounter = 0; 587 } 588 589 synchronized (c.channelSendLock) 590 { 591 if (c.closeMessageSent) 592 throw new IOException ("Cannot request PTY on this channel (" + c.getReasonClosed() + ")"); 593 tm.sendMessage(spr.getPayload()); 594 } 595 596 try 597 { 598 waitForChannelSuccessOrFailure(c); 599 } 600 catch (IOException e) 601 { 602 throw (IOException ) new IOException ("PTY request failed").initCause(e); 603 } 604 } 605 606 public void requestX11(Channel c, boolean singleConnection, String x11AuthenticationProtocol, 607 String x11AuthenticationCookie, int x11ScreenNumber) throws IOException  608 { 609 PacketSessionX11Request psr; 610 611 synchronized (c) 612 { 613 if (c.state != Channel.STATE_OPEN) 614 throw new IOException ("Cannot request X11 on this channel (" + c.getReasonClosed() + ")"); 615 616 psr = new PacketSessionX11Request(c.remoteID, true, singleConnection, x11AuthenticationProtocol, 617 x11AuthenticationCookie, x11ScreenNumber); 618 619 c.successCounter = c.failedCounter = 0; 620 } 621 622 synchronized (c.channelSendLock) 623 { 624 if (c.closeMessageSent) 625 throw new IOException ("Cannot request X11 on this channel (" + c.getReasonClosed() + ")"); 626 tm.sendMessage(psr.getPayload()); 627 } 628 629 if (log.isEnabled()) 630 log.log(50, "Requesting X11 forwarding (Channel " + c.localID + "/" + c.remoteID + ")"); 631 632 try 633 { 634 waitForChannelSuccessOrFailure(c); 635 } 636 catch (IOException e) 637 { 638 throw (IOException ) new IOException ("The X11 request failed.").initCause(e); 639 } 640 } 641 642 public void requestSubSystem(Channel c, String subSystemName) throws IOException  643 { 644 PacketSessionSubsystemRequest ssr; 645 646 synchronized (c) 647 { 648 if (c.state != Channel.STATE_OPEN) 649 throw new IOException ("Cannot request subsystem on this channel (" + c.getReasonClosed() + ")"); 650 651 ssr = new PacketSessionSubsystemRequest(c.remoteID, true, subSystemName); 652 653 c.successCounter = c.failedCounter = 0; 654 } 655 656 synchronized (c.channelSendLock) 657 { 658 if (c.closeMessageSent) 659 throw new IOException ("Cannot request subsystem on this channel (" + c.getReasonClosed() + ")"); 660 tm.sendMessage(ssr.getPayload()); 661 } 662 663 try 664 { 665 waitForChannelSuccessOrFailure(c); 666 } 667 catch (IOException e) 668 { 669 throw (IOException ) new IOException ("The subsystem request failed.").initCause(e); 670 } 671 } 672 673 public void requestExecCommand(Channel c, String cmd) throws IOException  674 { 675 PacketSessionExecCommand sm; 676 677 synchronized (c) 678 { 679 if (c.state != Channel.STATE_OPEN) 680 throw new IOException ("Cannot execute command on this channel (" + c.getReasonClosed() + ")"); 681 682 sm = new PacketSessionExecCommand(c.remoteID, true, cmd); 683 684 c.successCounter = c.failedCounter = 0; 685 } 686 687 synchronized (c.channelSendLock) 688 { 689 if (c.closeMessageSent) 690 throw new IOException ("Cannot execute command on this channel (" + c.getReasonClosed() + ")"); 691 tm.sendMessage(sm.getPayload()); 692 } 693 694 if (log.isEnabled()) 695 log.log(50, "Executing command (channel " + c.localID + ", '" + cmd + "')"); 696 697 try 698 { 699 waitForChannelSuccessOrFailure(c); 700 } 701 catch (IOException e) 702 { 703 throw (IOException ) new IOException ("The execute request failed.").initCause(e); 704 } 705 } 706 707 public void requestShell(Channel c) throws IOException  708 { 709 PacketSessionStartShell sm; 710 711 synchronized (c) 712 { 713 if (c.state != Channel.STATE_OPEN) 714 throw new IOException ("Cannot start shell on this channel (" + c.getReasonClosed() + ")"); 715 716 sm = new PacketSessionStartShell(c.remoteID, true); 717 718 c.successCounter = c.failedCounter = 0; 719 } 720 721 synchronized (c.channelSendLock) 722 { 723 if (c.closeMessageSent) 724 throw new IOException ("Cannot start shell on this channel (" + c.getReasonClosed() + ")"); 725 tm.sendMessage(sm.getPayload()); 726 } 727 728 try 729 { 730 waitForChannelSuccessOrFailure(c); 731 } 732 catch (IOException e) 733 { 734 throw (IOException ) new IOException ("The shell request failed.").initCause(e); 735 } 736 } 737 738 public void msgChannelExtendedData(byte[] msg, int msglen) throws IOException  739 { 740 if (msglen <= 13) 741 throw new IOException ("SSH_MSG_CHANNEL_EXTENDED_DATA message has wrong size (" + msglen + ")"); 742 743 int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); 744 int dataType = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff); 745 int len = ((msg[9] & 0xff) << 24) | ((msg[10] & 0xff) << 16) | ((msg[11] & 0xff) << 8) | (msg[12] & 0xff); 746 747 Channel c = getChannel(id); 748 749 if (c == null) 750 throw new IOException ("Unexpected SSH_MSG_CHANNEL_EXTENDED_DATA message for non-existent channel " + id); 751 752 if (dataType != Packets.SSH_EXTENDED_DATA_STDERR) 753 throw new IOException ("SSH_MSG_CHANNEL_EXTENDED_DATA message has unknown type (" + dataType + ")"); 754 755 if (len != (msglen - 13)) 756 throw new IOException ("SSH_MSG_CHANNEL_EXTENDED_DATA message has wrong len (calculated " + (msglen - 13) 757 + ", got " + len + ")"); 758 759 if (log.isEnabled()) 760 log.log(80, "Got SSH_MSG_CHANNEL_EXTENDED_DATA (channel " + id + ", " + len + ")"); 761 762 synchronized (c) 763 { 764 if (c.state == Channel.STATE_CLOSED) 765 return; 767 if (c.state != Channel.STATE_OPEN) 768 throw new IOException ("Got SSH_MSG_CHANNEL_EXTENDED_DATA, but channel is not in correct state (" 769 + c.state + ")"); 770 771 if (c.localWindow < len) 772 throw new IOException ("Remote sent too much data, does not fit into window."); 773 774 c.localWindow -= len; 775 776 System.arraycopy(msg, 13, c.stderrBuffer, c.stderrWritepos, len); 777 c.stderrWritepos += len; 778 779 c.notifyAll(); 780 } 781 } 782 783 795 public int waitForCondition(Channel c, long timeout, int condition_mask) 796 { 797 long end_time = 0; 798 boolean end_time_set = false; 799 800 synchronized (c) 801 { 802 while (true) 803 { 804 int current_cond = 0; 805 806 int stdoutAvail = c.stdoutWritepos - c.stdoutReadpos; 807 int stderrAvail = c.stderrWritepos - c.stderrReadpos; 808 809 if (stdoutAvail > 0) 810 current_cond = current_cond | ChannelCondition.STDOUT_DATA; 811 812 if (stderrAvail > 0) 813 current_cond = current_cond | ChannelCondition.STDERR_DATA; 814 815 if (c.EOF) 816 current_cond = current_cond | ChannelCondition.EOF; 817 818 if (c.getExitStatus() != null) 819 current_cond = current_cond | ChannelCondition.EXIT_STATUS; 820 821 if (c.getExitSignal() != null) 822 current_cond = current_cond | ChannelCondition.EXIT_SIGNAL; 823 824 if (c.state == Channel.STATE_CLOSED) 825 return current_cond | ChannelCondition.CLOSED | ChannelCondition.EOF; 826 827 if ((current_cond & condition_mask) != 0) 828 return current_cond; 829 830 if (timeout > 0) 831 { 832 if (!end_time_set) 833 { 834 end_time = System.currentTimeMillis() + timeout; 835 end_time_set = true; 836 } 837 else 838 { 839 timeout = end_time - System.currentTimeMillis(); 840 841 if (timeout <= 0) 842 return current_cond | ChannelCondition.TIMEOUT; 843 } 844 } 845 846 try 847 { 848 if (timeout > 0) 849 c.wait(timeout); 850 else 851 c.wait(); 852 } 853 catch (InterruptedException e) 854 { 855 } 856 } 857 } 858 } 859 860 public int getAvailable(Channel c, boolean extended) throws IOException  861 { 862 synchronized (c) 863 { 864 int avail; 865 866 if (extended) 867 avail = c.stderrWritepos - c.stderrReadpos; 868 else 869 avail = c.stdoutWritepos - c.stdoutReadpos; 870 871 return ((avail > 0) ? avail : (c.EOF ? -1 : 0)); 872 } 873 } 874 875 public int getChannelData(Channel c, boolean extended, byte[] target, int off, int len) throws IOException  876 { 877 int copylen = 0; 878 int increment = 0; 879 int remoteID = 0; 880 int localID = 0; 881 882 synchronized (c) 883 { 884 int stdoutAvail = 0; 885 int stderrAvail = 0; 886 887 while (true) 888 { 889 893 894 stdoutAvail = c.stdoutWritepos - c.stdoutReadpos; 895 stderrAvail = c.stderrWritepos - c.stderrReadpos; 896 897 if ((!extended) && (stdoutAvail != 0)) 898 break; 899 900 if ((extended) && (stderrAvail != 0)) 901 break; 902 903 904 905 if ((c.EOF) || (c.state != Channel.STATE_OPEN)) 906 return -1; 907 908 try 909 { 910 c.wait(); 911 } 912 catch (InterruptedException ignore) 913 { 914 } 915 } 916 917 918 919 if (!extended) 920 { 921 copylen = (stdoutAvail > len) ? len : stdoutAvail; 922 System.arraycopy(c.stdoutBuffer, c.stdoutReadpos, target, off, copylen); 923 c.stdoutReadpos += copylen; 924 925 if (c.stdoutReadpos != c.stdoutWritepos) 926 927 System.arraycopy(c.stdoutBuffer, c.stdoutReadpos, c.stdoutBuffer, 0, c.stdoutWritepos 928 - c.stdoutReadpos); 929 930 c.stdoutWritepos -= c.stdoutReadpos; 931 c.stdoutReadpos = 0; 932 } 933 else 934 { 935 copylen = (stderrAvail > len) ? len : stderrAvail; 936 System.arraycopy(c.stderrBuffer, c.stderrReadpos, target, off, copylen); 937 c.stderrReadpos += copylen; 938 939 if (c.stderrReadpos != c.stderrWritepos) 940 941 System.arraycopy(c.stderrBuffer, c.stderrReadpos, c.stderrBuffer, 0, c.stderrWritepos 942 - c.stderrReadpos); 943 944 c.stderrWritepos -= c.stderrReadpos; 945 c.stderrReadpos = 0; 946 } 947 948 if (c.state != Channel.STATE_OPEN) 949 return copylen; 950 951 if (c.localWindow < ((Channel.CHANNEL_BUFFER_SIZE + 1) / 2)) 952 { 953 int minFreeSpace = Math.min(Channel.CHANNEL_BUFFER_SIZE - c.stdoutWritepos, Channel.CHANNEL_BUFFER_SIZE 954 - c.stderrWritepos); 955 956 increment = minFreeSpace - c.localWindow; 957 c.localWindow = minFreeSpace; 958 } 959 960 remoteID = c.remoteID; 961 localID = c.localID; 962 } 963 964 969 970 if (increment > 0) 971 { 972 if (log.isEnabled()) 973 log.log(80, "Sending SSH_MSG_CHANNEL_WINDOW_ADJUST (channel " + localID + ", " + increment + ")"); 974 975 synchronized (c.channelSendLock) 976 { 977 byte[] msg = c.msgWindowAdjust; 978 979 msg[0] = Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST; 980 msg[1] = (byte) (remoteID >> 24); 981 msg[2] = (byte) (remoteID >> 16); 982 msg[3] = (byte) (remoteID >> 8); 983 msg[4] = (byte) (remoteID); 984 msg[5] = (byte) (increment >> 24); 985 msg[6] = (byte) (increment >> 16); 986 msg[7] = (byte) (increment >> 8); 987 msg[8] = (byte) (increment); 988 989 if (c.closeMessageSent == false) 990 tm.sendMessage(msg); 991 } 992 } 993 994 return copylen; 995 } 996 997 public void msgChannelData(byte[] msg, int msglen) throws IOException  998 { 999 if (msglen <= 9) 1000 throw new IOException ("SSH_MSG_CHANNEL_DATA message has wrong size (" + msglen + ")"); 1001 1002 int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); 1003 int len = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff); 1004 1005 Channel c = getChannel(id); 1006 1007 if (c == null) 1008 throw new IOException ("Unexpected SSH_MSG_CHANNEL_DATA message for non-existent channel " + id); 1009 1010 if (len != (msglen - 9)) 1011 throw new IOException ("SSH_MSG_CHANNEL_DATA message has wrong len (calculated " + (msglen - 9) + ", got " 1012 + len + ")"); 1013 1014 if (log.isEnabled()) 1015 log.log(80, "Got SSH_MSG_CHANNEL_DATA (channel " + id + ", " + len + ")"); 1016 1017 synchronized (c) 1018 { 1019 if (c.state == Channel.STATE_CLOSED) 1020 return; 1022 if (c.state != Channel.STATE_OPEN) 1023 throw new IOException ("Got SSH_MSG_CHANNEL_DATA, but channel is not in correct state (" + c.state + ")"); 1024 1025 if (c.localWindow < len) 1026 throw new IOException ("Remote sent too much data, does not fit into window."); 1027 1028 c.localWindow -= len; 1029 1030 System.arraycopy(msg, 9, c.stdoutBuffer, c.stdoutWritepos, len); 1031 c.stdoutWritepos += len; 1032 1033 c.notifyAll(); 1034 } 1035 } 1036 1037 public void msgChannelWindowAdjust(byte[] msg, int msglen) throws IOException  1038 { 1039 if (msglen != 9) 1040 throw new IOException ("SSH_MSG_CHANNEL_WINDOW_ADJUST message has wrong size (" + msglen + ")"); 1041 1042 int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); 1043 int windowChange = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff); 1044 1045 Channel c = getChannel(id); 1046 1047 if (c == null) 1048 throw new IOException ("Unexpected SSH_MSG_CHANNEL_WINDOW_ADJUST message for non-existent channel " + id); 1049 1050 synchronized (c) 1051 { 1052 final long huge = 0xFFFFffffL; 1053 1054 c.remoteWindow += (windowChange & huge); 1055 1056 1057 1058 if ((c.remoteWindow > huge)) 1059 c.remoteWindow = huge; 1060 1061 c.notifyAll(); 1062 } 1063 1064 if (log.isEnabled()) 1065 log.log(80, "Got SSH_MSG_CHANNEL_WINDOW_ADJUST (channel " + id + ", " + windowChange + ")"); 1066 } 1067 1068 public void msgChannelOpen(byte[] msg, int msglen) throws IOException  1069 { 1070 TypesReader tr = new TypesReader(msg, 0, msglen); 1071 1072 tr.readByte(); String channelType = tr.readString(); 1074 int remoteID = tr.readUINT32(); 1075 int remoteWindow = tr.readUINT32(); 1076 int remoteMaxPacketSize = tr.readUINT32(); 1077 1078 if ("x11".equals(channelType)) 1079 { 1080 synchronized (x11_magic_cookies) 1081 { 1082 1083 1084 if (x11_magic_cookies.size() == 0) 1085 { 1086 PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID, 1087 Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, "X11 forwarding not activated", ""); 1088 1089 tm.sendAsynchronousMessage(pcof.getPayload()); 1090 1091 if (log.isEnabled()) 1092 log.log(20, "Unexpected X11 request, denying it!"); 1093 1094 return; 1095 } 1096 } 1097 1098 String remoteOriginatorAddress = tr.readString(); 1099 int remoteOriginatorPort = tr.readUINT32(); 1100 1101 Channel c = new Channel(this); 1102 1103 synchronized (c) 1104 { 1105 c.remoteID = remoteID; 1106 c.remoteWindow = remoteWindow & 0xFFFFffffL; 1107 c.remoteMaxPacketSize = remoteMaxPacketSize; 1108 c.localID = addChannel(c); 1109 } 1110 1111 1114 1115 RemoteX11AcceptThread rxat = new RemoteX11AcceptThread(c, remoteOriginatorAddress, remoteOriginatorPort); 1116 rxat.setDaemon(true); 1117 rxat.start(); 1118 1119 return; 1120 } 1121 1122 if ("forwarded-tcpip".equals(channelType)) 1123 { 1124 String remoteConnectedAddress = tr.readString(); 1125 int remoteConnectedPort = tr.readUINT32(); 1126 String remoteOriginatorAddress = tr.readString(); 1127 int remoteOriginatorPort = tr.readUINT32(); 1128 1129 RemoteForwardingData rfd = null; 1130 1131 synchronized (remoteForwardings) 1132 { 1133 rfd = (RemoteForwardingData) remoteForwardings.get(new Integer (remoteConnectedPort)); 1134 } 1135 1136 if (rfd == null) 1137 { 1138 PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID, 1139 Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, 1140 "No thanks, unknown port in forwarded-tcpip request", ""); 1141 1142 1143 1144 tm.sendAsynchronousMessage(pcof.getPayload()); 1145 1146 if (log.isEnabled()) 1147 log.log(20, "Unexpected forwarded-tcpip request, denying it!"); 1148 1149 return; 1150 } 1151 1152 Channel c = new Channel(this); 1153 1154 synchronized (c) 1155 { 1156 c.remoteID = remoteID; 1157 c.remoteWindow = remoteWindow & 0xFFFFffffL; 1158 c.remoteMaxPacketSize = remoteMaxPacketSize; 1159 c.localID = addChannel(c); 1160 } 1161 1162 1165 1166 RemoteAcceptThread rat = new RemoteAcceptThread(c, remoteConnectedAddress, remoteConnectedPort, 1167 remoteOriginatorAddress, remoteOriginatorPort, rfd.targetAddress, rfd.targetPort); 1168 1169 rat.setDaemon(true); 1170 rat.start(); 1171 1172 return; 1173 } 1174 1175 1176 1177 PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID, Packets.SSH_OPEN_UNKNOWN_CHANNEL_TYPE, 1178 "Unknown channel type", ""); 1179 1180 tm.sendAsynchronousMessage(pcof.getPayload()); 1181 1182 if (log.isEnabled()) 1183 log.log(20, "The peer tried to open an unsupported channel type (" + channelType + ")"); 1184 } 1185 1186 public void msgChannelRequest(byte[] msg, int msglen) throws IOException  1187 { 1188 TypesReader tr = new TypesReader(msg, 0, msglen); 1189 1190 tr.readByte(); int id = tr.readUINT32(); 1192 1193 Channel c = getChannel(id); 1194 1195 if (c == null) 1196 throw new IOException ("Unexpected SSH_MSG_CHANNEL_REQUEST message for non-existent channel " + id); 1197 1198 String type = tr.readString("US-ASCII"); 1199 boolean wantReply = tr.readBoolean(); 1200 1201 if (log.isEnabled()) 1202 log.log(80, "Got SSH_MSG_CHANNEL_REQUEST (channel " + id + ", '" + type + "')"); 1203 1204 if (type.equals("exit-status")) 1205 { 1206 if (wantReply != false) 1207 throw new IOException ("Badly formatted SSH_MSG_CHANNEL_REQUEST message, 'want reply' is true"); 1208 1209 int exit_status = tr.readUINT32(); 1210 1211 if (tr.remain() != 0) 1212 throw new IOException ("Badly formatted SSH_MSG_CHANNEL_REQUEST message"); 1213 1214 synchronized (c) 1215 { 1216 c.exit_status = new Integer (exit_status); 1217 c.notifyAll(); 1218 } 1219 1220 if (log.isEnabled()) 1221 log.log(50, "Got EXIT STATUS (channel " + id + ", status " + exit_status + ")"); 1222 1223 return; 1224 } 1225 1226 if (type.equals("exit-signal")) 1227 { 1228 if (wantReply != false) 1229 throw new IOException ("Badly formatted SSH_MSG_CHANNEL_REQUEST message, 'want reply' is true"); 1230 1231 String signame = tr.readString("US-ASCII"); 1232 tr.readBoolean(); 1233 tr.readString(); 1234 tr.readString(); 1235 1236 if (tr.remain() != 0) 1237 throw new IOException ("Badly formatted SSH_MSG_CHANNEL_REQUEST message"); 1238 1239 synchronized (c) 1240 { 1241 c.exit_signal = signame; 1242 c.notifyAll(); 1243 } 1244 1245 if (log.isEnabled()) 1246 log.log(50, "Got EXIT SIGNAL (channel " + id + ", signal " + signame + ")"); 1247 1248 return; 1249 } 1250 1251 1254 1255 if (wantReply) 1256 { 1257 byte[] reply = new byte[5]; 1258 1259 reply[0] = Packets.SSH_MSG_CHANNEL_FAILURE; 1260 reply[1] = (byte) (c.remoteID >> 24); 1261 reply[2] = (byte) (c.remoteID >> 16); 1262 reply[3] = (byte) (c.remoteID >> 8); 1263 reply[4] = (byte) (c.remoteID); 1264 1265 tm.sendAsynchronousMessage(reply); 1266 } 1267 1268 if (log.isEnabled()) 1269 log.log(50, "Channel request '" + type + "' is not known, ignoring it"); 1270 } 1271 1272 public void msgChannelEOF(byte[] msg, int msglen) throws IOException  1273 { 1274 if (msglen != 5) 1275 throw new IOException ("SSH_MSG_CHANNEL_EOF message has wrong size (" + msglen + ")"); 1276 1277 int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); 1278 1279 Channel c = getChannel(id); 1280 1281 if (c == null) 1282 throw new IOException ("Unexpected SSH_MSG_CHANNEL_EOF message for non-existent channel " + id); 1283 1284 synchronized (c) 1285 { 1286 c.EOF = true; 1287 c.notifyAll(); 1288 } 1289 1290 if (log.isEnabled()) 1291 log.log(50, "Got SSH_MSG_CHANNEL_EOF (channel " + id + ")"); 1292 } 1293 1294 public void msgChannelClose(byte[] msg, int msglen) throws IOException  1295 { 1296 if (msglen != 5) 1297 throw new IOException ("SSH_MSG_CHANNEL_CLOSE message has wrong size (" + msglen + ")"); 1298 1299 int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); 1300 1301 Channel c = getChannel(id); 1302 1303 if (c == null) 1304 throw new IOException ("Unexpected SSH_MSG_CHANNEL_CLOSE message for non-existent channel " + id); 1305 1306 synchronized (c) 1307 { 1308 c.EOF = true; 1309 c.state = Channel.STATE_CLOSED; 1310 c.setReasonClosed("Close requested by remote"); 1311 c.closeMessageRecv = true; 1312 1313 removeChannel(c.localID); 1314 1315 c.notifyAll(); 1316 } 1317 1318 if (log.isEnabled()) 1319 log.log(50, "Got SSH_MSG_CHANNEL_CLOSE (channel " + id + ")"); 1320 } 1321 1322 public void msgChannelSuccess(byte[] msg, int msglen) throws IOException  1323 { 1324 if (msglen != 5) 1325 throw new IOException ("SSH_MSG_CHANNEL_SUCCESS message has wrong size (" + msglen + ")"); 1326 1327 int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); 1328 1329 Channel c = getChannel(id); 1330 1331 if (c == null) 1332 throw new IOException ("Unexpected SSH_MSG_CHANNEL_SUCCESS message for non-existent channel " + id); 1333 1334 synchronized (c) 1335 { 1336 c.successCounter++; 1337 c.notifyAll(); 1338 } 1339 1340 if (log.isEnabled()) 1341 log.log(80, "Got SSH_MSG_CHANNEL_SUCCESS (channel " + id + ")"); 1342 } 1343 1344 public void msgChannelFailure(byte[] msg, int msglen) throws IOException  1345 { 1346 if (msglen != 5) 1347 throw new IOException ("SSH_MSG_CHANNEL_FAILURE message has wrong size (" + msglen + ")"); 1348 1349 int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); 1350 1351 Channel c = getChannel(id); 1352 1353 if (c == null) 1354 throw new IOException ("Unexpected SSH_MSG_CHANNEL_FAILURE message for non-existent channel " + id); 1355 1356 synchronized (c) 1357 { 1358 c.failedCounter++; 1359 c.notifyAll(); 1360 } 1361 1362 if (log.isEnabled()) 1363 log.log(50, "Got SSH_MSG_CHANNEL_FAILURE (channel " + id + ")"); 1364 } 1365 1366 public void msgChannelOpenConfirmation(byte[] msg, int msglen) throws IOException  1367 { 1368 PacketChannelOpenConfirmation sm = new PacketChannelOpenConfirmation(msg, 0, msglen); 1369 1370 Channel c = getChannel(sm.recipientChannelID); 1371 1372 if (c == null) 1373 throw new IOException ("Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION message for non-existent channel " 1374 + sm.recipientChannelID); 1375 1376 synchronized (c) 1377 { 1378 if (c.state != Channel.STATE_OPENING) 1379 throw new IOException ("Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION message for channel " 1380 + sm.recipientChannelID); 1381 1382 c.remoteID = sm.senderChannelID; 1383 c.remoteWindow = sm.initialWindowSize & 0xFFFFffffL; 1384 c.remoteMaxPacketSize = sm.maxPacketSize; 1385 c.state = Channel.STATE_OPEN; 1386 c.notifyAll(); 1387 } 1388 1389 if (log.isEnabled()) 1390 log.log(50, "Got SSH_MSG_CHANNEL_OPEN_CONFIRMATION (channel " + sm.recipientChannelID + " / remote: " 1391 + sm.senderChannelID + ")"); 1392 } 1393 1394 public void msgChannelOpenFailure(byte[] msg, int msglen) throws IOException  1395 { 1396 if (msglen < 5) 1397 throw new IOException ("SSH_MSG_CHANNEL_OPEN_FAILURE message has wrong size (" + msglen + ")"); 1398 1399 TypesReader tr = new TypesReader(msg, 0, msglen); 1400 1401 tr.readByte(); int id = tr.readUINT32(); 1403 1404 Channel c = getChannel(id); 1405 1406 if (c == null) 1407 throw new IOException ("Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE message for non-existent channel " + id); 1408 1409 int reasonCode = tr.readUINT32(); 1410 String description = tr.readString("UTF-8"); 1411 1412 String reasonCodeSymbolicName = null; 1413 1414 switch (reasonCode) 1415 { 1416 case 1: 1417 reasonCodeSymbolicName = "SSH_OPEN_ADMINISTRATIVELY_PROHIBITED"; 1418 break; 1419 case 2: 1420 reasonCodeSymbolicName = "SSH_OPEN_CONNECT_FAILED"; 1421 break; 1422 case 3: 1423 reasonCodeSymbolicName = "SSH_OPEN_UNKNOWN_CHANNEL_TYPE"; 1424 break; 1425 case 4: 1426 reasonCodeSymbolicName = "SSH_OPEN_RESOURCE_SHORTAGE"; 1427 break; 1428 default: 1429 reasonCodeSymbolicName = "UNKNOWN REASON CODE (" + reasonCode + ")"; 1430 } 1431 1432 StringBuffer descriptionBuffer = new StringBuffer (); 1433 descriptionBuffer.append(description); 1434 1435 for (int i = 0; i < descriptionBuffer.length(); i++) 1436 { 1437 char cc = descriptionBuffer.charAt(i); 1438 1439 if ((cc >= 32) && (cc <= 126)) 1440 continue; 1441 descriptionBuffer.setCharAt(i, '\uFFFD'); 1442 } 1443 1444 synchronized (c) 1445 { 1446 c.EOF = true; 1447 c.state = Channel.STATE_CLOSED; 1448 c.setReasonClosed("The server refused to open the channel (" + reasonCodeSymbolicName + ", '" 1449 + descriptionBuffer.toString() + "')"); 1450 c.notifyAll(); 1451 } 1452 1453 if (log.isEnabled()) 1454 log.log(50, "Got SSH_MSG_CHANNEL_OPEN_FAILURE (channel " + id + ")"); 1455 } 1456 1457 public void msgGlobalRequest(byte[] msg, int msglen) throws IOException  1458 { 1459 1460 1461 TypesReader tr = new TypesReader(msg, 0, msglen); 1462 1463 tr.readByte(); String requestName = tr.readString(); 1465 boolean wantReply = tr.readBoolean(); 1466 1467 if (wantReply) 1468 { 1469 byte[] reply_failure = new byte[1]; 1470 reply_failure[0] = Packets.SSH_MSG_REQUEST_FAILURE; 1471 1472 tm.sendAsynchronousMessage(reply_failure); 1473 } 1474 1475 1476 1477 if (log.isEnabled()) 1478 log.log(80, "Got SSH_MSG_GLOBAL_REQUEST (" + requestName + ")"); 1479 } 1480 1481 public void msgGlobalSuccess() throws IOException  1482 { 1483 synchronized (channels) 1484 { 1485 globalSuccessCounter++; 1486 channels.notifyAll(); 1487 } 1488 1489 if (log.isEnabled()) 1490 log.log(80, "Got SSH_MSG_REQUEST_SUCCESS"); 1491 } 1492 1493 public void msgGlobalFailure() throws IOException  1494 { 1495 synchronized (channels) 1496 { 1497 globalFailedCounter++; 1498 channels.notifyAll(); 1499 } 1500 1501 if (log.isEnabled()) 1502 log.log(80, "Got SSH_MSG_REQUEST_FAILURE"); 1503 } 1504 1505 public void handleMessage(byte[] msg, int msglen) throws IOException  1506 { 1507 if (msg == null) 1508 { 1509 if (log.isEnabled()) 1510 log.log(50, "HandleMessage: got shutdown"); 1511 1512 synchronized (listenerThreads) 1513 { 1514 for (int i = 0; i < listenerThreads.size(); i++) 1515 { 1516 IChannelWorkerThread lat = (IChannelWorkerThread) listenerThreads.elementAt(i); 1517 lat.stopWorking(); 1518 } 1519 listenerThreadsAllowed = false; 1520 } 1521 1522 synchronized (channels) 1523 { 1524 shutdown = true; 1525 1526 for (int i = 0; i < channels.size(); i++) 1527 { 1528 Channel c = (Channel) channels.elementAt(i); 1529 synchronized (c) 1530 { 1531 c.EOF = true; 1532 c.state = Channel.STATE_CLOSED; 1533 c.setReasonClosed("The connection is being shutdown"); 1534 c.closeMessageRecv = true; 1540 c.notifyAll(); 1541 } 1542 } 1543 1544 channels.setSize(0); 1545 channels.trimToSize(); 1546 channels.notifyAll(); 1547 return; 1548 } 1549 } 1550 1551 switch (msg[0]) 1552 { 1553 case Packets.SSH_MSG_CHANNEL_OPEN_CONFIRMATION: 1554 msgChannelOpenConfirmation(msg, msglen); 1555 break; 1556 case Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST: 1557 msgChannelWindowAdjust(msg, msglen); 1558 break; 1559 case Packets.SSH_MSG_CHANNEL_DATA: 1560 msgChannelData(msg, msglen); 1561 break; 1562 case Packets.SSH_MSG_CHANNEL_EXTENDED_DATA: 1563 msgChannelExtendedData(msg, msglen); 1564 break; 1565 case Packets.SSH_MSG_CHANNEL_REQUEST: 1566 msgChannelRequest(msg, msglen); 1567 break; 1568 case Packets.SSH_MSG_CHANNEL_EOF: 1569 msgChannelEOF(msg, msglen); 1570 break; 1571 case Packets.SSH_MSG_CHANNEL_OPEN: 1572 msgChannelOpen(msg, msglen); 1573 break; 1574 case Packets.SSH_MSG_CHANNEL_CLOSE: 1575 msgChannelClose(msg, msglen); 1576 break; 1577 case Packets.SSH_MSG_CHANNEL_SUCCESS: 1578 msgChannelSuccess(msg, msglen); 1579 break; 1580 case Packets.SSH_MSG_CHANNEL_FAILURE: 1581 msgChannelFailure(msg, msglen); 1582 break; 1583 case Packets.SSH_MSG_CHANNEL_OPEN_FAILURE: 1584 msgChannelOpenFailure(msg, msglen); 1585 break; 1586 case Packets.SSH_MSG_GLOBAL_REQUEST: 1587 msgGlobalRequest(msg, msglen); 1588 break; 1589 case Packets.SSH_MSG_REQUEST_SUCCESS: 1590 msgGlobalSuccess(); 1591 break; 1592 case Packets.SSH_MSG_REQUEST_FAILURE: 1593 msgGlobalFailure(); 1594 break; 1595 default: 1596 throw new IOException ("Cannot handle unknown channel message " + (msg[0] & 0xff)); 1597 } 1598 } 1599} 1600 | Popular Tags |