mirror of
https://github.com/mumble-voip/mumble.git
synced 2025-10-26 11:19:16 +00:00
Add mutex for csCrypt usage in Murmur.
This commit is contained in:
parent
f260bd1913
commit
f03b74db2d
@ -67,6 +67,10 @@ class Connection : public QObject {
|
||||
qint64 activityTime() const;
|
||||
void resetActivityTime();
|
||||
|
||||
#ifdef MURMUR
|
||||
/// qmCrypt locks access to csCrypt.
|
||||
QMutex qmCrypt;
|
||||
#endif
|
||||
CryptState csCrypt;
|
||||
|
||||
QList<QSslCertificate> peerCertificateChain() const;
|
||||
|
||||
@ -194,13 +194,17 @@ void Server::msgAuthenticate(ServerUser *uSource, MumbleProto::Authenticate &msg
|
||||
}
|
||||
|
||||
// Setup UDP encryption
|
||||
uSource->csCrypt.genKey();
|
||||
{
|
||||
QMutexLocker l(&uSource->qmCrypt);
|
||||
|
||||
MumbleProto::CryptSetup mpcrypt;
|
||||
mpcrypt.set_key(std::string(reinterpret_cast<const char *>(uSource->csCrypt.raw_key), AES_BLOCK_SIZE));
|
||||
mpcrypt.set_server_nonce(std::string(reinterpret_cast<const char *>(uSource->csCrypt.encrypt_iv), AES_BLOCK_SIZE));
|
||||
mpcrypt.set_client_nonce(std::string(reinterpret_cast<const char *>(uSource->csCrypt.decrypt_iv), AES_BLOCK_SIZE));
|
||||
sendMessage(uSource, mpcrypt);
|
||||
uSource->csCrypt.genKey();
|
||||
|
||||
MumbleProto::CryptSetup mpcrypt;
|
||||
mpcrypt.set_key(std::string(reinterpret_cast<const char *>(uSource->csCrypt.raw_key), AES_BLOCK_SIZE));
|
||||
mpcrypt.set_server_nonce(std::string(reinterpret_cast<const char *>(uSource->csCrypt.encrypt_iv), AES_BLOCK_SIZE));
|
||||
mpcrypt.set_client_nonce(std::string(reinterpret_cast<const char *>(uSource->csCrypt.decrypt_iv), AES_BLOCK_SIZE));
|
||||
sendMessage(uSource, mpcrypt);
|
||||
}
|
||||
|
||||
bool fake_celt_support = false;
|
||||
if (msg.celt_versions_size() > 0) {
|
||||
@ -1400,6 +1404,9 @@ void Server::msgQueryUsers(ServerUser *uSource, MumbleProto::QueryUsers &msg) {
|
||||
|
||||
void Server::msgPing(ServerUser *uSource, MumbleProto::Ping &msg) {
|
||||
MSG_SETUP_NO_UNIDLE(ServerUser::Authenticated);
|
||||
|
||||
QMutexLocker l(&uSource->qmCrypt);
|
||||
|
||||
CryptState &cs=uSource->csCrypt;
|
||||
|
||||
cs.uiRemoteGood = msg.good();
|
||||
@ -1428,6 +1435,9 @@ void Server::msgPing(ServerUser *uSource, MumbleProto::Ping &msg) {
|
||||
|
||||
void Server::msgCryptSetup(ServerUser *uSource, MumbleProto::CryptSetup &msg) {
|
||||
MSG_SETUP_NO_UNIDLE(ServerUser::Authenticated);
|
||||
|
||||
QMutexLocker l(&uSource->qmCrypt);
|
||||
|
||||
if (! msg.has_client_nonce()) {
|
||||
log(uSource, "Requested crypt-nonce resync");
|
||||
msg.set_server_nonce(std::string(reinterpret_cast<const char *>(uSource->csCrypt.encrypt_iv), AES_BLOCK_SIZE));
|
||||
@ -1605,7 +1615,6 @@ void Server::msgCodecVersion(ServerUser *, MumbleProto::CodecVersion &) {
|
||||
void Server::msgUserStats(ServerUser*uSource, MumbleProto::UserStats &msg) {
|
||||
MSG_SETUP_NO_UNIDLE(ServerUser::Authenticated);
|
||||
VICTIM_SETUP;
|
||||
const CryptState &cs = pDstServerUser->csCrypt;
|
||||
const BandwidthRecord &bwr = pDstServerUser->bwr;
|
||||
const QList<QSslCertificate> &certs = pDstServerUser->peerCertificateChain();
|
||||
|
||||
@ -1636,6 +1645,9 @@ void Server::msgUserStats(ServerUser*uSource, MumbleProto::UserStats &msg) {
|
||||
if (local) {
|
||||
MumbleProto::UserStats_Stats *mpusss;
|
||||
|
||||
QMutexLocker l(&pDstServerUser->qmCrypt);
|
||||
const CryptState &cs = pDstServerUser->csCrypt;
|
||||
|
||||
mpusss = msg.mutable_from_client();
|
||||
mpusss->set_good(cs.uiGood);
|
||||
mpusss->set_late(cs.uiLate);
|
||||
|
||||
@ -820,7 +820,7 @@ void Server::run() {
|
||||
} else {
|
||||
// Unknown peer
|
||||
foreach(ServerUser *usr, qhHostUsers.value(ha)) {
|
||||
if (usr->csCrypt.isValid() && checkDecrypt(usr, encrypt, buffer, len)) {
|
||||
if (checkDecrypt(usr, encrypt, buffer, len)) { // checkDecrypt takes the User's qrwlCrypt lock.
|
||||
// Every time we relock, reverify users' existance.
|
||||
// The main thread might delete the user while the lock isn't held.
|
||||
unsigned int uiSession = usr->uiSession;
|
||||
@ -879,6 +879,8 @@ void Server::run() {
|
||||
}
|
||||
|
||||
bool Server::checkDecrypt(ServerUser *u, const char *encrypt, char *plain, unsigned int len) {
|
||||
QMutexLocker l(&u->qmCrypt);
|
||||
|
||||
if (u->csCrypt.isValid() && u->csCrypt.decrypt(reinterpret_cast<const unsigned char *>(encrypt), reinterpret_cast<unsigned char *>(plain), len))
|
||||
return true;
|
||||
|
||||
@ -892,14 +894,23 @@ bool Server::checkDecrypt(ServerUser *u, const char *encrypt, char *plain, unsig
|
||||
}
|
||||
|
||||
void Server::sendMessage(ServerUser *u, const char *data, int len, QByteArray &cache, bool force) {
|
||||
if ((u->bUdp || force) && (u->sUdpSocket != INVALID_SOCKET) && u->csCrypt.isValid()) {
|
||||
if ((u->bUdp || force) && (u->sUdpSocket != INVALID_SOCKET)) {
|
||||
#if defined(__LP64__)
|
||||
STACKVAR(char, ebuffer, len+4+16);
|
||||
char *buffer = reinterpret_cast<char *>(((reinterpret_cast<quint64>(ebuffer) + 8) & ~7) + 4);
|
||||
#else
|
||||
STACKVAR(char, buffer, len+4);
|
||||
#endif
|
||||
u->csCrypt.encrypt(reinterpret_cast<const unsigned char *>(data), reinterpret_cast<unsigned char *>(buffer), len);
|
||||
{
|
||||
QMutexLocker wl(&u->qmCrypt);
|
||||
|
||||
if (!u->csCrypt.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
u->csCrypt.encrypt(reinterpret_cast<const unsigned char *>(data), reinterpret_cast<unsigned char *>(buffer),
|
||||
len);
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
DWORD dwFlow = 0;
|
||||
if (Meta::hQoS)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user