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 + -
显示快捷键?