diff --git a/scripts/generateIceWrapper.py b/scripts/generateIceWrapper.py index 2a6eac385..eaf208983 100755 --- a/scripts/generateIceWrapper.py +++ b/scripts/generateIceWrapper.py @@ -37,23 +37,23 @@ def create_disclaimerComment(): def generateFunction(className, functionName, wrapArgs, callArgs): function = "void ::MumbleServer::" + className + "I::" + functionName + "_async(" + (", ".join(wrapArgs)) + ") {\n" - function += "\t// qWarning() << \"" + functionName + "\" << meta->mp.qsIceSecretRead.isNull() << meta->mp.qsIceSecretRead.isEmpty();\n" + function += "\t// qWarning() << \"" + functionName + "\" << ::Meta::mp->qsIceSecretRead.isNull() << ::Meta::mp->qsIceSecretRead.isEmpty();\n" function += "#ifndef ACCESS_" + className + "_" + functionName + "_ALL\n" function += "#\tifdef ACCESS_" + className + "_" + functionName + "_READ\n" - function += "\tif (!meta->mp.qsIceSecretRead.isNull()) {\n" - function += "\t\tbool ok = !meta->mp.qsIceSecretRead.isEmpty();\n" + function += "\tif (!::Meta::mp->qsIceSecretRead.isNull()) {\n" + function += "\t\tbool ok = !::Meta::mp->qsIceSecretRead.isEmpty();\n" function += "#\telse\n" - function += "\tif (!meta->mp.qsIceSecretRead.isNull() || !meta->mp.qsIceSecretWrite.isNull()) {\n" - function += "\t\tbool ok = !meta->mp.qsIceSecretWrite.isEmpty();\n" + function += "\tif (!::Meta::mp->qsIceSecretRead.isNull() || !::Meta::mp->qsIceSecretWrite.isNull()) {\n" + function += "\t\tbool ok = !::Meta::mp->qsIceSecretWrite.isEmpty();\n" function += "#\tendif // ACCESS_" + className + "_" + functionName + "_READ\n" function += "\t\t::Ice::Context::const_iterator i = current.ctx.find(\"secret\");\n" function += "\t\tok = ok && (i != current.ctx.end());\n" function += "\t\tif (ok) {\n" function += "\t\t\tconst QString &secret = u8((*i).second);\n" function += "#\tifdef ACCESS_" + className + "_" + functionName + "_READ\n" - function += "\t\t\tok = ((secret == meta->mp.qsIceSecretRead) || (secret == meta->mp.qsIceSecretWrite));\n" + function += "\t\t\tok = ((secret == ::Meta::mp->qsIceSecretRead) || (secret == ::Meta::mp->qsIceSecretWrite));\n" function += "#\telse\n" - function += "\t\t\tok = (secret == meta->mp.qsIceSecretWrite);\n" + function += "\t\t\tok = (secret == ::Meta::mp->qsIceSecretWrite);\n" function += "#\tendif // ACCESS_" + className + "_" + functionName + "_READ\n" function += "\t\t}\n" function += "\n" diff --git a/src/PacketDataStream.cpp b/src/PacketDataStream.cpp new file mode 100644 index 000000000..56a6d0451 --- /dev/null +++ b/src/PacketDataStream.cpp @@ -0,0 +1,353 @@ +// Copyright The Mumble Developers. All rights reserved. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file at the root of the +// Mumble source tree or at . + +#include "PacketDataStream.h" + +quint32 PacketDataStream::size() const { + return offset; +} + +quint32 PacketDataStream::capacity() const { + return maxsize; +} + +bool PacketDataStream::isValid() const { + return ok; +} + +quint32 PacketDataStream::left() const { + return maxsize - offset; +} + +quint32 PacketDataStream::undersize() const { + return overshoot; +} + +void PacketDataStream::append(const quint64 v) { +#ifndef QT_NO_DEBUG + Q_ASSERT(v <= 0xff); +#endif + if (offset < maxsize) + data[offset++] = static_cast< unsigned char >(v); + else { + ok = false; + overshoot++; + } +}; + +void PacketDataStream::append(const char *d, quint32 len) { + if (left() >= len) { + memcpy(&data[offset], d, len); + offset += len; + } else { + unsigned int l = left(); + memset(&data[offset], 0, l); + offset += l; + overshoot += len - l; + ok = false; + } +} + +void PacketDataStream::skip(quint32 len) { + if (left() >= len) + offset += len; + else + ok = false; +} + +quint64 PacketDataStream::next() { + if (offset < maxsize) + return data[offset++]; + else { + ok = false; + return 0; + } +}; + +quint8 PacketDataStream::next8() { + if (offset < maxsize) + return data[offset++]; + else { + ok = false; + return 0; + } +} + +void PacketDataStream::rewind() { + offset = 0; +} + +void PacketDataStream::truncate() { + maxsize = offset; +} + +const unsigned char *PacketDataStream::dataPtr() const { + return reinterpret_cast< const unsigned char * >(&data[offset]); +} + +unsigned char *PacketDataStream::dataPtr() { + return reinterpret_cast< unsigned char * >(&data[offset]); +} + +const char *PacketDataStream::charPtr() const { + return reinterpret_cast< const char * >(&data[offset]); +} + +QByteArray PacketDataStream::dataBlock(quint32 len) { + if (len <= left()) { + QByteArray a(charPtr(), static_cast< int >(len)); + offset += len; + return a; + } else { + ok = false; + return QByteArray(); + } +} + +void PacketDataStream::setup(unsigned char *d, unsigned int msize) { + data = d; + offset = 0; + overshoot = 0; + maxsize = msize; + ok = true; +} + +PacketDataStream::PacketDataStream(const unsigned char *d, unsigned int msize) { + setup(const_cast< unsigned char * >(d), msize); +}; + +PacketDataStream::PacketDataStream(const char *d, unsigned int msize) { + setup(const_cast< unsigned char * >(reinterpret_cast< const unsigned char * >(d)), msize); +}; + +PacketDataStream::PacketDataStream(char *d, unsigned int msize) { + setup(reinterpret_cast< unsigned char * >(d), msize); +}; + +PacketDataStream::PacketDataStream(unsigned char *d, unsigned int msize) { + setup(d, msize); +}; + +PacketDataStream::PacketDataStream(const QByteArray &qba) { + setup(const_cast< unsigned char * >(reinterpret_cast< const unsigned char * >(qba.constData())), + static_cast< unsigned int >(qba.size())); +} + +PacketDataStream::PacketDataStream(QByteArray &qba) { + unsigned char *ptr = reinterpret_cast< unsigned char * >(qba.data()); + setup(ptr, static_cast< unsigned int >(qba.capacity())); +} + +PacketDataStream &PacketDataStream::operator<<(const quint64 value) { + quint64 i = value; + + if ((i & 0x8000000000000000LL) && (~i < 0x100000000LL)) { + // Signed number. + i = ~i; + if (i <= 0x3) { + // Special case for -1 to -4. The most significant bits of the first byte must be (in binary) 111111 + // followed by the 2 bits representing the absolute value of the encoded number. Shortcase for -1 to -4 + append(0xFC | i); + return *this; + } else { + // Add flag byte, whose most significant bits are (in binary) 111110 that indicates + // that what follows is the varint encoding of the absolute value of i, but that the + // value itself is supposed to be negative. + append(0xF8); + } + } + if (i < 0x80) { + // Encode as 7-bit, positive number -> most significant bit of first byte must be zero + append(i); + } else if (i < 0x4000) { + // Encode as 14-bit, positive number -> most significant bits of first byte must be (in binary) 10 + append((i >> 8) | 0x80); + append(i & 0xFF); + } else if (i < 0x200000) { + // Encode as 21-bit, positive number -> most significant bits of first byte must be (in binary) 110 + append((i >> 16) | 0xC0); + append((i >> 8) & 0xFF); + append(i & 0xFF); + } else if (i < 0x10000000) { + // Encode as 28-bit, positive number -> most significant bits of first byte must be (in binary) 1110 + append((i >> 24) | 0xE0); + append((i >> 16) & 0xFF); + append((i >> 8) & 0xFF); + append(i & 0xFF); + } else if (i < 0x100000000LL) { + // Encode as 32-bit, positive number -> most significant bits of first byte must be (in binary) 111100 + // Remaining bits in first byte remain unused + append(0xF0); + append((i >> 24) & 0xFF); + append((i >> 16) & 0xFF); + append((i >> 8) & 0xFF); + append(i & 0xFF); + } else { + // Encode as 64-bit, positive number -> most significant bits of first byte must be (in binary) 111101 + // Remaining bits in first byte remain unused + append(0xF4); + append((i >> 56) & 0xFF); + append((i >> 48) & 0xFF); + append((i >> 40) & 0xFF); + append((i >> 32) & 0xFF); + append((i >> 24) & 0xFF); + append((i >> 16) & 0xFF); + append((i >> 8) & 0xFF); + append(i & 0xFF); + } + return *this; +} + +PacketDataStream &PacketDataStream::operator>>(quint64 &i) { + quint64 v = next(); + + if ((v & 0x80) == 0x00) { + i = (v & 0x7F); + } else if ((v & 0xC0) == 0x80) { + i = (v & 0x3F) << 8 | next(); + } else if ((v & 0xF0) == 0xF0) { + switch (v & 0xFC) { + case 0xF0: + i = next() << 24 | next() << 16 | next() << 8 | next(); + break; + case 0xF4: + i = next() << 56 | next() << 48 | next() << 40 | next() << 32 | next() << 24 | next() << 16 + | next() << 8 | next(); + break; + case 0xF8: + *this >> i; + i = ~i; + break; + case 0xFC: + i = v & 0x03; + i = ~i; + break; + default: + ok = false; + i = 0; + break; + } + } else if ((v & 0xF0) == 0xE0) { + i = (v & 0x0F) << 24 | next() << 16 | next() << 8 | next(); + } else if ((v & 0xE0) == 0xC0) { + i = (v & 0x1F) << 16 | next() << 8 | next(); + } + return *this; +} + +PacketDataStream &PacketDataStream::operator<<(const QByteArray &a) { + *this << a.size(); + append(a.constData(), static_cast< unsigned int >(a.size())); + return *this; +} + +PacketDataStream &PacketDataStream::operator>>(QByteArray &a) { + quint32 len; + *this >> len; + if (len > left()) { + len = left(); + ok = false; + } + a = QByteArray(reinterpret_cast< const char * >(&data[offset]), static_cast< int >(len)); + offset += len; + return *this; +} + +PacketDataStream &PacketDataStream::operator<<(const QString &s) { + return *this << s.toUtf8(); +} + +// Using the data directly instead of through qbuff avoids a copy. +PacketDataStream &PacketDataStream::operator>>(QString &s) { + quint32 len; + *this >> len; + if (len > left()) { + len = left(); + ok = false; + } + s = QString::fromUtf8(reinterpret_cast< const char * >(&data[offset]), static_cast< int >(len)); + offset += len; + return *this; +} + +PacketDataStream &PacketDataStream::operator<<(const bool b) { + quint32 v = b ? 1 : 0; + return *this << v; +} + +PacketDataStream &PacketDataStream::operator>>(bool &b) { + quint32 v; + *this >> v; + b = v ? true : false; + return *this; +} + +union double64u { + quint64 ui; + double d; +}; + +PacketDataStream &PacketDataStream::operator<<(const double v) { + double64u u; + u.d = v; + return *this << u.ui; +} + +PacketDataStream &PacketDataStream::operator>>(double &v) { + double64u u; + *this >> u.ui; + v = u.d; + return *this; +} + +union float32u { + quint8 ui[4]; + float f; +}; + +PacketDataStream &PacketDataStream::operator<<(const float v) { + float32u u; + u.f = v; + append(u.ui[0]); + append(u.ui[1]); + append(u.ui[2]); + append(u.ui[3]); + return *this; +} + +PacketDataStream &PacketDataStream::operator>>(float &v) { + float32u u; + if (left() < 4) { + ok = false; + v = 0; + } + u.ui[0] = next8(); + u.ui[1] = next8(); + u.ui[2] = next8(); + u.ui[3] = next8(); + v = u.f; + return *this; +} + +#define INTMAPOPERATOR(type) \ + template<> PacketDataStream &PacketDataStream::operator<<< type >(const type v) { \ + return *this << static_cast< quint64 >(v); \ + } \ + template<> PacketDataStream &PacketDataStream::operator>>< type >(type &v) { \ + quint64 vv; \ + *this >> vv; \ + v = static_cast< type >(vv); \ + return *this; \ + } + +// INTMAPOPERATOR(qsizetype); +INTMAPOPERATOR(int); +INTMAPOPERATOR(unsigned int); +INTMAPOPERATOR(short); +INTMAPOPERATOR(unsigned short); +INTMAPOPERATOR(char); +INTMAPOPERATOR(unsigned char); + +#undef INTMAPOPERATOR diff --git a/src/backup b/src/backup new file mode 100644 index 000000000..6edac69a2 --- /dev/null +++ b/src/backup @@ -0,0 +1,187 @@ +// Copyright The Mumble Developers. All rights reserved. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file at the root of the +// Mumble source tree or at . + +#ifndef MUMBLE_PACKETDATASTREAM_H_ +#define MUMBLE_PACKETDATASTREAM_H_ + +#include +#include +#include + +#include +#include +#include + +class PacketDataStream { +private: + Q_DISABLE_COPY(PacketDataStream) +private: + unsigned char *data; + quint32 maxsize; + quint32 offset; + quint32 overshoot; + bool ok; + +public: + quint32 size() const; + + quint32 capacity() const; + + bool isValid() const; + + quint32 left() const; + + quint32 undersize() const; + + void append(const quint64 v); + + void append(const char *d, quint32 len); + + void skip(quint32 len); + + quint64 next(); + quint8 next8(); + void rewind(); + + void truncate(); + + const unsigned char *dataPtr() const; + + unsigned char *dataPtr(); + + const char *charPtr() const; + + QByteArray dataBlock(quint32 len); + +protected: + void setup(unsigned char *d, unsigned int msize); + +public: + PacketDataStream(const unsigned char *d, unsigned int msize); + + PacketDataStream(const char *d, unsigned int msize); + + PacketDataStream(char *d, unsigned int msize); + + PacketDataStream(unsigned char *d, unsigned int msize); + + PacketDataStream(const QByteArray &qba); + + PacketDataStream(QByteArray &qba); + + PacketDataStream &operator<<(const quint64 value); + + PacketDataStream &operator>>(quint64 &i); + + PacketDataStream &operator<<(const QByteArray &a); + + PacketDataStream &operator>>(QByteArray &a); + + PacketDataStream &operator<<(const QString &s); + + // Using the data directly instead of through qbuff avoids a copy. + PacketDataStream &operator>>(QString &s); + + PacketDataStream &operator<<(const bool b); + + PacketDataStream &operator>>(bool &b); + + template< typename Integer, typename = std::enable_if_t< std::is_integral_v< Integer > > > + PacketDataStream &operator<<(const Integer v); + template< typename Integer, typename = std::enable_if_t< std::is_integral_v< Integer > > > + PacketDataStream &operator>>(Integer &v); + + PacketDataStream &operator<<(const double v); + + PacketDataStream &operator>>(double &v); + + PacketDataStream &operator<<(const float v); + + PacketDataStream &operator>>(float &v); + + template< typename T > PacketDataStream &operator<<(const QList< T > &l) { + *this << l.size(); + for (int i = 0; i < l.size(); i++) + *this << l.at(i); + return *this; + } + + template< typename T > PacketDataStream &operator>>(QList< T > &l) { + l.clear(); + quint32 len; + *this >> len; + if (len > left()) { + len = left(); + ok = false; + } + for (quint32 i = 0; i < len; i++) { + if (left() == 0) { + ok = false; + break; + } + + T t; + *this >> t; + l.append(t); + } + return *this; + } + + + template< typename T > PacketDataStream &operator<<(const QSet< T > &s) { + *this << s.size(); + for (typename QSet< T >::const_iterator i = s.constBegin(); i != s.constEnd(); ++i) + *this << *i; + return *this; + } + + template< typename T > PacketDataStream &operator>>(QSet< T > &s) { + s.clear(); + quint32 len; + *this >> len; + if (len > left()) { + len = left(); + ok = false; + } + for (quint32 i = 0; i < len; i++) { + if (left() == 0) { + ok = false; + break; + } + + T t; + *this >> t; + s.insert(t); + } + return *this; + } + + template< typename T, typename U > PacketDataStream &operator<<(const QPair< T, U > &p) { + return *this << p.first << p.second; + } + + template< typename T, typename U > PacketDataStream &operator>>(QPair< T, U > &p) { + return *this >> p.first >> p.second; + } +}; + +#define INTMAPOPERATOR_DECLARE(type) \ + template<> PacketDataStream &PacketDataStream::operator<<< type >(const type v); \ + template<> PacketDataStream &PacketDataStream::operator>>< type >(type &v); + +//INTMAPOPERATOR_DECLARE(qsizetype) +INTMAPOPERATOR_DECLARE(std::int8_t) +INTMAPOPERATOR_DECLARE(std::uint8_t) +INTMAPOPERATOR_DECLARE(std::int16_t) +INTMAPOPERATOR_DECLARE(std::uint16_t) +INTMAPOPERATOR_DECLARE(std::int32_t) +INTMAPOPERATOR_DECLARE(std::uint32_t) +INTMAPOPERATOR_DECLARE(std::int64_t) +INTMAPOPERATOR_DECLARE(std::uint64_t) + +#undef INTMAPOPERATOR_DECLARE + + +#endif diff --git a/src/murmur/Cert.cpp b/src/murmur/Cert.cpp index afbf00f09..71ec363df 100644 --- a/src/murmur/Cert.cpp +++ b/src/murmur/Cert.cpp @@ -81,7 +81,7 @@ void Server::initializeCert() { crt = getConf("certificate", QString()).toByteArray(); key = getConf("key", QString()).toByteArray(); pass = getConf("passphrase", QByteArray()).toByteArray(); - dhparams = getConf("sslDHParams", Meta::mp.qbaDHParams).toByteArray(); + dhparams = getConf("sslDHParams", Meta::mp->qbaDHParams).toByteArray(); QList< QSslCertificate > ql; @@ -148,10 +148,10 @@ void Server::initializeCert() { // This allows a self-signed certificate generated by Murmur to be // replaced by a CA-signed certificate in the .ini file. if (!qscCert.isNull() && issuer.startsWith(QString::fromUtf8("Murmur Autogenerated Certificate")) - && !Meta::mp.qscCert.isNull() && !Meta::mp.qskKey.isNull() && (Meta::mp.qlBind == qlBind)) { - qscCert = Meta::mp.qscCert; - qskKey = Meta::mp.qskKey; - qlIntermediates = Meta::mp.qlIntermediates; + && !Meta::mp->qscCert.isNull() && !Meta::mp->qskKey.isNull() && (Meta::mp->qlBind == qlBind)) { + qscCert = Meta::mp->qscCert; + qskKey = Meta::mp->qskKey; + qlIntermediates = Meta::mp->qlIntermediates; if (!qscCert.isNull() && !qskKey.isNull()) { bUsingMetaCert = true; @@ -164,9 +164,9 @@ void Server::initializeCert() { log("Certificate specified, but failed to load."); } - qskKey = Meta::mp.qskKey; - qscCert = Meta::mp.qscCert; - qlIntermediates = Meta::mp.qlIntermediates; + qskKey = Meta::mp->qskKey; + qscCert = Meta::mp->qscCert; + qlIntermediates = Meta::mp->qlIntermediates; if (!qscCert.isNull() && !qskKey.isNull()) { bUsingMetaCert = true; diff --git a/src/murmur/Messages.cpp b/src/murmur/Messages.cpp index ae4f7eb64..afb96c4b7 100644 --- a/src/murmur/Messages.cpp +++ b/src/murmur/Messages.cpp @@ -610,14 +610,14 @@ void Server::msgAuthenticate(ServerUser *uSource, MumbleProto::Authenticate &msg sendMessage(uSource, mpsug); } - if (uSource->m_version < Version::fromComponents(1, 4, 0) && Meta::mp.iMaxListenersPerChannel != 0 - && Meta::mp.iMaxListenerProxiesPerUser != 0) { + if (uSource->m_version < Version::fromComponents(1, 4, 0) && Meta::mp->iMaxListenersPerChannel != 0 + && Meta::mp->iMaxListenerProxiesPerUser != 0) { // The server has the ChannelListener feature enabled but the client that connects doesn't have version 1.4.0 or // newer meaning that this client doesn't know what ChannelListeners are. Thus we'll send that user a // text-message informing about this. MumbleProto::TextMessage mptm; - if (Meta::mp.bAllowHTML) { + if (Meta::mp->bAllowHTML) { mptm.set_message("[WARNING]: This server has the ChannelListener feature enabled but your " "client version does not support it. " "This means that users might be listening to what you are saying in your channel " @@ -797,16 +797,17 @@ void Server::msgUserState(ServerUser *uSource, MumbleProto::UserState &msg) { continue; } - if (Meta::mp.iMaxListenersPerChannel >= 0 - && Meta::mp.iMaxListenersPerChannel - m_channelListenerManager.getListenerCountForChannel(c->iId) - 1 < 0) { + if (Meta::mp->iMaxListenersPerChannel >= 0 + && Meta::mp->iMaxListenersPerChannel - m_channelListenerManager.getListenerCountForChannel(c->iId) - 1 + < 0) { // A limit for the amount of listener proxies per channel is set and it has been reached already PERM_DENIED_FALLBACK(ChannelListenerLimit, Version::fromComponents(1, 4, 0), QLatin1String("No more listeners allowed in this channel")); continue; } - if (Meta::mp.iMaxListenerProxiesPerUser >= 0 - && Meta::mp.iMaxListenerProxiesPerUser + if (Meta::mp->iMaxListenerProxiesPerUser >= 0 + && Meta::mp->iMaxListenerProxiesPerUser - m_channelListenerManager.getListenedChannelCountForUser(uSource->uiSession) - passedChannelListener - 1 < 0) { @@ -1856,11 +1857,11 @@ void Server::msgACL(ServerUser *uSource, MumbleProto::ACL &msg) { QHash< QString, QSet< int > > hOldTemp; - if (Meta::mp.bLogGroupChanges || Meta::mp.bLogACLChanges) { + if (Meta::mp->bLogGroupChanges || Meta::mp->bLogACLChanges) { log(uSource, QString::fromLatin1("Updating ACL in channel %1").arg(*c)); } - if (Meta::mp.bLogGroupChanges) { + if (Meta::mp->bLogGroupChanges) { logGroups(this, c, QLatin1String("These are the groups before applying the change:")); } @@ -1869,7 +1870,7 @@ void Server::msgACL(ServerUser *uSource, MumbleProto::ACL &msg) { delete g; } - if (Meta::mp.bLogACLChanges) { + if (Meta::mp->bLogACLChanges) { logACLs(this, c, QLatin1String("These are the ACLs before applying the changed:")); } @@ -1897,7 +1898,7 @@ void Server::msgACL(ServerUser *uSource, MumbleProto::ACL &msg) { g->qsTemporary = hOldTemp.value(g->qsName); } - if (Meta::mp.bLogGroupChanges) { + if (Meta::mp->bLogGroupChanges) { logGroups(this, c, QLatin1String("And these are the new groups:")); } @@ -1918,7 +1919,7 @@ void Server::msgACL(ServerUser *uSource, MumbleProto::ACL &msg) { a->pAllow = static_cast< ChanACL::Permissions >(mpacl.grant()) & ChanACL::All; } - if (Meta::mp.bLogACLChanges) { + if (Meta::mp->bLogACLChanges) { logACLs(this, c, QLatin1String("And these are the new ACLs:")); } } diff --git a/src/murmur/Meta.cpp b/src/murmur/Meta.cpp index ef750b547..c0971149a 100644 --- a/src/murmur/Meta.cpp +++ b/src/murmur/Meta.cpp @@ -37,7 +37,7 @@ #include -MetaParams Meta::mp; +std::unique_ptr< MetaParams > Meta::mp; #ifdef Q_OS_WIN HANDLE Meta::hQoS = nullptr; @@ -651,7 +651,7 @@ Meta::~Meta() { bool Meta::reloadSSLSettings() { // Reload SSL settings. - if (!Meta::mp.loadSSLSettings()) { + if (!Meta::mp->loadSSLSettings()) { return false; } @@ -744,7 +744,7 @@ void Meta::killAll() { } void Meta::successfulConnectionFrom(const QHostAddress &addr) { - if (!mp.bBanSuccessful) { + if (!mp->bBanSuccessful) { QList< Timer > &ql = qhAttempts[addr]; // Seems like this is the most efficient way to clear the list, given: // 1. ql.clear() allocates a new array @@ -757,12 +757,12 @@ void Meta::successfulConnectionFrom(const QHostAddress &addr) { } bool Meta::banCheck(const QHostAddress &addr) { - if ((mp.iBanTries <= 0) || (mp.iBanTimeframe <= 0)) + if ((mp->iBanTries <= 0) || (mp->iBanTimeframe <= 0)) return false; if (qhBans.contains(addr)) { Timer t = qhBans.value(addr); - if (t.elapsed() < (1000000ULL * static_cast< unsigned long long >(mp.iBanTime))) + if (t.elapsed() < (1000000ULL * static_cast< unsigned long long >(mp->iBanTime))) return true; qhBans.remove(addr); } @@ -770,10 +770,10 @@ bool Meta::banCheck(const QHostAddress &addr) { QList< Timer > &ql = qhAttempts[addr]; ql.append(Timer()); - while (!ql.isEmpty() && (ql.at(0).elapsed() > (1000000ULL * static_cast< unsigned long long >(mp.iBanTimeframe)))) + while (!ql.isEmpty() && (ql.at(0).elapsed() > (1000000ULL * static_cast< unsigned long long >(mp->iBanTimeframe)))) ql.removeFirst(); - if (ql.count() > mp.iBanTries) { + if (ql.count() > mp->iBanTries) { qhBans.insert(addr, Timer()); return true; } diff --git a/src/murmur/Meta.h b/src/murmur/Meta.h index 4a151506e..c409da67b 100644 --- a/src/murmur/Meta.h +++ b/src/murmur/Meta.h @@ -24,6 +24,8 @@ #include #include +#include + class Server; class QSettings; @@ -177,7 +179,7 @@ private: Q_DISABLE_COPY(Meta) public: - static MetaParams mp; + static std::unique_ptr< MetaParams > mp; QHash< int, Server * > qhServers; QHash< QHostAddress, QList< Timer > > qhAttempts; QHash< QHostAddress, Timer > qhBans; diff --git a/src/murmur/MumbleServerIce.cpp b/src/murmur/MumbleServerIce.cpp index cb6477eb4..11a6ff82d 100644 --- a/src/murmur/MumbleServerIce.cpp +++ b/src/murmur/MumbleServerIce.cpp @@ -231,16 +231,16 @@ public: MumbleServerIce::MumbleServerIce() { count = 0; - if (meta->mp.qsIceEndpoint.isEmpty()) + if (::Meta::mp->qsIceEndpoint.isEmpty()) return; Ice::PropertiesPtr ipp = Ice::createProperties(); - ::Meta::mp.qsSettings->beginGroup("Ice"); - foreach (const QString &v, ::Meta::mp.qsSettings->childKeys()) { - ipp->setProperty(iceString(v), iceString(::Meta::mp.qsSettings->value(v).toString())); + ::Meta::mp->qsSettings->beginGroup("Ice"); + foreach (const QString &v, ::Meta::mp->qsSettings->childKeys()) { + ipp->setProperty(iceString(v), iceString(::Meta::mp->qsSettings->value(v).toString())); } - ::Meta::mp.qsSettings->endGroup(); + ::Meta::mp->qsSettings->endGroup(); Ice::PropertyDict props = ippProperties->getPropertiesForPrefix(""); Ice::PropertyDict::iterator i; @@ -254,12 +254,13 @@ MumbleServerIce::MumbleServerIce() { try { communicator = Ice::initialize(idd); - if (!meta->mp.qsIceSecretWrite.isEmpty()) { + if (!::Meta::mp->qsIceSecretWrite.isEmpty()) { ::Ice::ImplicitContextPtr impl = communicator->getImplicitContext(); if (impl) - impl->put("secret", iceString(meta->mp.qsIceSecretWrite)); + impl->put("secret", iceString(::Meta::mp->qsIceSecretWrite)); } - adapter = communicator->createObjectAdapterWithEndpoints("Mumble Server", qPrintable(meta->mp.qsIceEndpoint)); + adapter = + communicator->createObjectAdapterWithEndpoints("Mumble Server", qPrintable(::Meta::mp->qsIceEndpoint)); MetaPtr m = new MetaI; #if ICE_INT_VERSION >= 30700 MetaPrx mprx = MetaPrx::uncheckedCast(adapter->add(m, Ice::stringToIdentity("Meta"))); @@ -1933,7 +1934,7 @@ static void impl_Meta_getAllServers(const ::MumbleServer::AMD_Meta_getAllServers static void impl_Meta_getDefaultConf(const ::MumbleServer::AMD_Meta_getDefaultConfPtr cb, const Ice::ObjectAdapterPtr) { ::MumbleServer::ConfigMap cm; QMap< QString, QString >::const_iterator i; - for (i = meta->mp.qmConfig.constBegin(); i != meta->mp.qmConfig.constEnd(); ++i) { + for (i = ::Meta::mp->qmConfig.constBegin(); i != ::Meta::mp->qmConfig.constEnd(); ++i) { if (i.key() == "key" || i.key() == "passphrase") continue; cm[iceString(i.key())] = iceString(i.value()); diff --git a/src/murmur/Register.cpp b/src/murmur/Register.cpp index b9f2de027..2af433fe4 100644 --- a/src/murmur/Register.cpp +++ b/src/murmur/Register.cpp @@ -105,12 +105,12 @@ void Server::update() { /* Work around bug in QSslConfiguration */ QList< QSslCertificate > calist = ssl.caCertificates(); calist << QSslConfiguration::defaultConfiguration().caCertificates(); - calist << Meta::mp.qlCA; - calist << Meta::mp.qlIntermediates; + calist << Meta::mp->qlCA; + calist << Meta::mp->qlIntermediates; calist << qscCert; ssl.setCaCertificates(calist); - ssl.setCiphers(Meta::mp.qlCiphers); + ssl.setCiphers(Meta::mp->qlCiphers); qnr.setSslConfiguration(ssl); diff --git a/src/murmur/Server.cpp b/src/murmur/Server.cpp index 17800b3c6..983247f82 100644 --- a/src/murmur/Server.cpp +++ b/src/murmur/Server.cpp @@ -323,44 +323,44 @@ Server::~Server() { } void Server::readParams() { - qsPassword = Meta::mp.qsPassword; - usPort = static_cast< unsigned short >(Meta::mp.usPort + iServerNum - 1); - iTimeout = Meta::mp.iTimeout; - iMaxBandwidth = Meta::mp.iMaxBandwidth; - iMaxUsers = Meta::mp.iMaxUsers; - iMaxUsersPerChannel = Meta::mp.iMaxUsersPerChannel; - iMaxTextMessageLength = Meta::mp.iMaxTextMessageLength; - iMaxImageMessageLength = Meta::mp.iMaxImageMessageLength; - bAllowHTML = Meta::mp.bAllowHTML; - iDefaultChan = Meta::mp.iDefaultChan; - bRememberChan = Meta::mp.bRememberChan; - iRememberChanDuration = Meta::mp.iRememberChanDuration; - qsWelcomeText = Meta::mp.qsWelcomeText; - qsWelcomeTextFile = Meta::mp.qsWelcomeTextFile; - qlBind = Meta::mp.qlBind; - qsRegName = Meta::mp.qsRegName; - qsRegPassword = Meta::mp.qsRegPassword; - qsRegHost = Meta::mp.qsRegHost; - qsRegLocation = Meta::mp.qsRegLocation; - qurlRegWeb = Meta::mp.qurlRegWeb; - bBonjour = Meta::mp.bBonjour; - bAllowPing = Meta::mp.bAllowPing; - allowRecording = Meta::mp.allowRecording; - bCertRequired = Meta::mp.bCertRequired; - bForceExternalAuth = Meta::mp.bForceExternalAuth; - qrUserName = Meta::mp.qrUserName; - qrChannelName = Meta::mp.qrChannelName; - iMessageLimit = Meta::mp.iMessageLimit; - iMessageBurst = Meta::mp.iMessageBurst; - iPluginMessageLimit = Meta::mp.iPluginMessageLimit; - iPluginMessageBurst = Meta::mp.iPluginMessageBurst; - broadcastListenerVolumeAdjustments = Meta::mp.broadcastListenerVolumeAdjustments; - m_suggestVersion = Meta::mp.m_suggestVersion; - qvSuggestPositional = Meta::mp.qvSuggestPositional; - qvSuggestPushToTalk = Meta::mp.qvSuggestPushToTalk; - iOpusThreshold = Meta::mp.iOpusThreshold; - iChannelNestingLimit = Meta::mp.iChannelNestingLimit; - iChannelCountLimit = Meta::mp.iChannelCountLimit; + qsPassword = Meta::mp->qsPassword; + usPort = static_cast< unsigned short >(Meta::mp->usPort + iServerNum - 1); + iTimeout = Meta::mp->iTimeout; + iMaxBandwidth = Meta::mp->iMaxBandwidth; + iMaxUsers = Meta::mp->iMaxUsers; + iMaxUsersPerChannel = Meta::mp->iMaxUsersPerChannel; + iMaxTextMessageLength = Meta::mp->iMaxTextMessageLength; + iMaxImageMessageLength = Meta::mp->iMaxImageMessageLength; + bAllowHTML = Meta::mp->bAllowHTML; + iDefaultChan = Meta::mp->iDefaultChan; + bRememberChan = Meta::mp->bRememberChan; + iRememberChanDuration = Meta::mp->iRememberChanDuration; + qsWelcomeText = Meta::mp->qsWelcomeText; + qsWelcomeTextFile = Meta::mp->qsWelcomeTextFile; + qlBind = Meta::mp->qlBind; + qsRegName = Meta::mp->qsRegName; + qsRegPassword = Meta::mp->qsRegPassword; + qsRegHost = Meta::mp->qsRegHost; + qsRegLocation = Meta::mp->qsRegLocation; + qurlRegWeb = Meta::mp->qurlRegWeb; + bBonjour = Meta::mp->bBonjour; + bAllowPing = Meta::mp->bAllowPing; + allowRecording = Meta::mp->allowRecording; + bCertRequired = Meta::mp->bCertRequired; + bForceExternalAuth = Meta::mp->bForceExternalAuth; + qrUserName = Meta::mp->qrUserName; + qrChannelName = Meta::mp->qrChannelName; + iMessageLimit = Meta::mp->iMessageLimit; + iMessageBurst = Meta::mp->iMessageBurst; + iPluginMessageLimit = Meta::mp->iPluginMessageLimit; + iPluginMessageBurst = Meta::mp->iPluginMessageBurst; + broadcastListenerVolumeAdjustments = Meta::mp->broadcastListenerVolumeAdjustments; + m_suggestVersion = Meta::mp->m_suggestVersion; + qvSuggestPositional = Meta::mp->qvSuggestPositional; + qvSuggestPushToTalk = Meta::mp->qvSuggestPushToTalk; + iOpusThreshold = Meta::mp->iOpusThreshold; + iChannelNestingLimit = Meta::mp->iChannelNestingLimit; + iChannelCountLimit = Meta::mp->iChannelCountLimit; QString qsHost = getConf("host", QString()).toString(); if (!qsHost.isEmpty()) { @@ -387,7 +387,7 @@ void Server::readParams() { foreach (const QHostAddress &qha, qlBind) log(QString("Binding to address %1").arg(qha.toString())); if (qlBind.isEmpty()) - qlBind = Meta::mp.qlBind; + qlBind = Meta::mp->qlBind; } qsPassword = getConf("password", qsPassword).toString(); @@ -476,11 +476,11 @@ void Server::setLiveConf(const QString &key, const QString &value) { QString v = value.trimmed().isEmpty() ? QString() : value; int i = v.toInt(); if ((key == "password") || (key == "serverpassword")) - qsPassword = !v.isNull() ? v : Meta::mp.qsPassword; + qsPassword = !v.isNull() ? v : Meta::mp->qsPassword; else if (key == "timeout") - iTimeout = i ? i : Meta::mp.iTimeout; + iTimeout = i ? i : Meta::mp->iTimeout; else if (key == "bandwidth") { - int length = i ? i : Meta::mp.iMaxBandwidth; + int length = i ? i : Meta::mp->iMaxBandwidth; if (length != iMaxBandwidth) { iMaxBandwidth = length; MumbleProto::ServerConfig mpsc; @@ -488,7 +488,7 @@ void Server::setLiveConf(const QString &key, const QString &value) { sendAll(mpsc); } } else if (key == "users") { - unsigned int newmax = i ? static_cast< unsigned int >(i) : Meta::mp.iMaxUsers; + unsigned int newmax = i ? static_cast< unsigned int >(i) : Meta::mp->iMaxUsers; if (iMaxUsers == newmax) return; @@ -502,9 +502,9 @@ void Server::setLiveConf(const QString &key, const QString &value) { mpsc.set_max_users(iMaxUsers); sendAll(mpsc); } else if (key == "usersperchannel") - iMaxUsersPerChannel = i ? static_cast< unsigned int >(i) : Meta::mp.iMaxUsersPerChannel; + iMaxUsersPerChannel = i ? static_cast< unsigned int >(i) : Meta::mp->iMaxUsersPerChannel; else if (key == "textmessagelength") { - int length = i ? i : Meta::mp.iMaxTextMessageLength; + int length = i ? i : Meta::mp->iMaxTextMessageLength; if (length != iMaxTextMessageLength) { iMaxTextMessageLength = length; MumbleProto::ServerConfig mpsc; @@ -512,7 +512,7 @@ void Server::setLiveConf(const QString &key, const QString &value) { sendAll(mpsc); } } else if (key == "imagemessagelength") { - int length = i ? i : Meta::mp.iMaxImageMessageLength; + int length = i ? i : Meta::mp->iMaxImageMessageLength; if (length != iMaxImageMessageLength) { iMaxImageMessageLength = length; MumbleProto::ServerConfig mpsc; @@ -520,7 +520,7 @@ void Server::setLiveConf(const QString &key, const QString &value) { sendAll(mpsc); } } else if (key == "allowhtml") { - bool allow = !v.isNull() ? QVariant(v).toBool() : Meta::mp.bAllowHTML; + bool allow = !v.isNull() ? QVariant(v).toBool() : Meta::mp->bAllowHTML; if (allow != bAllowHTML) { bAllowHTML = allow; MumbleProto::ServerConfig mpsc; @@ -528,21 +528,21 @@ void Server::setLiveConf(const QString &key, const QString &value) { sendAll(mpsc); } } else if (key == "defaultchannel") - iDefaultChan = i ? static_cast< unsigned int >(i) : Meta::mp.iDefaultChan; + iDefaultChan = i ? static_cast< unsigned int >(i) : Meta::mp->iDefaultChan; else if (key == "rememberchannel") - bRememberChan = !v.isNull() ? QVariant(v).toBool() : Meta::mp.bRememberChan; + bRememberChan = !v.isNull() ? QVariant(v).toBool() : Meta::mp->bRememberChan; else if (key == "rememberchannelduration") { - iRememberChanDuration = !v.isNull() ? v.toInt() : Meta::mp.iRememberChanDuration; + iRememberChanDuration = !v.isNull() ? v.toInt() : Meta::mp->iRememberChanDuration; if (iRememberChanDuration < 0) { iRememberChanDuration = 0; } } else if (key == "welcometext") { - QString text = !v.isNull() ? v : Meta::mp.qsWelcomeText; + QString text = !v.isNull() ? v : Meta::mp->qsWelcomeText; if (text != qsWelcomeText) { qsWelcomeText = text; } } else if (key == "registername") { - QString text = !v.isNull() ? v : Meta::mp.qsRegName; + QString text = !v.isNull() ? v : Meta::mp->qsRegName; if (text != qsRegName) { qsRegName = text; if (!qsRegName.isEmpty()) { @@ -553,19 +553,19 @@ void Server::setLiveConf(const QString &key, const QString &value) { } } } else if (key == "registerpassword") - qsRegPassword = !v.isNull() ? v : Meta::mp.qsRegPassword; + qsRegPassword = !v.isNull() ? v : Meta::mp->qsRegPassword; else if (key == "registerhostname") - qsRegHost = !v.isNull() ? v : Meta::mp.qsRegHost; + qsRegHost = !v.isNull() ? v : Meta::mp->qsRegHost; else if (key == "registerlocation") - qsRegLocation = !v.isNull() ? v : Meta::mp.qsRegLocation; + qsRegLocation = !v.isNull() ? v : Meta::mp->qsRegLocation; else if (key == "registerurl") - qurlRegWeb = !v.isNull() ? v : Meta::mp.qurlRegWeb; + qurlRegWeb = !v.isNull() ? v : Meta::mp->qurlRegWeb; else if (key == "certrequired") - bCertRequired = !v.isNull() ? QVariant(v).toBool() : Meta::mp.bCertRequired; + bCertRequired = !v.isNull() ? QVariant(v).toBool() : Meta::mp->bCertRequired; else if (key == "forceExternalAuth") - bForceExternalAuth = !v.isNull() ? QVariant(v).toBool() : Meta::mp.bForceExternalAuth; + bForceExternalAuth = !v.isNull() ? QVariant(v).toBool() : Meta::mp->bForceExternalAuth; else if (key == "bonjour") { - bBonjour = !v.isNull() ? QVariant(v).toBool() : Meta::mp.bBonjour; + bBonjour = !v.isNull() ? QVariant(v).toBool() : Meta::mp->bBonjour; #ifdef USE_ZEROCONF if (bBonjour && !zeroconf) { initZeroconf(); @@ -574,38 +574,38 @@ void Server::setLiveConf(const QString &key, const QString &value) { } #endif } else if (key == "allowping") - bAllowPing = !v.isNull() ? QVariant(v).toBool() : Meta::mp.bAllowPing; + bAllowPing = !v.isNull() ? QVariant(v).toBool() : Meta::mp->bAllowPing; else if (key == "allowrecording") - allowRecording = !v.isNull() ? QVariant(v).toBool() : Meta::mp.allowRecording; + allowRecording = !v.isNull() ? QVariant(v).toBool() : Meta::mp->allowRecording; else if (key == "username") - qrUserName = !v.isNull() ? QRegularExpression(v) : Meta::mp.qrUserName; + qrUserName = !v.isNull() ? QRegularExpression(v) : Meta::mp->qrUserName; else if (key == "channelname") - qrChannelName = !v.isNull() ? QRegularExpression(v) : Meta::mp.qrChannelName; + qrChannelName = !v.isNull() ? QRegularExpression(v) : Meta::mp->qrChannelName; else if (key == "suggestversion") - m_suggestVersion = !v.isNull() ? Version::fromConfig(v) : Meta::mp.m_suggestVersion; + m_suggestVersion = !v.isNull() ? Version::fromConfig(v) : Meta::mp->m_suggestVersion; else if (key == "suggestpositional") - qvSuggestPositional = !v.isNull() ? (v.isEmpty() ? QVariant() : v) : Meta::mp.qvSuggestPositional; + qvSuggestPositional = !v.isNull() ? (v.isEmpty() ? QVariant() : v) : Meta::mp->qvSuggestPositional; else if (key == "suggestpushtotalk") - qvSuggestPushToTalk = !v.isNull() ? (v.isEmpty() ? QVariant() : v) : Meta::mp.qvSuggestPushToTalk; + qvSuggestPushToTalk = !v.isNull() ? (v.isEmpty() ? QVariant() : v) : Meta::mp->qvSuggestPushToTalk; else if (key == "opusthreshold") - iOpusThreshold = (i >= 0 && !v.isNull()) ? qBound(0, i, 100) : Meta::mp.iOpusThreshold; + iOpusThreshold = (i >= 0 && !v.isNull()) ? qBound(0, i, 100) : Meta::mp->iOpusThreshold; else if (key == "channelnestinglimit") - iChannelNestingLimit = (i >= 0 && !v.isNull()) ? i : Meta::mp.iChannelNestingLimit; + iChannelNestingLimit = (i >= 0 && !v.isNull()) ? i : Meta::mp->iChannelNestingLimit; else if (key == "channelcountlimit") - iChannelCountLimit = (i >= 0 && !v.isNull()) ? i : Meta::mp.iChannelCountLimit; + iChannelCountLimit = (i >= 0 && !v.isNull()) ? i : Meta::mp->iChannelCountLimit; else if (key == "messagelimit") { - iMessageLimit = (!v.isNull()) ? v.toUInt() : Meta::mp.iMessageLimit; + iMessageLimit = (!v.isNull()) ? v.toUInt() : Meta::mp->iMessageLimit; if (iMessageLimit < 1) { iMessageLimit = 1; } } else if (key == "messageburst") { - iMessageBurst = (!v.isNull()) ? v.toUInt() : Meta::mp.iMessageBurst; + iMessageBurst = (!v.isNull()) ? v.toUInt() : Meta::mp->iMessageBurst; if (iMessageBurst < 1) { iMessageBurst = 1; } } else if (key == "broadcastlistenervolumeadjustments") { broadcastListenerVolumeAdjustments = - (!v.isNull() ? QVariant(v).toBool() : Meta::mp.broadcastListenerVolumeAdjustments); + (!v.isNull() ? QVariant(v).toBool() : Meta::mp->broadcastListenerVolumeAdjustments); } } @@ -1414,13 +1414,13 @@ void Server::newClient() { // Add CA certificates specified via // murmur.ini's sslCA option. - config.addCaCertificates(Meta::mp.qlCA); + config.addCaCertificates(Meta::mp->qlCA); // Add intermediate CAs found in the PEM // bundle used for this server's certificate. config.addCaCertificates(qlIntermediates); - config.setCiphers(Meta::mp.qlCiphers); + config.setCiphers(Meta::mp->qlCiphers); #if defined(USE_QSSLDIFFIEHELLMANPARAMETERS) config.setDiffieHellmanParameters(qsdhpDHParams); #endif @@ -1463,7 +1463,7 @@ void Server::encrypted() { MumbleProto::Version mpv; MumbleProto::setVersion(mpv, Version::get()); - if (Meta::mp.bSendVersion) { + if (Meta::mp->bSendVersion) { mpv.set_release(u8(Version::getRelease())); mpv.set_os(u8(meta->qsOS)); mpv.set_os_version(u8(meta->qsOSVersion)); @@ -2109,13 +2109,13 @@ void Server::clearWhisperTargetCache() { QString Server::addressToString(const QHostAddress &adr, unsigned short port) { HostAddress ha(adr); - if ((Meta::mp.iObfuscate != 0)) { + if ((Meta::mp->iObfuscate != 0)) { QCryptographicHash h(QCryptographicHash::Sha1); - QByteArrayView byteView(reinterpret_cast< const char * >(&Meta::mp.iObfuscate), sizeof(Meta::mp.iObfuscate)); + QByteArrayView byteView(reinterpret_cast< const char * >(&Meta::mp->iObfuscate), sizeof(Meta::mp->iObfuscate)); #if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0) h.addData(byteView); #else - h.addData(reinterpret_cast< const char * >(&Meta::mp.iObfuscate), sizeof(Meta::mp.iObfuscate)); + h.addData(reinterpret_cast< const char * >(&Meta::mp->iObfuscate), sizeof(Meta::mp->iObfuscate)); #endif if (adr.protocol() == QAbstractSocket::IPv4Protocol) { quint32 num = adr.toIPv4Address(); diff --git a/src/murmur/ServerDB.cpp b/src/murmur/ServerDB.cpp index 4536641ea..ae0831035 100644 --- a/src/murmur/ServerDB.cpp +++ b/src/murmur/ServerDB.cpp @@ -64,30 +64,30 @@ Timer ServerDB::tLogClean; QString ServerDB::qsUpgradeSuffix; void ServerDB::loadOrSetupMetaPBKDF2IterationCount(QSqlQuery &query) { - if (!Meta::mp.legacyPasswordHash) { - if (Meta::mp.kdfIterations <= 0) { + if (!Meta::mp->legacyPasswordHash) { + if (Meta::mp->kdfIterations <= 0) { // Configuration doesn't specify an override, load from db SQLDO("SELECT `value` FROM `%1meta` WHERE `keystring` = 'pbkdf2_iterations'"); if (query.next()) { - Meta::mp.kdfIterations = query.value(0).toInt(); + Meta::mp->kdfIterations = query.value(0).toInt(); } - if (Meta::mp.kdfIterations <= 0) { + if (Meta::mp->kdfIterations <= 0) { // Didn't get a valid iteration count from DB, overwrite - Meta::mp.kdfIterations = PBKDF2::benchmark(); + Meta::mp->kdfIterations = PBKDF2::benchmark(); - qWarning() << "Performed initial PBKDF2 benchmark. Will use" << Meta::mp.kdfIterations + qWarning() << "Performed initial PBKDF2 benchmark. Will use" << Meta::mp->kdfIterations << "iterations as default"; SQLPREP("INSERT INTO `%1meta` (`keystring`, `value`) VALUES('pbkdf2_iterations',?)"); - query.addBindValue(Meta::mp.kdfIterations); + query.addBindValue(Meta::mp->kdfIterations); SQLEXEC(); } } - if (Meta::mp.kdfIterations < PBKDF2::BENCHMARK_MINIMUM_ITERATION_COUNT) { - qWarning() << "Configured default PBKDF2 iteration count of" << Meta::mp.kdfIterations + if (Meta::mp->kdfIterations < PBKDF2::BENCHMARK_MINIMUM_ITERATION_COUNT) { + qWarning() << "Configured default PBKDF2 iteration count of" << Meta::mp->kdfIterations << "is below minimum recommended value of" << PBKDF2::BENCHMARK_MINIMUM_ITERATION_COUNT << "and could be insecure."; } @@ -95,32 +95,32 @@ void ServerDB::loadOrSetupMetaPBKDF2IterationCount(QSqlQuery &query) { } ServerDB::ServerDB() { - if (Meta::mp.qsDBDriver != QLatin1String("QMYSQL") && Meta::mp.qsDBDriver != QLatin1String("QSQLITE") - && Meta::mp.qsDBDriver != QLatin1String("QPSQL")) { + if (Meta::mp->qsDBDriver != QLatin1String("QMYSQL") && Meta::mp->qsDBDriver != QLatin1String("QSQLITE") + && Meta::mp->qsDBDriver != QLatin1String("QPSQL")) { qFatal("ServerDB: invalid DB driver specified: '%s'. Murmur only supports QSQLITE, QMYSQL, and QPSQL.", - qPrintable(Meta::mp.qsDBDriver)); + qPrintable(Meta::mp->qsDBDriver)); } - if (!QSqlDatabase::isDriverAvailable(Meta::mp.qsDBDriver)) { - qFatal("ServerDB: Database driver %s not available", qPrintable(Meta::mp.qsDBDriver)); + if (!QSqlDatabase::isDriverAvailable(Meta::mp->qsDBDriver)) { + qFatal("ServerDB: Database driver %s not available", qPrintable(Meta::mp->qsDBDriver)); } if (db) { // Don't hide away our previous instance. Fail hard. qFatal("ServerDB has already been instantiated!"); } - db = new QSqlDatabase(QSqlDatabase::addDatabase(Meta::mp.qsDBDriver)); + db = new QSqlDatabase(QSqlDatabase::addDatabase(Meta::mp->qsDBDriver)); qsUpgradeSuffix = QString::fromLatin1("_old_%1").arg(QDateTime::currentDateTime().toSecsSinceEpoch()); bool found = false; - if (Meta::mp.qsDBDriver == "QSQLITE") { - if (!Meta::mp.qsDatabase.isEmpty()) { - db->setDatabaseName(Meta::mp.qsDatabase); + if (Meta::mp->qsDBDriver == "QSQLITE") { + if (!Meta::mp->qsDatabase.isEmpty()) { + db->setDatabaseName(Meta::mp->qsDatabase); found = db->open(); } else { QStringList datapaths; - datapaths << Meta::mp.qdBasePath.absolutePath(); + datapaths << Meta::mp->qdBasePath.absolutePath(); datapaths << QDir::currentPath(); datapaths << QCoreApplication::instance()->applicationDirPath(); datapaths << QDir::homePath(); @@ -154,12 +154,12 @@ ServerDB::ServerDB() { qFatal("ServerDB: Database is not writable"); } } else { - db->setDatabaseName(Meta::mp.qsDatabase); - db->setHostName(Meta::mp.qsDBHostName); - db->setPort(Meta::mp.iDBPort); - db->setUserName(Meta::mp.qsDBUserName); - db->setPassword(Meta::mp.qsDBPassword); - db->setConnectOptions(Meta::mp.qsDBOpts); + db->setDatabaseName(Meta::mp->qsDatabase); + db->setHostName(Meta::mp->qsDBHostName); + db->setPort(Meta::mp->iDBPort); + db->setUserName(Meta::mp->qsDBUserName); + db->setPassword(Meta::mp->qsDBPassword); + db->setConnectOptions(Meta::mp->qsDBOpts); found = db->open(); } @@ -169,10 +169,10 @@ ServerDB::ServerDB() { } // Use SQLite in WAL mode if possible. - if (Meta::mp.qsDBDriver == "QSQLITE") { - if (Meta::mp.iSQLiteWAL == 0) { + if (Meta::mp->qsDBDriver == "QSQLITE") { + if (Meta::mp->iSQLiteWAL == 0) { qWarning("ServerDB: Using SQLite's default rollback journal."); - } else if (Meta::mp.iSQLiteWAL > 0 && Meta::mp.iSQLiteWAL <= 2) { + } else if (Meta::mp->iSQLiteWAL > 0 && Meta::mp->iSQLiteWAL <= 2) { QSqlQuery query; bool hasversion = false; @@ -196,10 +196,10 @@ ServerDB::ServerDB() { if (okversion) { SQLDO("PRAGMA journal_mode=WAL;"); - if (Meta::mp.iSQLiteWAL == 1) { + if (Meta::mp->iSQLiteWAL == 1) { SQLDO("PRAGMA synchronous=NORMAL;"); qWarning("ServerDB: Configured SQLite for journal_mode=WAL, synchronous=NORMAL"); - } else if (Meta::mp.iSQLiteWAL == 2) { + } else if (Meta::mp->iSQLiteWAL == 2) { SQLDO("PRAGMA synchronous=FULL;"); qWarning("ServerDB: Configured SQLite for journal_mode=WAL, synchronous=FULL"); } @@ -213,7 +213,7 @@ ServerDB::ServerDB() { } else { qFatal("ServerDB: Invalid value '%i' for sqlite_wal. Please use 0 (no wal), 1 (wal), 2 (wal with " "synchronous=full)", - Meta::mp.iSQLiteWAL); + Meta::mp->iSQLiteWAL); } } @@ -222,10 +222,10 @@ ServerDB::ServerDB() { QSqlQuery &query = *th.qsqQuery; // Ensure that a proper encoding is used for the DB - if (Meta::mp.qsDBDriver == "QMYSQL") { + if (Meta::mp->qsDBDriver == "QMYSQL") { query.exec(QString::fromLatin1( "SELECT default_character_set_name FROM information_schema.SCHEMATA WHERE schema_name = '%1'") - .arg(Meta::mp.qsDatabase)); + .arg(Meta::mp->qsDatabase)); if (query.next()) { QString encoding = query.value(0).toString(); @@ -238,7 +238,7 @@ ServerDB::ServerDB() { if (!query.exec( QString::fromLatin1("ALTER DATABASE `%1` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci") - .arg(Meta::mp.qsDatabase))) { + .arg(Meta::mp->qsDatabase))) { qFatal("ServerDB: Failed to set default encoding & collation to UTF-8: %s", qPrintable(query.lastError().text())); } @@ -246,7 +246,7 @@ ServerDB::ServerDB() { } else { qFatal("Failed to get character encoding: %s", qPrintable(query.lastError().text())); } - } else if (Meta::mp.qsDBDriver == "QSQLITE") { + } else if (Meta::mp->qsDBDriver == "QSQLITE") { // Verify that the SQLite database has been initialized with UTF-8 or UTF-16 SQLQUERY("PRAGMA ENCODING;"); @@ -286,9 +286,9 @@ ServerDB::ServerDB() { // Make sure a table called "meta" is present // We use the meta table to keep track of various meta information such as the // database structure version this database conforms to. - if (Meta::mp.qsDBDriver == "QSQLITE") + if (Meta::mp->qsDBDriver == "QSQLITE") SQLDO("CREATE TABLE IF NOT EXISTS `%1meta` (`keystring` TEXT PRIMARY KEY, `value` TEXT)"); - else if (Meta::mp.qsDBDriver == "QPSQL") + else if (Meta::mp->qsDBDriver == "QPSQL") SQLQUERY("CREATE TABLE IF NOT EXISTS `%1meta` (`keystring` varchar(255) PRIMARY KEY, `value` varchar(255))"); else // MySQL @@ -341,7 +341,7 @@ ServerDB::ServerDB() { // Now we generate new tables that conform to the state-of-the-art structure qWarning("Generating new tables..."); - if (Meta::mp.qsDBDriver == "QSQLITE") { + if (Meta::mp->qsDBDriver == "QSQLITE") { if (version > 0) { SQLDO("DROP TRIGGER IF EXISTS `%1log_timestamp`"); SQLDO("DROP TRIGGER IF EXISTS `%1log_server_del`"); @@ -475,7 +475,7 @@ ServerDB::ServerDB() { SQLDO("CREATE TRIGGER `%1channel_listeners_del_user` AFTER DELETE ON `%1users` FOR EACH ROW BEGIN " "DELETE FROM `%1channel_listeners` WHERE `server_id` = old.`server_id` AND `user_id` = " "old.`user_id`; END;"); - } else if (Meta::mp.qsDBDriver == "QPSQL") { + } else if (Meta::mp->qsDBDriver == "QPSQL") { if (version > 0) { typedef QPair< QString, QString > qsp; QList< qsp > qlForeignKeys; @@ -483,13 +483,13 @@ ServerDB::ServerDB() { SQLPREP("SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE " "TABLE_SCHEMA=? AND CONSTRAINT_TYPE='FOREIGN KEY'"); - query.addBindValue(Meta::mp.qsDatabase); + query.addBindValue(Meta::mp->qsDatabase); SQLEXEC(); while (query.next()) qlForeignKeys << qsp(query.value(0).toString(), query.value(1).toString()); foreach (const qsp &key, qlForeignKeys) { - if (key.first.startsWith(Meta::mp.qsDBPrefix)) + if (key.first.startsWith(Meta::mp->qsDBPrefix)) ServerDB::exec(query, QString::fromLatin1("ALTER TABLE `%1` DROP CONSTRAINT FOREIGN KEY `%2`") .arg(key.first) @@ -499,13 +499,13 @@ ServerDB::ServerDB() { SQLPREP("SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE " "TABLE_SCHEMA=? AND CONSTRAINT_TYPE='PRIMARY KEY'"); - query.addBindValue(Meta::mp.qsDatabase); + query.addBindValue(Meta::mp->qsDatabase); SQLEXEC(); while (query.next()) qlIndexes << qsp(query.value(0).toString(), query.value(1).toString()); foreach (const qsp &key, qlIndexes) { - if (key.first.startsWith(Meta::mp.qsDBPrefix)) + if (key.first.startsWith(Meta::mp->qsDBPrefix)) ServerDB::exec(query, QString::fromLatin1("ALTER TABLE `%1` DROP CONSTRAINT PRIMARY KEY `%2`") .arg(key.first) @@ -627,13 +627,13 @@ ServerDB::ServerDB() { SQLPREP("SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE " "TABLE_SCHEMA=? AND CONSTRAINT_TYPE='FOREIGN KEY'"); - query.addBindValue(Meta::mp.qsDatabase); + query.addBindValue(Meta::mp->qsDatabase); SQLEXEC(); while (query.next()) qlForeignKeys << qsp(query.value(0).toString(), query.value(1).toString()); foreach (const qsp &key, qlForeignKeys) { - if (key.first.startsWith(Meta::mp.qsDBPrefix)) + if (key.first.startsWith(Meta::mp->qsDBPrefix)) ServerDB::exec(query, QString::fromLatin1("ALTER TABLE `%1` DROP FOREIGN KEY `%2`") .arg(key.first) @@ -741,7 +741,7 @@ ServerDB::ServerDB() { } else { qWarning("Importing old data..."); - if (Meta::mp.qsDBDriver == "QMYSQL") + if (Meta::mp->qsDBDriver == "QMYSQL") SQLDO("SET FOREIGN_KEY_CHECKS = 0;"); SQLDO("INSERT INTO `%1servers` (`server_id`) SELECT `server_id` FROM `%1servers%2`"); SQLDO("INSERT INTO `%1slog` (`server_id`, `msg`, `msgtime`) SELECT `server_id`, `msg`, `msgtime` FROM " @@ -845,7 +845,7 @@ ServerDB::ServerDB() { if (version >= 9) { SQLDO("INSERT INTO `%1channel_listeners` SELECT * FROM `%1channel_listeners%2`"); } - if (Meta::mp.qsDBDriver == "QMYSQL") + if (Meta::mp->qsDBDriver == "QMYSQL") SQLDO("SET FOREIGN_KEY_CHECKS = 1;"); qWarning("Removing old tables..."); @@ -885,14 +885,14 @@ bool ServerDB::prepare(QSqlQuery &query, const QString &str, bool fatal, bool wa QString q; if (str.contains(QLatin1String("%1"))) { if (str.contains(QLatin1String("%2"))) - q = str.arg(Meta::mp.qsDBPrefix, qsUpgradeSuffix); + q = str.arg(Meta::mp->qsDBPrefix, qsUpgradeSuffix); else - q = str.arg(Meta::mp.qsDBPrefix); + q = str.arg(Meta::mp->qsDBPrefix); } else { q = str; } - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { q.replace("`", "\""); } @@ -928,14 +928,14 @@ bool ServerDB::query(QSqlQuery &query, const QString &str, bool fatal, bool warn QString q; if (str.contains(QLatin1String("%1"))) { if (str.contains(QLatin1String("%2"))) - q = str.arg(Meta::mp.qsDBPrefix, qsUpgradeSuffix); + q = str.arg(Meta::mp->qsDBPrefix, qsUpgradeSuffix); else - q = str.arg(Meta::mp.qsDBPrefix); + q = str.arg(Meta::mp->qsDBPrefix); } else { q = str; } - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { q.replace("`", "\""); } @@ -1126,7 +1126,7 @@ int Server::registerUser(const QMap< int, QString > &info) { id = res; } - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { SQLPREP("INSERT INTO `%1users` (`server_id`, `user_id`, `name`) VALUES (:server_id,:user_id,:name) ON " "CONFLICT (`server_id`, `name`) DO UPDATE SET `user_id` = :u_user_id WHERE `%1users`.`server_id` = " ":u_server_id AND `%1users`.`name` = :u_name"); @@ -1317,7 +1317,7 @@ int Server::authenticate(QString &name, const QString &password, int sessionId, if (lchan < 0) lchan = 0; - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { SQLPREP("INSERT INTO `%1users` (`server_id`, `user_id`, `name`, `lastchannel`) VALUES " "(:server_id,:user_id,:name,:lastchannel) ON CONFLICT (`server_id`, `user_id`) DO UPDATE SET " "`name` = :u_name, `lastchannel` = :u_lastchannel WHERE `%1users`.`server_id` = :u_server_id " @@ -1372,11 +1372,11 @@ int Server::authenticate(QString &name, const QString &password, int sessionId, name = query.value(1).toString(); res = query.value(0).toInt(); - if (!Meta::mp.legacyPasswordHash) { + if (!Meta::mp->legacyPasswordHash) { // Unless disabled upgrade the user password hash QMap< int, QString > info; info.insert(ServerDB::User_Password, password); - info.insert(ServerDB::User_KDFIterations, QString::number(Meta::mp.kdfIterations)); + info.insert(ServerDB::User_KDFIterations, QString::number(Meta::mp->kdfIterations)); if (!setInfo(userId, info)) { qWarning("ServerDB: Failed to upgrade user account to PBKDF2 hash, rejecting login."); @@ -1389,7 +1389,7 @@ int Server::authenticate(QString &name, const QString &password, int sessionId, name = query.value(1).toString(); res = query.value(0).toInt(); - if (Meta::mp.legacyPasswordHash) { + if (Meta::mp->legacyPasswordHash) { // Downgrade the password to the legacy hash QMap< int, QString > info; info.insert(ServerDB::User_Password, password); @@ -1398,15 +1398,15 @@ int Server::authenticate(QString &name, const QString &password, int sessionId, qWarning("ServerDB: Failed to downgrade user account to legacy hash, rejecting login."); return -1; } - } else if (storedKdfIterations != Meta::mp.kdfIterations) { + } else if (storedKdfIterations != Meta::mp->kdfIterations) { // User kdfiterations not equal to the global one. Update it. QMap< int, QString > info; info.insert(ServerDB::User_Password, password); - info.insert(ServerDB::User_KDFIterations, QString::number(Meta::mp.kdfIterations)); + info.insert(ServerDB::User_KDFIterations, QString::number(Meta::mp->kdfIterations)); if (!setInfo(userId, info)) { qWarning() << "ServerDB: Failed to update user PBKDF2 to new iteration count" - << Meta::mp.kdfIterations << ", rejecting login."; + << Meta::mp->kdfIterations << ", rejecting login."; return -1; } } @@ -1458,7 +1458,7 @@ int Server::authenticate(QString &name, const QString &password, int sessionId, } } if (!certhash.isEmpty() && (res > 0)) { - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { SQLPREP("INSERT INTO `%1user_info` (`server_id`, `user_id`, `key`, `value`) VALUES (:server_id, :user_id, " ":key, :value) ON CONFLICT (`server_id`, `user_id`, `key`) DO UPDATE SET `value` = :u_value WHERE " "`%1user_info`.`server_id` = :u_server_id AND `%1user_info`.`user_id` = :u_user_id AND " @@ -1482,7 +1482,7 @@ int Server::authenticate(QString &name, const QString &password, int sessionId, } if (!emails.isEmpty()) { - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { query.bindValue(":server_id", iServerNum); query.bindValue(":user_id", res); query.bindValue(":key", ServerDB::User_Email); @@ -1540,10 +1540,10 @@ bool Server::setInfo(int id, const QMap< int, QString > &setinfo) { QString passwordHash, salt; int kdfIterations = -1; - if (Meta::mp.legacyPasswordHash) { + if (Meta::mp->legacyPasswordHash) { passwordHash = ServerDB::getLegacySHA1Hash(password); } else { - kdfIterations = Meta::mp.kdfIterations; + kdfIterations = Meta::mp->kdfIterations; if (info.contains(ServerDB::User_KDFIterations)) { const int targetIterations = info.value(ServerDB::User_KDFIterations).toInt(); if (targetIterations > 0) { @@ -1583,7 +1583,7 @@ bool Server::setInfo(int id, const QMap< int, QString > &setinfo) { keys << i.key(); values << i.value(); } - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { SQLPREP("INSERT INTO `%1user_info` (`server_id`, `user_id`, `key`, `value`) VALUES (:server_id, :user_id, " ":key, :value) ON CONFLICT (`server_id`, `user_id`, `key`) DO UPDATE SET `value` = :u_value WHERE " "`%1user_info`.`server_id` = :u_server_id AND `%1user_info`.`user_id` = :u_user_id AND " @@ -1671,14 +1671,14 @@ void ServerDB::writeSUPW(int srvnum, const QString &pwHash, const QString &saltH void ServerDB::setSUPW(int srvnum, const QString &pw) { QString pwHash, saltHash; - if (!Meta::mp.legacyPasswordHash) { + if (!Meta::mp->legacyPasswordHash) { saltHash = PBKDF2::getSalt(); - pwHash = PBKDF2::getHash(saltHash, pw, Meta::mp.kdfIterations); + pwHash = PBKDF2::getHash(saltHash, pw, Meta::mp->kdfIterations); } else { pwHash = getLegacySHA1Hash(pw); } - writeSUPW(srvnum, pwHash, saltHash, Meta::mp.kdfIterations); + writeSUPW(srvnum, pwHash, saltHash, Meta::mp->kdfIterations); } void ServerDB::disableSU(int srvnum) { @@ -1900,7 +1900,7 @@ void Server::updateChannel(const Channel *c) { SQLEXEC(); // Update channel description information - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { SQLPREP("INSERT INTO `%1channel_info` (`server_id`, `channel_id`, `key`, `value`) VALUES (:server_id, " ":channel_id, :key, :value) ON CONFLICT (`server_id`, `channel_id`, `key`) DO UPDATE SET `value` = " ":u_value WHERE `%1channel_info`.`server_id` = :u_server_id AND `%1channel_info`.`channel_id` = " @@ -1923,7 +1923,7 @@ void Server::updateChannel(const Channel *c) { SQLEXEC(); } // Update channel position information - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { query.bindValue(":server_id", iServerNum); query.bindValue(":channel_id", c->iId); query.bindValue(":key", ServerDB::Channel_Position); @@ -1941,7 +1941,7 @@ void Server::updateChannel(const Channel *c) { SQLEXEC(); } // Update channel maximum channels - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { query.bindValue(":server_id", iServerNum); query.bindValue(":channel_id", c->iId); query.bindValue(":key", ServerDB::Channel_Max_Users); @@ -1973,7 +1973,7 @@ void Server::updateChannel(const Channel *c) { int id = 0; int pid; - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { SQLPREP("INSERT INTO `%1groups` (`server_id`, `channel_id`, `name`, `inherit`, `inheritable`) VALUES " "(?,?,?,?,?) RETURNING group_id"); query.addBindValue(iServerNum); @@ -2079,7 +2079,7 @@ void Server::readChannelPrivs(Channel *c) { QSqlQuery mem; mem.prepare(QString::fromLatin1("SELECT user_id, addit FROM %1group_members WHERE group_id = ?") - .arg(Meta::mp.qsDBPrefix)); + .arg(Meta::mp->qsDBPrefix)); mem.addBindValue(gid); mem.exec(); while (mem.next()) { @@ -2179,7 +2179,7 @@ void Server::setLastChannel(const User *p) { TransactionHolder th; QSqlQuery &query = *th.qsqQuery; - if (Meta::mp.qsDBDriver == "QSQLITE") { + if (Meta::mp->qsDBDriver == "QSQLITE") { SQLPREP("UPDATE `%1users` SET `lastchannel`=? WHERE `server_id` = ? AND `user_id` = ?"); } else { SQLPREP("UPDATE `%1users` SET `lastchannel`=?, `last_active` = now() WHERE `server_id` = ? AND `user_id` = ?"); @@ -2194,7 +2194,7 @@ int Server::readLastChannel(int id) { if (id < 0) return -1; - if (!Meta::mp.bRememberChan) + if (!Meta::mp->bRememberChan) return -1; TransactionHolder th; @@ -2213,7 +2213,7 @@ int Server::readLastChannel(int id) { return -1; } - int duration = Meta::mp.iRememberChanDuration; + int duration = Meta::mp->iRememberChanDuration; if (duration <= 0) { return static_cast< int >(cid); @@ -2266,7 +2266,7 @@ void Server::setLastDisconnect(const User *p) { TransactionHolder th; QSqlQuery &query = *th.qsqQuery; - if (Meta::mp.qsDBDriver == "QSQLITE") { + if (Meta::mp->qsDBDriver == "QSQLITE") { SQLPREP("UPDATE `%1users` SET `last_disconnect` = datetime('now') WHERE `server_id` = ? AND `user_id` = ?"); } else { // MySQL or PostgreSQL @@ -2401,19 +2401,19 @@ void Server::dblog(const QString &str) const { QSqlQuery &query = *th.qsqQuery; // Is logging disabled? - if (Meta::mp.iLogDays < 0) + if (Meta::mp->iLogDays < 0) return; // Once per hour - if (Meta::mp.iLogDays > 0) { + if (Meta::mp->iLogDays > 0) { if (ServerDB::tLogClean.isElapsed(3600ULL * 1000000ULL)) { QString qstr; - if (Meta::mp.qsDBDriver == "QSQLITE") { - qstr = QString::fromLatin1("msgtime < datetime('now','-%1 days')").arg(Meta::mp.iLogDays); - } else if (Meta::mp.qsDBDriver == "QPSQL") { - qstr = QString::fromLatin1("msgtime < now() - INTERVAL '%1 day'").arg(Meta::mp.iLogDays); + if (Meta::mp->qsDBDriver == "QSQLITE") { + qstr = QString::fromLatin1("msgtime < datetime('now','-%1 days')").arg(Meta::mp->iLogDays); + } else if (Meta::mp->qsDBDriver == "QPSQL") { + qstr = QString::fromLatin1("msgtime < now() - INTERVAL '%1 day'").arg(Meta::mp->iLogDays); } else { - qstr = QString::fromLatin1("msgtime < now() - INTERVAL %1 day").arg(Meta::mp.iLogDays); + qstr = QString::fromLatin1("msgtime < now() - INTERVAL %1 day").arg(Meta::mp->iLogDays); } ServerDB::prepare(query, QString::fromLatin1("DELETE FROM %1slog WHERE ") + qstr); SQLEXEC(); @@ -2560,7 +2560,7 @@ QList< ServerDB::LogRecord > ServerDB::getLog(int server_id, unsigned int offs_m TransactionHolder th; QSqlQuery &query = *th.qsqQuery; - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { SQLPREP("SELECT `msgtime`, `msg` FROM `%1slog` WHERE `server_id` = ? ORDER BY `msgtime` DESC LIMIT ? OFFSET ?"); query.addBindValue(server_id); query.addBindValue(offs_max); @@ -2609,7 +2609,7 @@ void ServerDB::setConf(int server_id, const QString &k, const QVariant &value) { query.addBindValue(server_id); query.addBindValue(key); } else { - if (Meta::mp.qsDBDriver == "QPSQL") { + if (Meta::mp->qsDBDriver == "QPSQL") { SQLPREP("INSERT INTO `%1config` (`server_id`, `key`, `value`) VALUES (:server_id, :key, :value) ON " "CONFLICT (`server_id`, `key`) DO UPDATE SET `value` = :u_value WHERE `%1config`.`server_id` = " ":u_server_id AND `%1config`.`key` = :u_key"); diff --git a/src/murmur/UnixMurmur.cpp b/src/murmur/UnixMurmur.cpp index 3c9330542..95927a59b 100644 --- a/src/murmur/UnixMurmur.cpp +++ b/src/murmur/UnixMurmur.cpp @@ -209,9 +209,9 @@ void UnixMurmur::handleSigHup() { qWarning("Caught SIGHUP, but logfile not in use -- interpreting as hint to quit"); QCoreApplication::instance()->quit(); } else { - qWarning("Caught SIGHUP, will reopen %s", qPrintable(Meta::mp.qsLogfile)); + qWarning("Caught SIGHUP, will reopen %s", qPrintable(Meta::mp->qsLogfile)); - QFile *newlog = new QFile(Meta::mp.qsLogfile); + QFile *newlog = new QFile(Meta::mp->qsLogfile); bool result = newlog->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text); if (!result) { delete newlog; @@ -263,38 +263,38 @@ void UnixMurmur::handleSigUsr1() { } void UnixMurmur::setuid() { - if (Meta::mp.uiUid != 0) { + if (Meta::mp->uiUid != 0) { #ifdef Q_OS_DARWIN qCritical("WARNING: You are launching murmurd as root on Mac OS X or Darwin. Murmur does not need " "special privileges to set itself up on these systems, so this behavior is highly discouraged."); - if (::setgid(Meta::mp.uiGid) != 0) - qFatal("Failed to switch to gid %d", Meta::mp.uiGid); - if (::setuid(Meta::mp.uiUid) != 0) - qFatal("Failed to switch to uid %d", Meta::mp.uiUid); + if (::setgid(Meta::mp->uiGid) != 0) + qFatal("Failed to switch to gid %d", Meta::mp->uiGid); + if (::setuid(Meta::mp->uiUid) != 0) + qFatal("Failed to switch to uid %d", Meta::mp->uiUid); uid_t uid = getuid(), euid = geteuid(); gid_t gid = getgid(), egid = getegid(); - if (uid == Meta::mp.uiUid && euid == Meta::mp.uiUid && gid == Meta::mp.uiGid && egid == Meta::mp.uiGid) { - qCritical("Successfully switched to uid %d", Meta::mp.uiUid); + if (uid == Meta::mp->uiUid && euid == Meta::mp->uiUid && gid == Meta::mp->uiGid && egid == Meta::mp->uiGid) { + qCritical("Successfully switched to uid %d", Meta::mp->uiUid); } else qFatal("Couldn't switch uid/gid."); #else - if (::initgroups(qPrintable(Meta::mp.qsName), Meta::mp.uiGid) != 0) + if (::initgroups(qPrintable(Meta::mp->qsName), Meta::mp->uiGid) != 0) qCritical("Can't initialize supplementary groups"); - if (::setgid(Meta::mp.uiGid) != 0) - qCritical("Failed to switch to gid %d", Meta::mp.uiGid); - if (::setuid(Meta::mp.uiUid) != 0) { - qFatal("Failed to become uid %d", Meta::mp.uiUid); + if (::setgid(Meta::mp->uiGid) != 0) + qCritical("Failed to switch to gid %d", Meta::mp->uiGid); + if (::setuid(Meta::mp->uiUid) != 0) { + qFatal("Failed to become uid %d", Meta::mp->uiUid); } else { - qCritical("Successfully switched to uid %d", Meta::mp.uiUid); + qCritical("Successfully switched to uid %d", Meta::mp->uiUid); initialcap(); } - if (!Meta::mp.qsHome.isEmpty()) { + if (!Meta::mp->qsHome.isEmpty()) { // QDir::homePath is broken. It only looks at $HOME // instead of getpwuid() so we have to set our home // ourselves - EnvUtils::setenv(QLatin1String("HOME"), Meta::mp.qsHome); + EnvUtils::setenv(QLatin1String("HOME"), Meta::mp->qsHome); } #endif } else if (bRoot) { diff --git a/src/murmur/main.cpp b/src/murmur/main.cpp index b75c4d58b..0c3c37957 100644 --- a/src/murmur/main.cpp +++ b/src/murmur/main.cpp @@ -176,8 +176,8 @@ void cleanup(int signum) { qInstallMessageHandler(nullptr); #ifdef Q_OS_UNIX - if (!Meta::mp.qsPid.isEmpty()) { - QFile pid(Meta::mp.qsPid); + if (!Meta::mp->qsPid.isEmpty()) { + QFile pid(Meta::mp->qsPid); pid.remove(); } #endif @@ -228,6 +228,9 @@ int main(int argc, char **argv) { a.setOrganizationName("Mumble"); a.setOrganizationDomain("mumble.sourceforge.net"); + // Initialize meta parameter + Meta::mp = std::make_unique< MetaParams >(); + MumbleSSL::initialize(); QString inifile; @@ -374,7 +377,7 @@ int main(int argc, char **argv) { #ifdef Q_OS_UNIX } else if (arg == "-limits") { detach = false; - Meta::mp.read(inifile); + Meta::mp->read(inifile); unixhandler.setuid(); unixhandler.finalcap(); LimitTest::testLimits(a); @@ -403,42 +406,42 @@ int main(int argc, char **argv) { inifile = unixhandler.trySystemIniFiles(inifile); #endif - Meta::mp.read(inifile); + Meta::mp->read(inifile); // Activating the logging of ACLs and groups via commandLine overwrites whatever is set in the ini file if (logGroups) { - Meta::mp.bLogGroupChanges = logGroups; + Meta::mp->bLogGroupChanges = logGroups; } if (logACL) { - Meta::mp.bLogACLChanges = logACL; + Meta::mp->bLogACLChanges = logACL; } // need to open log file early so log dir can be root owned: // http://article.gmane.org/gmane.comp.security.oss.general/4404 #ifdef Q_OS_UNIX - unixhandler.logToSyslog = Meta::mp.qsLogfile == QLatin1String("syslog"); - if (detach && !Meta::mp.qsLogfile.isEmpty() && !unixhandler.logToSyslog) { + unixhandler.logToSyslog = Meta::mp->qsLogfile == QLatin1String("syslog"); + if (detach && !Meta::mp->qsLogfile.isEmpty() && !unixhandler.logToSyslog) { #else - if (detach && !Meta::mp.qsLogfile.isEmpty()) { + if (detach && !Meta::mp->qsLogfile.isEmpty()) { #endif - qfLog = new QFile(Meta::mp.qsLogfile); + qfLog = new QFile(Meta::mp->qsLogfile); if (!qfLog->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { delete qfLog; qfLog = nullptr; #ifdef Q_OS_UNIX fprintf(stderr, "murmurd: failed to open logfile %s: no logging will be done\n", - qPrintable(Meta::mp.qsLogfile)); + qPrintable(Meta::mp->qsLogfile)); #else - qWarning("Failed to open logfile %s. No logging will be performed.", qPrintable(Meta::mp.qsLogfile)); + qWarning("Failed to open logfile %s. No logging will be performed.", qPrintable(Meta::mp->qsLogfile)); #endif } else { qfLog->setTextModeEnabled(true); QFileInfo qfi(*qfLog); - Meta::mp.qsLogfile = qfi.absoluteFilePath(); + Meta::mp->qsLogfile = qfi.absoluteFilePath(); #ifdef Q_OS_UNIX - if (Meta::mp.uiUid != 0 && fchown(qfLog->handle(), Meta::mp.uiUid, Meta::mp.uiGid) == -1) { - qFatal("can't change log file owner to %d %d:%d - %s", qfLog->handle(), Meta::mp.uiUid, Meta::mp.uiGid, - strerror(errno)); + if (Meta::mp->uiUid != 0 && fchown(qfLog->handle(), Meta::mp->uiUid, Meta::mp->uiGid) == -1) { + qFatal("can't change log file owner to %d %d:%d - %s", qfLog->handle(), Meta::mp->uiUid, + Meta::mp->uiGid, strerror(errno)); } #endif } @@ -477,11 +480,11 @@ int main(int argc, char **argv) { _exit(0); } - if (!Meta::mp.qsPid.isEmpty()) { - QFile pid(Meta::mp.qsPid); + if (!Meta::mp->qsPid.isEmpty()) { + QFile pid(Meta::mp->qsPid); if (pid.open(QIODevice::WriteOnly)) { QFileInfo fi(pid); - Meta::mp.qsPid = fi.absoluteFilePath(); + Meta::mp->qsPid = fi.absoluteFilePath(); QTextStream out(&pid); out << getpid();