chiark / gitweb /
modrelays-probe: wip
[modbot-ulm.git] / probes / modrelays-probe
1 #!/bin/bash
2
3 set -e
4
5 id=$(date +%s)_$$
6
7 fail () {
8         printf >&2 "%s\n" "modrelays-probe: error: $1"
9         exit 16
10 }
11
12 record-probing () {
13         # implicitly uses newsgroup, id, domain
14         # prints working dir filename
15         local probeid=$1
16
17         probeid=${probeid//[^=-.,_0-9A-Za-z]/%/}
18         case $probeid in
19         .*|*/*) fail "yikes, sanitisation bug!" ;;
20         esac
21
22         local newtd="monitoring/modrelays.probes/$probeid"
23         mkdir -p $newtd
24         printf "%s" $newtd
25 }
26
27 record-outcome () {
28         local probeid=$1
29         local outcome=$2
30         local message=$3
31         local td=`record-probing "$probeid"`
32         printf "%s\n" >"$td"/"$outcome"
33 }
34
35 record-success () { record-outcome "$1" ok '' }
36 record-tempfail () { record-outcome "$1" tempfail "$2" }
37 record-permfail () { record-outcome "$1" permfail "$2" }
38
39 probe-addr () {
40         local mx=$1
41         local addr=$2
42
43         local td=`record-probing "mx=$mx,addr=$addr"`
44
45         set +e
46         swaks   --to "${GROUP//./-/}@$domain" \
47                 --server $addr \
48                 --tls-optional-strict \
49                 --header 'Subject: test modrelays probe test' \
50                 --header \
51         "X-WebSTUMP-Relay-Probe: $GROUP $id $domain $mx $addr" \
52                 -n >$td/swaks.log 2>$td/swaks.err
53         rc=$?
54         set -e
55
56         case $rc in
57         0) return ;; # record-success done by receiver
58         esac
59         local permfail=''
60
61         local rhs
62         local prefix
63         local expect_no_5xx='initial connection'
64         while read <$td/swaks.log prefix rhs; do
65                 case "$prefix" in
66                 '<'*)
67                         case "$rhs" in
68                         5*)
69                                 if [ "x$expect_no_5xx" != x ] && \
70                                    [ "x$permfail" = x ]; then
71                                         permfail="$rhs ($expect_no_5xx)" ;;
72                                 fi
73                                 ;;
74                         esac
75                         ;;
76                 *'>')
77                         case "$rhs" in
78                         EHLO*|STARTTLS*) expect_no_5xx='' ;;
79                         *) expect_no_5xx="after $rhs" ;;
80                         esac
81                         ;;
82                 *)
83         done
84
85         if [ "x$permfail" = x ]; then
86                 record-tempfail "mx=$mx,addr=$addr" "see swaks.log / swaks.err"
87         else
88                 record-permfail "mx=$mx,addr=$addr" "$permfail"
89         fi
90 }
91
92 probe-domain () {
93         local domain=$1
94         local td=`record-probing dns`
95         
96         set +e
97         adnshost -Fi -Tn +Do +Dt -t mx $domain >$td/dns
98         rc=$?
99         set -e
100
101         case $rc in
102         0)
103                 # have a list of MX's
104                 exec <$td/dns
105                 local pref
106                 local mx
107                 local statustype
108                 local rhs
109                 while read pref mx statustype rhs; do
110                         case $statustype in
111                         0)
112                                 # have a list of relays
113                                 case $rhs in
114                                 *" ( "*")") ;;
115                                 *)
116                                         record-permfail "mx=$mx" \
117                                                 "dns format $rhs"
118                                         continue
119                                 ;;
120                                 rhs=${rhs%%* (}
121                                 rhs=${rhs# )}
122                                 local addr
123                                 for addr in $rhs; do
124                                         case $addr in
125                                         INET|INET6) continue ;;
126                                         esac
127                                         probe-addr $mx $addr
128                                 done
129                                 ;;
130                         [123])
131                                 # temporary errors
132                                 record-tempfail "mx=$mx" "dns $rc $rhs"
133                                 ;;
134                         *)
135                                 # yikes
136                                 record-permfail "mx=$mx" "dns $rc $rhs"
137                                 ;;
138                         esac
139                 done
140                 record-success dns
141                 return
142                 ;;
143         6)
144                 permfail, try A
145                 set +e
146                 adnshost -Fi -Tn +Do +Dt -t a $domain >$td
147                 rc=$?
148                 set -e
149                 ;;
150         esac
151
152         case $rc in
153         0)
154                 # have a list of A's (dealt with MXs above)
155                 exec <$td/dns
156                 local addr
157                 while read addr; do
158                         probe-addr '<no-mx>' $addr
159                 done
160                 record-success dns
161                 return
162                 ;;
163         [123])
164                 local emsg
165                 read <$td/dns emsg
166                 record-tempfail dns "dns <no-mx> $emsg"
167                 ;;
168         *)
169                 local emsg
170                 read <$td/dns emsg
171                 record-permfail dns "dns <no-mx> $emsg"
172                 ;;
173         esac
174 }
175
176 no_args () {
177         case $1 in
178         0) return ;;
179         *) fail
180
181 mode_all () {
182         no_args $#
183         for domain in $MODRELAYS; do
184                 probe $domain
185         done
186 }
187
188 mode_auto () {
189         no_args $#
190         xxx do something to cause sleeping
191         mode_all
192 }
193
194 mode_relay () {
195         relay="$1"
196         probe "$relay"
197 }
198
199 mode=$1; shift||:
200
201 "mode_$mode" "$@"