⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssh2ftpproxyfilter.java

📁 一个非常好的ssh客户端实现
💻 JAVA
字号:
/****************************************************************************** * * Copyright (c) 1999-2003 AppGate Network Security AB. All Rights Reserved. *  * This file contains Original Code and/or Modifications of Original Code as * defined in and that are subject to the MindTerm Public Source License, * Version 2.0, (the 'License'). You may not use this file except in compliance * with the License. *  * You should have received a copy of the MindTerm Public Source License * along with this software; see the file LICENSE.  If not, write to * AppGate Network Security AB, Otterhallegatan 2, SE-41118 Goteborg, SWEDEN * *****************************************************************************/package com.mindbright.ssh2;import java.io.InputStream;import java.io.OutputStream;import java.io.FilterInputStream;import java.io.FilterOutputStream;import java.io.IOException;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.Random;/** * Implements support for FTP over SSH. This implemntation sits on the * client side of the FTP command stream and opens new port forwards as * needed for the various data transfers. No server-side proxy is needed. */public class SSH2FTPProxyFilter implements SSH2StreamFilter,					   SSH2StreamFilterFactory{    class FTPInput extends FilterInputStream {	Random portRandomizer;	int    lastBoundPort;	public FTPInput(InputStream toBeFiltered) {	    super(toBeFiltered);	    portRandomizer = new Random();	    lastBoundPort  = -1;	}	public int read(byte b[], int off, int len) throws IOException {	    len = in.read(b, off, len);	    if(len < 0) {		return len;	    }	    String msg = new String(b, off, len);	    if(msg.startsWith("PASV") || msg.startsWith("pasv")) {		waitingPASVResponse = true;	    } else if(msg.startsWith("PORT ") || msg.startsWith("port ")) {		msg = msg.substring(5);		int[] d = new int[6];		if(parseHostAndPort(msg, d)) {		    String toHost = d[0] + "." + d[1] + "." + d[2] + "." + d[3];		    int    toPort = (d[4] << 8) | d[5];		    if(lastBoundPort > 0) {			connection.deleteRemoteForward(serverLocalAddr.						       getHostAddress(),						       lastBoundPort);		    }		    int port = 0;		    boolean success = false;		    while(!success) {			port = Math.abs(portRandomizer.nextInt());			port %= (65536 - 1024);			port += 1024;			success =			    connection.newRemoteForwardBlocking(serverLocalAddr.								getHostAddress(),								port,								toHost, toPort,								null);		    }		    lastBoundPort = port;		    int p1 = (port >>> 8) & 0xff;		    int p2 = port & 0xff;		    		    msg = "PORT " + localAddrPORTStr + "," +			p1 + "," + p2 + "\n";		    byte[] newmsg = msg.getBytes();		    len = newmsg.length;		    System.arraycopy(newmsg, 0, b, off, len);		} else {		    connection.getLog().warning("SSH2FTPProxyFilter",				"error in FTP proxy filter (port) for: " +						msg);		}	    }	    return len;	}    }    class FTPOutput extends FilterOutputStream {	public FTPOutput(OutputStream toBeFiltered) {	    super(toBeFiltered);	}	public void write(byte b[], int off, int len) throws IOException {	    SSH2Listener listener = null;	    String msg = new String(b, off, len);	    if(waitingPASVResponse && msg.startsWith("227 ")) {		byte[] newmsg;		waitingPASVResponse = false;		msg = msg.substring(27);		int[] d = new int[6];		if(parseHostAndPort(msg, d)) {		    String toHost = d[0] + "." + d[1] + "." + d[2] + "." + d[3];		    int    toPort = (d[4] << 8) | d[5];		    int    localPort;		    try {			listener =			    connection.newLocalForward(					       localHost.getHostAddress(),					       0, toHost, toPort);			// !!! TODO should have a blocking listener.ready()			Thread.sleep(250);		    } catch(InterruptedException e) {			connection.getLog().warning("SSH2FTPProxyFilter",				    "interrupted in FTP proxy filter: " +						    e.toString());			listener = null;		    } catch(IOException e) {			connection.getLog().warning("SSH2FTPProxyFilter",				    "error in FTP proxy filter: " +						    e.toString());			listener = null;		    }		    if(listener != null) {			listener.setAcceptMax(1); // Go away after next accept...			localPort = listener.getListenPort();			int p1 = (localPort >>> 8) & 0xff;			int p2 = localPort & 0xff;			msg = "227 Entering Passive Mode (" +			    localAddrPASVStr + "," + p1 + "," + p2 + ")\n";			newmsg = msg.getBytes();			out.write(newmsg, 0, newmsg.length);		    }		} else {		    connection.getLog().warning("SSH2FTPProxyFilter",				"error in FTP proxy filter (pasv) for: " +						msg);		}	    } else {		out.write(b, off, len);	    }	}    }    private boolean parseHostAndPort(String msg, int[] d) {	boolean ok = true;	int   cl   = 0;	int   cn   = 0;	try {	    for(int i = 0; i < 6; i++) {		String num;		if(i == 5) {		    cn = msg.indexOf(')', cl);		    if(cn == -1)			cn = msg.indexOf('\r', cl);		    else if(cn == -1)			cn = msg.indexOf('\n', cl);		} else		    cn = msg.indexOf(',', cl);		num = msg.substring(cl, cn);		cl = cn + 1;		d[i] = Integer.parseInt(num);	    }	} catch (Exception e) {	    ok = false;	}	return ok;    }    private String      localAddrPASVStr;    private String      localAddrPORTStr;    private InetAddress serverLocalAddr;    private InetAddress localHost;    /**     * Factory instance constructor     */    public SSH2FTPProxyFilter(String localHost, String serverLocalAddr)	throws UnknownHostException    {	this(InetAddress.getByName(localHost),	     InetAddress.getByName(serverLocalAddr));    }    /**     * Factory instance constructor     */    public SSH2FTPProxyFilter(InetAddress localHost,			      InetAddress serverLocalAddr)    {	this.localHost       = localHost;	this.serverLocalAddr = serverLocalAddr;	byte[] localAddrArr = localHost.getAddress();	// !!! TODO: want to be able to get actual connected adress	// i.e. through call to our stream ("instanceof TCP")	//	if((localAddrArr[0] & 0xff) == 0) {	    try {		localAddrArr = InetAddress.getLocalHost().getAddress();	    } catch (UnknownHostException e) {		throw new Error("Error in SSH2FTPProxyFilter: " + e);	    }	}	localAddrPASVStr = "";	for(int i = 0; i < 4; i++) {	    localAddrPASVStr += (localAddrArr[i] & 0xff) + (i < 3 ? "," : "");	}	localAddrArr = serverLocalAddr.getAddress();	localAddrPORTStr = "";	for(int i = 0; i < 4; i++) {	    localAddrPORTStr += (localAddrArr[i] & 0xff) + (i < 3 ? "," : "");	}    }    protected SSH2Connection    connection;    protected SSH2StreamChannel channel;    protected FTPInput          ftpIn;    protected FTPOutput         ftpOut;    protected volatile boolean waitingPASVResponse;    protected SSH2FTPProxyFilter(SSH2Connection connection,				 SSH2StreamChannel channel,				 SSH2FTPProxyFilter factory) {	this.connection = connection;	this.channel    = channel;	this.localAddrPASVStr = factory.localAddrPASVStr;	this.localAddrPORTStr = factory.localAddrPORTStr;	this.serverLocalAddr  = factory.serverLocalAddr;	this.localHost        = factory.localHost;	this.waitingPASVResponse = false;    }    public SSH2StreamFilter createFilter(SSH2Connection connection,					 SSH2StreamChannel channel) {	return new SSH2FTPProxyFilter(connection, channel, this);    }    public InputStream getInputFilter(InputStream toBeFiltered) {	this.ftpIn = new FTPInput(toBeFiltered);	return this.ftpIn;    }    public OutputStream getOutputFilter(OutputStream toBeFiltered) {	this.ftpOut = new FTPOutput(toBeFiltered);	return this.ftpOut;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -