Android: Check if SMTP server is up and running - java

I'm developing a small app for Android, which monitors the availability of servers and their services on my network.
So far I have implemented ping and HTTP(S) checks. I'd also like to monitor some mail servers. I know about libs like javamail-android, but I don't need to really send a mail. I'm looking for a simple solution (ideally without an additional lib) to connect to my MTAs and to check whether they respond correctly.
What is the best way to check the availability of mail servers on Android?

Open a socket to port 25 (smtp, no ssl) and see if you get a 220 prompt like this conversation (on a command shell):
$ telnet lilly 25
Trying lilly...
Connected to lilly.
Escape character is '^]'.
220 lilly ESMTP Postfix
noop
250 2.0.0 Ok
quit
221 2.0.0 Bye
Connection closed by foreign host.
You may also check how long the individual steps (connect until 220 , noop , quit) are taking and react on slow response times.

Related

Very long connection time to some SMTP servers

I'm currently trying to write a simple Spring email verification microservice. I'm using Apache SMTPClient API to connect to an SMTP server and verify the email address existence (connect -> login -> setSender -> setRecipient -> logout -> disconnect). When connecting to most big email providers (gmail, yahoo, etc.) there are no issues, but for others there's a bizarre 5-20s delay when connecting. For example, with protonmail I sometimes wait for what looks like a fixed 5s delay, sometimes I connect normally after ~150ms. With some other, smaller services it's a fixed delay every time I try to connect.
Since I'm doing my best to reduce the time required for such verification, this is a pretty massive issue, given it generally takes <2s when no such issues are encountered.
I was trying to find a reason for this delay, and I encountered 2 potential explanations:
tarpitting - while the delay it causes fits the issue, I am sending a singular connection request, while the mechanism is supposed to prevent spam/bulk emails,
being blacklisted - that also could be the cause, but in general that information is put into a (negative) reply to one of the SMTP commands I send.
I would appreciate any suggestions on what could be causing the delay and how to avoid it (if it's even possible).
I made a couple of SMTP connections to mail.protonmail.ch, and it is definitely doing some things that are unusual. I think they're implementing a variation of tarpitting.
For instance, sometimes after the connecting, mail.protonmail.ch immediately responds with an SMTP banner (that looks very much like a 220 response):
220-mailin008.protonmail.ch ESMTP Postfix
then, after a seemingly random delay, an actual 220 response:
220 mailin008.protonmail.ch ESMTP Postfix
Other times, after a seemingly random delay, it responds with a 220 response without sending a banner first:
220 mailin025.protonmail.ch ESMTP Postfix
Many client SMTP programs that are used to send spam do not implement SMTP properly. A shoddy program might 'get fooled' by the unusual way that mail.protonmail.ch responds, and send EHLO before it should. Then, mail.protonmail.ch can drop the connection, on the assumption that the client is not a 'real' SMTP MTA. A real MTA, however, would wait for the 'real' 220 response, before sending EHLO.
In this case I was able to solve the problem by simply using sockets - if all you need to do is verify the existnace of an email by sending RCPT TO command, this is the best way to do it. I personally could not find any Java APIs that both avoided the problem I had and allowed for easy sending of SMTP commands.

Change FTPClient port in order to send a command

I'm connecting and logging in to a server on port 21. What I want to do next is to send a command string, however I have been instructed to send this command through port 50.
How do I change the port to 50 whilst connected on port 21?
I have tried connecting to the server on port 50 intially, and the onnection is refused. I have tried sending the command whilst connected on port 21 using ftpClient.sendCommand and I get a reply code 500 Unknown command
You should go back to the one who told you this requirement and ask about specifics because - to be blunt - the whole thing doesn't make real sense:
FTP works with two connections, control and data. The control channel is the one you open on port 21 and there is only this one, you can't change it back to another port afterwards. So "send a command on port 50 but connect on port 21" is not a thing with FTP.
A data connection on a port < 1024 is not usual, so it's hard to believe that the one with that requirement meant that, either. For one that would require active FTP connections that everybody nowadays tries to avoid because they are a pain to configure. Opening a listener on a port < 1024 would require root-privileges on Unix-systems which is unlikely you will get just for doing FTP-transfers.
You also said that the command you actually try to send to the server is confidential. I find that hard to believe but if it really is that would mean that we're talking about a non-standard FTP-server working with its own set of FTP-commands, i.e. regular FTP-clients might not be able to do what you need at all.
So go back to the one who gave you this requirement and ask, what the heck he's talking about, ideally with an example how to do it, let's say using the FTP-client that comes with the Windows Command-Shell.
Typically when you connect, the server controls the port assignment. So when you issue a pasv command (passive mode), it typically sends you back an IP / Port to connect to for the data connection. I'm not aware of anything that will allow you to do what you want. The server can restrict the port range for these types of things. Here's a nice explanation that goes over this.
Active vs Passive FTP
You may be able to send a PORT command to connect to port 50 specifically, but it's really unusual to do something like this.
** Edit **
There's two things you can try, I've never used either, so YMMV.
In Active mode, the client gives the server a port to connect to.
Try setting the default port to 50 and turn on Active mode. Hopefully this is on your internal networks, because this would never get past security for a firewall request.
client.setDefaultPort(50);
client.enterLocalActiveMode(); // Apache FTPClient
For Passive mode, you can try to set the active port range.
client.setActivePortRange(50, 50)
client.enterLocalPassiveMode();
You should ask what mode the server is expecting.

Suddenly not able to send email by amazon SES - unable to connect smtp host

I am using Amazon SES from almost 4 months with same code, same port number(25) everything same. But from past 1 week I am not able to send email - while sending this error comes:
The email was not sent.
Error message: Could not connect to SMTP host: email-smtp.us-east-1.amazonaws.com, port: 25
I am using the same code for sending email that amazon suggests to use from link (http://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-smtp-java.html)
We are working on a website project and using it inside it. Its not a problem with me alone, my team members of 4 working under same internet gateway, all of them are not able to send email from 1 week from their localhost.
But when we deploy the same code on Amazon ec2, top-level domain say sample.com then it starts working but when we deploy the same code under a sub-domain say beta.sample.com then again same error starts coming.
Does anyone have any idea about this?
Passing outgoing SMTP (25) port connections bloc
Try sending your email via email-smtp.us-east-1.amazonaws.com:587.
Outgoing connections to SMTP (25) port may be blocked by a firewall to stop outgoing spam.
Can you telnet any of the two ports? Do you get SMTP greeting messages?
telnet email-smtp.us-east-1.amazonaws.com 25
telnet email-smtp.us-east-1.amazonaws.com 587
https://en.wikipedia.org/wiki/Mail_submission_agent
Many Internet service providers and enterprise or institutional networks restrict the ability to connect to remote MTAs on port 25. The accessibility of a Mail Submission Agent on port 587[1] enables nomadic users to continue to send mail via their preferred submission servers even from within others' network

Problem in java ftp code

i'm getting error in java ftp code.
SimpleFTP could not request passive mode.
i copied this code from net. but it's not working
sendLine("PASV");
String response = readLine();
System.out.println(response);
System.out.println(response);
if (!response.startsWith("227")) {
throw new IOException("SimpleFTP could not request passive mode: " + response);
}
It looks like you're able to connect to the ftp server - otherwise you had received IOExceptions or NullPointerExceptions much earlier.
Problem is, that you can't establish a passive mode connection. If the server is a standard product, then I assume, it would respond correctly with a 227 message.
If I had to debug, I'd start with the following:
use a normal shell based ftp client and try to enter passive mode manually. Maybe you get a different response, maybe the server just sends one empty line before the real message
use a network sniffer like wireshark to monitor traffic.
try to connect to a different ftp server
check firewall settings - those may block passive mode because it uses different ports
start a command line ftp client with no arguments. Issue the debug command to enable display of protocol messages and the passive command to set passive mode. (Note: the windows command line ftp does not support passive mode!) Use the open command to connect to a host. You'll be prompted if you need to log in. Issue the ls command to get a directory listing.
Through all of this, the client will display the messages sent and received. There is probably some message variant that your code is not handling. For example, the SimpleFTP code here does not handle multi-line responses. See RFC-959 ยง 4.2: FTP Responses.
One embedded system I work with responds to a successful login with:
220-Setting memory limit to 1024+1024kbytes
220-Local time is now 10:33 and the load is 1.36.
220 You will be disconnected after 1800 seconds of inactivity.
The SimpleFTP code fails because it's expecting a single line beginning with "220 ".
Additionally, despite the FTP protocol being quite old, you will encounter quite a few non-conforming implementations.
If you need to do anything more complex than 'put file' or 'get file', take a look at edtFTPj/Free.

How to check status of an SMTP server from Java?

In a Java program, what is the best way of determining if an SMTP server is ready to accept and send an email?
You can use JavaMail API and try to send an email.
If you don't want to actually send the email, you can open a TCP socket to port number 25 of your mail server and send the following commands:
HELO yourdomain.com
MAIL FROM: youremail#yourdomain.com
RCPT TO: recipient#recipientdomain.com
Make sure you check all server responses after each command issued. If you don't see any errors until that point, then probably you will be able to send emails with that SMTP server.
And, as Jordan Stewart kindly appointed:
You'll also want to make sure that the
HELO domain has a complementary A /
PTR dns record pair, with the IP
address the domain is mapped to being
the IP address you're connecting from.
The domain also needs at least one MX
record. I.e. if the server you're
connecting from is 123.45.67.89 then
you'd need an A record mapping
yourdomain.com to 123.45.67.89 and a
PTR ("reverse DNS") record mapping
123.45.67.89 back to yourdomain.com. If any of these conditions aren't met
you'll run into problems with some
mail servers as checks for these
things are anti-spam measures.

Categories