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