--- /dev/null
+build*
+*.pyc
+tags
)
endif()
endif()
- add_feature_info("WITH_WEBKIT, QtWebKit and QtWebKitWidgets modules" Qt5WebKitWidgets_FOUND "Support showing previews for URLs in chat")
+
+ if (WITH_WEBKIT AND Qt5WebKitWidgets_FOUND)
+ set(HAVE_WEBKIT true)
+ endif()
+ add_feature_info("WITH_WEBKIT, QtWebKit and QtWebKitWidgets modules" HAVE_WEBKIT "Support showing previews for URLs in chat")
# KDE Frameworks
################
# enviroment
if (NOT GIT_HEAD OR NOT GIT_DESCRIBE)
if (DEFINED ENV{GIT_HEAD})
- set(GIT_HEAD ${GIT_HEAD})
+ set(GIT_HEAD $ENV{GIT_HEAD})
endif ()
if (DEFINED ENV{GIT_DESCRIBE})
- set(GIT_DESCRIBE ${GIT_DESCRIBE})
+ set(GIT_DESCRIBE $ENV{GIT_DESCRIBE})
endif()
endif()
"""
-
-
class InstallQt(object):
- def __init__(self, appdir, bundle = True, requestedPlugins=[]):
+ def __init__(self, appdir, bundle=True, requestedPlugins=[]):
self.appDir = appdir
self.bundle = bundle
self.frameworkDir = self.appDir + "/Frameworks"
for executable in executables:
self.resolveDependancies(executable)
-
self.findPluginsPath()
self.installPlugins(requestedPlugins)
self.installQtConf()
raise OSError
return result
-
def installPlugins(self, requestedPlugins):
try:
os.mkdir(self.pluginDir)
def resolveDependancies(self, obj):
# obj must be either an application binary or a framework library
- #print "resolving deps for:", obj
+ # print "resolving deps for:", obj
for framework, lib in self.determineDependancies(obj):
self.installFramework(framework)
self.changeDylPath(obj, framework, lib)
except:
libname = ''
otoolProcess.stdout.close()
- if otoolProcess.wait() == 1: # we found some Resource dir or similar -> skip
+ if otoolProcess.wait() == 1: # we found some Resource dir or similar -> skip
continue
frameworkpath, libpath = libname.split(frameworkname)
if self.bundle:
newlibname = "@executable_path/../%s%s" % (frameworkname, libpath)
else:
newlibname = "@executable_path/%s%s" % (frameworkname, libpath)
- #print 'install_name_tool -id "%s" "%s"' % (newlibname, lib)
+ # print 'install_name_tool -id "%s" "%s"' % (newlibname, lib)
os.system('install_name_tool -id "%s" "%s"' % (newlibname, lib))
self.resolveDependancies(lib)
otoolPipe = Popen('otool -L "%s"' % app, shell=True, stdout=PIPE).stdout
otoolOutput = [line for line in otoolPipe]
otoolPipe.close()
- libs = [line.split()[0] for line in otoolOutput[1:] if ("Qt" in line
- or "phonon" in line)
- and not "@executable_path" in line]
- frameworks = [lib[:lib.find(".framework")+len(".framework")] for lib in libs]
- frameworks = [framework[framework.rfind('/')+1:] for framework in frameworks]
+ libs = [line.split()[0] for line in otoolOutput[1:] if ("Qt" in line or "phonon" in line) and "@executable_path" not in line]
+ frameworks = [lib[:lib.find(".framework") + len(".framework")] for lib in libs]
+ frameworks = [framework[framework.rfind('/') + 1:] for framework in frameworks]
return zip(frameworks, libs)
-
def changeDylPath(self, obj, framework, lib):
newlibname = framework + lib.split(framework)[1]
if self.bundle:
else:
newlibname = "@executable_path/Frameworks/%s" % newlibname
- #print 'install_name_tool -change "%s" "%s" "%s"' % (lib, newlibname, obj)
+ # print 'install_name_tool -change "%s" "%s" "%s"' % (lib, newlibname, obj)
os.system('install_name_tool -change "%s" "%s" "%s"' % (lib, newlibname, obj))
if __name__ == "__main__":
SOURCE_DIR = sys.argv[1]
if len(sys.argv) < 4:
- BUNDLE_NAME= "Quassel Client"
+ BUNDLE_NAME = "Quassel Client"
EXE_NAME = "quasselclient"
else:
EXE_NAME = sys.argv[3]
CONTENTS_DIR = os.path.dirname(EXE_NAME) + "/"
CONTENTS_DIR += BUNDLE_NAME + ".app/Contents/"
-BUNDLE_VERSION = commands.getoutput("git --git-dir="+SOURCE_DIR+"/.git/ describe")
+BUNDLE_VERSION = commands.getoutput("git --git-dir=" + SOURCE_DIR + "/.git/ describe")
ICON_FILE = "pics/quassel.icns"
+
def createBundle():
try:
os.makedirs(CONTENTS_DIR + "MacOS")
except:
pass
+
def copyFiles(exeFile, iconFile):
os.system("cp %s %sMacOs/%s" % (exeFile, CONTENTS_DIR.replace(' ', '\ '), BUNDLE_NAME.replace(' ', '\ ')))
os.system("cp %s/%s %s/Resources" % (SOURCE_DIR, iconFile, CONTENTS_DIR.replace(' ', '\ ')))
+
def createPlist(bundleName, iconFile, bundleVersion):
templateFile = file(SOURCE_DIR + "/scripts/build/Info.plist", 'r')
template = templateFile.read()
templateFile.close()
plistFile = file(CONTENTS_DIR + "Info.plist", 'w')
- plistFile.write(template % {"BUNDLE_NAME" : bundleName,
- "ICON_FILE" : iconFile[iconFile.rfind("/")+1:],
- "BUNDLE_VERSION" : bundleVersion})
+ plistFile.write(template % {"BUNDLE_NAME": bundleName,
+ "ICON_FILE": iconFile[iconFile.rfind("/") + 1:],
+ "BUNDLE_VERSION": bundleVersion})
plistFile.close()
if __name__ == "__main__":
createBundle()
createPlist(BUNDLE_NAME, ICON_FILE, BUNDLE_VERSION)
copyFiles(EXE_NAME, ICON_FILE)
- pass
#include "clientsettings.h"
#include "peerfactory.h"
+#if QT_VERSION < 0x050000
+# include "../../3rdparty/sha512/sha512.h"
+#endif
+
using namespace Protocol;
ClientAuthHandler::ClientAuthHandler(CoreAccount account, QObject *parent)
}
s.setAccountValue("ShowNoCoreSslWarning", false);
s.setAccountValue("SslCert", QString());
+ s.setAccountValue("SslCertDigestVersion", QVariant(QVariant::Int));
}
if (_legacy)
onConnectionReady();
// That way, a warning will appear in case it becomes invalid at some point
CoreAccountSettings s;
s.setAccountValue("SSLCert", QString());
+ s.setAccountValue("SslCertDigestVersion", QVariant(QVariant::Int));
}
emit encrypted(true);
CoreAccountSettings s;
QByteArray knownDigest = s.accountValue("SslCert").toByteArray();
+ ClientAuthHandler::DigestVersion knownDigestVersion = static_cast<ClientAuthHandler::DigestVersion>(s.accountValue("SslCertDigestVersion").toInt());
+
+ QByteArray calculatedDigest;
+ switch (knownDigestVersion) {
+ case ClientAuthHandler::DigestVersion::Md5:
+ calculatedDigest = socket->peerCertificate().digest(QCryptographicHash::Md5);
+ break;
- if (knownDigest != socket->peerCertificate().digest()) {
+ case ClientAuthHandler::DigestVersion::Sha2_512:
+#if QT_VERSION >= 0x050000
+ calculatedDigest = socket->peerCertificate().digest(QCryptographicHash::Sha512);
+#else
+ calculatedDigest = sha2_512(socket->peerCertificate().toDer());
+#endif
+ break;
+
+ default:
+ qWarning() << "Certificate digest version" << QString(knownDigestVersion) << "is not supported";
+ }
+
+ if (knownDigest != calculatedDigest) {
bool accepted = false;
bool permanently = false;
emit handleSslErrors(socket, &accepted, &permanently);
return;
}
- if (permanently)
- s.setAccountValue("SslCert", socket->peerCertificate().digest());
- else
+ if (permanently) {
+#if QT_VERSION >= 0x050000
+ s.setAccountValue("SslCert", socket->peerCertificate().digest(QCryptographicHash::Sha512));
+#else
+ s.setAccountValue("SslCert", sha2_512(socket->peerCertificate().toDer()));
+#endif
+ s.setAccountValue("SslCertDigestVersion", ClientAuthHandler::DigestVersion::Latest);
+ }
+ else {
s.setAccountValue("SslCert", QString());
+ s.setAccountValue("SslCertDigestVersion", QVariant(QVariant::Int));
+ }
+ }
+ else if (knownDigestVersion != ClientAuthHandler::DigestVersion::Latest) {
+#if QT_VERSION >= 0x050000
+ s.setAccountValue("SslCert", socket->peerCertificate().digest(QCryptographicHash::Sha512));
+#else
+ s.setAccountValue("SslCert", sha2_512(socket->peerCertificate().toDer()));
+#endif
+ s.setAccountValue("SslCertDigestVersion", ClientAuthHandler::DigestVersion::Latest);
}
socket->ignoreSslErrors();
}
+#if QT_VERSION < 0x050000
+QByteArray ClientAuthHandler::sha2_512(const QByteArray &input) {
+ unsigned char output[64];
+ sha512((unsigned char*) input.constData(), input.size(), output, false);
+ // QByteArray::fromRawData() cannot be used here because that constructor
+ // does not copy "output" and the data is clobbered when the variable goes
+ // out of scope.
+ QByteArray result;
+ result.append((char*) output, 64);
+ return result;
+}
+#endif
+
#endif /* HAVE_SSL */
public:
ClientAuthHandler(CoreAccount account, QObject *parent = 0);
+ enum DigestVersion {
+ Md5,
+ Sha2_512,
+ Latest=Sha2_512
+ };
+
public slots:
void connectToCore();
void checkAndEnableSsl(bool coreSupportsSsl);
void startRegistration();
+#if QT_VERSION < 0x050000
+ QByteArray sha2_512(const QByteArray &input);
+#endif
+
private slots:
void onSocketConnected();
void onSocketStateChanged(QAbstractSocket::SocketState state);
ChildStatus cs = _childStatus;
#ifndef QT_NO_DEBUG
QModelIndex parent = indexByItem(parentItem);
-#endif
Q_ASSERT(cs.parent == parent);
Q_ASSERT(rowCount(parent) == cs.childCount + cs.end - cs.start + 1);
-
+#endif
_aboutToRemoveOrInsert = false;
for (int i = cs.start; i <= cs.end; i++) {
connectItem(parentItem->child(i));
#ifndef QT_NO_DEBUG
ChildStatus cs = _childStatus;
QModelIndex parent = indexByItem(parentItem);
-#endif
Q_ASSERT(cs.parent == parent);
Q_ASSERT(rowCount(parent) == cs.childCount - cs.end + cs.start - 1);
+#endif
_aboutToRemoveOrInsert = false;
endRemoveRows();
# endif
#endif
- // Migrate settings from KDE4 to KF5 if appropriate
-#ifdef HAVE_KF5
- Kdelibs4ConfigMigrator migrator(QCoreApplication::applicationName());
- migrator.setConfigFiles(QStringList() << "quasselrc" << "quassel.notifyrc");
- migrator.migrate();
-#endif
-
AbstractCliParser *cliParser;
#ifdef HAVE_KDE4
cliParser->addOption("oidentd-conffile", 0, "Set path to oidentd configuration file", "file");
#ifdef HAVE_SSL
cliParser->addSwitch("require-ssl", 0, "Require SSL for remote (non-loopback) client connections");
+ cliParser->addOption("ssl-cert", 0, "Specify the path to the SSL Certificate", "path", "configdir/quasselCert.pem");
+ cliParser->addOption("ssl-key", 0, "Specify the path to the SSL key", "path", "ssl-cert-path");
#endif
cliParser->addSwitch("enable-experimental-dcc", 0, "Enable highly experimental and unfinished support for CTCP DCC (DANGEROUS)");
#endif
}
#endif
+// Migrate settings from KDE4 to KF5 if appropriate
+#ifdef HAVE_KF5
+ Kdelibs4ConfigMigrator migrator(QCoreApplication::applicationName());
+ migrator.setConfigFiles(QStringList() << "quasselrc" << "quassel.notifyrc");
+ migrator.migrate();
+#endif
+
#ifdef HAVE_KF5
// FIXME: This should be done after loading the translation catalogue, but still in main()
AboutData aboutData;
#define PEER_H
#include <QAbstractSocket>
+#include <QDataStream>
#include <QPointer>
#include "authhandler.h"
useSsl = _connectionFeatures & Protocol::Encryption;
if (Quassel::isOptionSet("require-ssl") && !useSsl && !_peer->isLocal()) {
+ quInfo() << qPrintable(tr("SSL required but non-SSL connection attempt from %1").arg(socket()->peerAddress().toString()));
_peer->dispatch(ClientDenied(tr("<b>SSL is required!</b><br>You need to use SSL in order to connect to this core.")));
_peer->close();
return;
UserId uid = Core::validateUser(msg.user, msg.password);
if (uid == 0) {
+ quInfo() << qPrintable(tr("Invalid login attempt from %1 as \"%2\"").arg(socket()->peerAddress().toString(), msg.user));
_peer->dispatch(LoginFailed(tr("<b>Invalid username or password!</b><br>The username/password combination you supplied could not be found in the database.")));
return;
}
_isCertValid(false)
{
static bool sslWarningShown = false;
- if (!setCertificate(Quassel::configDirPath() + "quasselCert.pem")) {
+
+ QString ssl_cert;
+ QString ssl_key;
+
+ if(Quassel::isOptionSet("ssl-cert")) {
+ ssl_cert = Quassel::optionValue("ssl-cert");
+ } else {
+ ssl_cert = Quassel::configDirPath() + "quasselCert.pem";
+ }
+
+ if(Quassel::isOptionSet("ssl-key")) {
+ ssl_key = Quassel::optionValue("ssl-key");
+ } else {
+ ssl_key = ssl_cert;
+ }
+
+ if (!setCertificate(ssl_cert, ssl_key)) {
if (!sslWarningShown) {
quWarning()
<< "SslServer: Unable to set certificate file\n"
}
-bool SslServer::setCertificate(const QString &path)
+bool SslServer::setCertificate(const QString &path, const QString &keyPath)
{
_isCertValid = false;
return false;
}
- _key = QSslKey(&certFile, QSsl::Rsa);
+ // load key from keyPath if it differs from path, otherwise load key from path
+ if(path != keyPath) {
+ QFile keyFile(keyPath);
+ if(!keyFile.exists()) {
+ quWarning() << "SslServer: Key file" << qPrintable(keyPath) << "does not exist";
+ return false;
+ }
+
+ if (!keyFile.open(QIODevice::ReadOnly)) {
+ quWarning()
+ << "SslServer: Failed to open key file" << qPrintable(keyPath)
+ << "error:" << keyFile.error();
+ return false;
+ }
+
+ _key = QSslKey(&keyFile, QSsl::Rsa);
+ keyFile.close();
+ } else {
+ _key = QSslKey(&certFile, QSsl::Rsa);
+ }
+
certFile.close();
if (_cert.isNull()) {
quWarning() << "SslServer: Certificate blacklisted";
}
if (_key.isNull()) {
- quWarning() << "SslServer:" << qPrintable(path) << "contains no key data";
+ quWarning() << "SslServer:" << qPrintable(keyPath) << "contains no key data";
return false;
}
virtual void incomingConnection(int socketDescriptor);
#endif
- virtual bool setCertificate(const QString &path);
+ virtual bool setCertificate(const QString &path, const QString &keyPath);
private:
QLinkedList<QTcpSocket *> _pendingConnections;
qt_add_dbus_adaptor (SOURCES ../../interfaces/org.kde.StatusNotifierItem.xml statusnotifieritemdbus.h StatusNotifierItemDBus)
endif()
-if (QT_QTWEBKIT_FOUND OR Qt5WebKitWidgets_FOUND)
+if (HAVE_WEBKIT)
add_definitions(-DHAVE_WEBKIT)
list(APPEND QT_MODULES WebKit)
if (USE_QT5)