We're attempting to access one of our FTPS servers using the same credentials as we would in our standard FTP client. However, when using the Java class FTPSClient
we are getting the error message:
530 User cannot log in.
And nothing else. So far we have the following code (Simplified for the example):
public final class FTPSExample {
public static final void main(String[] args) {
boolean error = false;
String server, username, password;
String protocol = "TLS"; // SSL/TLS
FTPSClient ftps;
server = "A_SERVER";
username = /*server + "|" + */"A_USER";
password = "A_PASS";
ftps = new FTPSClient(protocol);
ftps.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());
ftps.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
try {
int reply;
ftps.connect(server, 21);
System.out.println("Connected to " + server + ".");
reply = ftps.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftps.disconnect();
System.err.println("FTP server refused connection.");
} else {
ftps.sendCommand("HOST", server);
if (!ftps.login(username, password)) {
String[] welcomeMessage = ftps.getReplyStrings();
for(String s : welcomeMessage) {
System.out.println(s);
}
ftps.logout();
error = true;
}
}
}
catch (IOException e) {
if (ftps.isConnected()) {
try {
ftps.disconnect();
}
catch (IOException f) {
// do nothing
}
}
System.err.println("Could not connect to server.");
e.printStackTrace();
System.exit(1);
}
System.exit(error ? 1 : 0);
}
}
The above code gives us the following log messages:
220 Microsoft FTP Service
AUTH TLS
234 AUTH command ok. Expecting TLS Negotiation.
Connected to A_SERVER.
HOST A_SERVER
220 Host accepted.
USER A_USER
331 Password required for A_USER.
PASS A_PASS
530 User cannot log in.
530 User cannot log in.
QUIT
221 Goodbye.
Meanwhile if we do the same in an FTP client (E.g. FTP Voyager) we get:
STATUS:> Connecting to "A_SERVER" on port 21.
220 Microsoft FTP Service
COMMAND:> AUTH TLS
234 AUTH command ok. Expecting TLS Negotiation.
STATUS:> Negotiating SSL connection with server.
STATUS:> SSL connection established. All transactions are now secure.
STATUS:> Connected. Logging into the server
COMMAND:> HOST A_SERVER
220 Host accepted.
COMMAND:> USER A_USER
331 Password required for A_USER.
COMMAND:> PASS *********************
230 User logged in.
STATUS:> Login successful
Some of the trouble shooting we've tried:
- Changing the
protocol
from TLS to SSL, both suffer the same problem - Adding the command
ftps.sendCommand("HOST", server);
. We saw that the FTP client was running this command before logging in, without that line we instead got the error:530 Valid hostname is expected.
- Using
FTPClient
, which results in the expected534 Policy requires SSL.
- Removing the
ftps.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());
which results in the same error - Instead of setting HOST, using the user as:
username = "A_SERVER|A_USER";
. Same error message
The server does come with a certificate, which for debugging purposes we are happy to ignore. This is why we set the TrustManager
as accepting all. Is there another setting we should be aware of?
We have no proxy set, and we're not getting a helpful error message. Googling for 530 User cannot log in.
does not provide anything useful so far. Does anyone have any suggestions?
EDIT
I manage to get it working using a different package called FTP4J
, however if anyone could shed any light on why the FTPSClient
isn't working, that would be fantastic. Here's the working code:
public final class FTPSExample {
public static final void main(String[] args) {
boolean error = false;
String server, username, password;
FTPClient ftps;
server = "A_SERVER";
username = server + "|" + "A_USER";
password = "A_PASS";
ftps = new FTPClient();
ftps.setSecurity(FTPClient.SECURITY_FTPES);
ftps.addCommunicationListener(new FTPCommunicationListener() {
@Override
public void sent(String s) {
System.out.println(s);
}
@Override
public void received(String s) {
System.out.println(s);
}
});
try {
ftps.connect(server);
System.out.println("Connected to " + server + ".");
if (!ftps.isConnected()) {
ftps.disconnect(false);
System.err.println("FTP server refused connection.");
} else {
//ftps.sendSiteCommand("HOST " + server);
ftps.login(username, password);
if (!ftps.isAuthenticated()) {
error = true;
} else {
System.out.println("Connected!");
}
ftps.logout();
}
}
catch (Exception e) {
if (ftps.isConnected()) {
try {
ftps.disconnect(false);
}
catch (Exception f) {
// do nothing
}
}
System.err.println("Could not connect to server.");
e.printStackTrace();
System.exit(1);
}
System.exit(error ? 1 : 0);
}
}
And the resulting data:
220 Microsoft FTP Service
Connected to A_SERVER.
AUTH TLS
234 AUTH command ok. Expecting TLS Negotiation.
USER A_SERVER|A_USER
331 Password required for A_SERVER|A_USER.
PASS A_PASS
230 User logged in.
Best Answer
I remember that when I have tried to change my code from FTP to FTPS I had the same error and I have solved it using this code: