1/* HELO consistency checker
2   Copyright (C) 2006, 2007, 2008, 2009, 2010 Jan Rafaj
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 3, or (at your option)
7   any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17module 'heloarg_test'.
18require 'is_ip'
19require 'dns'
20
21const HELO_SUCCESS      0
22const HELO_MYIP         1  #  ARG is our IP address.
23const HELO_IPNOMATCH    2  #  ARG is an IP, but it does not match the remote
24                           #  party IP address.
25const HELO_ARGNORESOLVE 3  #  ARG is an IP, but it does not resolve.
26const HELO_ARGNOIP      4  #  ARG is in square brackets, but it is not an
27                           #  IP address.
28const HELO_ARGINVALID   5  #  ARG is not an IP address and does not resolve
29                           #  to one.
30const HELO_MYSERVERIP   6  #  ARG resolves to our server IP.
31const HELO_IPMISMATCH   7  #  ARG does not resolve to the remote client
32                           #  IP address
33
34#pragma regex push +extended
35
36static func __domainof(string arg)
37  returns string
38do
39  if arg matches '[^.]+\.(.*)'
40    return \1
41  else
42    return arg
43  fi
44done
45
46func heloarg_test(string arg, string remote_ip, string local_ip)
47  returns number
48do
49  string helo_arg
50  number heloarg_must_be_ip
51
52  set helo_arg arg
53  set heloarg_must_be_ip 0
54
55  if arg matches '^\[(.*)\]$'
56    set helo_arg "\1"
57    set heloarg_must_be_ip 1
58  fi
59
60  if is_ip (helo_arg)
61    if (helo_arg = local_ip and local_ip != remote_ip)
62      # `HELO' arg may not be this server's IP
63      return HELO_MYIP
64    elif helo_arg != remote_ip
65      # `HELO' arg does not match remote server's IP
66      return HELO_IPNOMATCH
67    elif (heloarg_must_be_ip = 0
68      and hostname(helo_arg) = helo_arg)
69      # `HELO' arg not in brackets and doesnt resolve
70      return HELO_ARGNORESOLVE
71    else
72      return HELO_SUCCESS
73    fi
74  elif heloarg_must_be_ip = 1
75    # `HELO' arg in brackets is not an IP
76    return HELO_ARGNOIP
77  elif ismx(helo_arg, remote_ip)
78       or __domainof(hostname(remote_ip)) = helo_arg
79    return HELO_SUCCESS
80  elif (resolve(helo_arg) = "0")
81    # `HELO' arg does not resolve to an IP
82    return HELO_ARGINVALID
83  elif (helo_arg = hostname(local_ip)
84        and local_ip != remote_ip)
85    # `HELO' arg may not be this server's hostname
86    return HELO_MYSERVERIP
87  elif (resolve(helo_arg) != remote_ip
88        and hostname(remote_ip) != helo_arg)
89    # `HELO' arg does not resolve to remote server's IP nor to its
90    # domain
91    return HELO_IPMISMATCH
92  else
93    return HELO_SUCCESS
94  fi
95done
96
97#pragma regex pop
98
99