I'm trying to connect to a SharePoint url so I used the example code in httpcomponents-client-4.2.1\examples\org\apache\http\examples\client\ClientAuthentication.java but changed it to NTCredentials to ignore certificate problems. Apart from this the code is the same but outputs this:
executing requestGET url HTTP/1.1
----------------------------------------
HTTP/1.1 401 Unauthorized
Response content length: 0
Here is the full code
public class DocumentApprover {
static final String user = "user"; // your account name
static final String pass = "password"; // your password for the account
public static DefaultHttpClient wrapClient(DefaultHttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = base.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, ssf));
return new DefaultHttpClient(ccm, base.getParams());
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
DefaultHttpClient httpclient = wrapClient(new DefaultHttpClient());
try {
httpclient.getCredentialsProvider().setCredentials(
new AuthScope("host", 443),
new NTCredentials(user, pass, "workstation", "domain"));
HttpGet httpget = new HttpGet("url");
System.out.println("executing request" + httpget.getRequestLine());
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
EntityUtils.consume(entity);
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Why is it failing? If the credentials were wrong wouldn't I get a different error?
Related
I'm trying to replace the following deprecated (e.g. Apache DefaultHttpClient, SSLSocketFactory are deprecated) code:
public class HttpUtil {
public static DefaultHttpClient getDefaultHttpClient(IClientConfiguration configuration,
ExternalAPILogger logger) {
DefaultHttpClient client = new DefaultHttpClient();
if(configuration.isIgnoreSSLCertificate()) {
try {
SSLContext context = SSLContext.getInstance("TLS");
X509TrustManager trustManager = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
context.init(null, new TrustManager[]{trustManager}, null);
SSLSocketFactory sslSocketFactory = new SSLSocketFactory(context);
sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager connectionManager = client.getConnectionManager();
SchemeRegistry schemeRegistry = connectionManager.getSchemeRegistry();
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
client = new DefaultHttpClient(connectionManager, client.getParams());
} catch (NoSuchAlgorithmException e) {
logger.log(HttpUtil.class.getName(), "TLS not available", e, ExternalAPILogger.DEBUG);
} catch(KeyManagementException e) {
logger.log(HttpUtil.class, "ssl context init failed", e, ExternalAPILogger.DEBUG);
}
}
if(configuration.isUseProxy()) {
HttpHost proxy = new HttpHost(configuration.getProxyHost(),
configuration.getProxyPort());
ConnRouteParams.setDefaultProxy(client.getParams(), proxy);
}
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 60 * 1000);
client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 60 * 1000);
return client;
}
}
by this new code:
public static HttpClient getHttpClient(IClientConfiguration configuration,
ExternalAPILogger logger) {
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
// clientBuilder.useSystemProperties();
if (configuration.isIgnoreSSLCertificate()) {
try {
SSLContext context = SSLContext.getInstance("TLS");
X509TrustManager trustManager = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
context.init(null, new TrustManager[] { trustManager }, null);
// clientBuilder.setSSLContext(context);
// clientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
SSLConnectionSocketFactory sslSocketFactory =
new SSLConnectionSocketFactory(context, NoopHostnameVerifier.INSTANCE);
clientBuilder.setSSLSocketFactory(sslSocketFactory);
Registry<ConnectionSocketFactory> schemeRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslSocketFactory).build();
HttpClientConnectionManager httpClientConnectionManager =
new BasicHttpClientConnectionManager(schemeRegistry);
clientBuilder.setConnectionManager(httpClientConnectionManager);
} catch (NoSuchAlgorithmException e) {
logger.log(HttpUtil.class.getName(), "TLS not available", e, ExternalAPILogger.DEBUG);
} catch (KeyManagementException e) {
logger.log(HttpUtil.class, "ssl context init failed", e, ExternalAPILogger.DEBUG);
}
}
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
if (configuration.isUseProxy()) {
HttpHost proxy = new HttpHost(
configuration.getProxyHost(),
configuration.getProxyPort());
// clientBuilder
// .setRoutePlanner(new DefaultProxyRoutePlanner(proxy))
// .setProxy(proxy)
// .setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
requestConfigBuilder.setProxy(proxy);
}
requestConfigBuilder
.setConnectTimeout(60 * 1000)
.setSocketTimeout(60 * 1000);
clientBuilder.setDefaultRequestConfig(requestConfigBuilder.build());
// SocketConfig.Builder socketConfig = SocketConfig.custom();
// socketConfig.setSoTimeout(60 * 1000);
// clientBuilder.setDefaultSocketConfig(socketConfig.build());
return clientBuilder.build();
}
but I have problems to get the code running using a http proxy. I get the following error message.:
Caused by: org.apache.http.conn.UnsupportedSchemeException: http protocol is not supported
Unable to sent request to FCM url from server (same code is working from local pc)
Below is the error i am receiving on server logs
javax.net.ssl.SSLException: Certificate for <fcm.googleapis.com> doesn't match any of the subject alternative names: [*.googleapis.com, *.clients6.google.com, *.cloudendpointsapis.com, cloudendpointsapis.com, googleapis.com]at org.apache.http.conn.ssl.DefaultHostnameVerifier.matchDNSName(DefaultHostnameVerifier.java:157)
Server notification sending code ( function )
Same code works perfectly on local system/pc
public int sendNotification(String registrationId, String title,String subtitle, String url ,String destitle, String description) throws JSONException {
String uri = "https://fcm.googleapis.com/fcm/send";
HttpClient client = HttpClientBuilder.create().build();
try {
HttpPost postRequest = new HttpPost(uri);
postRequest.setHeader("Authorization","key=XXXXXXXXXXXXXXXXXXXXXXXXXXX");
postRequest.setHeader("Content-type", "application/json");
JSONObject json = new JSONObject();
json.put("to",registrationId.trim());
JSONObject data = new JSONObject();
data.put("title", title); // Notification title
data.put("subtitle", subtitle); // Notification body
data.put("destitle", destitle);
data.put("url", url);
data.put("description", description);
json.put("data", data);
StringEntity entity = new StringEntity(json.toString());
postRequest.setEntity(entity);
try {
HttpResponse response = client.execute(postRequest);
InputStreamReader inputStreamReader = new InputStreamReader(response.getEntity().getContent());
BufferedReader rd = new BufferedReader(inputStreamReader);
//System.out.println("NOTIFICATION RESPONSE ----->"+msg1+msg2);
String line = "";
while((line = rd.readLine()) != null)
{
System.out.println(line);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 1;
}
Add host name verification code..... to create httpclient object
public HttpClient getHttpClient() {
try {
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient client = new DefaultHttpClient();
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());
// Set verifier
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
// Example send http request
return httpClient;
} catch (Exception ex) {
return HttpClientBuilder.create().build();
}
}
I am doing a asynchronous http request to a web service. I am not that sure if this is the correct way to do it but it works.
Is this the correct way to make POST + authentication with HttpAsyncClient?
Should I close the httpclient at the end with httpclient.close(); ?
public void asyncHttpRequest() {
try {
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(3000)
.setConnectTimeout(3000).build();
CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
.setDefaultRequestConfig(requestConfig)
.build();
httpclient.start();
String postParameter = new JSONObject().put("key", "value").toString(); //Creating JSON string
HttpPost httpPost = new HttpPost("http://www.url.com");
httpPost.setEntity(new StringEntity(postParameter));
UsernamePasswordCredentials creds
= new UsernamePasswordCredentials("username", "password");
httpPost.addHeader(new BasicScheme().authenticate(creds, httpPost, null));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
httpclient.execute(httpPost, new FutureCallback<HttpResponse>() {
#Override
public void completed(final HttpResponse response) {
try {
InputStream responseBody = response.getEntity().getContent();
String serverResponse = IOUtils.toString(responseBody);
System.out.println("Server response : " + serverResponse);
System.out.println(httpPost.getRequestLine() + "->" + response.getStatusLine());
} catch (IOException | UnsupportedOperationException ex) {
//Do something
}
}
#Override
public void failed(final Exception ex) {
//Do something
}
#Override
public void cancelled() {
//Do something
}
});
} catch (IOException ex) {
//Do something
} catch (AuthenticationException ex) {
//Do something
}
}
Any help is appreciated!
I would suggest using a credentials provider like below, instead of explicitly adding a header for basic authentication:
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials creds =
new UsernamePasswordCredentials("username", "password");
provider.setCredentials(AuthScope.ANY, creds);
CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
.setDefaultRequestConfig(requestConfig)
.setDefaultCredentialsProvider(provider)
.build();
Also, it would be best to explicitly close the httpclient after the request has been completely processed.
I am trying to interact with a webservice which is a HTTPS call that works totally fine on different variants of 4.0(I havent checked it below 4.0 so I cant say about them) and its perfectly working. The issue I am facing is on Android 5.0 and the device I was able to grab was Nexus 5 and below is the exception i get when doing connectivity
javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
at org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:146)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93)
After tonnes of searching and analyzing our production server SSL certificate i figured out that the server accept TLSv1 and the only cipher suite it supports is TLS_RSA_WITH_3DES_EDE_CBC_SHA. Though i understand that its not safe and it should be upgraded but right now i have to find out some way to get my Android app connected with the server.
I tried through the way suggested on this page
https://code.google.com/p/android-developer-preview/issues/attachmentText?id=1200&aid=12000009000&name=CompatSSLSocketFactory.java&token=ABZ6GAcWKpRZhuG6Skof32VtvF0Lzv3Z-A%3A1435550700632
And replaced my required algorithm i.e TLS_RSA_WITH_3DES_EDE_CBC_SHA but now the problem is that i am seeing this exception
Caused by: java.lang.IllegalArgumentException: cipherSuite
TLS_RSA_WITH_3DES_EDE_CBC_SHA is not supported.
at com.android.org.conscrypt.NativeCrypto.checkEnabledCipherSuites(NativeCrypto.java:1091)
at com.android.org.conscrypt.SSLParametersImpl.setEnabledCipherSuites(SSLParametersImpl.java:244)
at com.android.org.conscrypt.OpenSSLSocketImpl.setEnabledCipherSuites(OpenSSLSocketImpl.java:822)
So according to this exception the cipher suite i required is not supported by Android 5.0. But i got puzzled after seeing it in Android 5.0's supported list on this page
http://developer.android.com/reference/javax/net/ssl/SSLEngine.html
Anybody any idea whats this mystery?
I got the answer finally after working out on the issue for three days. Posting out the correct solution for people who gets stuck in a similar issue in future
First implement CustomTrustManager
public class CustomX509TrustManager implements X509TrustManager {
#Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
#Override
public void checkServerTrusted(X509Certificate[] certs,
String authType) throws CertificateException {
// Here you can verify the servers certificate. (e.g. against one which is stored on mobile device)
// InputStream inStream = null;
// try {
// inStream = MeaApplication.loadCertAsInputStream();
// CertificateFactory cf = CertificateFactory.getInstance("X.509");
// X509Certificate ca = (X509Certificate)
// cf.generateCertificate(inStream);
// inStream.close();
//
// for (X509Certificate cert : certs) {
// // Verifing by public key
// cert.verify(ca.getPublicKey());
// }
// } catch (Exception e) {
// throw new IllegalArgumentException("Untrusted Certificate!");
// } finally {
// try {
// inStream.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
Than implement your own Socket Factory
public class CustomSSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public CustomSSLSocketFactory(KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException,
KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new CustomX509TrustManager();
sslContext.init(null, new TrustManager[] { tm }, null);
}
public CustomSSLSocketFactory(SSLContext context)
throws KeyManagementException, NoSuchAlgorithmException,
KeyStoreException, UnrecoverableKeyException {
super(null);
sslContext = context;
}
#Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
Socket newSocket = sslContext.getSocketFactory().createSocket(socket, host, port,
autoClose);
((SSLSocket) newSocket).setEnabledCipherSuites(((SSLSocket) newSocket).getSupportedCipherSuites());
AdjustSocket(newSocket);
return newSocket;
}
#Override
public Socket createSocket() throws IOException {
Socket socket = sslContext.getSocketFactory().createSocket();
((SSLSocket) socket).setEnabledCipherSuites(((SSLSocket) socket).getSupportedCipherSuites());
adjustSocket(socket);
return socket;
}
private void adjustSocket(Socket socket)
{
String[] cipherSuites = ((SSLSocket) socket).getSSLParameters().getCipherSuites();
ArrayList<String> cipherSuiteList = new ArrayList<String>(Arrays.asList(cipherSuites));
cipherSuiteList.add("TLS_RSA_WITH_3DES_EDE_CBC_SHA");
cipherSuites = cipherSuiteList.toArray(new String[cipherSuiteList.size()]);
((SSLSocket) socket).getSSLParameters().setCipherSuites(cipherSuites);
String[] protocols = ((SSLSocket) socket).getSSLParameters().getProtocols();
ArrayList<String> protocolList = new ArrayList<String>(Arrays.asList(protocols));
for (int ii = protocolList.size() - 1; ii >= 0; --ii )
{
if ((protocolList.get(ii).contains("SSLv3")) || (protocolList.get(ii).contains("TLSv1.1")) || (protocolList.get(ii).contains("TLSv1.2")))
protocolList.remove(ii);
}
protocols = protocolList.toArray(new String[protocolList.size()]);
((SSLSocket)socket).setEnabledProtocols(protocols);
}
}
Now add a function in the class to create a HttpClient
public HttpClient createHttpClient(){
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
CustomSSLSocketFactory sf = new CustomSSLSocketFactory(trustStore);
sf.setHostnameVerifier(CustomSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 15000);
HttpConnectionParams.setSoTimeout(params, 5000);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
And now write below lines to call the server/webservice
HttpClient httpClient = createHttpClient();
HttpPost httpost = new HttpPost(url);
HttpResponse response = null;
try {
response = httpClient.execute(httpost);
StatusLine statusLine = response.getStatusLine();
} catch (IOException e) {
e.printStackTrace();
}
I'm really trying to better understand how a CONNECT HTTP request process is handled. I'm stuck at this point in my HttpServer that I'm building and was hoping others can help give me incite on how I should approach these next challenges. A little info on my code thus far . I have a class HTTPServer listening on a socket on port 8080 (initially its a non SSL socket). I have a a class called DefaultHttpRequestHandler that holds an instance of HTTPClient that handles all requests needing to be made by the server and a worker thread inside HttpServer handles dispatching all requests sent by browser to port 8080.
My question is the following:
When the CONNECT request comes in and is sent to DefaultHttpRequestHandler it gets passed to the handle(HttpRequest request, HttpResponse response,HttpContext context) method. At this point I peek at the request and if I see it is a CONNECT what next? I was thinking I then establish the SSL socket connection on port 8080 which was before a normal socket? or do I always hold two sockets one as a standard socket and one as ssl than switch to the ssl one. This part is really frustrating me very confused how to code this sucker!
DefaultHttpServer.java - the server
public class DefaultHttpServer {
public static void main(String[] args) throws Exception {
Thread t = new RequestListenerThread(8080);
t.setDaemon(false);
t.start();
//send a request to proxy server for testing
testSendReqFromClient() ;
}
public static void testSendReqFromClient() throws Exception
{
SSLContext sslCtx = SSLContext.getInstance("TLS");
// sslCtx.init(null,new TrustManager[] { new EasyX509TrustManager() }, null);
sslCtx.init(null, new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
System.out.println("getAcceptedIssuers =============");
return null;
}
public void checkClientTrusted(X509Certificate[] certs,
String authType) {
System.out.println("checkClientTrusted =============");
}
public void checkServerTrusted(X509Certificate[] certs,
String authType) {
System.out.println("checkServerTrusted =============");
}
#Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] arg0,
String arg1) throws CertificateException {
// TODO Auto-generated method stub
}
#Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] arg0,
String arg1) throws CertificateException {
// TODO Auto-generated method stub
}
} }, new SecureRandom());
Thread.sleep(5000);
SSLSocketFactory sf = new SSLSocketFactory(sslCtx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Scheme https = new Scheme("https", 443, sf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(https);
Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
schemeRegistry.register(http);
BasicHttpRequest req = new BasicHttpRequest("GET","https://www.yahoo.com");
ThreadSafeClientConnManager tm = new ThreadSafeClientConnManager(schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(tm);
ConnRouteParams.setDefaultProxy(req.getParams(), new HttpHost("localhost",8080,"http"));
httpClient.execute(new RequestWrapper(req));
}
}
DefaultRequestHandler.java - the client that sends requests to server from my proxy server
public class DefaultHttpRequestHandler implements HttpRequestHandler {
private static String sslType = "TLS";
private HttpClient httpClient = null;
private ThreadSafeClientConnManager tm;
public DefaultHttpRequestHandler() {
super();
init();
}
private void init() {
try {
SSLContext sslCtx = SSLContext.getInstance(sslType);
// sslCtx.init(null,new TrustManager[] { new EasyX509TrustManager() }, null);
sslCtx.init(null, new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
System.out.println("getAcceptedIssuers =============");
return null;
}
public void checkClientTrusted(X509Certificate[] certs,
String authType) {
System.out.println("checkClientTrusted =============");
}
public void checkServerTrusted(X509Certificate[] certs,
String authType) {
System.out.println("checkServerTrusted =============");
}
#Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] arg0,
String arg1) throws CertificateException {
// TODO Auto-generated method stub
}
#Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] arg0,
String arg1) throws CertificateException {
// TODO Auto-generated method stub
}
} }, new SecureRandom());
SSLSocketFactory sf = new SSLSocketFactory(sslCtx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Scheme https = new Scheme("https", 443, sf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(https);
Scheme http = new Scheme("http", 80, PlainSocketFactory.getSocketFactory());
schemeRegistry.register(http);
tm = new ThreadSafeClientConnManager(schemeRegistry);
//httpClient = new ContentEncodingHttpClient(tm);
httpClient = new DefaultHttpClient(tm);
httpClient.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
//httpClient.getConnectionManager().getSchemeRegistry() .register(https);
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
public void handle(HttpRequest request, HttpResponse response,
HttpContext context) throws HttpException, IOException {
System.out.println(request);
RequestLine reqLine = request.getRequestLine();
if(reqLine.getMethod().equalsIgnoreCase("CONNECT"))
{
response.setEntity(new BufferedHttpEntity(new StringEntity("HTTP/1.0 200 Connection established\r\nProxy-agent: proxy client\r\n\r\n")));
//do i switch the socket to sslsocketconnection in defaulthttpserver here?
}
else
{
try {
HttpResponse clientResponse = null;
HttpEntity entity = null;
clientResponse = httpClient.execute(new RequestWrapper(request));
entity = clientResponse.getEntity();
if (entity != null) {
response.setEntity(new BufferedHttpEntity(entity));
}
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
}
}
RequestListenerThread - This is run method inside my httpserver that handles dispatching requests
class RequestListenerThread extends Thread {
private static ServerSocket sslServersocket = null;
private static ServerSocket serversocket = null;
static ServerSocketFactory ssocketFactory = null;
private final HttpParams params;
private final HttpService httpService;
Selector selector ;
public RequestListenerThread(int port) throws Exception {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("privateKey2.store"), "whitehatsec123".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "whitehatsec123".toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(), null, null);
ssocketFactory = context.getServerSocketFactory();
//serversocket = ssocketFactory.createServerSocket(port);
serversocket = new ServerSocket(port);
this.params = new SyncBasicHttpParams();
this.params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, true).setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 50000)
.setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE,
8 * 1024)
.setBooleanParameter(
CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
.setParameter(CoreProtocolPNames.ORIGIN_SERVER,
"HttpComponents/1.1");
// Set up the HTTP protocol processor
HttpProcessor httpproc = new ImmutableHttpProcessor(
new HttpResponseInterceptor[] { new ResponseDate(),
new ResponseServer(), new ResponseContent(),
new ResponseConnControl() });
// Set up request handlers
HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
reqistry.register("*", new DefaultHttpRequestHandler());
// Set up the HTTP service
this.httpService = new HttpService(httpproc,
new DefaultConnectionReuseStrategy(),
new DefaultHttpResponseFactory(), reqistry, this.params);
}
public void run()
{
System.out.println("Listening on port "
+ serversocket.getLocalPort());
while (!Thread.interrupted())
{
try
{
// Set up HTTP connection
Socket socket = serversocket.accept();
DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
System.out.println("Incoming connection from "
+ socket.getInetAddress());
conn.bind(socket, this.params);
// Start worker thread
Thread t = new WorkerThread(this.httpService, conn);
t.setDaemon(true);
t.start();
} catch (InterruptedIOException ex) {
break;
} catch (IOException ex) {
System.err
.println("I/O error initialising connection thread: "
+ ex.getMessage());
ex.printStackTrace();
break;
}
}
}
}
class WorkerThread extends Thread {
private final HttpService httpservice;
private final HttpServerConnection conn;
public WorkerThread(final HttpService httpservice,
final HttpServerConnection conn) {
super();
this.httpservice = httpservice;
this.conn = conn;
}
public void run() {
System.out.println("New connection thread");
HttpContext context = new BasicHttpContext(null);
try {
while (!Thread.interrupted() && this.conn.isOpen()) {
this.httpservice.handleRequest(this.conn, context);
}
} catch (ConnectionClosedException ex) {
System.err.println("Client closed connection");
} catch (IOException ex) {
System.err.println("I/O error: " + ex.getMessage());
ex.printStackTrace();
} catch (HttpException ex) {
System.err.println("Unrecoverable HTTP protocol violation: "
+ ex.getMessage());
} finally {
try {
this.conn.shutdown();
} catch (IOException ignore) {
}
}
}
}
A proxy receiving a CONNECT request (and accepting it) doesn't do any SSL/TLS initialisation or processing (if it did, it would be a potential MITM attacker). It merely relays all the traffic between the target HTTPS host and the initial client back and forth.
More detailed in these answers perhaps:
SSL (https) error on my custom proxy server
CONNECT request to a forward HTTP proxy over an SSL connection?
What you would need is to be able to get hold of the underlying socket (or input/output streams) and write every byte you read on the other side.