Bezpečné vygenerovanie mailu s diakritikou v Perle

Začiatočníci v skriptovaní môžu mať v Perle menší problém ako „poskladať“ e-mail s diakritikou. Všeobecne platí, že najbezpečnejším kódovaním diakritiky pre e-mail je ISO-8859-2, ktorému by mali rozumieť najčastejšie používané e-mailové klienty. Text, ktorý budeme odosielať musí teda byť v tomto kódovaní. Samostatnou kapitolou je kódovanie diakritiky v predmete správy (Subject), ktorý si zjednodušíme a v našom príklade si dáme pravidlo „predmet bude bez diakritiky“. Toto pravidlo uplatníme aj na ďalšie kolónky hlavičky (príjemca a odosielateľ).


Najprv samotný kus kódu:
$from = 'sender@example.org';
$meno = 'meno odosielatela bez diakritiky';
$to = 'receipient@example.org';
$subject = 'predmet spravy bez diakritiky';

$mailprog = '/usr/lib/sendmail';
open (MAIL, "|$mailprog $to") || die "Can't run mail program!\n";
$mail = 'Content-Class: urn:content-classes:message'."\n";
$mail .= 'MIME-Version: 1.0'."\n";
$mail .= "Content-Type: text/plain;\n";
$mail .= ' charset="iso-8859-2"'."\n";
$mail .= 'Content-Transfer-Encoding: quoted-printable'."\n";
$mail .= "Subject: $subject\n";
$mail .= "From: $meno \<$from\>\n";
$mail .= "\n$messsage\n\n";
print MAIL $mail; close (MAIL);

Predpokladáme, že máme už naplnené premenné $from, $to, $meno, $subject a $message a ich význam pochopíme z ich pomenovania.
V premennej $message už máme pripravený text v kódovaní ISO-8859-2. V ňom nemožno používať na formátovanie žiadne HTML značky.
Základom riešenia v hlavičke e-mailu je určenie Content-type s parametrom text/plain a kódovaním iso-8859-2.
Pretože máme text v premennej $message v prirodzenom prekódovaní znakov mimo základnej ASCII tabuľky, tak ďalší povinný parameter je Content-Transfer-Encoding a toto prirodzené kódovanie znakov ASCII sa volá quoted-printable. Používajú sa ešte iné spôsoby zakódovania znakov mimo ASCII ale potom musí byť text špeciálne prekódovaný a prevodné tabuľky sú zložitejšie ako bežné prekódovacie funkcie medzi známymi kódovaniami diakritiky. Pozor rozlišujte kódovanie diakritiky a kódovanie znakov mimo ASCII tabuľku. Preto používame quoted-printable, pretože je naozaj najmenej náročné na ďalšie funkcie.
Obligátne určenie MIME verzie je už iba doplnením povinného obsadenia hlavičky e-mailu.
Pre pochopenie problematiky e-mailu je nutné vedieť, že mimo toho, čo vidíte v bežnom e-mailovom klientovi sa do e-mailu ukladajú dáta zásadne ako text. To znamená, že prípadné prílohy sa musia „prekódovať“ do zmetku písmen a číslic a rôznymi technikami pridať do textového tela e-mailu. S diaktritikou v e-mailoch je podobný problém a v princípe je nutné chápať email bez diakritiky za niečo úplne iné ako email s diakritikou. Môj príklad sa najviac blíži spôsobu generovania jednoduchého emailu pretože nevyžaduje zakódovať text s diakritikou od emailu ako „prílohu“.
Okrem toho každý e-mail chápte ako textový súbor, ktorý začína dohodnutým formátom hlavičky. Hlavička sa skladá z riadkov textu, ktoré začínajú dohodnutými slovami (From, To, Subject). Bežné poštové programy si tento súbor s mailom rozoberajú a snažia sa povyberať z hlavičky to, čomu rozumejú a podľa toho zobrazia e-mail. Niektoré časti hlavičky potom zobrazujú v poliach ako je Odosielateľ, Predmet, Komu, telo e-mailu či prílohy.
Potreba vniesť do pôvodne textoveho e-mailu diakritiku a prílohy (súbory) priniesla rôzne typy mechanizmov, ktoré včarujú do primitíva e-mailu všetky tieto vymoženosti. Daňou za to je možné vzájomné nepochopenie sa poštových systémov a pomerne komplikované rôzne spôsoby k dosiahnutiu toho istého výsledku (a tým pádom aj rôzny spôsob jeho interpretovania).
Mohol som Vám priniesť príklad ako skomplikovať takto jednoduchý príklad pomocou base64 prekódovania tela správy. Mohli sme vidieť ako sa musí prekódovať predmet správy pokiaľ obsahuje diakritiku. Ale zbavili sme sa toho predpokladom, že v predmete žiadna diakritika nesmie byť a telo správy bude „quoted-printable“.
Technicky je možné v perle odoslať mail dvomi spôsobmi (aspoň mne sú známe):
* knižnica Sendmail.pm – jej riziko je v menšej podpore (nenachádza sa v knižniciach perlu vždy,
* priamym poslaním mailu do sendmailu ako vidno v príklade.
Ten druhý spôsob funguje pokiaľ máme sendmail umiestnený v /usr/lib a je administrátorom nakonfigurovaný. Sendmail je najbežnejší poštový systém na unixových systémoch a zvyčajne by mal fungovať pokiaľ sa administrátor nerozhodne inak.
Môj príklad nerieši problém keď je nutné mail „poslať“ vzdialenému SMTP serveru!

Môže sa Vám ešte páčiť...

5 komentárov

  1. Kozo píše:

    Osobne by som pre istotu v hlavickach doplnil, ze to posielam v 8-bit. Aj ked tam sice pises, ze to ide v QP, tak si si nevsimol, ze by si to do QP niekde kodoval. Mam chapat tak, ze $message uz je QP ? Potom byu bolo mozno zahodno doplnit, ako to bezny user do QP prekoduje.

  2. rony píše:

    aha dik za doplnenie

  3. Ján Pavlík píše:

    Funguje skript aj ked nemame sendmail, ale napr. postfix?

  4. rony píše:

    ak je ako exim kompatibilny so sendmailom tak preco to neodskusat?

  5. 2ge píše:

    ja som nuteny posielat maily v utf-8, myslim si ze zaoberat sa inym kodovanim patri do minulosti. Je pravda, ze mozno 1% mailovych programov moje maily neprecita (je to mime64 a vidia len zhluk znakov), ale…