#!/usr/bin/env perl

# NAME:
#	validate_host - validate that a host is ok to add to DNS
#
# SYNOPSIS:
#	validate_host "fqdn" "ip"
#
# DESCRIPTION:
#	This script attempts to verify whether the host at address
#	"ip" really believes its name is "fqdn".  One of the main
#	goals is to check whether the SMTP daemon such as sendmail(8)
#	will recognize mail addressed to "fqdn" as being for itself.
#	For many commercial *nix that simple criteria is not true
#	``out of the box'' and a single machine can present Postmaster
#	with a full /var partition over a weekend.
#	
#	Options:
#
#	-d	Debug. Show the output from each check.
#
#	-v	Verbose.  Show check results.
#
#	-I "keys"
#		Insist that the checks listed in "keys" succeed.
#		For instance -I smtp would insist that SMTP be
#		available for checking.
#
# BUGS:
#	Does not (yet) handle IPv6.
#
# AUTHOR:
#	Simon J. Gerraty <sjg@crufty.net>

$RCSid='$Id: validate_host,v 1.6 2022/10/10 00:39:06 sjg Exp $'; #'emacs

# RCSid:
#	$Id: validate_host,v 1.6 2022/10/10 00:39:06 sjg Exp $
#
#	@(#) Copyright (c) 1997-2022 Simon J. Gerraty.
#
#	This file is provided in the hope that it will
#	be of use.  There is absolutely NO WARRANTY.
#	Permission to copy, redistribute or otherwise
#	use this file is hereby granted provided that 
#	the above copyright notice and this notice are
#	left intact. 
#      
#	Please send copies of changes and bug-fixes to:
#	sjg@crufty.net
#

if ($0 =~ m,^(.*)/([^/]+)$,) {
  $Mydir = $1;
  $Myname = $2;
} else {
  $Mydir = '.';
  $Myname = $0;
}

require "$Mydir/funcs.pl";
require 'getopts.pl';
require 'tcp.pl';

&Getopts('dvI:');
&main;
exit 0;

sub main {
  ($fqdn,$ip) = @ARGV;

  $ok = 1;

  $fqdn =~ y/A-Z/a-z/;

  if ($fqdn !~ m/^[a-z][a-z0-9._-]+(\.[a-z][a-z0-9._-]+)+$/o) {
    &err(1, "invalid FQDN: $fqdn");
  }
  if ($ip !~ m/^\d+(\.\d+){3}$/o) {
    &err(1, "invalid IP: $ip");
  }
  &show($opt_v, "$Myname: checking $fqdn/$ip\n");
  &check_smtp($fqdn,$ip);
  
  exit(1) if (!$ok);
}

sub check_smtp {
  local($fqdn,$ip) = @_;
  local($line,$him,$vers,$sts);
  
  if (&tcp_open($ip, 25)) {
    $line = &tcp_getline(0);
    &show($opt_d, $line);
    if ($line =~ m/^220[\s-]\s*([^\s]+)\s+(.+)/i) {
      $him = $1;
      $vers = $2;
    }
    &tcp_print("quit\r\n");
    &tcp_close;
    if ($him !~ m/^$fqdn$/i) {
      &err(2, "Host at $ip calls itself $him != $fqdn");
    }
    &show($opt_v, "SMTP daemon: OK\n");
    $sts = 1;
  } else {
    if (",$opt_I," =~ m/smtp/oi) {
      &err(2, "SMTP daemon: unavailable");
    }
    &warn("SMTP daemon: unavailable");
    $sts = 0;			# who knows
  }
  $sts;
}
