【php】SMTPの認証方式CRAM-MD5を実装する
問題
phpでSMTP接続してメールを送信したい。
答え
fsockopenで587番ポートに話しかけます。
以下のような形になります。
<?php $smtp_id = 'test@example.com'; $smtp_password = 'test-password-test-password'; $smtp_host = 'mail.example.com'; // 認証は cram-md5 で try { // これは1行しか返ってこない前提 $sock = fsockopen('tcp://' . $smtp_host . ':587', 587, $err, $errno, 10); $result = fgets($sock); if (strpos($result, '220 ') !== 0) { throw new Exception('1001' . ' ' . $result); } // 複数行返ってくることがある fwrite($sock, "EHLO " . $smtp_host . "\r\n"); do { $result = fgets($sock); $_ = stream_get_meta_data($sock); } while ($_['unread_bytes'] > 0); if (strpos($result, '250 ') !== 0) { throw new Exception('1002' . ' ' . $result); } // 1行しか返ってこないはず fwrite($sock, "AUTH CRAM-MD5" . "\r\n"); $result = fgets($sock); if (strpos($result, '334 ') !== 0) { throw new Exception('1003' . ' ' . $result); } $cc = base64_decode(substr($result, 4)); // 認証文字列送信 $authstr = base64_encode($smtp_id . ' ' . hash_hmac('md5', $cc, $smtp_password, false)); fwrite($sock, $authstr . "\r\n"); // 認証結果 $result = fgets($sock); if (strpos($result, '235 ') !== 0) { throw new Exception('1004' . ' ' . $result); } fwrite($sock, "MAIL FROM:<" . $mail['from'] . ">\r\n"); $result = fgets($sock); fwrite($sock, "RCPT TO:<" . $mail['to'] . ">\r\n"); $result = fgets($sock); fwrite($sock, "DATA\r\n"); $result = fgets($sock); // $message はメールのソース fwrite($sock, $message . "\r\n" . "." . "\r\n"); $result = fgets($sock); if (! ereg("^250", $result)) { throw new Exception('1005' . ' ' . $result); } fclose($sock); } catch (Exception $e) { echo $e->getMessage(); }
コメント