昔から運用しているサーバを移設することになりました。
メール送信にqdmailおよびqdsmtpを使用しています。
一部改修が必要なため、以下URLを参考にAUTH LOGINへ対応させました。
AUTH LOGIN認証は、SMTPサーバーに対して「AUTH LOGIN」コマンドを送ります。
その後、ユーザー名とパスワードをBase64でエンコードして送ります。
実行するソースコード test.php
require_once('/include_dir/qdmail.php');
require_once('/include_dir/qdsmtp.php');
$mail = new Qdmail();
$mail -> errorDisplay( true );
$mail -> smtp(true);
$param = array(
'host'=>'email-smtp.us-east-1.amazonaws.com',
'port'=> 587 ,
'from'=>'from@exapmle.com',
'protocol'=>'SMTP_AUTH',
'user'=> 'username',
'pass' => 'userpass'
);
$mail -> smtpServer($param);
$message="メールの中身をここに書きます。";
$mail ->to('toadress@example.com','test');
$mail ->subject('メールのテスト');
$mail ->from('from@example.com');
$mail ->text($message);
$return_flag = $mail ->send();
実行結果抜粋
QdSmtp error: Unkown Error :status530 message:530 Must issue a STARTTLS command first on auth login
エラーが発生します。
auth loginはSTARTTLSを先に始めてくださいねという内容ですね。
今回は、SMTPサーバにAmazon SESを使用しています。
Amazon SESは全ての通信を暗号化(TLS)必要があるため、
上記のようなエラーが発生します。
解決策
qdsmtp.phpを改修し、STARTTLSに対応します。
変更と追加が必要な箇所だけ抜粋します。
function sendBase( $data = null ,$protocol = null ){
if( !is_null( $data ) ){
$this->data = $data;
}
if( is_null( $protocol ) ){
$protocol = $this->protocol_def;
}
switch($protocol){
case 'POP_BEFORE'://POP3
if( !$this->pop3() ){
return $this->errorGather('POP failure',__LINE);
}
case 'SMTP':
if( !is_resource( $this->sock ) ){
$this->sock = $this->connect();
}
$this->sayHello();
if( !$this->sendData() ){
return false;
}
break;
case 'SMTP_AUTH':
if(!is_resource($this->sock)){
$this->sock = $this->connect();
}
if( !$this->already_auth ){
$this->sayHello();
if( 0 === preg_match('/[\s-]AUTH\s+([^\r\n]*)\r?\n/is', implode($this->smtpLFC,$this->smtp_log) , $matches)){
return $this->errorGather('HOST:'.$this->smtp_param['HOST'].' doesnot suppoted SMTP AUTH Protocol',__LINE__);
}
//STARTTLSの処理追加
if( !$this->enableTLS() ){
$this->already_auth = false;
return $this->errorGather('STARTTLS Error',__LINE__);
}
stream_socket_enable_crypto($this->sock, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
//再度 EHLO hostname
$this->sayHello();
//暗号化有効にする
$mes = strtoupper( $matches
);
$decide = null;
foreach($this->smtp_auth_kind as $auth){
if( false !== strpos( $mes , $auth ) ){
$decide = $auth;
break;
}
}
if( is_null( $decide ) ){
return $this->errorGather('HOST:'.$this->smtp_param['HOST'].' doesnot suppoted MY Abalable SMTP AUTH Protocol '.implode(' or ',$this->smtp_auth_kind),__LINE__);
}
$decide = strtolower( str_replace( '-' , '_' ,$decide ) );
if( !$this->{$decide}() ){
return $this->errorGather('Auth Error',__LINE__);;
}
$this->already_auth = true;
}
if( !$this->sendData() ){
$this->already_auth = false;
return $this->errorGather('Send Data Error or Auth Error',__LINE__);
}
break;
case 'OVER_SSL':
break;
default:
break;
}
return $this->errorGather();
}
/*必要な関数だけ抜粋*/
function enableTLS(){
$items = array(
array( 'STARTTLS' , null ),
);
list( $st , $mes , $com ) = $this->communicate($items);
if(!$st){
return 0;
}
return 1;
}
enableTLS関数を追加して、SendBase関数を変更しています。
改修前後のSMTPの通信の流れを示します。
改修前

改修後

まとめ
SMTPのいい勉強になりました。
qdmailをやめたかったですが、改修ボリュームが大きかったので
今回はqdsmtpを改修するに至りました。