SMTP Yanıtları doğrulamak için Regex

2 Cevap php

SMTP dialog is completed aşağıdaki regex (bazı parantezler daha iyi okunabilmesi için eklenmiştir) geçmelidir keresinde, etkileşimli SMTP yanıtları kodları doğrulamak için normal bir ifade yazıyorum:

^(220)(250){3,}(354)(250)(221)$

Veya (out) kimlik doğrulaması ile:

^(220)(250)((334){2}(235))?(250){2,}(354)(250)(221)$

Beklendiği gibi iletişim gidiyor eğer interactively kontrol edebilirsiniz böylece ben aksi kibarca bir QUIT komutu göndermek ve bağlantı tasarrufu bant genişliği ve zaman kapatın, yukarıdaki ifadelerin yeniden yapmaya çalışıyorum ama ben bir sabit zaman optimal bir regex yazıyorum yaşıyorum. Bugüne kadar ben ile gelip başardı ettik:

^(220(250(334(235(250(354(250(221)?)?)?){0,})?){0,2})?)?$

Sadece kimliği doğrulanmış bağlantıları eşleşen yanı sıra, bazı hatalar var ki ... Örneğin, o maçlar:

220250334235250354250221
220250334334235250354250221

Ayrıca aşağıdaki modifikasyon denedim:

^(220(250)?)?((334(235)?){2})?(250(354(250(221)?)?)?){0,}$

Bu bir non-doğrulanmış yanıtları kabul eder ama (en azından 2 250 önce ihtiyaç vardır 220250334 eşleştirememişse ve yanlış 220250334334235250354250221 maçları {[(3)] } yanıt kodu).

Birisi bana bu konuda yardımcı olabilir misiniz? Şimdiden teşekkürler.


Ben yapmaya çalışıyorum ne bir örnek:

$smtp = fsockopen('mail.example.com', 25);
$result = null;
$commands = array('HELO', 'AUTH LOGIN', 'user', 'pass', 'MAIL FROM', 'RCPT TO', 'RCPT TO', 'DATA', "\r\n.", 'QUIT');

foreach ($commands as $command)
{
    $result .= substr(fgets($smtp), 0, 3);

    if (preg_match('~^(220(250)?)?((334){1,2}(235)?)?(250(354(250(221)?)?)?){0,}$~S', $result) > 0)
    {
        fwrite($smtp, $command . "\r\n");
    }

    else
    {
        fwrite($smtp, "QUIT\r\n");
        fclose($smtp);
        break;
    }
}

Hangi aşağıdaki usul kodu için bir yedek olarak hareket etmelidir:

$smtp = fsockopen('mail.example.com', 25);
$result = substr(fgets($smtp), 0, 3); // 220

if ($result == '220')
{
    fwrite($smtp, 'HELO' . "\r\n");
    $result = substr(fgets($smtp), 0, 3); // 220

    if ($result == '250')
    {
        fwrite($smtp, 'AUTH LOGIN' . "\r\n");
        $result = substr(fgets($smtp), 0, 3); // 334

        if ($result == '334')
        {
            fwrite($smtp, 'user' . "\r\n");
            $result = substr(fgets($smtp), 0, 3); // 334

            if ($result == '334')
            {
                fwrite($smtp, 'pass' . "\r\n");
                $result = substr(fgets($smtp), 0, 3); // 235

                if ($result == '235')
                {
                    fwrite($smtp, 'MAIL FROM' . "\r\n");
                    $result = substr(fgets($smtp), 0, 3); // 250

                    if ($result == '250')
                    {
                        foreach ($to as $mail)
                        {
                            fwrite($smtp, 'RCPT TO' . "\r\n");
                            $result = substr(fgets($smtp), 0, 3); // 250

                            if ($result != '250')
                            {
                                fwrite($smtp, 'QUIT' . "\r\n");
                                $result = substr(fgets($smtp), 0, 3); // 221
                                fclose($smtp);

                                break;
                            }
                        }

                        if ($result == '250')
                        {
                            fwrite($smtp, 'DATA' . "\r\n");
                            $result = substr(fgets($smtp), 0, 3); // 354

                            if ($result == '354')
                            {
                                fwrite($smtp, "\r\n.\r\n");
                                $result = substr(fgets($smtp), 0, 3); // 250

                                if ($result == '250')
                                {
                                    fwrite($smtp, 'QUIT' . "\r\n");
                                    $result = substr(fgets($smtp), 0, 3); // 221
                                    fclose($smtp);

                                    if ($result == '221')
                                    {
                                        echo 'SUCESS!';
                                    }
                                }

                                else
                                {
                                    fwrite($smtp, 'QUIT' . "\r\n");
                                    $result = substr(fgets($smtp), 0, 3); // 221
                                    fclose($smtp);
                                }
                            }

                            else
                            {
                                fwrite($smtp, 'QUIT' . "\r\n");
                                $result = substr(fgets($smtp), 0, 3); // 221
                                fclose($smtp);
                            }
                        }
                    }

                    else
                    {
                        fwrite($smtp, 'QUIT' . "\r\n");
                        $result = substr(fgets($smtp), 0, 3); // 221
                        fclose($smtp);
                    }
                }

                else
                {
                    fwrite($smtp, 'QUIT' . "\r\n");
                    $result = substr(fgets($smtp), 0, 3); // 221
                    fclose($smtp);
                }
            }

            else
            {
                fwrite($smtp, 'QUIT' . "\r\n");
                $result = substr(fgets($smtp), 0, 3); // 221
                fclose($smtp);
            }
        }

        else
        {
            fwrite($smtp, 'QUIT' . "\r\n");
            $result = substr(fgets($smtp), 0, 3); // 221
            fclose($smtp);
        }
    }

    else
    {
        fwrite($smtp, 'QUIT' . "\r\n");
        $result = substr(fgets($smtp), 0, 3); // 221
        fclose($smtp);
    }
}

else
{
    fwrite($smtp, 'QUIT' . "\r\n");
    $result = substr(fgets($smtp), 0, 3); // 221
    fclose($smtp);
}

2 Cevap

Düzenli ifadeler uyku iyi bir gece sonra çok daha kolay hale nasıl inanılmaz, işte burada:

(?>220(?>250(?>(?>334){1,2}(?>235)?)?(?>(?>250){1,}(?>354(?>250(?>221)?)?)?)?)?)?

Bu basitleştirilmiş olabilir ki:

^220(?>250(?>(?>334){1,2}(?>235)?)?(?>(?>250){1,}(?>354(?>250)?)?)?)?$

İlk yanıt kodu (220) isteğe bağlı değil ve biz her zaman son QUIT komutu göndermek beri.

Senin mesajın geri kalanını dışarı sıyırma aldığınız tüm yanıt kodları ile bir dize bina konum tahmin?

Bu muhtemelen istediğiniz cevap değil, ama ben regex burada sadece doğru aracı olmadığını yardım ancak duygu alınamıyor. Düzenli ifadeler belirteçleri içine metin ayrıştırma ya da daha büyük bir dize dışında ilginç alt dizeleri ayıklanan de iyi. Ama zaten belirteçleri (SMTP yanıt kodları) var ve onlar beklenen sırayla ulaşmasını sağlamak için çalışıyoruz. Ben sadece bir sıraya yanıt kodları eklemek ve her ilave sıranın başlangıç ​​içeri konum devlet için beklenen desen birini uygun olup olmadığını kontrol sonra yaparsa, kuyruğundan o kısmı kaldırmak ve gitmek istiyorum sonraki durum. Orada birkaç devletlerin sadece, bu yüzden ben sadece bu özel kod yazmak yerine, bir devlet makinesinin bir çeşit soyut denemek istiyorum.

Eğer ayırıcı olarak dize alanı tutmak isteyebilirsiniz Regex yol yaparsanız - bu da programı okumak kolay kolay kodları maç yapmak, ama değil sadece.

Edit: Teşekkürler kodu yazabilmek için. Bu hemen hemen ben kabul buydu. Temelde bu sorunun soyut bir çözüm oluşturmak için çalışıyoruz, böylece komutlar bir verilen bir dizi göndermek ve geri tepkiler verilen bir model beklemek yeteneği var. Eğer gerçekten soyut yapmak gerekmez - ekledi karmaşıklığı büyük ve yeniden kullanımı ödemek mümkün değildir. Sadece diyor kodu yazmak: send X, if you receive Y continue, otherwise QUIT. Bu çok daha kolay ve daha okunabilir olacaktır.