Re: Querying SSL/TLS capabilities of SMTP servers

2004-07-09 Thread Justin
This one should work better.  The last one had string comparison
problems.


#!/usr/bin/perl

use IO::Select;
use IO::Socket;
use Net::DNS;

$ehloname = mail.senate.gov;
$timeout = 15;
$dlevel = 0;

sub debug {
(my $str, my $mlevel) = @_;
if ($mlevel = $dlevel) { print DEBUG $str; }
}

sub checkmailtls {
my ($domain, $mpri, $mrelay) = @_;
my $proto = smtp;
my $hastls = no-tls;
my @flags;

my $mhost = IO::Socket::INET-new (
Proto = tcp, PeerAddr = $mrelay,
PeerPort = 25, Timeout = 10
);
if (! defined $mhost) {
print $domain $mpri $mrelay noconnect\n;
return;
}

debug(opened connection to $mrelay\n, 1);

$sel = IO::Select-new($mhost);
@readable = $sel-can_read($timeout);   # magic number
if ($#readable == -1) {
print $domain $mpri $mrelay timeout-a\n;
goto OUT;
}
$greeting .= $mhost; # there's only one handle; we know which it is.

debug(greeting: $greeting, 2);
if ($greeting =~ /[\\*]{8}/) {
$proto = smtp;
push (@flags, filtered);
}
if ($greeting =~ /\b(esmtp|postfix|exim|sendmail)\b/i) {
debug(setting esmtp (greet)!\n, 1);
$proto = esmtp;
debug(found esmtp-indicator in greeting\n, 1);
}

print $mhost EHLO $ehloname\r\n;
print $mhost QUIT\r\n;

if (! (@readable = $sel-can_read($timeout))) {
print $domain $mpri $mrelay timeout-b\n;
goto OUT;
}
while ($mhost) { #$sel-can_read(0)) {
chomp;
debug(loop-recv: $_\n, 2);
if (/^5[0-9]{2}/) {
if ($proto =~ /^esmtp/) {
push(@flags, lies);
$proto = smtp;
}
$hastls = no-tls;
last;
}
if (/STARTTLS/) {
if ($proto =~ /^smtp/) {
debug(setting esmtp (stls)!\n, 1);
$proto = esmtp;
push(@flags, nobproto);
}
$hastls = adv-tls;
last;
}
}
print $domain $mpri $mrelay $proto $hastls @flags\n;

# try again just in case the remote host didn't notice the first one
print $mhost QUIT\r\n;
OUT:
close $mhost;
debug(closed connection to $mrelay\n, 1);
}

### begin 
if ($#ARGV = 0) {
for ($i = 0; $i = $#ARGV; $i++) { push (@hostfifo, $ARGV[$i]); }
} else {
while () { chomp; push (@hostfifo, $_); }
}

while ($domain = shift(@hostfifo)) {
my @mx = mx($domain);
if ($#mx == -1) {
checkmailtls($domain, A, $domain);
} else {
foreach $record (@mx) {
my $mrelay = $record-exchange;
my $mpri = $record-preference;
checkmailtls($domain, $mpri, $mrelay);
}
}
}




Re: Querying SSL/TLS capabilities of SMTP servers

2004-07-09 Thread Thomas Shaddack

It fails on hotmail.com; my script has problems there as well (and with 
couple others, the cure seems to be adding delays between the lines sent 
to the server; it makes the program slow, but more reliable).

In my case I added -i 3 to the netcat options. Isn't a panacea, but 
helped in most cases. In the rest, I have to resort to telnet.

Thanks a lot. Seems I have to learn perl. Looks powerful.


On Thu, 8 Jul 2004, Justin wrote:

 On 2004-07-08T17:50:57+0200, Thomas Shaddack wrote:
  I cobbled up together a small bash shell script that does this. It lists 
  the MX records for a domain, and then tries to connect to each of them, 
  issue an EHLO command, disconnect, then list the output of the server, 
 ..
 
 Or, in perl... though I wonder if there's a way to get capabilities with
 Net::SMTP.  Might make this cleaner.
 
 
 #!/usr/bin/perl
 
 use IO::Socket;
 use Net::DNS;
 
 for ($i = 0; $i = $#ARGV; $i++) {
 my @mx = mx($ARGV[$i]);
 foreach $record (@mx) {
   my $hastls = 0;
   my $mhost = IO::Socket::INET-new (
   Proto = tcp,
   PeerAddr = $record-exchange,
   PeerPort = 25,
   Timeout = 10
   );
   print $mhost EHLO I-love-my-country.whitehouse.gov\n;
   print $mhost QUIT\n;
   while ($mhost) {
   if (/STARTTLS/) {
   $hastls = 1;
   last;
   }
   }
   print $ARGV[$i]  . $record-preference .   . $record-exchange;
   print $hastls ?  adv-tls\n :  no-tls\n;
   close $mhost;
 }
 }
 



Querying SSL/TLS capabilities of SMTP servers

2004-07-08 Thread Thomas Shaddack

I cobbled up together a small bash shell script that does this. It lists 
the MX records for a domain, and then tries to connect to each of them, 
issue an EHLO command, disconnect, then list the output of the server, 
alerting if the server supports STARTTLS. It should be easy to further 
query the server for the certificate, using some external utility called
from the script.

It requires netcat and a pair of djbdns utilities. It's a bit crude, but 
could be helpful.

Script follows:
- cut here --

#!/bin/bash
## Query the capabilities of mailservers for a domain.
##
## Requirements: nc (netcat), dnsmx and dnsip (from djbdns package)

TMP=`mktemp /tmp/queryehlo.XX`
EHLOSTRING=capquery
TIMEOUT=15

function help()
{
cat  EOF
queryehlo - query the capabilities of mailservers for a domain
Usage: queryehlo domain
EOF
exit 0
}

function checkresources()
{
ERR=;
if [ ! `which nc 2/dev/null` ]; then
echo ERROR: nc (netcat) not available in \$PATH.
echo netcat should be part of standard distro, or can be acquired from eg.
echohttp://www.atstake.com/research/tools/network_utilities/;.
echo
ERR=1
fi
if [ ! `which dnsmx 2/dev/null` ]; then
echo ERROR: dnsmx (from djbdns) not available in \$PATH.
echo djbdns can be downloaded from eg. http://cr.yp.to/djbdns.html;
echo
ERR=1
fi
if [ $ERR == 1 ]; then exit; fi
}

function queryrelay()
{
if [ ! $x ]; then return; fi
echo Querying mail relay $1, `dnsip $x`
cat  EOF | nc -w $TIMEOUT $1 25  $TMP
EHLO $EHLOSTRING
QUIT
EOF
if [ `cat $TMP|grep STARTTLS` ]; then
 echo *** RELAY ADVERTISES SMTP/TLS SUPPORT
 # insert eventual further interrogations here
fi
echo
cat $TMP
echo
echo
rm $TMP
}


checkresources
if [ $1 ==  ];   then help; fi
if [ $1 == -h ]; then help; fi
if [ $1 == --help ]; then help; fi


dnsmx $1 | sort -n |
while true; do
  read x1 x; if [ $? == 1 ]; then break; fi
  queryrelay $x;
done



Re: Querying SSL/TLS capabilities of SMTP servers

2004-07-08 Thread Justin
On 2004-07-08T17:50:57+0200, Thomas Shaddack wrote:
 I cobbled up together a small bash shell script that does this. It lists 
 the MX records for a domain, and then tries to connect to each of them, 
 issue an EHLO command, disconnect, then list the output of the server, 
..

Or, in perl... though I wonder if there's a way to get capabilities with
Net::SMTP.  Might make this cleaner.


#!/usr/bin/perl

use IO::Socket;
use Net::DNS;

for ($i = 0; $i = $#ARGV; $i++) {
my @mx = mx($ARGV[$i]);
foreach $record (@mx) {
my $hastls = 0;
my $mhost = IO::Socket::INET-new (
Proto = tcp,
PeerAddr = $record-exchange,
PeerPort = 25,
Timeout = 10
);
print $mhost EHLO I-love-my-country.whitehouse.gov\n;
print $mhost QUIT\n;
while ($mhost) {
if (/STARTTLS/) {
$hastls = 1;
last;
}
}
print $ARGV[$i]  . $record-preference .   . $record-exchange;
print $hastls ?  adv-tls\n :  no-tls\n;
close $mhost;
}
}