WordPress
SSL
sourceCode

WordPressのソースコード読んでたら、SSLかどうかを判定する関数にぶつかった

More than 1 year has passed since last update.

WordPressのソースコードを読んでたら、SSLかどうかを判定する関数にぶつかりました
抜粋したソースコードは以下の通り

function is_ssl() {
    if ( isset( $_SERVER['HTTPS'] ) ) {
        if ( 'on' == strtolower( $_SERVER['HTTPS'] ) ) {
            return true;
        }

        if ( '1' == $_SERVER['HTTPS'] ) {
            return true;
        }
    } elseif ( isset($_SERVER['SERVER_PORT'] ) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
        return true;
    }
    return false;
}

\$_SERVERは、サーバー情報を保存しています。 isset( \$_SERVER['HTTPS'] )によって、サーバー情報の、HTTPSのインデックスの項目が保存されているかどうかを判定する。
設定されていたら、"on"かどうかを判定して、"on"であったならば、trueを返す。つまり、SSLであると返すわけですね。
"1"の場合もtrueを返すようです。
"on"か"1"の数値の可能性があって、それ以外の、例えば、"true"とか、"Yes"とかじゃないところが面白いですね。

elseif ( isset($_SERVER['SERVER_PORT'] ) && ( '443' == $_SERVER['SERVER_PORT'] ) ) 

この行では、サーバーのポートがセットされているかどうかをチェックして、サーバーのポートが"443"であった場合に、trueを返しています。
ここで注目するべきは、サーバのポートが443であるか、サーバの設定が"HTTPS"か、どちらかであればSSL通信が成り立つということです。
"HTTPS"ではなく、SSLであることが存在するのかなとか、ポートが、"443"でない場合に、SSLであることが存在するのかなとか考えたりしますが、おそらくですが、どちらかが明確に設定されていないことがあるんだと思います。
では、このis_ssl()が、どこで呼び出されているかを調査します。

if ( ! ( isset( $_REQUEST['action'] ) && 'upload-attachment' == $_REQUEST['action'] ) ) {
    // Flash often fails to send cookies with the POST or upload, so we need to pass it in GET or POST instead
    if ( is_ssl() && empty($_COOKIE[SECURE_AUTH_COOKIE]) && !empty($_REQUEST['auth_cookie']) )
        $_COOKIE[SECURE_AUTH_COOKIE] = $_REQUEST['auth_cookie'];
    elseif ( empty($_COOKIE[AUTH_COOKIE]) && !empty($_REQUEST['auth_cookie']) )
        $_COOKIE[AUTH_COOKIE] = $_REQUEST['auth_cookie'];
    if ( empty($_COOKIE[LOGGED_IN_COOKIE]) && !empty($_REQUEST['logged_in_cookie']) )
        $_COOKIE[LOGGED_IN_COOKIE] = $_REQUEST['logged_in_cookie'];
    unset($current_user);
}

これは、async_upload.phpの一部です。\$_REQUESTは、HTTPリクエストの変数です。'action'インデックスにおいて、アップロードが付加されているかどうかを'upload-attachment' == \$_REQUEST['action']を使って、判定しています。
このコードからわかるように、is_ssl()が有効であり、 empty(\$_COOKIE[SECURE_AUTH_COOKIE])が、trueである、つまり、セキュアな認証クッキーが空であり、\$_REQUEST['auth_cookie']が空であるならば、

$_COOKIE[SECURE_AUTH_COOKIE] = $_REQUEST['auth_cookie'];

この文によって、認証クッキーをCOOKIEに設定する。
そうでないなら、別のルーチンが走って、セキュアな認証クッキーには設定されません。

では、別の呼び出されているルーチンを調査してみましょう。次は、ajax_action.phpです。
一部抜粋

    if ( is_ssl() && 0 === strpos( $url, 'http://' ) ) {
        // Admin is ssl and the user pasted non-ssl URL.
        // Check if the provider supports ssl embeds and use that for the preview.
        $ssl_shortcode = preg_replace( '%^(\\[embed[^\\]]*\\])http://%i', '$1https://', $shortcode );
        $parsed = $wp_embed->run_shortcode( $ssl_shortcode );

        if ( ! $parsed ) {
            $no_ssl_support = true;
        }
    }

これは、SSLでありながら、https://ではない、つまり、http://であった場合、httpをhttpsに置き換えます。preg_replaceは、正規表現を引数に取って、正規表現と一致した場合、httpsに置換します。

$parsed = $wp_embed->run_shortcode( $ssl_shortcode );

ここって何やってるのかなと思っちゃったりしますが、これはトレースしてみてもよくわからないです。おそらく、リダイレクトかパースに近いことでもやるのかなと思います。
run_shortcode関数が失敗したら、$parseにfalseが設定されて、SSLがサポートされていないことを記録するようです。
いやー、ソースコード読みは面白いですね。