The knights who said "rcpt! rcpt! rcpt!" (was: Qmail and badmailfrom)
Giorgos Keramidas
charon at labs.gr
Mon Sep 24 21:09:01 EEST 2001
% Όποιος έχει αλλεργία στα μεγάλα postings, να σβήσει αυτό το γράμμα και να
% περιμένει μέχρι να αυτοκαταστραφεί το qmail του.
% Αν δεν έχει qmail, να βάλει, και τότε να περιμένει να αυτοκαταστραφεί...
% (και το qmail και αυτός)
Bill Nikolopoulos <billy at mycosmos.gr> wrote:
> Kalimera,
>
> To badmailfrom mou exei stasei esios ta 240 entries. To problima mou den
> einai oti me peirazei na prosteto kathe mera kai kati kainourio alla to
> gegonos oti to kainourio email pou bazo itan apo spam gia xristi pou den
> iparxei sto sistima mou.
>
> Iparxei loipon tropos gia kati san bad rcpt to ?
>
> Giati etsi poli apla me merika entry tha isixaso teleios.
>
> PS Den einai thema open relay.
Κατ' αρχήν πέτα το mailer σου, έχει σκίσει το μήνυμα στο wrapping και κόβει
τις γραμμές όπου του κατέβει! Ας πάμε παρακάτω όμως. Νά 'ναι καλά το vim, το
reformatting είναι πανεύκολο.
Μάλλον θες κάτι σαν το παρακάτω:
% socket 0 25
220 hades.hell.gr ESMTP Sendmail 8.11.6/8.11.6; Mon, 24 Sep 2001 19:50:00 +0300 (EEST)
HELO ELRIK
250 hades.hell.gr Hello hades [127.0.0.1], pleased to meet you
MAIL FROM: stormbringer at hell.gr
250 2.1.0 stormbringer at hell.gr... Sender ok
RCPT TO: mournblade at hell.gr
550 5.1.1 mournblade at hell.gr... User unknown
QUIT
221 2.0.0 hades.hell.gr closing connection
______________________________________________________________________________
Part I: qmail and the 550 errors
[ μια διασκευή του "ο αλλαντίν και τα 40 λυχνάρια" ]
______________________________________________________________________________
Δεν θυμάμαι γιατί μου έχει κολλήσει η ιδέα, αλλά δεν νομίζω το qmail να έχει
τρόπο να του πεις ότι 'στα unknown user θα απαντάς με error 550 βλαμμένο'.
Το μόνο σχετικό που βρήκα στο qmail FAQ είναι η ερώτηση 4.1:
4.1. How do I forward unrecognized usernames to another host?
Στην αρχή σκέφτηκα να απαντήσω με τον κλασσικό τρόπο: εσείς οι gay qmail
χρήστες θα καείτε στην κόλαση, σε καζάνια που η φωτιά τους θα τροφοδοτείται με
τα κομμάτια του Bernstein. Αλλά το ξανασκέφτηκα, κι είπα να το ψάξω λίγο να
βρώ γιατί και πως δουλεύει το qmail. Ξεκίνησα το lynx, και έτρεξα στο γνωστό
πορνό-site που ο Bernstein χρησιμοποιεί για να διανέμει φωτογραφίες από
ανήλικα αγοράκια τα οποία τρέχουν στους δρόμους γυμνά κρατώντας μόνο ένα
holy qmail, κατέβασα το source και το κοίταξα.
Η σύντομη απάντηση λοιπόν είναι: όχι, δεν γίνεται αυτό που θέλεις.
Η πιο μακροσκελής και μπερδεμένη απάντηση είναι: το qmail είναι μικρό,
ευκολοχώνευτο και χαριτωμένο, οπότε διάβασε κι εσύ το source.
______________________________________________________________________________
Part II: qmail and the knights of the smtp table
[ αλλιώς γνωστοί και ως "οι ιππότες που έλεγαν rcpt! rcpt!" ]
______________________________________________________________________________
Ελπίζω να ξέρεις C...
Αλλιώς τα παρακάτω θα σου φανούν επιοικώς κινέζικα.
Κοιτάζοντας το source του qmail-smtpd.c από τον κώδικα του qmail μπορώ να δω
τα εξής:
α) ο Bernstein πρέπει να πεθάνει, να Πεθάνει, ΝΑ ΠΕΘΑΝΕΙ, γιατί έχει το πιο
άθλιο στυλ γραψίματος κώδικα που έχω δει ως τώρα. Περιμένω μέχρι να δω και
τον πηγαίο των Windows, μήπως τελικά δεν είναι το στυλ του Bernstein το
χειρότερο στον κόσμο.
b) Όταν πάρει μια RCPT TO γραμμή το qmail-smtpd τρέχει την συνάρτηση:
83 char *relayclient;
...
250 void smtp_rcpt(arg) char *arg; {
...
254 if (relayclient) {
255 --addr.len;
256 if (!stralloc_cats(&addr,relayclient)) die_nomem();
257 if (!stralloc_0(&addr)) die_nomem();
258 }
259 else
260 if (!addrallowed()) { err_nogateway(); return; }
...
265 }
Ο βασικός έλεγχος που γίνεται δηλαδή είναι [γραμμή 254] αν υπάρχει ορισμένο το
relayclient, το οποίο θα είναι μη-NULL μόνο αν η setup() παραπάνω το
έχει βρεί στο περιβάλλον:
100 void setup()
101 {
...
133 relayclient = env_get("RELAYCLIENT");
...
135 }
Οπότε για όσους έχεις ορίσει το RELAYCLIENT, τα mail που στέλνονται από το
δικό τους smtp connection γίνονται *πάντα* αποδεκτά, χωρίς τον έλεγχο της
γραμμής 260 μέσω της addrallowed(). Η ίδια η addrallowed() είναι αρκετά μικρή
για να καταλάβεις αμέσως τι κάνει:
211 int addrallowed()
212 {
213 int r;
214 r = rcpthosts(addr.s,str_len(addr.s));
215 if (r == -1) die_control();
216 return r;
217 }
Οπότε, όπως βλέπεις, ΜΟΝΟ το rcpthosts κοιτάζει το qmail όταν παίρνει μια
"rcpt to" γραμμή από SMTP σύνδεση. Τζίφος!
______________________________________________________________________________
Part III: qmail inferno, purgatorio e paradiso
[όπου το qmail λυτρώνεται από τις αμαρτίες του πατέρα του]
______________________________________________________________________________
Το ότι το qmail-smtpd δουλέυει έτσι όμως δεν είναι εντελώς παράλογο. Δεν
είναι ότι ο Bernstein αποφάσισε ξαφνικά ότι σκοτίστηκε για τα 550 λάθη.
Ο τρόπος που γίνεται η παράδοση ενός mail στο τελικό mailbox/maildir/οτιδήποτε
στο qmail είναι αρκετά μπλεγμένος ώστε το qmail-smtpd να μην μπορεί με
*τίποτα* να ξέρει πότε και που μπορεί να παραδοθεί ένα mail. Πρέπει το mail
να φτάσει (περνώντας από όλη την διαδικασία qmail-smtpd -> qmail-queue -> κλπ)
μέχρι το qmail-lspawn και το qmail-local για να ξέρει το qmail αν το
συγκεκριμένο mail μπορεί να παραδοθεί κανονικά ή υπάρχει κάποιο από τα 550
λάθη. Αυτό σημαίνει βέβαια ότι το qmail-smtpd δεν μπορεί από πριν να μαντέψει
τι θα γίνει, και απλά δέχεται όλα τα recipients σαν να ήταν σωστά.
Είμαι περίεργος αν το Postfix (που έχει επίσης την ίδια σχεδιαστική φιλοσοφία
με το qmail (πολλά, μικρά, ανεξάρτητα προγράμματα, που "συνεργάζονται" κάπως))
έχει το ίδιο πρόβλημα με το qmail στα unknown recipients.
-giorgos
More information about the Linux-greek-users
mailing list