HTTPS post: bypass SSL security check and trust all the hosts

peterchen-easyli發表於2013-10-25
import com.eviware.soapui.model.testsuite.TestRunContext;
import javax.net.ssl.*
import java.net.URL
import java.net.URLEncoder
import java.net.CookieHandler;
import java.net.CookieManager;
 
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;

class AUTHttps {
	def dataDir = null
	def conn = null
	def sc = null
	def weguid = null
	def String weguidPrefix = "weguid"
	/* I have to set Cookie manually, so the device can receives weguid correctly.*/
	/* If ACCEPT_ALL, the device will receives weguid likes "79ffb31f54dbe461" $Path="/" $Domain="10.68.6.127" */
	def cookieManager = new CookieManager( null, CookiePolicy.ACCEPT_NONE ) 

	public AUTHttps(String dir) {
		initHttps(dir)
	}

	public AUTHttps(TestRunContext context) {
		dataDir = AUTProject.getDataDir(context)
		initHttps(dataDir)
	}

	private initHttps(String dir) {
		def nullTrustManager = [
			checkClientTrusted: { chain, authType ->  },
			checkServerTrusted: { chain, authType ->  },
			getAcceptedIssuers: { null }
		]
	
		sc = SSLContext.getInstance("SSL")
		sc.init(null, [nullTrustManager as X509TrustManager] as TrustManager[], null)
		
		// make sure cookies is turn on
		CookieHandler.setDefault(cookieManager)
		
		//System.setProperty("http.keepAlive", "true")
	}

	public HttpsURLConnection getHttpsURLConnection() {
		return conn
	}

	public String getResponseMessage() {
		if (null == conn) {
			return "null"
		}
		
		return conn.getResponseMessage()
	}

	public int post(String url, Map params) {
		def nullHostnameVerifier = [ verify: { hostname, session -> true } ]
		def postParams = ""
		if (null != params) {
			params.each{
				if ("" == postParams) {
					postParams += it.key + "=" + URLEncoder.encode(it.value, "UTF-8")
				} else {
					postParams += '&' + it.key + "=" + URLEncoder.encode(it.value, "UTF-8")
				}
			}
		}
		
		def oldConn = conn
		
		def urlObj = new URL(url)
		conn = (HttpsURLConnection)(urlObj.openConnection())
		
		System.setProperty("javax.net.ssl.trustStore", "${dataDir}/keystore")
		System.setProperty("javax.net.ssl.trustStorePassword", "cert123456")

		conn.setDefaultSSLSocketFactory(new FixedSSLSocketFactory(sc.getSocketFactory()))
		//conn.setDefaultSSLSocketFactory(sc.getSocketFactory())
		conn.setDefaultHostnameVerifier(nullHostnameVerifier as HostnameVerifier)
		
		conn.setRequestMethod("POST")
		conn.setRequestProperty("Host", urlObj.getHost())
		conn.setRequestProperty("User-Agent", "Mozilla/5.0")
		conn.setRequestProperty("DNT", "1")
		conn.setRequestProperty("Accept", "*/*")
		conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5")
		conn.setRequestProperty("Accept-Encoding", "gzip, deflate")
//		conn.setRequestProperty("Connection", "Keep-Alive") this is default for https
//		conn.setRequestProperty("Connection", "Close")
		conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")	
		conn.setRequestProperty("Referer", "https://${urlObj.getHost()}/")
		conn.setRequestProperty("Content-Length", Integer.toString(postParams.length()))
		
		println("\nSending 'POST' request to URL : ${url}")
		println "http.keepAlive = " + System.getProperty("http.keepAlive").toString()

		if (null != weguid) {
			println "set cookies: ${weguidPrefix}=${weguid}"  
			conn.setRequestProperty("Cookie", "${weguidPrefix}=${weguid}")
		}

		conn.setDoOutput(true)
		conn.setDoInput(true)
		
		for (item in conn.getRequestProperties()) {
			println "${item.key}: ${item.value}"
		}
		println("Post parameters : " + postParams)

		// Send post request
		def wr = new DataOutputStream(conn.getOutputStream())
		wr.writeBytes(postParams)
		wr.flush()
		wr.close()
		
		def responseCode = conn.getResponseCode()
		println("\nRespose code: ${conn.getResponseMessage()}")
		for (item in conn.getHeaderFields()) {
			println "${item.key}: ${item.value}"
			if (item.key == "Set-Cookie") {
				def String propStr = item.value.toString().substring(1, item.value.toString().size() - 2)
				for (String str : propStr.split(";[ \t]*")) {
					//println str
					if (str.startsWith(weguidPrefix + "=")) {
						weguid = str.substring(str.indexOf(weguidPrefix + "=") + weguidPrefix.size() + 1)
						//println "${weguidPrefix}=${weguid}"
					}
				}
			}
		}
		return responseCode
	}
}

import javax.net.ssl.SSLSocket
import javax.net.ssl.SSLSocketFactory

/*
 * http://stackoverflow.com/questions/6851461/java-why-does-ssl-handshake-give-could-not-generate-dh-keypair-exception
 */
class FixedSSLSocketFactory extends javax.net.ssl.SSLSocketFactory {
	def SSLSocketFactory sf = null
	def enabledCiphers = null

	public FixedSSLSocketFactory(SSLSocketFactory sf, String[] enabledCiphers) {
		super()
		this.sf = sf;
		this.enabledCiphers = enabledCiphers
	}

	public FixedSSLSocketFactory(SSLSocketFactory sf) {
		super()
		this.sf = sf;
		def excludes = ["_DHE_","_DH_"]
		def ciphers = []
		for (s in sf.getDefaultCipherSuites()) {
			def excluded = false
			for (subStr in excludes) {
				if (s.indexOf(subStr) >= 0) {
					excluded = true
				}
			}
			if (excluded == false) {
				ciphers.add(s)
			}
		}
		//println ciphers 
		this.enabledCiphers = new String[ciphers.size()]
		ciphers.toArray(this.enabledCiphers)
	}

	private Socket getSocketWithEnabledCiphers(Socket socket) {
		if (enabledCiphers != null && socket != null && socket instanceof SSLSocket)
			((SSLSocket)socket).setEnabledCipherSuites(enabledCiphers)

		return socket;
	}

	@Override
	public Socket createSocket(Socket s, String host, int port,
			boolean autoClose) throws IOException {
		return getSocketWithEnabledCiphers(sf.createSocket(s, host, port, autoClose))
	}

	@Override
	public String[] getDefaultCipherSuites() {
		return sf.getDefaultCipherSuites()
	}

	@Override
	public String[] getSupportedCipherSuites() {
		if (enabledCiphers == null)
			return sf.getSupportedCipherSuites()
		else
			return enabledCiphers;
	}

	@Override
	public Socket createSocket(String host, int port) throws IOException,
			UnknownHostException {
		return getSocketWithEnabledCiphers(sf.createSocket(host, port));
	}

	@Override
	public Socket createSocket(InetAddress address, int port)
			throws IOException {
		return getSocketWithEnabledCiphers(sf.createSocket(address, port));
	}

	@Override
	public Socket createSocket(String host, int port, InetAddress localAddress,
			int localPort) throws IOException, UnknownHostException {
		return getSocketWithEnabledCiphers(sf.createSocket(host, port, localAddress, localPort));
	}

	@Override
	public Socket createSocket(InetAddress address, int port,
			InetAddress localaddress, int localport) throws IOException {
		return getSocketWithEnabledCiphers(sf.createSocket(address, port, localaddress, localport));
	}
}


相關文章