2014-11-07 9 views
8

Il caso: vorrei aprire la connessione SSL per localhost mentre certificato SSL era problemi per nome di dominio completo.Come impostare '= false verify_peer_name' opzione contesto SSL tramite php.ini in PHP 5.6

Il problema: Senza una gestione speciale in linea (*) il programma qui di seguito non riesce con il seguente messaggio:

PHP Warning: stream_socket_enable_crypto(): Peer certificate CN='myhost.com' did not match expected CN='localhost' in test.php

Il programma di test PHP:

$fp = stream_socket_client("tcp://localhost:993", $errno, $errstr, 30); 

// (*) if commented, the program fails 
//stream_context_set_option($fp, 'ssl', 'verify_peer_name', false); 

if (!$fp) { 
     die("Unable to connect: $errstr ($errno)"); 
} 
if (!stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { 
     die("Failed to start SSL"); 
} 
fwrite($fp, "USER god\r\n"); 
fwrite($fp, "PASS secret\r\n"); 
while ($motd = fgets($fp)) { 
     echo $motd; 
} 
fclose($fp); 

Come ho un sacco di eredità codice, mi piacerebbe avere una soluzione applicando solo le modifiche a php.ini (o CLI), ma sfortunatamente nessuna delle seguenti funzioni:

php -d verify_peer_name=false test.php

php -d ssl.verify_peer_name=false test.php

Idee?

Riferimenti:

+0

questo è solo un avvertimento, non dovrebbe mancare – cmorrissey

+2

Stampa un avviso alla console, ma in realtà 'stream_socket_enable_crypto()' restituisce 0 (fallisce). –

+0

Hai trovato la soluzione per questo? – Thibault

risposta

7

TL; DR

Quando cafile e capath sono allo stesso tempo runtime configuration e SSL context options, verify_peer_name e verify_peer sono solo SSL context options.

Quindi, quelli successivi non possono essere modificati tramite le direttive di configurazione runtime.


posso capire la confusione dalla documentazione riprodotta qui sotto, ma quei due paragrafi in realtà fare riferimento a due diversi concept in PHP.

Il fascio di default CA può essere sostituito su base globale impostando sia l'impostazione openssl.cafile o openssl.capath configurazione, o su una base per richiesta utilizzando il contesto CAFile o capath opzioni.

Anche se non è raccomandato in generale, è possibile disabilitare pari verifica dei certificati per una richiesta di impostando l'opzione contesto verify_peer FALSE, e per disattivare la convalida nome peer dal impostando l'opzione contesto verify_peer_name FALSE.

Link to PHP manual source

Prima nota che la documentazione si fa una chiara differenza tra openssl.cafile e openssl.capath essendo su base globale o su una base per ogni richiesta contro verify_peer e verify_peer_name essendo per una richiesta solo.

Quindi questo significa sostanzialmente che, quando openssl.cafile e openssl.capath possono essere adattate sia via php.ini o via stream_context_set_option, invece verify_peer e verify_peer_name sono accessibili solo tramite stream_context_set_option.

Questo è anche confermato dal codice sorgente PHP stesso, qui ci sono alcune linee che mostrano che PHP sotto la lingua C sta ottenendo il valore solo da php_stream_context_get_option.

must_verify_peer_name = GET_VER_OPT("verify_peer_name") 
     ? zend_is_true(val) 
     : sslsock->is_client; 

Link to PHP github source code

Per chiarezza, ecco la dichiarazione della macro GET_VER_OPT

#define GET_VER_OPT(name)    (PHP_STREAM_CONTEXT(stream) && (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", name)) != NULL) 

Link to PHP github source code

Quando cafile e capath sono effettivamente primo confrontati php_stream_context_get_option valore, ma poi, se quelli sono NULL nel contesto, vengono quindi recuperati nella configurazione ini.

GET_VER_OPT_STRING("cafile", cafile); 
GET_VER_OPT_STRING("capath", capath); 

if (cafile == NULL) { 
    cafile = zend_ini_string("openssl.cafile", sizeof("openssl.cafile")-1, 0); 
    cafile = strlen(cafile) ? cafile : NULL; 
} 

Link to PHP github source code

Poi un po 'più basso in esatta la stessa funzione:

if (capath == NULL) { 
    capath = zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0); 
    capath = strlen(capath) ? capath : NULL; 
} 

Link to PHP github source code

Per chiarezza, ecco la dichiarazione della macro GET_VER_OPT_STRING

#define GET_VER_OPT_STRING(name, str) if (GET_VER_OPT(name)) { convert_to_string_ex(val); str = Z_STRVAL_P(val); } 

Link to PHP github source code

Si può anche vedere che, quando quei due valore openssl.capth e openssl.cafile sono definiti come ini di configurazione, il più tardi verify_peer e verify_peer_name sono in nessun posto esistente da trovare.

così tristemente l'unico modo per andare, come la documentazione sta spingendo, è quello di configurarlo per una richiesta via stream_context_set_option ($stream_or_context , 'ssl' , 'verify_peer_name' , false)



Si prega di notare anche: il valore di default di queste due opzioni di contesto SSL modificato in PHP versione 5.6.0, come richiesto dalla documentazione:

5.6.0 aggiunto peer_fingerprint e verify_peer_name. verify_peer default è cambiato in TRUE.

Link to PHP documentation

Il che significa che questo tipo di problema può comparire dopo l'aggiornamento di PHP da PHP < 5.6.0 così, anche se io non consiglio che, dal PHP 5.5 is coming to the end of is support life cycle, il valore di default di queste due opzioni può essere ridotto al falso attenendosi a una versione PHP inferiore a 5.6.0.

+1

Ottima risposta a proposito; Sto [aspettando che il periodo di bounty finisca] (http://meta.stackoverflow.com/questions/323729/bounty-etiquette-early-awards) prima dell'assegnazione, ma non immagino che qualcuno stia per venire una risposta migliore di questa. – miken32

+0

Non ho visto il link al meta post a prima vista nel tuo commento. Penso che sia del tutto giusto lasciare la taglia aperta, davvero, non preoccuparti. –