ssh2connection.java
来自「一个非常好的ssh客户端实现」· Java 代码 · 共 939 行 · 第 1/2 页
JAVA
939 行
} /** * Creates a new remote forward from the given remote address and port on * the server to the local address and port using the given filter factory * to insert filters in the input/output streams of the forwarded channels. * * @param remoteAddr the remote address where the server listens * @param remotePort the remote port where the server listens * @param localAddr the local address to connect through to * @param localAddr the local port to connect through to * @param filterFactory the filter factory instance to use for producing * filters. */ public synchronized void newRemoteForward(String remoteAddr, int remotePort, String localAddr, int localPort, SSH2StreamFilterFactory filterFactory) { newRemoteForward(remoteAddr, remotePort, localAddr, localPort, filterFactory, false); } /** * Creates a new remote forward from the given remote address and port on * the server to the local address and port using the given filter factory * to insert filters in the input/output streams of the forwarded * channel. This is a blocking version of the method * <code>newRemoteForward</code> with the same parameters which waits until * a result is reported from the server which indicates whether the forward * could be set up or not. * * @param remoteAddr the remote address where the server listens * @param remotePort the remote port where the server listens * @param localAddr the local address to connect through to * @param localAddr the local port to connect through to * @param filterFactory the filter factory instance to use for producing * filters. */ public boolean newRemoteForwardBlocking(String remoteAddr, int remotePort, String localAddr, int localPort, SSH2StreamFilterFactory filterFactory) { synchronized(reqMonitor) { newRemoteForward(remoteAddr, remotePort, localAddr, localPort, filterFactory, true); try { reqMonitor.wait(); } catch (InterruptedException e) { /* don't care, someone interrupted us on purpose */ } return reqStatus; } } private synchronized void newRemoteForward(String remoteAddr, int remotePort, String localAddr, int localPort, SSH2StreamFilterFactory filterFactory, boolean wantReply) { connLog.debug("SSH2Connection", "newRemoteForward", remoteAddr + ":" + remotePort + "->" + localAddr + ":" + localPort); remoteForwards.put(remoteAddr + ":" + remotePort, localAddr + ":" + localPort); if(filterFactory != null) { remoteFilters.put(remoteAddr + ":" + remotePort, filterFactory); } SSH2TransportPDU pdu = SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_GLOBAL_REQUEST); pdu.writeString(GL_REQ_START_FORWARD); pdu.writeBoolean(wantReply); pdu.writeString(remoteAddr); pdu.writeInt(remotePort); transport.transmit(pdu); } /** * Deletes the remote forward identified by the given remote address and * port pair. Note that the channels that was previously opened through this * forward are not deleted, only a CANCEL_FORWARD request is sent to the * server which deletes the forward on the server preventing further * channels to be opened through this forward. * * @param remoteAddr the remote address of the forward * @param remotePort the remote port of the forward */ public synchronized void deleteRemoteForward(String remoteAddr, int remotePort) { connLog.debug("SSH2Connection", "deleteRemoteForward", remoteAddr + ":" + remotePort); String tgStr = (String)remoteForwards.get(remoteAddr + ":" + remotePort); if(tgStr != null) { SSH2TransportPDU pdu = SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_GLOBAL_REQUEST); pdu.writeString(GL_REQ_CANCEL_FORWARD); pdu.writeBoolean(true); pdu.writeString(remoteAddr); pdu.writeInt(remotePort); transport.transmit(pdu); remoteForwards.remove(remoteAddr + ":" + remotePort); } } /** * Creates a new local forward from the given local address and port to * the remote address and port on the server side. * * @param localAddr the local address to listen to * @param localAddr the local port to listen to * @param remoteAddr the remote address where the connects to * @param remotePort the remote port where the connects to * * @return a listener instance accepting connections to forward */ public synchronized SSH2Listener newLocalForward(String localAddr, int localPort, String remoteAddr, int remotePort) throws IOException { return newLocalForward(localAddr, localPort, remoteAddr, remotePort, (SSH2StreamFilterFactory)null); } /** * Creates a new local forward from the given local address and port to the * remote address and port on the server side using the given filter factory * to insert filters in the input/output streams of the forwarded channels. * * @param localAddr the local address to listen to * @param localAddr the local port to listen to * @param remoteAddr the remote address where the connects to * @param remotePort the remote port where the connects to * @param filterFactory the filter factory instance to use for producing * filters. * * @return a listener instance accepting connections to forward */ public synchronized SSH2Listener newLocalForward(String localAddr, int localPort, String remoteAddr, int remotePort, SSH2StreamFilterFactory filterFactory) throws IOException { connLog.debug("SSH2Connection", "newLocalForward", localAddr + ":" + localPort + "->" + remoteAddr + ":" + remotePort); SSH2Listener listener = new SSH2Listener(localAddr, localPort, remoteAddr, remotePort, this, filterFactory); localForwards.put(localAddr + ":" + localPort, listener); return listener; } /** * Creates a new internal forward to * the remote address and port on the server side. * * @param remoteAddr the remote address where the connects to * @param remotePort the remote port where the connects to * * @return an internal channel */ public synchronized SSH2InternalChannel newLocalInternalForward(String remoteAddr, int remotePort) { return newLocalInternalForward(remoteAddr, remotePort, null); } /** * Creates a new internal forward to * remote address and port on the server side using the given filter * factory to insert filters in the input/output streams of the forwarded * channels. * * @param remoteAddr the remote address where the connects to * @param remotePort the remote port where the connects to * @param filterFactory the filter factory instance to use for producing * filters. * * @return an internal channel */ public synchronized SSH2InternalChannel newLocalInternalForward(String remoteAddr, int remotePort, SSH2StreamFilterFactory filterFactory) { connLog.debug("SSH2Connection", "newLocalInternalForward", "->" + remoteAddr + ":" + remotePort); SSH2InternalChannel chan = new SSH2InternalChannel(CH_TYPE_DIR_TCPIP, this); if(filterFactory != null) { chan.applyFilter(filterFactory.createFilter(this, chan)); } connectLocalChannel(chan, remoteAddr, remotePort, "127.0.0.1", remotePort); return chan; } /** * Deletes the local forward identified by the given local address and port * pair. Note that the channels that was previously opened through this * forward are not deleted, only the corresponding listener is stopped * preventing further channels to be opened through this forward. * * @param localAddr the local address of the forward * @param localAddr the local port of the forward */ public synchronized void deleteLocalForward(String localAddr, int localPort) { connLog.debug("SSH2Connection", "deleteLocalForward", localAddr + ":" + localPort); SSH2Listener listener = (SSH2Listener)localForwards.get(localAddr + ":" + localPort); if(listener != null) { listener.stop(); localForwards.remove(localAddr + ":" + localPort); } } /** * Creates a new session channel. * * @return the new session channel */ public synchronized SSH2SessionChannel newSession() { return newSession((SSH2StreamFilterFactory)null); } /** * Creates a new session channel using the given filter for filtering the * standard input/output streams of the session. * * @param filter the filter to use * * @return the new session channel */ public synchronized SSH2SessionChannel newSession(SSH2StreamFilterFactory filterFactory) { SSH2SessionChannel channel = new SSH2SessionChannel(this); if(filterFactory != null) { channel.applyFilter(filterFactory.createFilter(this, channel)); } SSH2TransportPDU pdu = getChannelOpenPDU(channel); transmit(pdu); return channel; } /** * Creates a new session channel attaching its standard input/output streams * to the given terminal adapter. It is up to the terminal adapter * implementation to attach itself to the I/O streams of the session * channel. For this purpose the interface method <code>attach</code> is * called before the channel open message is sent to the server so the * terminal adapter is attached before I/O is started. * * @param termAdapter the terminal adapter to attach to the session * * @return the new session channel */ public synchronized SSH2SessionChannel newTerminal(SSH2TerminalAdapter termAdapter) { SSH2SessionChannel channel = new SSH2SessionChannel(this); SSH2TransportPDU pdu = getChannelOpenPDU(channel); termAdapter.attach(channel); transmit(pdu); return channel; } public void setSocketOptions(String desc, Socket sock) throws IOException { transport.setSocketOptions(desc, sock); } synchronized boolean hasX11Mapping() { boolean hasMapping = (x11Mappings > 0); if(x11Single) { x11Mappings--; } return hasMapping; } synchronized void setX11Mapping(boolean single) { x11Single = single; x11Mappings++; } synchronized void clearX11Mapping() { if(x11Mappings > 0) { x11Mappings--; } } byte[] getX11FakeCookie() { if(x11FakeCookie == null) { x11FakeCookie = new byte[16]; SecureRandomAndPad srap = (SecureRandomAndPad) transport.getSecureRandom(); srap.nextPadBytes(x11FakeCookie, 0, 16); } return x11FakeCookie; } void setX11RealCookie(byte[] cookie) { x11RealCookie = cookie; } byte[] getX11RealCookie() { if(x11RealCookie == null) { x11RealCookie = getX11FakeCookie(); } return x11RealCookie; } synchronized void terminate() { if(connector != null) { connector.stop(); } Enumeration listeners = localForwards.elements(); while(listeners.hasMoreElements()) { ((SSH2Listener)listeners.nextElement()).stop(); } for(int i = 0; i < channels.length; i++) { if(channels[i] != null) { channels[i].close(); } } if(reaperActive) { stopChannelReaper(); } } synchronized void addChannel(SSH2Channel channel) { int newChan = nextEmptyChan; if(nextEmptyChan < channels.length) { int i; for(i = nextEmptyChan + 1; i < channels.length; i++) if(channels[i] == null) break; nextEmptyChan = i; } else { if(channels.length + 16 > MAX_ACTIVE_CHANNELS) { fatalDisconnect(SSH2.DISCONNECT_TOO_MANY_CONNECTIONS, "Number of channels exceeded maximum"); return; } SSH2Channel[] tmp = new SSH2Channel[channels.length + 16]; System.arraycopy(channels, 0, tmp, 0, channels.length); channels = tmp; nextEmptyChan++; } channel.channelId = newChan; channels[newChan] = channel; totalChannels++; eventHandler.channelAdded(this, channel); } synchronized void killChannel(SSH2Channel channel) { if(channel == null || channel.channelId == -1 || channel.channelId >= channels.length || channels[channel.channelId] == null) { connLog.error("SSH2Connection", "killChannel", "ch. # " + (channel != null ? String.valueOf(channel.getId()) : "<null>") + " not present"); return; } totalChannels--; channels[channel.channelId] = null; if(channel.channelId < nextEmptyChan) nextEmptyChan = channel.channelId; eventHandler.channelDeleted(this, channel); } void delChannel(SSH2Channel channel) { if(reaperActive) { life.addElement(channel); } else { killChannel(channel); } } SSH2TransportPDU getChannelOpenPDU(SSH2Channel channel) { SSH2TransportPDU pdu = SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_OPEN); pdu.writeString(channelTypes[channel.channelType]); pdu.writeInt(channel.channelId); pdu.writeInt(channel.rxInitWinSz); pdu.writeInt(channel.rxMaxPktSz); return pdu; } public void connectLocalChannel(SSH2Channel channel, String remoteAddr, int remotePort, String originAddr, int originPort) { SSH2TransportPDU pdu = getChannelOpenPDU(channel); pdu.writeString(remoteAddr); pdu.writeInt(remotePort); pdu.writeString(originAddr); pdu.writeInt(originPort); transmit(pdu); } private Vector life; private volatile boolean reaperActive; /** * Start a new thread which repeatedly tries to kill channels * which should be killed. */ protected void startChannelReaper() { this.life = new Vector(); this.reaperActive = true; Thread reaper = new Thread(this, "SSH2ChannelReaper"); reaper.setDaemon(true); reaper.setPriority(Thread.MIN_PRIORITY); reaper.start(); } /** * Stop the channel reaper. */ protected void stopChannelReaper() { reaperActive = false; } /** * The <code>run</code> routine which implements the channel reaper. */ public void run() { Vector death = new Vector(); while(reaperActive) { try { Thread.sleep(3000); } catch (InterruptedException e) { /* Don't care really, somebody interrupted us? */ } while(!death.isEmpty()) { SSH2Channel toBeKilled = (SSH2Channel)death.firstElement(); killChannel(toBeKilled); death.removeElementAt(0); } Vector limbo = death; death = life; life = limbo; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?