A simple Qt based browser with no bullshit that supports PKCS#11 tokens (such as the SuisseID).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

259 lines
9.9 KiB

/*! @file
@id $Id: main.cxx 15 2010-06-03 14:17:27Z marc $
Build für Windoof:
<code>QMAKESPEC=$(pwd)/mkspecs/mingw-g++ qmake-qt4 && make release</code>
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
#include <qbrowserlib/log.hxx>
#include <qbrowserlib/browser.hxx>
#include <QApplication>
#include <QtCore/QTranslator>
#include <QtCore/QTextCodec>
#include <QtCore/QLocale>
#include <QtCore/QProcess>
#include <QtCore/QFileInfo>
#include <QtNetwork/QNetworkProxy>
#include <QtNetwork/QSslConfiguration>
#include <QtNetwork/QSslCertificate>
#include <QtNetwork/QSslKey>
#include <QWebSettings>
#include <iostream>
#include <sstream>
#include <memory>
//! @defgroup browser The Surfer Executable and Main Window
//! @defgroup pkcs11 The PKCS#11 Client Authentication
//! @defgroup qbrowserlib The Browser Library
//! @defgroup designer Qt Designer Plugin for Browser Related Widgets
/*! @mainpage The Secure PKCS#11 WebBrowser
The browser is divided into a library, @ref qbrowserlib that implements
generic browsing utilities, the main @ref browser page that collects
those features into a main window, a @ref pkcs11 SuisseID
hardware token client authentication and a @ref designer plugin for
flexible GUI creation.
*/
//! @addtogroup browser
//! @{
QMap<QString, QString>& env() {
static QStringList l(QProcess::systemEnvironment());
static QMap<QString, QString> env;
if (env.isEmpty())
for (QStringList::iterator it(l.begin()); it!=l.end(); ++it) {
QStringList v(it->split('='));
QString key(*v.begin());
QString value((v.pop_front(), v.join("=")));
env.insert(key, value);
}
return env;
}
QString helptext() {
return QObject::trUtf8
("Usage: %1 [OPTIONS...] [<url> ...]\n"
"Options:\n"
" -h, --help show this help text\n"
" -d, --debug enable verbose debug mode\n"
" -t --tmp path temporary folder for data caching\n"
" -k, --kiosk no url bar\n"
" if you sepcify -k and -s, -k must be first\n"
" -q, --quirks alternate user interface\n"
" -n, --no-settings don't load or store any settings\n"
" --login ask for smartcard password at startup\n"
" -l, --lib <file> path to file libengine_act.so\n"
" -s, --settings <file>\n"
" load settings from <file>\n"
" if you sepcify -k and -s, -k must be first\n"
" -c, --cert <file> load local client certificate from <file>\n"
" -y, --key <file> load local certificate key from <file>\n"
" -m, --mime <mime> <ext> <tool>\n"
" start <tool> for mimetype <mime>\n"
" -b, --bookmarks <file>\n"
" load and save bookmarks from and to <file>\n"
" -e, --edit-bookmarks\n"
" start in bookmark-edition mode\n"
" <url> optional full URL\n"
"Environment:\n"
" LANGUAGE \"de\", \"en\", ... "
"(actual: %5)\n"
" PROXY_TYPE \"http\" or \"socks\" or \"\" "
"(actual: %2)\n"
" PROXY_PORT proxy port number (actual: %3)\n"
" PROXY_HOST proxy host name (actual: %4)\n"
" _USERAGENT fake user agent (actual: %6)")
.arg(QFileInfo(QCoreApplication::arguments().at(0)).fileName())
.arg(env()["PROXY_TYPE"]).arg(env()["PROXY_PORT"]).arg(env()["PROXY_HOST"])
.arg(env()["LANGUAGE"]).arg(env()["_USERAGENT"]);
}
int main(int argv, char** argc) try {
//............................................................................
QSslConfiguration sslConfig(QSslConfiguration::defaultConfiguration());
sslConfig.setProtocol(QSsl::AnyProtocol);
sslConfig.setPeerVerifyMode(QSslSocket::AutoVerifyPeer);
//............................................................................
QTextCodec* utf8(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForLocale(utf8);
QApplication app(argv, argc);
app.setWindowIcon(QIcon(":/icons/32x32/surfer.png"));
app.setApplicationName(QObject::trUtf8("Surfer", "application name"));
app.setApplicationVersion(VERSION);
QTranslator qtTranslator;
if (env().contains("LANGUAGE")) QLocale::setDefault(env()["LANGUAGE"]);
qtTranslator.load(":/language/qt_" + QLocale().name());
app.installTranslator(&qtTranslator);
QTranslator appTranslator;
appTranslator.load(":/language/surfer_"+ QLocale().name());
app.installTranslator(&appTranslator);
//----------------------------------------------------------------------------
QString tmp(QDir::toNativeSeparators(QDir::tempPath()));
QStringList urls;
QString actlib
#ifdef Q_OS_LINUX
("libcvP11.so")
#else
#ifdef Q_OS_MAC
("libcvP11.dylib")
#else
#ifdef Q_OS_WIN
("cvP11.dll")
#endif
#endif
#endif
;
QWebSettings::globalSettings()->setAttribute
(QWebSettings::PluginsEnabled, true);
bool silent(false);
bool quirks(false);
bool login(false);
qbrowserlib::Settings::MimeTypes mimetypes;
QString bookmarks;
bool editbookmarks(false);
QStringList args(app.arguments());
std::unique_ptr<QSettings> settings
(std::unique_ptr<QSettings>(new QSettings("Sign", "Surfer")));
for (QStringList::iterator it(args.begin()); ++it!=args.end();)
if (*it=="-h" || *it=="--help" || *it=="-help" || *it=="/?") {
std::cout<<helptext().toStdString()<<std::endl;
return 0;
} else if (*it=="-d" || *it=="--debug") {
qbrowserlib::Log::DEBUG = true;
} else if ((*it=="-t" || *it=="--tmp") && ++it!=args.end()) {
tmp=*it;
} else if ((*it=="-k" || *it=="--kiosk")) {
silent=true;
settings.reset();
} else if ((*it=="-q" || *it=="--quirks")) {
quirks=true;
} else if ((*it=="-n" || *it=="--no-settings")) {
settings.reset();
} else if (*it=="--login") {
login = true;
} else if ((*it=="-l" || *it=="--lib") && ++it!=args.end()) {
actlib = *it;
} else if ((*it=="-b" || *it=="--bookmarks") && ++it!=args.end()) {
bookmarks = *it;
} else if ((*it=="-e" || *it=="--edit-bookmarks")) {
editbookmarks = true;
} else if ((*it=="-s" || *it=="--settings") && ++it!=args.end()) {
settings = std::unique_ptr<QSettings>
(new QSettings(*it, QSettings::IniFormat));
} else if ((*it=="-c" || *it=="--cert") && ++it!=args.end()) {
QFile file(*it);
file.open(QIODevice::ReadOnly);
QSslCertificate c(&file);
if (c.isNull()) {
std::cerr<<QObject::trUtf8("Cannot read PEM certificate from file: %1")
.arg(*it).toStdString()<<std::endl;
return 1;
}
sslConfig.setLocalCertificate(c);
file.close();
std::cout<<QObject::trUtf8("Read PEM certificates from file: %1")
.arg(*it).toStdString()<<std::endl;
} else if ((*it=="-y" || *it=="--key") && ++it!=args.end()) {
QFile file(*it);
file.open(QIODevice::ReadOnly);
QSslKey k(&file, QSsl::Rsa);
if (k.isNull()) {
std::cerr<<QObject::trUtf8("Cannot read PEM RSA key from file: %1")
.arg(*it).toStdString()<<std::endl;
return 1;
}
sslConfig.setPrivateKey(k);
std::cout<<QObject::trUtf8("Read private key from file: %1")
.arg(*it).toStdString()<<std::endl;
} else if ((*it=="-m" || *it=="--mime")
&& ++it!=args.end() && ++it!=args.end() && ++it!=args.end()) {
QString mt(*----it);
QString ext(*++it);
QString app(*++it);
mimetypes[mt] = QStringList()<<ext<<app;
} else if (it!=args.end()) {
urls<<*it;
} else {
std::cerr<<QObject::trUtf8("Too few arguments.\nTry: %1 --help")
.arg(QFileInfo(argc[0]).fileName()).toStdString()<<std::endl;
return 1;
}
TRC_FN;
QList<QSslCertificate> certs(sslConfig.caCertificates());
for (QList<QSslCertificate>::iterator cert(certs.begin());
cert!=certs.end(); ++cert) {
LOG_FN<<"CERTIFICATE: "
<<cert->issuerInfo(QSslCertificate::Organization)
<<cert->issuerInfo(QSslCertificate::CommonName)
<<cert->subjectInfo(QSslCertificate::Organization)
<<cert->subjectInfo(QSslCertificate::CommonName);
}
QSslConfiguration::setDefaultConfiguration(sslConfig);
//............................................................................
if (env()["PROXY_TYPE"]=="http")
QNetworkProxy::setApplicationProxy
(QNetworkProxy
(QNetworkProxy::HttpProxy,
env()["PROXY_HOST"], env()["PROXY_PORT"].toInt()));
if (env()["PROXY_TYPE"]=="socks")
QNetworkProxy::setApplicationProxy
(QNetworkProxy
(QNetworkProxy::Socks5Proxy,
env()["PROXY_HOST"], env()["PROXY_PORT"].toInt()));
else
QNetworkProxyFactory::setUseSystemConfiguration(true);
LOG_FN<<"Start - Proxy:"
<<(QNetworkProxy::applicationProxy().type()==QNetworkProxy::NoProxy
? "No Proxy"
: (QNetworkProxy::applicationProxy().type()
==QNetworkProxy::Socks5Proxy ? "socks" : "http"))
<<"Hostname"<<QNetworkProxy::applicationProxy().hostName()
<<"Port"<<QNetworkProxy::applicationProxy().port();
//............................................................................
qbrowserlib::Browser browser(actlib, urls, settings.get(), tmp, helptext(),
mimetypes, silent,
login, quirks, bookmarks);
if (editbookmarks) browser.on_actionEditBookmarks_triggered();
return app.exec();
} catch (std::exception& x) {
TRC_FN; LOG_FN<<"Terminated with Exception"<<x.what();
std::cerr<<"**** Terminated with Error:"
<<std::endl<<x.what()<<std::endl;
return 1;
} catch (...) {
// unexpected exception - just terminate
TRC_FN; LOG_FN<<"Terminated with unknown Exception";
std::cerr<<"**** Terminated with unknown Error"<<std::endl;
return 1;
}
//! @}