1

ソケット経由で SMTP サーバーと通信するスクリプトを作成しており、DIGEST-MD5 認証を実装しようとしていますが、AUTH コマンドの後に返される文字列の解析に問題があります。

後はbase64_decode()次のようになります。

realm="smtp.domain.net",nonce="AJRUc5Jx0UQbv5SJ9FoyUnaZpqZIHDhLTU+Awn/K0Uw=",qop="auth,auth-int",charset=utf-8,algorithm=md5-sess

を使用したかったstr_getcsv()のですが、サーバーはまだ PHP 5.2 を使用しているため、PHP.net のコメントから次のコードを取得しました。

<?php
if (!function_exists('str_getcsv')) {
        function str_getcsv($input, $delimiter=',', $enclosure='"', $escape=null, $eol=null) {
                $temp=fopen("php://memory", "rw");
                fwrite($temp, $input);
                fseek($temp, 0);
                $r = array();
                while (($data = fgetcsv($temp, 4096, $delimiter, $enclosure)) !== false) {
                        $r[] = $data;
                }
                fclose($temp);
                return $r;
        }
}

しかし、それは以下を返します:

array (
  0 =>
  array (
    0 => 'realm="smtp.domain.net"',
    1 => 'nonce="2PuESkmrNzGu/5b8N6eIYQoW7mSlScnYAB/PSYebkYo="',
    2 => 'qop="auth',
    3 => 'auth-int"',
    4 => 'charset=utf-8',
    5 => 'algorithm=md5-sess',
  ),
)

インデックス 2 と 3 は単一である必要があることに注意してくださいqop="auth,auth-int"

これを書いているときにfgetcsv()、文字にはフィールドの一部だけでなくフィールド全体が含まれていると予想される可能性があることに気付き$enclosureましたが、その場合、この文字列を適切に解析する方法を考えなければなりません。

4

2 に答える 2

0

'PHP DIGEST-MD5'のグーグルで、次の行と同じフォーマット文字列を処理する別のプロジェクトのパッチに出くわしました。

preg_match_all('/(\w+)=(?:"([^"]*)|([^,]*))/', $challenge, $matches);

それは私に与えます:

array (
  0 =>
  array (
    0 => 'realm="smtp.domain.net',
    1 => 'nonce="AJRUc5Jx0UQbv5SJ9FoyUnaZpqZIHDhLTU+Awn/K0Uw=',
    2 => 'qop="auth,auth-int',
    3 => 'charset=utf-8',
    4 => 'algorithm=md5-sess',
  ),
  1 =>
  array (
    0 => 'realm',
    1 => 'nonce',
    2 => 'qop',
    3 => 'charset',
    4 => 'algorithm',
  ),
  2 =>
  array (
    0 => 'smtp.domain.net',
    1 => 'AJRUc5Jx0UQbv5SJ9FoyUnaZpqZIHDhLTU+Awn/K0Uw=',
    2 => 'auth,auth-int',
    3 => '',
    4 => '',
  ),
  3 =>
  array (
    0 => '',
    1 => '',
    2 => '',
    3 => 'utf-8',
    4 => 'md5-sess',
  ),
)

次に、このループで有用な配列に入力できます。

$authvars = array();
foreach( $auth_matches[1] as $key => $val ) {
    if( !empty($auth_matches[2][$key]) ) {
        $authvars[$val] = $auth_matches[2][$key];
    } else {
        $authvars[$val] = $auth_matches[3][$key];
    }
}

それは私に与えます:

array (
  'realm' => 'ns103.zabco.net',
  'nonce' => 'xITX1qgqlCDmYX6IrctN0WZRx7+Q4W7jjaXCCeUZnU8=',
  'qop' => 'auth,auth-int',
  'charset' => 'utf-8',
  'algorithm' => 'md5-sess',
)

それは正確にはきれいではありませんが、それは仕事を成し遂げます。

于 2013-01-25T22:28:07.347 に答える
0
$decodedString = 'realm="smtp.domain.net",nonce="AJRUc5Jx0UQbv5SJ9FoyUnaZpqZIHDhLTU+Awn/K0Uw=",qop="auth,auth-int",charset=utf-8,algorithm=md5-sess';

parse_str(preg_replace('/(?:(")(.*?)("))?,(?:(")(.*?)("))?/','$1$2$3&$4$5$6',$decodedString), $values);
var_dump($values);

結果の配列値を囲む引用符も取り除きたい場合は、次を使用します

$values = array_map(
    function ($value) {
        return trim($value,'"');
    },
    $values
);
var_dump($values);
于 2013-01-25T22:54:34.927 に答える