Mercurial > 510Connectbot
diff src/ch/ethz/ssh2/channel/ChannelManager.java @ 308:42b15aaa7ac7 ganymed
merge
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Wed, 30 Jul 2014 14:21:50 -0700 |
parents | 071eccdff8ea |
children | f6d26c5f878e |
line wrap: on
line diff
--- a/src/ch/ethz/ssh2/channel/ChannelManager.java Wed Jul 30 13:38:04 2014 -0700 +++ b/src/ch/ethz/ssh2/channel/ChannelManager.java Wed Jul 30 14:21:50 2014 -0700 @@ -95,20 +95,21 @@ } private Channel getChannel(int id) { - synchronized(channels) { - for(Channel c : channels) { - if(c.localID == id) { + synchronized (channels) { + for (Channel c : channels) { + if (c.localID == id) { return c; } } } + return null; } private void removeChannel(int id) { - synchronized(channels) { - for(Channel c : channels) { - if(c.localID == id) { + synchronized (channels) { + for (Channel c : channels) { + if (c.localID == id) { channels.remove(c); break; } @@ -117,24 +118,24 @@ } private int addChannel(Channel c) { - synchronized(channels) { + synchronized (channels) { channels.add(c); return nextLocalChannel++; } } private void waitUntilChannelOpen(Channel c) throws IOException { - synchronized(c) { - while(c.state == Channel.STATE_OPENING) { + synchronized (c) { + while (c.state == Channel.STATE_OPENING) { try { c.wait(); } - catch(InterruptedException e) { + catch (InterruptedException e) { throw new InterruptedIOException(e.getMessage()); } } - if(c.state != Channel.STATE_OPEN) { + if (c.state != Channel.STATE_OPEN) { removeChannel(c.localID); throw c.getReasonClosed(); } @@ -142,84 +143,90 @@ } private void waitForGlobalSuccessOrFailure() throws IOException { - synchronized(channels) { - while((globalSuccessCounter == 0) && (globalFailedCounter == 0)) { - if(shutdown) { + synchronized (channels) { + while ((globalSuccessCounter == 0) && (globalFailedCounter == 0)) { + if (shutdown) { throw new IOException("The connection is being shutdown"); } try { channels.wait(); } - catch(InterruptedException e) { + catch (InterruptedException e) { throw new InterruptedIOException(e.getMessage()); } } - if((globalFailedCounter == 0) && (globalSuccessCounter == 1)) { + + if ((globalFailedCounter == 0) && (globalSuccessCounter == 1)) { return; } - if((globalFailedCounter == 1) && (globalSuccessCounter == 0)) { + + if ((globalFailedCounter == 1) && (globalSuccessCounter == 0)) { throw new IOException("The server denied the request (did you enable port forwarding?)"); } + throw new IOException("Illegal state. The server sent " + globalSuccessCounter - + " SSH_MSG_REQUEST_SUCCESS and " + globalFailedCounter + " SSH_MSG_REQUEST_FAILURE messages."); + + " SSH_MSG_REQUEST_SUCCESS and " + globalFailedCounter + " SSH_MSG_REQUEST_FAILURE messages."); } } private void waitForChannelSuccessOrFailure(Channel c) throws IOException { - synchronized(c) { - while((c.successCounter == 0) && (c.failedCounter == 0)) { - if(c.state != Channel.STATE_OPEN) { + synchronized (c) { + while ((c.successCounter == 0) && (c.failedCounter == 0)) { + if (c.state != Channel.STATE_OPEN) { throw c.getReasonClosed(); } + try { c.wait(); } - catch(InterruptedException ignore) { + catch (InterruptedException ignore) { throw new InterruptedIOException(); } } - if((c.failedCounter == 0) && (c.successCounter == 1)) { + + if ((c.failedCounter == 0) && (c.successCounter == 1)) { return; } - if((c.failedCounter == 1) && (c.successCounter == 0)) { + + if ((c.failedCounter == 1) && (c.successCounter == 0)) { throw new IOException("The server denied the request."); } + throw new IOException("Illegal state. The server sent " + c.successCounter - + " SSH_MSG_CHANNEL_SUCCESS and " + c.failedCounter + " SSH_MSG_CHANNEL_FAILURE messages."); + + " SSH_MSG_CHANNEL_SUCCESS and " + c.failedCounter + " SSH_MSG_CHANNEL_FAILURE messages."); } } public void registerX11Cookie(String hexFakeCookie, X11ServerData data) { - synchronized(x11_magic_cookies) { + synchronized (x11_magic_cookies) { x11_magic_cookies.put(hexFakeCookie, data); } } public void unRegisterX11Cookie(String hexFakeCookie, boolean killChannels) { - if(hexFakeCookie == null) { + if (hexFakeCookie == null) { throw new IllegalStateException("hexFakeCookie may not be null"); } - synchronized(x11_magic_cookies) { + synchronized (x11_magic_cookies) { x11_magic_cookies.remove(hexFakeCookie); } - if(killChannels == false) { + if (killChannels == false) { return; } log.debug("Closing all X11 channels for the given fake cookie"); - List<Channel> channel_copy = new ArrayList<Channel>(); - synchronized(channels) { + synchronized (channels) { channel_copy.addAll(channels); } - for(Channel c : channel_copy) { - synchronized(c) { - if(hexFakeCookie.equals(c.hexX11FakeCookie) == false) { + for (Channel c : channel_copy) { + synchronized (c) { + if (hexFakeCookie.equals(c.hexX11FakeCookie) == false) { continue; } } @@ -227,34 +234,34 @@ try { closeChannel(c, "Closing X11 channel since the corresponding session is closing", true); } - catch(IOException ignored) { + catch (IOException ignored) { } } } public X11ServerData checkX11Cookie(String hexFakeCookie) { - synchronized(x11_magic_cookies) { - if(hexFakeCookie != null) { + synchronized (x11_magic_cookies) { + if (hexFakeCookie != null) { return x11_magic_cookies.get(hexFakeCookie); } } + return null; } public void closeAllChannels() { log.debug("Closing all channels"); - List<Channel> channel_copy = new ArrayList<Channel>(); - synchronized(channels) { + synchronized (channels) { channel_copy.addAll(channels); } - for(Channel c : channel_copy) { + for (Channel c : channel_copy) { try { closeChannel(c, "Closing all channels", true); } - catch(IOException ignored) { + catch (IOException ignored) { } } } @@ -266,27 +273,26 @@ public void closeChannel(Channel c, IOException reason, boolean force) throws IOException { byte msg[] = new byte[5]; - synchronized(c) { - if(force) { + synchronized (c) { + if (force) { c.state = Channel.STATE_CLOSED; c.EOF = true; } c.setReasonClosed(reason); - msg[0] = Packets.SSH_MSG_CHANNEL_CLOSE; - msg[1] = (byte) (c.remoteID >> 24); - msg[2] = (byte) (c.remoteID >> 16); - msg[3] = (byte) (c.remoteID >> 8); - msg[4] = (byte) (c.remoteID); - + msg[1] = (byte)(c.remoteID >> 24); + msg[2] = (byte)(c.remoteID >> 16); + msg[3] = (byte)(c.remoteID >> 8); + msg[4] = (byte)(c.remoteID); c.notifyAll(); } - synchronized(c.channelSendLock) { - if(c.closeMessageSent) { + synchronized (c.channelSendLock) { + if (c.closeMessageSent) { return; } + tm.sendMessage(msg); c.closeMessageSent = true; } @@ -297,113 +303,110 @@ public void sendEOF(Channel c) throws IOException { byte[] msg = new byte[5]; - synchronized(c) { - if(c.state != Channel.STATE_OPEN) { + synchronized (c) { + if (c.state != Channel.STATE_OPEN) { return; } msg[0] = Packets.SSH_MSG_CHANNEL_EOF; - msg[1] = (byte) (c.remoteID >> 24); - msg[2] = (byte) (c.remoteID >> 16); - msg[3] = (byte) (c.remoteID >> 8); - msg[4] = (byte) (c.remoteID); + msg[1] = (byte)(c.remoteID >> 24); + msg[2] = (byte)(c.remoteID >> 16); + msg[3] = (byte)(c.remoteID >> 8); + msg[4] = (byte)(c.remoteID); } - synchronized(c.channelSendLock) { - if(c.closeMessageSent == true) { + synchronized (c.channelSendLock) { + if (c.closeMessageSent == true) { return; } + tm.sendMessage(msg); } - log.debug("Sent EOF (Channel " + c.localID + "/" + c.remoteID + ")"); } public void sendOpenConfirmation(Channel c) throws IOException { PacketChannelOpenConfirmation pcoc = null; - synchronized(c) { - if(c.state != Channel.STATE_OPENING) { + synchronized (c) { + if (c.state != Channel.STATE_OPENING) { return; } c.state = Channel.STATE_OPEN; - pcoc = new PacketChannelOpenConfirmation(c.remoteID, c.localID, c.localWindow, c.localMaxPacketSize); } - synchronized(c.channelSendLock) { - if(c.closeMessageSent == true) { + synchronized (c.channelSendLock) { + if (c.closeMessageSent == true) { return; } + tm.sendMessage(pcoc.getPayload()); } } public void sendData(Channel c, byte[] buffer, int pos, int len) throws IOException { - while(len > 0) { + while (len > 0) { int thislen = 0; byte[] msg; - synchronized(c) { - while(true) { - if(c.state == Channel.STATE_CLOSED) { + synchronized (c) { + while (true) { + if (c.state == Channel.STATE_CLOSED) { throw c.getReasonClosed(); } - if(c.state != Channel.STATE_OPEN) { + + if (c.state != Channel.STATE_OPEN) { throw new ChannelClosedException("SSH channel in strange state. (" + c.state + ")"); } - if(c.remoteWindow != 0) { + if (c.remoteWindow != 0) { break; } try { c.wait(); } - catch(InterruptedException e) { + catch (InterruptedException e) { throw new InterruptedIOException(e.getMessage()); } } /* len > 0, no sign extension can happen when comparing */ - thislen = (c.remoteWindow >= len) ? len : (int) c.remoteWindow; - int estimatedMaxDataLen = c.remoteMaxPacketSize - (tm.getPacketOverheadEstimate() + 9); /* The worst case scenario =) a true bottleneck */ - if(estimatedMaxDataLen <= 0) { + if (estimatedMaxDataLen <= 0) { estimatedMaxDataLen = 1; } - if(thislen > estimatedMaxDataLen) { + if (thislen > estimatedMaxDataLen) { thislen = estimatedMaxDataLen; } c.remoteWindow -= thislen; - msg = new byte[1 + 8 + thislen]; - msg[0] = Packets.SSH_MSG_CHANNEL_DATA; - msg[1] = (byte) (c.remoteID >> 24); - msg[2] = (byte) (c.remoteID >> 16); - msg[3] = (byte) (c.remoteID >> 8); - msg[4] = (byte) (c.remoteID); - msg[5] = (byte) (thislen >> 24); - msg[6] = (byte) (thislen >> 16); - msg[7] = (byte) (thislen >> 8); - msg[8] = (byte) (thislen); - + msg[1] = (byte)(c.remoteID >> 24); + msg[2] = (byte)(c.remoteID >> 16); + msg[3] = (byte)(c.remoteID >> 8); + msg[4] = (byte)(c.remoteID); + msg[5] = (byte)(thislen >> 24); + msg[6] = (byte)(thislen >> 16); + msg[7] = (byte)(thislen >> 8); + msg[8] = (byte)(thislen); System.arraycopy(buffer, pos, msg, 9, thislen); } - synchronized(c.channelSendLock) { - if(c.closeMessageSent) { + synchronized (c.channelSendLock) { + if (c.closeMessageSent) { throw c.getReasonClosed(); } + tm.sendMessage(msg); } @@ -413,37 +416,37 @@ } public int requestGlobalForward(String bindAddress, int bindPort, String targetAddress, int targetPort) - throws IOException { + throws IOException { RemoteForwardingData rfd = new RemoteForwardingData(); - rfd.bindAddress = bindAddress; rfd.bindPort = bindPort; rfd.targetAddress = targetAddress; rfd.targetPort = targetPort; - synchronized(remoteForwardings) { - if(remoteForwardings.get(bindPort) != null) { + synchronized (remoteForwardings) { + if (remoteForwardings.get(bindPort) != null) { throw new IOException("There is already a forwarding for remote port " + bindPort); } + remoteForwardings.put(bindPort, rfd); } - synchronized(channels) { + synchronized (channels) { globalSuccessCounter = globalFailedCounter = 0; } PacketGlobalForwardRequest pgf = new PacketGlobalForwardRequest(true, bindAddress, bindPort); tm.sendMessage(pgf.getPayload()); - log.debug("Requesting a remote forwarding ('" + bindAddress + "', " + bindPort + ")"); try { waitForGlobalSuccessOrFailure(); } - catch(IOException e) { - synchronized(remoteForwardings) { + catch (IOException e) { + synchronized (remoteForwardings) { remoteForwardings.remove(bindPort); } + throw e; } @@ -453,29 +456,27 @@ public void requestCancelGlobalForward(int bindPort) throws IOException { RemoteForwardingData rfd; - synchronized(remoteForwardings) { + synchronized (remoteForwardings) { rfd = remoteForwardings.get(bindPort); - if(rfd == null) { + if (rfd == null) { throw new IOException("Sorry, there is no known remote forwarding for remote port " + bindPort); } } - synchronized(channels) { + synchronized (channels) { globalSuccessCounter = globalFailedCounter = 0; } PacketGlobalCancelForwardRequest pgcf = new PacketGlobalCancelForwardRequest(true, rfd.bindAddress, rfd.bindPort); tm.sendMessage(pgcf.getPayload()); - log.debug("Requesting cancelation of remote forward ('" + rfd.bindAddress + "', " + rfd.bindPort + ")"); - waitForGlobalSuccessOrFailure(); - /* Only now we are sure that no more forwarded connections will arrive */ + /* Only now we are sure that no more forwarded connections will arrive */ - synchronized(remoteForwardings) { + synchronized (remoteForwardings) { remoteForwardings.remove(bindPort); } } @@ -497,29 +498,31 @@ } log.debug("Requesting agent forwarding"); + PacketChannelAuthAgentReq aar = new PacketChannelAuthAgentReq(c.remoteID); - PacketChannelAuthAgentReq aar = new PacketChannelAuthAgentReq(c.remoteID); - synchronized(c.channelSendLock) { + synchronized (c.channelSendLock) { if (c.closeMessageSent) { throw c.getReasonClosed(); } + tm.sendMessage(aar.getPayload()); } try { waitForChannelSuccessOrFailure(c); } - catch(IOException e) { + catch (IOException e) { authAgent = null; throw e; } } public void registerThread(IChannelWorkerThread thr) throws IOException { - synchronized(listenerThreads) { - if(listenerThreadsAllowed == false) { + synchronized (listenerThreads) { + if (listenerThreadsAllowed == false) { throw new IOException("Too late, this connection is closed."); } + listenerThreads.add(thr); } } @@ -528,36 +531,30 @@ int originator_port) throws IOException { Channel c = new Channel(this); - synchronized(c) { + synchronized (c) { c.localID = addChannel(c); // end of synchronized block forces writing out to main memory } PacketOpenDirectTCPIPChannel dtc = new PacketOpenDirectTCPIPChannel(c.localID, c.localWindow, c.localMaxPacketSize, host_to_connect, port_to_connect, originator_IP_address, originator_port); - tm.sendMessage(dtc.getPayload()); - waitUntilChannelOpen(c); - return c; } public Channel openSessionChannel() throws IOException { Channel c = new Channel(this); - synchronized(c) { + synchronized (c) { c.localID = addChannel(c); // end of synchronized block forces the writing out to main memory } log.debug("Sending SSH_MSG_CHANNEL_OPEN (Channel " + c.localID + ")"); - PacketOpenSessionChannel smo = new PacketOpenSessionChannel(c.localID, c.localWindow, c.localMaxPacketSize); tm.sendMessage(smo.getPayload()); - waitUntilChannelOpen(c); - return c; } @@ -565,27 +562,28 @@ int term_width_pixels, int term_height_pixels, byte[] terminal_modes) throws IOException { PacketSessionPtyRequest spr; - synchronized(c) { - if(c.state != Channel.STATE_OPEN) { + synchronized (c) { + if (c.state != Channel.STATE_OPEN) { throw c.getReasonClosed(); } + spr = new PacketSessionPtyRequest(c.remoteID, true, term, term_width_characters, term_height_characters, - term_width_pixels, term_height_pixels, terminal_modes); - + term_width_pixels, term_height_pixels, terminal_modes); c.successCounter = c.failedCounter = 0; } - synchronized(c.channelSendLock) { - if(c.closeMessageSent) { + synchronized (c.channelSendLock) { + if (c.closeMessageSent) { throw c.getReasonClosed(); } + tm.sendMessage(spr.getPayload()); } try { waitForChannelSuccessOrFailure(c); } - catch(IOException e) { + catch (IOException e) { throw new IOException("PTY request failed", e); } } @@ -594,27 +592,28 @@ int term_width_pixels, int term_height_pixels) throws IOException { PacketWindowChange pwc; - synchronized(c) { - if(c.state != Channel.STATE_OPEN) { + synchronized (c) { + if (c.state != Channel.STATE_OPEN) { throw c.getReasonClosed(); } + pwc = new PacketWindowChange(c.remoteID, term_width_characters, term_height_characters, - term_width_pixels, term_height_pixels); - + term_width_pixels, term_height_pixels); c.successCounter = c.failedCounter = 0; } - synchronized(c.channelSendLock) { - if(c.closeMessageSent) { + synchronized (c.channelSendLock) { + if (c.closeMessageSent) { throw c.getReasonClosed(); } + tm.sendMessage(pwc.getPayload()); } try { waitForChannelSuccessOrFailure(c); } - catch(IOException e) { + catch (IOException e) { throw new IOException("The window-change request failed.", e); } } @@ -623,20 +622,21 @@ String x11AuthenticationCookie, int x11ScreenNumber) throws IOException { PacketSessionX11Request psr; - synchronized(c) { - if(c.state != Channel.STATE_OPEN) { + synchronized (c) { + if (c.state != Channel.STATE_OPEN) { throw c.getReasonClosed(); } + psr = new PacketSessionX11Request(c.remoteID, true, singleConnection, x11AuthenticationProtocol, - x11AuthenticationCookie, x11ScreenNumber); - + x11AuthenticationCookie, x11ScreenNumber); c.successCounter = c.failedCounter = 0; } - synchronized(c.channelSendLock) { - if(c.closeMessageSent) { + synchronized (c.channelSendLock) { + if (c.closeMessageSent) { throw c.getReasonClosed(); } + tm.sendMessage(psr.getPayload()); } @@ -645,7 +645,7 @@ try { waitForChannelSuccessOrFailure(c); } - catch(IOException e) { + catch (IOException e) { throw new IOException("The X11 request failed.", e); } } @@ -653,26 +653,27 @@ public void requestSubSystem(Channel c, String subSystemName) throws IOException { PacketSessionSubsystemRequest ssr; - synchronized(c) { - if(c.state != Channel.STATE_OPEN) { + synchronized (c) { + if (c.state != Channel.STATE_OPEN) { throw c.getReasonClosed(); } + ssr = new PacketSessionSubsystemRequest(c.remoteID, true, subSystemName); - c.successCounter = c.failedCounter = 0; } - synchronized(c.channelSendLock) { - if(c.closeMessageSent) { + synchronized (c.channelSendLock) { + if (c.closeMessageSent) { throw c.getReasonClosed(); } + tm.sendMessage(ssr.getPayload()); } try { waitForChannelSuccessOrFailure(c); } - catch(IOException e) { + catch (IOException e) { throw new IOException("The subsystem request failed.", e); } } @@ -687,19 +688,20 @@ public void requestExecCommand(Channel c, String cmd, String charsetName) throws IOException { PacketSessionExecCommand sm; - synchronized(c) { - if(c.state != Channel.STATE_OPEN) { + synchronized (c) { + if (c.state != Channel.STATE_OPEN) { throw c.getReasonClosed(); } + sm = new PacketSessionExecCommand(c.remoteID, true, cmd, charsetName); - c.successCounter = c.failedCounter = 0; } - synchronized(c.channelSendLock) { - if(c.closeMessageSent) { + synchronized (c.channelSendLock) { + if (c.closeMessageSent) { throw c.getReasonClosed(); } + tm.sendMessage(sm.getPayload()); } @@ -708,7 +710,7 @@ try { waitForChannelSuccessOrFailure(c); } - catch(IOException e) { + catch (IOException e) { throw new IOException("The execute request failed.", e); } } @@ -716,75 +718,73 @@ public void requestShell(Channel c) throws IOException { PacketSessionStartShell sm; - synchronized(c) { - if(c.state != Channel.STATE_OPEN) { + synchronized (c) { + if (c.state != Channel.STATE_OPEN) { throw c.getReasonClosed(); } + sm = new PacketSessionStartShell(c.remoteID, true); - c.successCounter = c.failedCounter = 0; } - synchronized(c.channelSendLock) { - if(c.closeMessageSent) { + synchronized (c.channelSendLock) { + if (c.closeMessageSent) { throw c.getReasonClosed(); } + tm.sendMessage(sm.getPayload()); } try { waitForChannelSuccessOrFailure(c); } - catch(IOException e) { + catch (IOException e) { throw new IOException("The shell request failed.", e); } } public void msgChannelExtendedData(byte[] msg) throws IOException { - if(msg.length <= 13) { + if (msg.length <= 13) { throw new PacketFormatException(String.format("SSH_MSG_CHANNEL_EXTENDED_DATA message has wrong size (%d)", msg.length)); } int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); int dataType = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff); int len = ((msg[9] & 0xff) << 24) | ((msg[10] & 0xff) << 16) | ((msg[11] & 0xff) << 8) | (msg[12] & 0xff); - Channel c = getChannel(id); - if(c == null) { + if (c == null) { throw new PacketTypeException("Unexpected SSH_MSG_CHANNEL_EXTENDED_DATA message for non-existent channel " + id); } - if(dataType != Packets.SSH_EXTENDED_DATA_STDERR) { + if (dataType != Packets.SSH_EXTENDED_DATA_STDERR) { throw new PacketFormatException("SSH_MSG_CHANNEL_EXTENDED_DATA message has unknown type (" + dataType + ")"); } - if(len != (msg.length - 13)) { + if (len != (msg.length - 13)) { throw new PacketFormatException("SSH_MSG_CHANNEL_EXTENDED_DATA message has wrong len (calculated " + (msg.length - 13) - + ", got " + len + ")"); + + ", got " + len + ")"); } log.debug("Got SSH_MSG_CHANNEL_EXTENDED_DATA (channel " + id + ", " + len + ")"); - synchronized(c) { - if(c.state == Channel.STATE_CLOSED) { + synchronized (c) { + if (c.state == Channel.STATE_CLOSED) { return; // ignore } - if(c.state != Channel.STATE_OPEN) { + if (c.state != Channel.STATE_OPEN) { throw new PacketTypeException("Got SSH_MSG_CHANNEL_EXTENDED_DATA, but channel is not in correct state (" - + c.state + ")"); + + c.state + ")"); } - if(c.localWindow < len) { + if (c.localWindow < len) { throw new PacketFormatException("Remote sent too much data, does not fit into window."); } c.localWindow -= len; - System.arraycopy(msg, 13, c.stderrBuffer, c.stderrWritepos, len); c.stderrWritepos += len; - c.notifyAll(); } } @@ -801,64 +801,63 @@ long end_time = 0; boolean end_time_set = false; - synchronized(c) { - while(true) { + synchronized (c) { + while (true) { int current_cond = 0; - int stdoutAvail = c.stdoutWritepos - c.stdoutReadpos; int stderrAvail = c.stderrWritepos - c.stderrReadpos; - if(stdoutAvail > 0) { + if (stdoutAvail > 0) { current_cond = current_cond | ChannelCondition.STDOUT_DATA; } - if(stderrAvail > 0) { + if (stderrAvail > 0) { current_cond = current_cond | ChannelCondition.STDERR_DATA; } - if(c.EOF) { + if (c.EOF) { current_cond = current_cond | ChannelCondition.EOF; } - if(c.getExitStatus() != null) { + if (c.getExitStatus() != null) { current_cond = current_cond | ChannelCondition.EXIT_STATUS; } - if(c.getExitSignal() != null) { + if (c.getExitSignal() != null) { current_cond = current_cond | ChannelCondition.EXIT_SIGNAL; } - if(c.state == Channel.STATE_CLOSED) { + if (c.state == Channel.STATE_CLOSED) { return current_cond | ChannelCondition.CLOSED | ChannelCondition.EOF; } - if((current_cond & condition_mask) != 0) { + if ((current_cond & condition_mask) != 0) { return current_cond; } - if(timeout > 0) { - if(!end_time_set) { + if (timeout > 0) { + if (!end_time_set) { end_time = System.currentTimeMillis() + timeout; end_time_set = true; } else { timeout = end_time - System.currentTimeMillis(); - if(timeout <= 0) { + if (timeout <= 0) { return current_cond | ChannelCondition.TIMEOUT; } } } try { - if(timeout > 0) { + if (timeout > 0) { c.wait(timeout); } else { c.wait(); } } - catch(InterruptedException e) { + catch (InterruptedException e) { throw new InterruptedIOException(e.getMessage()); } } @@ -866,10 +865,10 @@ } public int getAvailable(Channel c, boolean extended) throws IOException { - synchronized(c) { + synchronized (c) { int avail; - if(extended) { + if (extended) { avail = c.stderrWritepos - c.stderrReadpos; } else { @@ -886,53 +885,50 @@ int remoteID = 0; int localID = 0; - synchronized(c) { + synchronized (c) { int stdoutAvail = 0; int stderrAvail = 0; - while(true) { + while (true) { /* * Data available? We have to return remaining data even if the * channel is already closed. */ - stdoutAvail = c.stdoutWritepos - c.stdoutReadpos; stderrAvail = c.stderrWritepos - c.stderrReadpos; - if((!extended) && (stdoutAvail != 0)) { + if ((!extended) && (stdoutAvail != 0)) { break; } - if((extended) && (stderrAvail != 0)) { + if ((extended) && (stderrAvail != 0)) { break; } /* Do not wait if more data will never arrive (EOF or CLOSED) */ - if((c.EOF) || (c.state != Channel.STATE_OPEN)) { + if ((c.EOF) || (c.state != Channel.STATE_OPEN)) { return -1; } try { c.wait(); } - catch(InterruptedException e) { + catch (InterruptedException e) { throw new InterruptedIOException(e.getMessage()); } } /* OK, there is some data. Return it. */ - if(!extended) { + if (!extended) { copylen = (stdoutAvail > len) ? len : stdoutAvail; System.arraycopy(c.stdoutBuffer, c.stdoutReadpos, target, off, copylen); c.stdoutReadpos += copylen; - if(c.stdoutReadpos != c.stdoutWritepos) - - { + if (c.stdoutReadpos != c.stdoutWritepos) { System.arraycopy(c.stdoutBuffer, c.stdoutReadpos, c.stdoutBuffer, 0, c.stdoutWritepos - - c.stdoutReadpos); + - c.stdoutReadpos); } c.stdoutWritepos -= c.stdoutReadpos; @@ -943,25 +939,22 @@ System.arraycopy(c.stderrBuffer, c.stderrReadpos, target, off, copylen); c.stderrReadpos += copylen; - if(c.stderrReadpos != c.stderrWritepos) - - { + if (c.stderrReadpos != c.stderrWritepos) { System.arraycopy(c.stderrBuffer, c.stderrReadpos, c.stderrBuffer, 0, c.stderrWritepos - - c.stderrReadpos); + - c.stderrReadpos); } c.stderrWritepos -= c.stderrReadpos; c.stderrReadpos = 0; } - if(c.state != Channel.STATE_OPEN) { + if (c.state != Channel.STATE_OPEN) { return copylen; } - if(c.localWindow < ((Channel.CHANNEL_BUFFER_SIZE + 1) / 2)) { + if (c.localWindow < ((Channel.CHANNEL_BUFFER_SIZE + 1) / 2)) { int minFreeSpace = Math.min(Channel.CHANNEL_BUFFER_SIZE - c.stdoutWritepos, - Channel.CHANNEL_BUFFER_SIZE - c.stderrWritepos); - + Channel.CHANNEL_BUFFER_SIZE - c.stderrWritepos); increment = minFreeSpace - c.localWindow; c.localWindow = minFreeSpace; } @@ -976,23 +969,22 @@ * does not matter in which order they arrive at the server. */ - if(increment > 0) { + if (increment > 0) { log.debug("Sending SSH_MSG_CHANNEL_WINDOW_ADJUST (channel " + localID + ", " + increment + ")"); - synchronized(c.channelSendLock) { + synchronized (c.channelSendLock) { byte[] msg = c.msgWindowAdjust; - msg[0] = Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST; - msg[1] = (byte) (remoteID >> 24); - msg[2] = (byte) (remoteID >> 16); - msg[3] = (byte) (remoteID >> 8); - msg[4] = (byte) (remoteID); - msg[5] = (byte) (increment >> 24); - msg[6] = (byte) (increment >> 16); - msg[7] = (byte) (increment >> 8); - msg[8] = (byte) (increment); + msg[1] = (byte)(remoteID >> 24); + msg[2] = (byte)(remoteID >> 16); + msg[3] = (byte)(remoteID >> 8); + msg[4] = (byte)(remoteID); + msg[5] = (byte)(increment >> 24); + msg[6] = (byte)(increment >> 16); + msg[7] = (byte)(increment >> 8); + msg[8] = (byte)(increment); - if(!c.closeMessageSent) { + if (!c.closeMessageSent) { tm.sendMessage(msg); } } @@ -1002,193 +994,170 @@ } public void msgChannelData(byte[] msg) throws IOException { - if(msg.length <= 9) { + if (msg.length <= 9) { throw new PacketFormatException(String.format("SSH_MSG_CHANNEL_DATA message has wrong size (%d)", msg.length)); } int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); int len = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff); - Channel c = getChannel(id); - if(c == null) { + if (c == null) { throw new PacketTypeException("Unexpected SSH_MSG_CHANNEL_DATA message for non-existent channel " + id); } - if(len != (msg.length - 9)) { + if (len != (msg.length - 9)) { throw new PacketFormatException("SSH_MSG_CHANNEL_DATA message has wrong len (calculated " + (msg.length - 9) + ", got " - + len + ")"); + + len + ")"); } log.debug("Got SSH_MSG_CHANNEL_DATA (channel " + id + ", " + len + ")"); - synchronized(c) { - if(c.state == Channel.STATE_CLOSED) { + synchronized (c) { + if (c.state == Channel.STATE_CLOSED) { return; // ignore } - if(c.state != Channel.STATE_OPEN) { + if (c.state != Channel.STATE_OPEN) { throw new PacketTypeException("Got SSH_MSG_CHANNEL_DATA, but channel is not in correct state (" + c.state + ")"); } - if(c.localWindow < len) { + if (c.localWindow < len) { throw new IOException("Remote sent too much data, does not fit into window."); } c.localWindow -= len; - System.arraycopy(msg, 9, c.stdoutBuffer, c.stdoutWritepos, len); c.stdoutWritepos += len; - c.notifyAll(); } } public void msgChannelWindowAdjust(byte[] msg) throws IOException { - if(msg.length != 9) { + if (msg.length != 9) { throw new PacketFormatException(String.format("SSH_MSG_CHANNEL_WINDOW_ADJUST message has wrong size (%d)", msg.length)); } int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); int windowChange = ((msg[5] & 0xff) << 24) | ((msg[6] & 0xff) << 16) | ((msg[7] & 0xff) << 8) | (msg[8] & 0xff); - Channel c = getChannel(id); - if(c == null) { + if (c == null) { throw new PacketTypeException("Unexpected SSH_MSG_CHANNEL_WINDOW_ADJUST message for non-existent channel " + id); } - synchronized(c) { + synchronized (c) { final long huge = 0xFFFFffffL; /* 2^32 - 1 */ - c.remoteWindow += (windowChange & huge); /* avoid sign extension */ - /* TODO - is this a good heuristic? */ + /* TODO - is this a good heuristic? */ - if((c.remoteWindow > huge)) { + if ((c.remoteWindow > huge)) { c.remoteWindow = huge; } c.notifyAll(); } - log.debug("Got SSH_MSG_CHANNEL_WINDOW_ADJUST (channel " + id + ", " + windowChange + ")"); } public void msgChannelOpen(byte[] msg) throws IOException { TypesReader tr = new TypesReader(msg); - tr.readByte(); // skip packet type String channelType = tr.readString(); int remoteID = tr.readUINT32(); /* sender channel */ int remoteWindow = tr.readUINT32(); /* initial window size */ int remoteMaxPacketSize = tr.readUINT32(); /* maximum packet size */ - if("x11".equals(channelType)) { - synchronized(x11_magic_cookies) { + if ("x11".equals(channelType)) { + synchronized (x11_magic_cookies) { /* If we did not request X11 forwarding, then simply ignore this bogus request. */ - - if(x11_magic_cookies.size() == 0) { + if (x11_magic_cookies.size() == 0) { PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID, Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, "X11 forwarding not activated", ""); - tm.sendAsynchronousMessage(pcof.getPayload()); - log.warning("Unexpected X11 request, denying it!"); - return; } } String remoteOriginatorAddress = tr.readString(); int remoteOriginatorPort = tr.readUINT32(); - Channel c = new Channel(this); - synchronized(c) { + synchronized (c) { c.remoteID = remoteID; c.remoteWindow = remoteWindow & 0xFFFFffffL; /* properly convert UINT32 to long */ c.remoteMaxPacketSize = remoteMaxPacketSize; c.localID = addChannel(c); } - /* + /* * The open confirmation message will be sent from another thread - */ - + */ RemoteX11AcceptThread rxat = new RemoteX11AcceptThread(c, remoteOriginatorAddress, remoteOriginatorPort); rxat.setDaemon(true); rxat.start(); - return; } - if("forwarded-tcpip".equals(channelType)) { + if ("forwarded-tcpip".equals(channelType)) { String remoteConnectedAddress = tr.readString(); /* address that was connected */ int remoteConnectedPort = tr.readUINT32(); /* port that was connected */ String remoteOriginatorAddress = tr.readString(); /* originator IP address */ int remoteOriginatorPort = tr.readUINT32(); /* originator port */ - RemoteForwardingData rfd; - synchronized(remoteForwardings) { + synchronized (remoteForwardings) { rfd = remoteForwardings.get(remoteConnectedPort); } - if(rfd == null) { + if (rfd == null) { PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID, Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, "No thanks, unknown port in forwarded-tcpip request", ""); - - /* Always try to be polite. */ - + /* Always try to be polite. */ tm.sendAsynchronousMessage(pcof.getPayload()); - log.debug("Unexpected forwarded-tcpip request, denying it!"); - return; } Channel c = new Channel(this); - synchronized(c) { + synchronized (c) { c.remoteID = remoteID; c.remoteWindow = remoteWindow & 0xFFFFffffL; /* convert UINT32 to long */ c.remoteMaxPacketSize = remoteMaxPacketSize; c.localID = addChannel(c); } - /* - * The open confirmation message will be sent from another thread. - */ - + /* + * The open confirmation message will be sent from another thread. + */ RemoteAcceptThread rat = new RemoteAcceptThread(c, remoteConnectedAddress, remoteConnectedPort, remoteOriginatorAddress, remoteOriginatorPort, rfd.targetAddress, rfd.targetPort); - rat.setDaemon(true); rat.start(); - return; } - if((server_state != null) && ("session".equals(channelType))) { + if ((server_state != null) && ("session".equals(channelType))) { ServerConnectionCallback cb; - synchronized(server_state) { + synchronized (server_state) { cb = server_state.cb_conn; } - if(cb == null) { + if (cb == null) { tm.sendAsynchronousMessage(new PacketChannelOpenFailure(remoteID, Packets.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, - "Sessions are currently not enabled", "en").getPayload()); - + "Sessions are currently not enabled", "en").getPayload()); return; } final Channel c = new Channel(this); - synchronized(c) { + synchronized (c) { c.remoteID = remoteID; c.remoteWindow = remoteWindow & 0xFFFFffffL; /* convert UINT32 to long */ c.remoteMaxPacketSize = remoteMaxPacketSize; @@ -1199,22 +1168,15 @@ PacketChannelOpenConfirmation pcoc = new PacketChannelOpenConfirmation(c.remoteID, c.localID, c.localWindow, c.localMaxPacketSize); - tm.sendAsynchronousMessage(pcoc.getPayload()); - c.ss.sscb = cb.acceptSession(c.ss); - return; } - /* Tell the server that we have no idea what it is talking about */ - + /* Tell the server that we have no idea what it is talking about */ PacketChannelOpenFailure pcof = new PacketChannelOpenFailure(remoteID, Packets.SSH_OPEN_UNKNOWN_CHANNEL_TYPE, "Unknown channel type", ""); - tm.sendAsynchronousMessage(pcof.getPayload()); - - log.warning("The peer tried to open an unsupported channel type (" + channelType + ")"); } @@ -1226,55 +1188,51 @@ public void msgChannelRequest(byte[] msg) throws IOException { TypesReader tr = new TypesReader(msg); - tr.readByte(); // skip packet type int id = tr.readUINT32(); - Channel c = getChannel(id); - if(c == null) { + if (c == null) { throw new IOException("Unexpected SSH_MSG_CHANNEL_REQUEST message for non-existent channel " + id); } ServerSessionImpl server_session = null; - if(server_state != null) { - synchronized(c) { + if (server_state != null) { + synchronized (c) { server_session = c.ss; } } String type = tr.readString("US-ASCII"); boolean wantReply = tr.readBoolean(); - log.debug("Got SSH_MSG_CHANNEL_REQUEST (channel " + id + ", '" + type + "')"); - if(type.equals("exit-status")) { - if(wantReply) { + if (type.equals("exit-status")) { + if (wantReply) { throw new IOException( - "Badly formatted SSH_MSG_CHANNEL_REQUEST exit-status message, 'want reply' is true"); + "Badly formatted SSH_MSG_CHANNEL_REQUEST exit-status message, 'want reply' is true"); } int exit_status = tr.readUINT32(); - if(tr.remain() != 0) { + if (tr.remain() != 0) { throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message"); } - synchronized(c) { + synchronized (c) { c.exit_status = exit_status; c.notifyAll(); } log.debug("Got EXIT STATUS (channel " + id + ", status " + exit_status + ")"); - return; } - if((server_state == null) && (type.equals("exit-signal"))) { - if(wantReply) { + if ((server_state == null) && (type.equals("exit-signal"))) { + if (wantReply) { throw new IOException( - "Badly formatted SSH_MSG_CHANNEL_REQUEST exit-signal message, 'want reply' is true"); + "Badly formatted SSH_MSG_CHANNEL_REQUEST exit-signal message, 'want reply' is true"); } String signame = tr.readString("US-ASCII"); @@ -1282,23 +1240,21 @@ tr.readString(); tr.readString(); - if(tr.remain() != 0) { + if (tr.remain() != 0) { throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message"); } - synchronized(c) { + synchronized (c) { c.exit_signal = signame; c.notifyAll(); } log.debug("Got EXIT SIGNAL (channel " + id + ", signal " + signame + ")"); - return; } - if((server_session != null) && (type.equals("pty-req"))) { + if ((server_session != null) && (type.equals("pty-req"))) { PtySettings pty = new PtySettings(); - pty.term = tr.readString(); pty.term_width_characters = tr.readUINT32(); pty.term_height_characters = tr.readUINT32(); @@ -1306,20 +1262,19 @@ pty.term_height_pixels = tr.readUINT32(); pty.terminal_modes = tr.readByteString(); - if(tr.remain() != 0) { + if (tr.remain() != 0) { throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message"); } Runnable run_after_sending_success = null; - ServerSessionCallback sscb = server_session.getServerSessionCallback(); - if(sscb != null) { + if (sscb != null) { run_after_sending_success = sscb.requestPtyReq(server_session, pty); } - if(wantReply) { - if(run_after_sending_success != null) { + if (wantReply) { + if (run_after_sending_success != null) { tm.sendAsynchronousMessage(new PacketChannelSuccess(c.remoteID).getPayload()); } else { @@ -1327,27 +1282,27 @@ } } - if(run_after_sending_success != null) { + if (run_after_sending_success != null) { runAsync(run_after_sending_success); } return; } - if((server_session != null) && (type.equals("shell"))) { - if(tr.remain() != 0) { + if ((server_session != null) && (type.equals("shell"))) { + if (tr.remain() != 0) { throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message"); } Runnable run_after_sending_success = null; ServerSessionCallback sscb = server_session.getServerSessionCallback(); - if(sscb != null) { + if (sscb != null) { run_after_sending_success = sscb.requestShell(server_session); } - if(wantReply) { - if(run_after_sending_success != null) { + if (wantReply) { + if (run_after_sending_success != null) { tm.sendAsynchronousMessage(new PacketChannelSuccess(c.remoteID).getPayload()); } else { @@ -1355,29 +1310,29 @@ } } - if(run_after_sending_success != null) { + if (run_after_sending_success != null) { runAsync(run_after_sending_success); } return; } - if((server_session != null) && (type.equals("exec"))) { + if ((server_session != null) && (type.equals("exec"))) { String command = tr.readString(); - if(tr.remain() != 0) { + if (tr.remain() != 0) { throw new IOException("Badly formatted SSH_MSG_CHANNEL_REQUEST message"); } Runnable run_after_sending_success = null; ServerSessionCallback sscb = server_session.getServerSessionCallback(); - if(sscb != null) { + if (sscb != null) { run_after_sending_success = sscb.requestExec(server_session, command); } - if(wantReply) { - if(run_after_sending_success != null) { + if (wantReply) { + if (run_after_sending_success != null) { tm.sendAsynchronousMessage(new PacketChannelSuccess(c.remoteID).getPayload()); } else { @@ -1385,18 +1340,18 @@ } } - if(run_after_sending_success != null) { + if (run_after_sending_success != null) { runAsync(run_after_sending_success); } return; } - /* We simply ignore unknown channel requests, however, if the server wants a reply, - * then we signal that we have no idea what it is about. - */ + /* We simply ignore unknown channel requests, however, if the server wants a reply, + * then we signal that we have no idea what it is about. + */ - if(wantReply) { + if (wantReply) { tm.sendAsynchronousMessage(new PacketChannelFailure(c.remoteID).getPayload()); } @@ -1404,19 +1359,18 @@ } public void msgChannelEOF(byte[] msg) throws IOException { - if(msg.length != 5) { + if (msg.length != 5) { throw new PacketFormatException(String.format("SSH_MSG_CHANNEL_EOF message has wrong size (%d)", msg.length)); } int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); - Channel c = getChannel(id); - if(c == null) { + if (c == null) { throw new PacketTypeException("Unexpected SSH_MSG_CHANNEL_EOF message for non-existent channel " + id); } - synchronized(c) { + synchronized (c) { c.EOF = true; c.notifyAll(); } @@ -1425,26 +1379,23 @@ } public void msgChannelClose(byte[] msg) throws IOException { - if(msg.length != 5) { + if (msg.length != 5) { throw new PacketFormatException("SSH_MSG_CHANNEL_CLOSE message has wrong size (" + msg.length + ")"); } int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); - Channel c = getChannel(id); - if(c == null) { + if (c == null) { throw new IOException("Unexpected SSH_MSG_CHANNEL_CLOSE message for non-existent channel " + id); } - synchronized(c) { + synchronized (c) { c.EOF = true; c.state = Channel.STATE_CLOSED; c.setReasonClosed(new ChannelClosedException("Close requested by remote")); c.closeMessageRecv = true; - removeChannel(c.localID); - c.notifyAll(); } @@ -1452,19 +1403,18 @@ } public void msgChannelSuccess(byte[] msg) throws IOException { - if(msg.length != 5) { + if (msg.length != 5) { throw new PacketFormatException("SSH_MSG_CHANNEL_SUCCESS message has wrong size (" + msg.length + ")"); } int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); - Channel c = getChannel(id); - if(c == null) { + if (c == null) { throw new PacketTypeException("Unexpected SSH_MSG_CHANNEL_SUCCESS message for non-existent channel " + id); } - synchronized(c) { + synchronized (c) { c.successCounter++; c.notifyAll(); } @@ -1473,19 +1423,18 @@ } public void msgChannelFailure(byte[] msg) throws IOException { - if(msg.length != 5) { + if (msg.length != 5) { throw new PacketFormatException(String.format("SSH_MSG_CHANNEL_FAILURE message has wrong size (%d)", msg.length)); } int id = ((msg[1] & 0xff) << 24) | ((msg[2] & 0xff) << 16) | ((msg[3] & 0xff) << 8) | (msg[4] & 0xff); - Channel c = getChannel(id); - if(c == null) { + if (c == null) { throw new PacketTypeException("Unexpected SSH_MSG_CHANNEL_FAILURE message for non-existent channel " + id); } - synchronized(c) { + synchronized (c) { c.failedCounter++; c.notifyAll(); } @@ -1495,18 +1444,17 @@ public void msgChannelOpenConfirmation(byte[] msg) throws IOException { PacketChannelOpenConfirmation sm = new PacketChannelOpenConfirmation(msg); - Channel c = getChannel(sm.getRecipientChannelID()); - if(c == null) { + if (c == null) { throw new PacketTypeException("Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION message for non-existent channel " - + sm.getRecipientChannelID()); + + sm.getRecipientChannelID()); } - synchronized(c) { - if(c.state != Channel.STATE_OPENING) { + synchronized (c) { + if (c.state != Channel.STATE_OPENING) { throw new PacketTypeException("Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION message for channel " - + sm.getRecipientChannelID()); + + sm.getRecipientChannelID()); } c.remoteID = sm.getSenderChannelID(); @@ -1517,43 +1465,44 @@ } log.debug("Got SSH_MSG_CHANNEL_OPEN_CONFIRMATION (channel " + sm.getRecipientChannelID() + " / remote: " - + sm.getSenderChannelID() + ")"); + + sm.getSenderChannelID() + ")"); } public void msgChannelOpenFailure(byte[] msg) throws IOException { - if(msg.length < 5) { + if (msg.length < 5) { throw new PacketFormatException(String.format("SSH_MSG_CHANNEL_OPEN_FAILURE message has wrong size (%d)", msg.length)); } TypesReader tr = new TypesReader(msg); - tr.readByte(); // skip packet type int id = tr.readUINT32(); /* sender channel */ - Channel c = getChannel(id); - if(c == null) { + if (c == null) { throw new PacketTypeException("Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE message for non-existent channel " + id); } int reasonCode = tr.readUINT32(); String description = tr.readString("UTF-8"); - String reasonCodeSymbolicName; - switch(reasonCode) { + switch (reasonCode) { case 1: reasonCodeSymbolicName = "SSH_OPEN_ADMINISTRATIVELY_PROHIBITED"; break; + case 2: reasonCodeSymbolicName = "SSH_OPEN_CONNECT_FAILED"; break; + case 3: reasonCodeSymbolicName = "SSH_OPEN_UNKNOWN_CHANNEL_TYPE"; break; + case 4: reasonCodeSymbolicName = "SSH_OPEN_RESOURCE_SHORTAGE"; break; + default: reasonCodeSymbolicName = "UNKNOWN REASON CODE (" + reasonCode + ")"; } @@ -1561,20 +1510,21 @@ StringBuilder descriptionBuffer = new StringBuilder(); descriptionBuffer.append(description); - for(int i = 0; i < descriptionBuffer.length(); i++) { + for (int i = 0; i < descriptionBuffer.length(); i++) { char cc = descriptionBuffer.charAt(i); - if((cc >= 32) && (cc <= 126)) { + if ((cc >= 32) && (cc <= 126)) { continue; } + descriptionBuffer.setCharAt(i, '\uFFFD'); } - synchronized(c) { + synchronized (c) { c.EOF = true; c.state = Channel.STATE_CLOSED; c.setReasonClosed(new ChannelClosedException(String.format("The server refused to open the channel (%s, '%s')", - reasonCodeSymbolicName, descriptionBuffer.toString()))); + reasonCodeSymbolicName, descriptionBuffer.toString()))); c.notifyAll(); } @@ -1582,28 +1532,24 @@ } public void msgGlobalRequest(byte[] msg) throws IOException { - /* Currently we do not support any kind of global request */ - + /* Currently we do not support any kind of global request */ TypesReader tr = new TypesReader(msg); - tr.readByte(); // skip packet type String requestName = tr.readString(); boolean wantReply = tr.readBoolean(); - if(wantReply) { + if (wantReply) { byte[] reply_failure = new byte[1]; reply_failure[0] = Packets.SSH_MSG_REQUEST_FAILURE; - tm.sendAsynchronousMessage(reply_failure); } - /* We do not clean up the requestName String - that is OK for debug */ - + /* We do not clean up the requestName String - that is OK for debug */ log.debug("Got SSH_MSG_GLOBAL_REQUEST (" + requestName + ")"); } public void msgGlobalSuccess() throws IOException { - synchronized(channels) { + synchronized (channels) { globalSuccessCounter++; channels.notifyAll(); } @@ -1612,7 +1558,7 @@ } public void msgGlobalFailure() throws IOException { - synchronized(channels) { + synchronized (channels) { globalFailedCounter++; channels.notifyAll(); } @@ -1623,18 +1569,19 @@ public void handleFailure(final IOException failure) { log.debug("HandleMessage: got shutdown"); - synchronized(listenerThreads) { - for(IChannelWorkerThread lat : listenerThreads) { + synchronized (listenerThreads) { + for (IChannelWorkerThread lat : listenerThreads) { lat.stopWorking(); } + listenerThreadsAllowed = false; } - synchronized(channels) { + synchronized (channels) { shutdown = true; - for(Channel c : channels) { - synchronized(c) { + for (Channel c : channels) { + synchronized (c) { c.EOF = true; c.state = Channel.STATE_CLOSED; c.setReasonClosed(failure); @@ -1642,55 +1589,70 @@ c.notifyAll(); } } + channels.clear(); channels.notifyAll(); /* Notify global response waiters */ } } public void handleMessage(byte[] msg) throws IOException { - switch(msg[0]) { + switch (msg[0]) { case Packets.SSH_MSG_CHANNEL_OPEN_CONFIRMATION: msgChannelOpenConfirmation(msg); break; + case Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST: msgChannelWindowAdjust(msg); break; + case Packets.SSH_MSG_CHANNEL_DATA: msgChannelData(msg); break; + case Packets.SSH_MSG_CHANNEL_EXTENDED_DATA: msgChannelExtendedData(msg); break; + case Packets.SSH_MSG_CHANNEL_REQUEST: msgChannelRequest(msg); break; + case Packets.SSH_MSG_CHANNEL_EOF: msgChannelEOF(msg); break; + case Packets.SSH_MSG_CHANNEL_OPEN: msgChannelOpen(msg); break; + case Packets.SSH_MSG_CHANNEL_CLOSE: msgChannelClose(msg); break; + case Packets.SSH_MSG_CHANNEL_SUCCESS: msgChannelSuccess(msg); break; + case Packets.SSH_MSG_CHANNEL_FAILURE: msgChannelFailure(msg); break; + case Packets.SSH_MSG_CHANNEL_OPEN_FAILURE: msgChannelOpenFailure(msg); break; + case Packets.SSH_MSG_GLOBAL_REQUEST: msgGlobalRequest(msg); break; + case Packets.SSH_MSG_REQUEST_SUCCESS: msgGlobalSuccess(); break; + case Packets.SSH_MSG_REQUEST_FAILURE: msgGlobalFailure(); break; + default: throw new PacketTypeException(msg[0]); }