Connect to FTPS through proxy - java

The initial problem we encountered was that a regular FTPs download started failing due to an untrusted server certificate. This prompted us to wonder whether the certificate had been updated without the counterparty notifying us so we wanted to download the current certificate and compare it to the one we have in our keystore.
This seems to be a trickier problem than we had anticipated. The usual suspects (firefox, filezilla, ...) did not seem up to the task of connecting to an FTPs server through an FTP proxy so out of curiosity I started playing around with a more low level java approach. I can not for the life of me get it to work though.
First (overly simplistic) java attempt:
// create proxy connection
SocketFactory plainFactory = SocketFactory.getDefault();
Socket proxy = plainFactory.createSocket(proxyServer, proxyPort);
// create ssl connection on top of it?
SSLSocketFactory sslFactory = getSocketFactory();
SSLSocket socket = (SSLSocket) sslFactory.createSocket(proxy, server, port, true);
This approach obviously does not work.
Next I started playing around with ftp4j (http://www.sauronsoftware.it/projects/ftp4j/) it seems to have a clean and accessible codebase:
FTPClient client = new FTPClient();
client.setConnector(new FTPProxyConnector(proxyHost, proxyPort));
client.getConnector().setConnectionTimeout(0);
client.getConnector().setReadTimeout(0);
client.setSSLSocketFactory(getSocketFactory());
// also tried SECURITY_FTPS
client.setSecurity(FTPClient.SECURITY_FTPES);
client.connect(server, port);
This outputs:
REPLY: 220 Blue Coat FTP Service
SEND: USER anonymous
REPLY: 530-User Access denied.
REPLY: 530-
REPLY: 530-Usage: USER username#hostname
REPLY: 331 PASS userpassword
Exception in thread "main" java.io.IOException: Invalid proxy response
The proxy server has optional authentication and on our development servers we generally use "user#host" without proxy authentication. As such I assume the username, hostname and password are those of the remote server?
So I tried adding the remote parameters, this does not work:
REPLY: 220 Blue Coat FTP Service
SEND: USER test#ftps.example.com
Exception in thread "main" java.io.IOException: FTPConnection closed
Adding the proxy user to match the bluecoat format does not seem to work either:
USER %u#%h %s
PASS %p
ACCT %w
Any help with either of these two problems would be most welcome:
how to retrieve the server certificate from an ftps server through an ftp proxy
how to connect to an ftps server through an ftp proxy in java

You might want to try Apache Net commons libs.
Here is a similar thread that uses that Net Commons library
Net commons also has a fully functional FTP Client Example so you can test with something you know works.

Related

can't connect to mqtt broker via ssl

I have a raspberry running a mqtt broker and a java backend. I can't establish a connection from backend to broker since I've implemented ssl. I can connect the backend to the broker on raspberry from my IDE running on my MacBook like:
client = new MqttAsyncClient(
"ssl://my-domain.com:1883", "backend");
if the backend is on the raspberry I tried:
client = new MqttAsyncClient(
"ssl://localhost:1883", "backend");
client = new MqttAsyncClient(
"ssl://127.0.0.1:1883", "backend");
No success. I´ve never used a ssl connection in this context. did I oversee something?
Error:
Exception in thread "main" No connection to client (32104)
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:31)
at org.eclipse.paho.client.mqttv3.internal.ClientComms.sendNoWait(ClientComms.java:143)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.subscribe(MqttAsyncClient.java:721)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.subscribe(MqttAsyncClient.java:681)
at com.cdh.Service.mqttManager.subscribe(mqttManager.java:243)
at com.cdh.main.main(main.java:14)
EDIT:
I changed the port to 8883. It works if I run the backend on an other device but not if the broker and the backend are on the raspberry. I also tried to use the domain name from my cert.
The hostname you use to connect needs to match the CN or SAN entries in the certificate presented by the broker or else it will fail validation.
Unless you included 127.0.0.1 or localhost in the certificate the the client will reject the connection because the certificate doesn't validate for that address.
p.s. you should probably use a different port for MQTT of TLS rather than 1883 as that is the standard port for MQTT without TLS.

Connect to POP3S server in linux

I want to connect to a POP3S (SSL security) server in linux(the pop3 server is dovecot). I tried with normal sockets but it doesn't work(i get no reply from server) new Socket("localhost", 995). I found this command searching on the internet: "openssl s_client -connect localhost:995" and it works from terminal (+OK Dovecot ready.). Any solutions? (with or without java.mail library) i prefer without java.mail, but its also good with it. Thanks!
You're getting no reply from the server when creating your own Socket because you're not creating an SSLSocket.
Try JavaMail, it should work fine. Start at the JavaMail FAQ.

FTPSClient failing to connect

I have been trying to change a working FTP connection FTPClient to a FTPSClient provided by apache. The only changes made were changing the class and indicating what port the application is going to connect.
The server connects to another server within the same network. For external servers, a proxy is required.
I already tried setting up the constructor to true, it shows the following message:
Unrecognized SSL message, plaintext connection?
final FTPSClient ftp = new FTPSClient( true );
//same results
//final FTPSClient ftp = new FTPSClient("SSL", true );
//final FTPSClient ftp = new FTPSClient("TLS", true );
ftp.setDefaultPort(22);
When I set it up to false, the connection hangs up for a lot of time. It shows the following message:
Could not parse response code. Server Reply: SSH-2.0-OpenSSH_4.1
and tomcat shows the following page:
Proxy Error
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request POST /myapppath/APage.htm.
Reason: Error reading from remote server
final FTPSClient ftp = new FTPSClient( false );
ftp.setDefaultPort(22);
I tried connecting manually with WinSCP via SFTP and the connection is successful.
FTPS (FTP over SSL/TLS) is not the same as SFTP (SSH file transfer); these are two completely different protocols. The reason you are getting the error Unrecognized SSL message, plaintext connection? is because you are not connecting to a FTPS server.
You can read more about the difference here. If you want to make an SFTP connection rather than an FTPS connection, I would recommend using the JSch library.

Missing ServerHelloDone while SSL Hanshake

I try to connect to a wss (Secure Websocket) server with a java applet but the ssl handshake fails without any helpfull log entrys.
If I connect to wss://echo.websocket.org the handshake works fine, so I think it's not a general java code error.
If I try to connect to my own server, the HelloDone bit is sent (verified by wireshark) but the connections ends in a hang-up and it's not in the log. Normally there should be the following message in the log: "*** ServerHelloDone"
See my java console log of "javax.net.debug=sll"
http://pastebin.com/ZuvKww4J
It is not truncated, it simply ends there.
After a couple of seconds the tcp connection timeout message is added to the log.
I use the following example of java code:
https://github.com/TooTallNate/Java-WebSocket/blob/master/src/main/example/SSLClientExample.java
But instead of keystore I use:
sslContext.init( null, null, null );
For the server I have two different test systems:
At port 443 a ha-proxy
at port 8443 a stunnel.
I tried to isolate the error with different methods. First I forced with stunnel the same cipher as echo.websocket.org "SSL_RSA_WITH_RC4_128_SHA" but no success.
Second I checked if the ssl certificate itself is still valid. But as web browser and normal https connection by my java applet, are accepted from the server (Same server. ha-proxy orstunnel) everything is working at that point to.
Problem was solved by maintainer of Java-WebSocket.
Big thans

Question on ssl handshake and behavior in java

I am using https to connect to an https server.
Specifically I am using apache httpclient and I configure the ssl context to use my keystore and truststore.
The https server I am using is IIS7 and is configured to require client authentication.
I think I have set it up properly.
Anyway, if I configure the httpClent's ssl context with a keystore (i.e. with client certificates) valid for IIS then there is no problem connecting.
Now my problem is the following:
If I do not configure the ssl context with any client certificate to send to IIS, there is no connection with the server. What makes me think though, is the fact that I was expecting to see some java exception in the code as a result of a hanshake failure alert.
Monitoring what is happening with wireshark, I could not see a certificate request from IIS to my application, but I noticed that after ServerHelloDone everything was encrypted.
I did not expect that. I think the handshake is usually in cleartext.
I used private key to decrypt traces and i saw a certificate request from IIS but after many starting and opening of new connections.
My app send back as a response a certificate of length 0 and IIS replies with a TLSv1 Finished.
After that the packets stop (i.e. seems that the communication ends).
I was expecting a handshake alert.
My question is, is this how it is supposed to work or at least how IIS works?
Or if I do not see the alert something is wrong with my use case?
Thanks
It sounds like IIS is only requiring client certificates for certain URLs (ie, for example.com/foo, but not example.com/bar).
In the initial handshake, it does not know which url you are requesting, so it does not require a certificate. When it sees that you are requesting a restricted resource (/foo), it then rehandshakes, requiring a certificate.
However, I would still expect a handshake_failure to occur.
As I was saying in an answer to this question, as far as I remember, IIS uses re-negotiation to get the client certificate. You should be able to change this behaviour using netsh and clientcertnegotiate=enable (depending on the version of IIS you're using).
You might also be interest in this similar question.
Failing to supply a certificate in response to a CertificateRequest isn't an SSL protocol error, so there is no handshake_error. 'Requiring' instead of just 'needing' client certificates is added-in by SSL libraries, and all they can do if you don't send one is just close the connection.

Categories

Resources