2013-08-07 78 views
1

我正在處理一個項目,該項目正在連接到服務器,希望在SSL握手之前以明文形式PROXY protocol行。服務器端需要該線路存在,如果沒有它,將無法正確握手。爲了避免客戶端和服務器之間有另一個軟件(如haproxy),我選擇嘗試擴展javax.net.ssl.SSLSocket類(和SSLProtocolSocketFactory類)。我已經能夠驗證我的課程是創建和訪問的課程。這是一個稍微修改版本的this class(SSLSocketWrapper)。嘗試覆蓋SSLSocket的startHandshake以便與Axis2一起使用

我現在運行的問題是,javax.net.ssl.SSLSocket中的startHandshake方法看起來並沒有被調用。我試過調試斷點,他們甚至不會觸發startHandshake。我一直在暫停這個過程並在調試器中加入了一段時間,我可以看到,當Axis2發送請求時,HTTP類肯定會使用我的Socket類。

我想知道如果我試圖覆蓋startHandshake完全吠叫錯誤的樹。也許我正在重新發明輪子(儘管我還沒有找到其他人這樣做)。任何幫助,將不勝感激

下面是工廠代碼:

import java.io.IOException; 
import java.net.InetAddress; 
import java.net.Socket; 
import java.net.UnknownHostException; 

import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSocket; 

import org.apache.commons.httpclient.ConnectTimeoutException; 
import org.apache.commons.httpclient.params.HttpConnectionParams; 
import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory; 

public class ProxyProtoSSLProtocolSocketFactory extends 
SSLProtocolSocketFactory { 

@Override 
public Socket createSocket(Socket socket, String host, int port, 
     boolean autoClose) throws IOException, UnknownHostException { 
    return new ProxySSLSocketWrapper((SSLSocket) super.createSocket(socket, host, port, autoClose)); 
} 

@Override 
public Socket createSocket(String arg0, int arg1, InetAddress arg2, 
     int arg3, HttpConnectionParams arg4) throws IOException, 
     UnknownHostException, ConnectTimeoutException { 
    // TODO Auto-generated method stub 
    return new ProxySSLSocketWrapper((SSLSocket)super.createSocket(arg0, arg1, arg2, arg3, arg4)); 
} 

@Override 
public Socket createSocket(String host, int port, InetAddress clientHost, 
     int clientPort) throws IOException, UnknownHostException { 
    // TODO Auto-generated method stub 
    return new ProxySSLSocketWrapper((SSLSocket) super.createSocket(host, port, clientHost, clientPort)); 
} 

@Override 
public Socket createSocket(String host, int port) throws IOException, 
     UnknownHostException { 
    return new ProxySSLSocketWrapper((SSLSocket) super.createSocket(host, port)); 
} 
} 

下面是我從上面鏈接的SSLSocketWrapper類改變的部分。我只是發佈了我已經改變的部分,因爲它接近385行,對於內聯來說有點多。在這一點上,它與上面的幾乎沒有什麼不同,我剛剛在startHandshake中放了一個斷點,作爲一個沒有被調用的健康檢查。

public class ProxySSLSocketWrapper extends SSLSocket { 
private SSLSocket s; 

public ProxySSLSocketWrapper(SSLSocket s) { 
    this.s = s; 
} 

/* javax.net.ssl.SSLSocket */ 

/** 
* Start handshake after sending over PROXY protocol line. 
*/ 
@Override 
public void startHandshake() throws IOException { 
    s.startHandshake(); 
    /* 
    if (s instanceof SSLSocket) { 
    InetAddress dest = s.getInetAddress(); 
    InetAddress local = s.getLocalAddress(); 
    int localPort = s.getLocalPort(); 
    int destPort = s.getPort(); 
    String proxyLine = String.format("PROXY TCP4 %s %s %d %d\r\n", local.getHostAddress(), dest.getHostAddress(), localPort, destPort); 
    System.err.print("Proxy line written: " + proxyLine); 
    System.err.flush(); 
    OutputStream out = s.getOutputStream(); 
    OutputStreamWriter writer = new OutputStreamWriter(out); 
    writer.write(proxyLine); 
    writer.flush(); 
     ((SSLSocket) s).startHandshake(); 
    } 
    */ 

}

連接的嘗試調用只是試圖使SOAP調用通過Axis2中生成的存根。

+0

我們可以看到您目前正在嘗試的一些示例嗎? – Joel

回答

0

無論如何,它將無法工作,因爲嵌套SSLSocket將加密PROXY TCP4請求。

您需要一個明文套接字,其中包含一個javax.net.ssl.SSLSocket,並且您的代理SSL套接字將其包裹。

我也會包裝明文套接字,重寫getOutputStream(),並在第一個輸出上發送PROXY TCP4行。

+0

我想我的印象是SSLSocket在握手之前不會加密請求。如果我有ProxySSLSocket(SSLSocket(明文)))不會getOutputStream仍然被加密?或者我在這裏誤解了這個想法? – hailunix

+0

'SSLSocket'將啓動第一個I/O上的handhshake,但不一定是通過調用'startHandshake()'本身。明文套接字的輸出流不能被加密。 – EJP

相關問題