Add support for specifying non-default CA certificate bundles.

This is done via SSL_CERT_DIR and --ssl-certstore.

Fixes issue #10916.

https://github.com/ariya/phantomjs/issues/10916
1.9
Jonathan Wilkins 2013-02-27 14:50:51 -08:00 committed by Ariya Hidayat
parent 52883ced68
commit 9f9053ec44
4 changed files with 59 additions and 0 deletions

View File

@ -33,6 +33,7 @@
#include "config.h"
#include <QDir>
#include <QFileInfo>
#include <QWebPage>
#include <QWebFrame>
#include <QNetworkProxy>
@ -66,6 +67,7 @@ static const struct QCommandLineConfigEntry flags[] =
{ QCommandLine::Option, '\0', "script-encoding", "Sets the encoding used for the starting script, default is 'utf8'", QCommandLine::Optional },
{ QCommandLine::Option, '\0', "web-security", "Enables web security, 'true' (default) or 'false'", QCommandLine::Optional },
{ QCommandLine::Option, '\0', "ssl-protocol", "Sets the SSL protocol (supported protocols: 'SSLv3' (default), 'SSLv2', 'TLSv1', 'any')", QCommandLine::Optional },
{ QCommandLine::Option, '\0', "ssl-certificates-path", "Sets the location for custom CA certificates (if none set, uses system default)", QCommandLine::Optional },
{ QCommandLine::Option, '\0', "webdriver", "Starts in 'Remote WebDriver mode' (embedded GhostDriver): '[[<IP>:]<PORT>]' (default '127.0.0.1:8910') ", QCommandLine::Optional },
{ QCommandLine::Option, '\0', "webdriver-logfile", "File where to write the WebDriver's Log (default 'none') (NOTE: needs '--webdriver') ", QCommandLine::Optional },
{ QCommandLine::Option, '\0', "webdriver-loglevel", "WebDriver Logging Level: (supported: 'ERROR', 'WARN', 'INFO', 'DEBUG') (default 'INFO') (NOTE: needs '--webdriver') ", QCommandLine::Optional },
@ -94,6 +96,10 @@ void Config::init(const QStringList *const args)
{
resetToDefaults();
QByteArray envSslCertDir = qgetenv("SSL_CERT_DIR");
if (!envSslCertDir.isEmpty())
setSslCertificatesPath(envSslCertDir);
processArgs(*args);
}
@ -542,6 +548,7 @@ void Config::resetToDefaults()
m_helpFlag = false;
m_printDebugMessages = false;
m_sslProtocol = "sslv3";
m_sslCertificatesPath.clear();
m_webdriverIp = QString();
m_webdriverPort = QString();
m_webdriverLogFile = QString();
@ -694,6 +701,9 @@ void Config::handleOption(const QString &option, const QVariant &value)
if (option == "ssl-protocol") {
setSslProtocol(value.toString());
}
if (option == "ssl-certificates-path") {
setSslCertificatesPath(value.toString());
}
if (option == "webdriver") {
setWebdriver(value.toString().length() > 0 ? value.toString() : DEFAULT_WEBDRIVER_CONFIG);
}
@ -732,3 +742,21 @@ void Config::setSslProtocol(const QString& sslProtocolName)
{
m_sslProtocol = sslProtocolName.toLower();
}
QString Config::sslCertificatesPath() const
{
return m_sslCertificatesPath;
}
void Config::setSslCertificatesPath(const QString& sslCertificatesPath)
{
QFileInfo sslPathInfo = QFileInfo(sslCertificatesPath);
if (sslPathInfo.isDir()) {
if (sslCertificatesPath.endsWith('/'))
m_sslCertificatesPath = sslCertificatesPath + "*";
else
m_sslCertificatesPath = sslCertificatesPath + "/*";
} else {
m_sslCertificatesPath = sslCertificatesPath;
}
}

View File

@ -58,6 +58,7 @@ class Config: public QObject
Q_PROPERTY(bool javascriptCanOpenWindows READ javascriptCanOpenWindows WRITE setJavascriptCanOpenWindows)
Q_PROPERTY(bool javascriptCanCloseWindows READ javascriptCanCloseWindows WRITE setJavascriptCanCloseWindows)
Q_PROPERTY(QString sslProtocol READ sslProtocol WRITE setSslProtocol)
Q_PROPERTY(QString sslCertificatesPath READ sslCertificatesPath WRITE setSslCertificatesPath)
Q_PROPERTY(QString webdriver READ webdriver WRITE setWebdriver)
Q_PROPERTY(QString webdriverLogFile READ webdriverLogFile WRITE setWebdriverLogFile)
Q_PROPERTY(QString webdriverLogLevel READ webdriverLogLevel WRITE setWebdriverLogLevel)
@ -156,6 +157,9 @@ public:
void setSslProtocol(const QString& sslProtocolName);
QString sslProtocol() const;
void setSslCertificatesPath(const QString& sslCertificatesPath);
QString sslCertificatesPath() const;
void setWebdriver(const QString& webdriverConfig);
QString webdriver() const;
bool isWebdriverMode() const;
@ -213,6 +217,7 @@ private:
bool m_javascriptCanOpenWindows;
bool m_javascriptCanCloseWindows;
QString m_sslProtocol;
QString m_sslCertificatesPath;
QString m_webdriverIp;
QString m_webdriverPort;
QString m_webdriverLogFile;

View File

@ -35,6 +35,8 @@
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QSslSocket>
#include <QSslCertificate>
#include <QRegExp>
#include "phantom.h"
#include "config.h"
@ -132,6 +134,13 @@ NetworkAccessManager::NetworkAccessManager(QObject *parent, const Config *config
} else if (config->sslProtocol() == "any") {
m_sslConfiguration.setProtocol(QSsl::AnyProtocol);
}
if (!config->sslCertificatesPath().isEmpty()) {
QList<QSslCertificate> caCerts = QSslCertificate::fromPath(
config->sslCertificatesPath(), QSsl::Pem, QRegExp::Wildcard);
m_sslConfiguration.setCaCertificates(caCerts);
}
}
connect(this, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(provideAuthentication(QNetworkReply*,QAuthenticator*)));

View File

@ -1148,6 +1148,23 @@ describe("WebPage object", function() {
expect(status).toEqual('success');
});
});
});
it('should fail on secure connection to url with bad cert', function() {
var page = require('webpage').create();
var url = 'https://tv.eurosport.com/';
/* example from:
* https://onlinessl.netlock.hu/en/test-center/bad-ssl-certificate-usage.html
*/
var handled = false;
runs(function() {
page.open(url, function(status) {
expect(status == 'success').toEqual(false);
handled = true;
});
});
waits(3000);