1 // Copyright 2005-2019 The Mumble Developers. All rights reserved.
2 // Use of this source code is governed by a BSD-style license
3 // that can be found in the LICENSE file at the root of the
4 // Mumble source tree or at <https://www.mumble.info/LICENSE>.
5
6 #include "mumble_pch.hpp"
7
8 #include "ServerHandler.h"
9
10 #include "AudioInput.h"
11 #include "AudioOutput.h"
12 #include "Cert.h"
13 #include "Connection.h"
14 #include "Database.h"
15 #include "MainWindow.h"
16 #include "Message.h"
17 #include "NetworkConfig.h"
18 #include "OSInfo.h"
19 #include "PacketDataStream.h"
20 #include "RichTextEditor.h"
21 #include "SSL.h"
22 #include "User.h"
23 #include "Net.h"
24 #include "HostAddress.h"
25 #include "ServerResolver.h"
26 #include "ServerResolverRecord.h"
27
28 // We define a global macro called 'g'. This can lead to issues when included code uses 'g' as a type or parameter name (like protobuf 3.7 does). As such, for now, we have to make this our last include.
29 #include "Global.h"
30
ServerHandlerMessageEvent(const QByteArray & msg,unsigned int mtype,bool flush)31 ServerHandlerMessageEvent::ServerHandlerMessageEvent(const QByteArray &msg, unsigned int mtype, bool flush) : QEvent(static_cast<QEvent::Type>(SERVERSEND_EVENT)) {
32 qbaMsg = msg;
33 uiType = mtype;
34 bFlush = flush;
35 }
36
37 #ifdef Q_OS_WIN
loadQoS()38 static HANDLE loadQoS() {
39 HANDLE hQoS = NULL;
40
41 HRESULT hr = E_FAIL;
42
43 // We don't support delay-loading QoS on MinGW. Only enable it for MSVC.
44 #ifdef _MSC_VER
45 __try {
46 hr = __HrLoadAllImportsForDll("qwave.dll");
47 }
48
49 __except(EXCEPTION_EXECUTE_HANDLER) {
50 hr = E_FAIL;
51 }
52 #endif
53
54 if (! SUCCEEDED(hr)) {
55 qWarning("ServerHandler: Failed to load qWave.dll, no QoS available");
56 } else {
57 QOS_VERSION qvVer;
58 qvVer.MajorVersion = 1;
59 qvVer.MinorVersion = 0;
60
61 if (! QOSCreateHandle(&qvVer, &hQoS)) {
62 qWarning("ServerHandler: Failed to create QOS2 handle");
63 hQoS = NULL;
64 } else {
65 qWarning("ServerHandler: QOS2 loaded");
66 }
67 }
68 return hQoS;
69 }
70 #endif
71
ServerHandler()72 ServerHandler::ServerHandler()
73 : database(new Database(QLatin1String("ServerHandler"))) {
74 cConnection.reset();
75 qusUdp = NULL;
76 bStrong = false;
77 usPort = 0;
78 bUdp = true;
79 tConnectionTimeoutTimer = NULL;
80 uiVersion = 0;
81 iInFlightTCPPings = 0;
82
83 // Historically, the qWarning line below initialized OpenSSL for us.
84 // It used to have this comment:
85 //
86 // "For some strange reason, on Win32, we have to call
87 // supportsSsl before the cipher list is ready."
88 //
89 // Now, OpenSSL is initialized in main() via MumbleSSL::initialize(),
90 // but since it's handy to have the OpenSSL version available, we
91 // keep this one around as well.
92 qWarning("OpenSSL Support: %d (%s)", QSslSocket::supportsSsl(), SSLeay_version(SSLEAY_VERSION));
93
94 MumbleSSL::addSystemCA();
95
96 {
97 QList<QSslCipher> ciphers = MumbleSSL::ciphersFromOpenSSLCipherString(g.s.qsSslCiphers);
98 if (ciphers.isEmpty()) {
99 qFatal("Invalid 'net/sslciphers' config option. Either the cipher string is invalid or none of the ciphers are available:: \"%s\"", qPrintable(g.s.qsSslCiphers));
100 }
101
102 QSslSocket::setDefaultCiphers(ciphers);
103
104 QStringList pref;
105 foreach (QSslCipher c, ciphers) {
106 pref << c.name();
107 }
108 qWarning("ServerHandler: TLS cipher preference is \"%s\"", qPrintable(pref.join(QLatin1String(":"))));
109 }
110
111 #ifdef Q_OS_WIN
112 hQoS = loadQoS();
113 if (hQoS)
114 Connection::setQoS(hQoS);
115 #endif
116
117 connect(this, SIGNAL(pingRequested()), this, SLOT(sendPingInternal()), Qt::QueuedConnection);
118 }
119
~ServerHandler()120 ServerHandler::~ServerHandler() {
121 wait();
122 cConnection.reset();
123 #ifdef Q_OS_WIN
124 if (hQoS) {
125 QOSCloseHandle(hQoS);
126 Connection::setQoS(NULL);
127 }
128 #endif
129 }
130
customEvent(QEvent * evt)131 void ServerHandler::customEvent(QEvent *evt) {
132 if (evt->type() != SERVERSEND_EVENT)
133 return;
134
135 ServerHandlerMessageEvent *shme = static_cast<ServerHandlerMessageEvent *>(evt);
136
137 ConnectionPtr connection(cConnection);
138 if (connection) {
139 if (shme->qbaMsg.size() > 0) {
140 connection->sendMessage(shme->qbaMsg);
141 if (shme->bFlush)
142 connection->forceFlush();
143 } else {
144 exit(0);
145 }
146 }
147 }
148
udpReady()149 void ServerHandler::udpReady() {
150 const unsigned int UDP_MAX_SIZE = 2048;
151 while (qusUdp->hasPendingDatagrams()) {
152 char encrypted[UDP_MAX_SIZE];
153 char buffer[UDP_MAX_SIZE];
154 unsigned int buflen = static_cast<unsigned int>(qusUdp->pendingDatagramSize());
155
156 if (buflen > UDP_MAX_SIZE) {
157 // Discard datagrams that exceed our buffer's size as we'd have to trim them down anyways and it is not very
158 // likely that the data is valid in the trimmed down form.
159 // As we're using a maxSize of 0 it is okay to pass NULL as the data buffer. Qt's docs (5.15) ensures that
160 // a maxSize of 0 means discarding the datagram.
161 qusUdp->readDatagram(NULL, 0);
162 continue;
163 }
164
165 QHostAddress senderAddr;
166 quint16 senderPort;
167 qusUdp->readDatagram(encrypted, buflen, &senderAddr, &senderPort);
168
169 if (!(HostAddress(senderAddr) == HostAddress(qhaRemote)) || (senderPort != usResolvedPort))
170 continue;
171
172 ConnectionPtr connection(cConnection);
173 if (! connection)
174 continue;
175
176 if (! connection->csCrypt.isValid())
177 continue;
178
179 if (buflen < 5)
180 continue;
181
182 if (! connection->csCrypt.decrypt(reinterpret_cast<const unsigned char *>(encrypted), reinterpret_cast<unsigned char *>(buffer), buflen)) {
183 if (connection->csCrypt.tLastGood.elapsed() > 5000000ULL) {
184 if (connection->csCrypt.tLastRequest.elapsed() > 5000000ULL) {
185 connection->csCrypt.tLastRequest.restart();
186 MumbleProto::CryptSetup mpcs;
187 sendMessage(mpcs);
188 }
189 }
190 continue;
191 }
192
193 PacketDataStream pds(buffer + 1, buflen-5);
194
195 MessageHandler::UDPMessageType msgType = static_cast<MessageHandler::UDPMessageType>((buffer[0] >> 5) & 0x7);
196 unsigned int msgFlags = buffer[0] & 0x1f;
197
198 switch (msgType) {
199 case MessageHandler::UDPPing: {
200 quint64 t;
201 pds >> t;
202 accUDP(static_cast<double>(tTimestamp.elapsed() - t) / 1000.0);
203 }
204 break;
205 case MessageHandler::UDPVoiceCELTAlpha:
206 case MessageHandler::UDPVoiceCELTBeta:
207 case MessageHandler::UDPVoiceSpeex:
208 case MessageHandler::UDPVoiceOpus:
209 handleVoicePacket(msgFlags, pds, msgType);
210 break;
211 default:
212 break;
213 }
214 }
215 }
216
handleVoicePacket(unsigned int msgFlags,PacketDataStream & pds,MessageHandler::UDPMessageType type)217 void ServerHandler::handleVoicePacket(unsigned int msgFlags, PacketDataStream &pds, MessageHandler::UDPMessageType type) {
218 unsigned int uiSession;
219 pds >> uiSession;
220 ClientUser *p = ClientUser::get(uiSession);
221 AudioOutputPtr ao = g.ao;
222 if (ao && p && ! p->bLocalMute && !(((msgFlags & 0x1f) == 2) && g.s.bWhisperFriends && p->qsFriendName.isEmpty())) {
223 unsigned int iSeq;
224 pds >> iSeq;
225 QByteArray qba;
226 qba.reserve(pds.left() + 1);
227 qba.append(static_cast<char>(msgFlags));
228 qba.append(pds.dataBlock(pds.left()));
229 ao->addFrameToBuffer(p, qba, iSeq, type);
230 }
231 }
232
sendMessage(const char * data,int len,bool force)233 void ServerHandler::sendMessage(const char *data, int len, bool force) {
234 STACKVAR(unsigned char, crypto, len+4);
235
236 QMutexLocker qml(&qmUdp);
237
238 if (! qusUdp)
239 return;
240
241 ConnectionPtr connection(cConnection);
242 if (!connection || !connection->csCrypt.isValid())
243 return;
244
245 if (!force && (NetworkConfig::TcpModeEnabled() || !bUdp)) {
246 QByteArray qba;
247
248 qba.resize(len + 6);
249 unsigned char *uc = reinterpret_cast<unsigned char *>(qba.data());
250 * reinterpret_cast<quint16 *>(& uc[0]) = qToBigEndian(static_cast<quint16>(MessageHandler::UDPTunnel));
251 * reinterpret_cast<quint32 *>(& uc[2]) = qToBigEndian(static_cast<quint32>(len));
252 memcpy(uc + 6, data, len);
253
254 QApplication::postEvent(this, new ServerHandlerMessageEvent(qba, MessageHandler::UDPTunnel, true));
255 } else {
256 if (!connection->csCrypt.encrypt(reinterpret_cast<const unsigned char *>(data), crypto, len)) {
257 return;
258 }
259 qusUdp->writeDatagram(reinterpret_cast<const char *>(crypto), len + 4, qhaRemote, usResolvedPort);
260 }
261 }
262
sendProtoMessage(const::google::protobuf::Message & msg,unsigned int msgType)263 void ServerHandler::sendProtoMessage(const ::google::protobuf::Message &msg, unsigned int msgType) {
264 QByteArray qba;
265
266 if (QThread::currentThread() != thread()) {
267 Connection::messageToNetwork(msg, msgType, qba);
268 ServerHandlerMessageEvent *shme=new ServerHandlerMessageEvent(qba, 0, false);
269 QApplication::postEvent(this, shme);
270 } else {
271 ConnectionPtr connection(cConnection);
272 if (!connection)
273 return;
274
275 connection->sendMessage(msg, msgType, qba);
276 }
277 }
278
isConnected() const279 bool ServerHandler::isConnected() const {
280 // If the digest isn't empty, then we are currently connected to a server (the digest being a hash
281 // of the server's certificate)
282 return !qbaDigest.isEmpty();
283 }
284
hasSynchronized() const285 bool ServerHandler::hasSynchronized() const {
286 return serverSyncronized;
287 }
288
setServerSynchronized(bool synchronized)289 void ServerHandler::setServerSynchronized(bool synchronized) {
290 serverSyncronized = synchronized;
291 }
292
hostnameResolved()293 void ServerHandler::hostnameResolved() {
294 ServerResolver *sr = qobject_cast<ServerResolver *>(QObject::sender());
295 QList<ServerResolverRecord> records = sr->records();
296
297 // Exit the ServerHandler thread's event loop with an
298 // error code in case our hostname lookup failed.
299 if (records.isEmpty()) {
300 exit(-1);
301 return;
302 }
303
304 // Create the list of target host:port pairs
305 // that the ServerHandler should try to connect to.
306 QList<ServerAddress> ql;
307 foreach (ServerResolverRecord record, records) {
308 foreach (HostAddress addr, record.addresses()) {
309 ql.append(ServerAddress(addr, record.port()));
310 }
311 }
312 qlAddresses = ql;
313
314 // Exit the event loop with 'success' status code,
315 // to continue connecting to the server.
316 exit(0);
317 }
318
run()319 void ServerHandler::run() {
320 // Resolve the hostname...
321 {
322 ServerResolver sr;
323 QObject::connect(&sr, SIGNAL(resolved()), this, SLOT(hostnameResolved()));
324 sr.resolve(qsHostName, usPort);
325 int ret = exec();
326 if (ret < 0) {
327 qWarning("ServerHandler: failed to resolve hostname");
328 emit error(QAbstractSocket::HostNotFoundError, tr("Unable to resolve hostname"));
329 return;
330 }
331 }
332
333 QList<ServerAddress> targetAddresses(qlAddresses);
334 bool shouldTryNextTargetServer = true;
335 do {
336 saTargetServer = qlAddresses.takeFirst();
337
338 tConnectionTimeoutTimer = NULL;
339 qbaDigest = QByteArray();
340 bStrong = true;
341 qtsSock = new QSslSocket(this);
342 qtsSock->setPeerVerifyName(qsHostName);
343
344 if (! g.s.bSuppressIdentity && CertWizard::validateCert(g.s.kpCertificate)) {
345 qtsSock->setPrivateKey(g.s.kpCertificate.second);
346 qtsSock->setLocalCertificate(g.s.kpCertificate.first.at(0));
347 QList<QSslCertificate> certs = qtsSock->caCertificates();
348 certs << g.s.kpCertificate.first;
349 qtsSock->setCaCertificates(certs);
350 }
351
352 {
353 ConnectionPtr connection(new Connection(this, qtsSock));
354 cConnection = connection;
355
356 // Technically it isn't necessary to reset this flag here since a ServerHandler will not be used
357 // for multiple connections in a row but just in case that at some point it will, we'll reset the
358 // flag here.
359 serverSyncronized = false;
360
361 qlErrors.clear();
362 qscCert.clear();
363
364 connect(qtsSock, SIGNAL(encrypted()), this, SLOT(serverConnectionConnected()));
365 connect(qtsSock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(serverConnectionStateChanged(QAbstractSocket::SocketState)));
366 connect(connection.get(), SIGNAL(connectionClosed(QAbstractSocket::SocketError, const QString &)), this, SLOT(serverConnectionClosed(QAbstractSocket::SocketError, const QString &)));
367 connect(connection.get(), SIGNAL(message(unsigned int, const QByteArray &)), this, SLOT(message(unsigned int, const QByteArray &)));
368 connect(connection.get(), SIGNAL(handleSslErrors(const QList<QSslError> &)), this, SLOT(setSslErrors(const QList<QSslError> &)));
369 }
370 bUdp = false;
371
372
373 #if QT_VERSION >= 0x050500
374 qtsSock->setProtocol(QSsl::TlsV1_0OrLater);
375 #elif QT_VERSION >= 0x050400
376 // In Qt 5.4, QSsl::SecureProtocols is equivalent
377 // to "TLSv1.0 or later", which we require.
378 qtsSock->setProtocol(QSsl::SecureProtocols);
379 #elif QT_VERSION >= 0x050000
380 qtsSock->setProtocol(QSsl::TlsV1_0);
381 #else
382 qtsSock->setProtocol(QSsl::TlsV1);
383 #endif
384 qtsSock->connectToHost(saTargetServer.host.toAddress(), saTargetServer.port);
385
386 tTimestamp.restart();
387
388 // Setup ping timer;
389 QTimer *ticker = new QTimer(this);
390 connect(ticker, SIGNAL(timeout()), this, SLOT(sendPing()));
391 ticker->start(g.s.iPingIntervalMsec);
392
393 g.mw->rtLast = MumbleProto::Reject_RejectType_None;
394
395 accUDP = accTCP = accClean;
396
397 uiVersion = 0;
398 qsRelease = QString();
399 qsOS = QString();
400 qsOSVersion = QString();
401
402 int ret = exec();
403 if (ret == -2) {
404 shouldTryNextTargetServer = true;
405 } else {
406 shouldTryNextTargetServer = false;
407 }
408
409 if (qusUdp) {
410 QMutexLocker qml(&qmUdp);
411
412 #ifdef Q_OS_WIN
413 if (hQoS != NULL) {
414 if (! QOSRemoveSocketFromFlow(hQoS, 0, dwFlowUDP, 0))
415 qWarning("ServerHandler: Failed to remove UDP from QoS");
416 dwFlowUDP = 0;
417 }
418 #endif
419 delete qusUdp;
420 qusUdp = NULL;
421 }
422
423 ticker->stop();
424
425 ConnectionPtr cptr(cConnection);
426 if (cptr) {
427 cptr->disconnectSocket(true);
428 }
429
430 cConnection.reset();
431 while (! cptr.unique()) {
432 msleep(100);
433 }
434 delete qtsSock;
435 delete tConnectionTimeoutTimer;
436 } while (shouldTryNextTargetServer && !qlAddresses.isEmpty());
437 }
438
439 #ifdef Q_OS_WIN
440 extern DWORD WinVerifySslCert(const QByteArray& cert);
441 #endif
442
setSslErrors(const QList<QSslError> & errors)443 void ServerHandler::setSslErrors(const QList<QSslError> &errors) {
444 ConnectionPtr connection(cConnection);
445 if (!connection) return;
446
447 qscCert = connection->peerCertificateChain();
448 QList<QSslError> newErrors = errors;
449
450 #ifdef Q_OS_WIN
451 bool bRevalidate = false;
452 QList<QSslError> errorsToRemove;
453 foreach (const QSslError& e, errors) {
454 switch (e.error()) {
455 case QSslError::UnableToGetLocalIssuerCertificate:
456 case QSslError::SelfSignedCertificateInChain:
457 bRevalidate = true;
458 errorsToRemove << e;
459 break;
460 default:
461 break;
462 }
463 }
464
465 if (bRevalidate) {
466 QByteArray der = qscCert.first().toDer();
467 DWORD errorStatus = WinVerifySslCert(der);
468 if (errorStatus == CERT_TRUST_NO_ERROR) {
469 foreach (const QSslError& e, errorsToRemove) {
470 newErrors.removeOne(e);
471 }
472 }
473 if (newErrors.isEmpty()) {
474 connection->proceedAnyway();
475 return;
476 }
477 }
478 #endif
479
480 bStrong = false;
481 if ((qscCert.size() > 0) && (QString::fromLatin1(qscCert.at(0).digest(QCryptographicHash::Sha1).toHex()) == database->getDigest(qsHostName, usPort)))
482 connection->proceedAnyway();
483 else
484 qlErrors = newErrors;
485 }
486
sendPing()487 void ServerHandler::sendPing() {
488 emit pingRequested();
489 }
490
sendPingInternal()491 void ServerHandler::sendPingInternal() {
492 ConnectionPtr connection(cConnection);
493 if (!connection)
494 return;
495
496 if (qtsSock->state() != QAbstractSocket::ConnectedState) {
497 return;
498 }
499
500 // Ensure the TLS handshake has completed before sending pings.
501 if (!qtsSock->isEncrypted()) {
502 return;
503 }
504
505 if (g.s.iMaxInFlightTCPPings > 0 && iInFlightTCPPings >= g.s.iMaxInFlightTCPPings) {
506 serverConnectionClosed(QAbstractSocket::UnknownSocketError, tr("Server is not responding to TCP pings"));
507 return;
508 }
509
510 CryptState &cs = connection->csCrypt;
511
512 quint64 t = tTimestamp.elapsed();
513
514 if (qusUdp) {
515 unsigned char buffer[256];
516 PacketDataStream pds(buffer + 1, 255);
517 buffer[0] = MessageHandler::UDPPing << 5;
518 pds << t;
519 sendMessage(reinterpret_cast<const char *>(buffer), pds.size() + 1, true);
520 }
521
522 MumbleProto::Ping mpp;
523
524 mpp.set_timestamp(t);
525 mpp.set_good(cs.uiGood);
526 mpp.set_late(cs.uiLate);
527 mpp.set_lost(cs.uiLost);
528 mpp.set_resync(cs.uiResync);
529
530
531 if (boost::accumulators::count(accUDP)) {
532 mpp.set_udp_ping_avg(static_cast<float>(boost::accumulators::mean(accUDP)));
533 mpp.set_udp_ping_var(static_cast<float>(boost::accumulators::variance(accUDP)));
534 }
535 mpp.set_udp_packets(static_cast<int>(boost::accumulators::count(accUDP)));
536
537 if (boost::accumulators::count(accTCP)) {
538 mpp.set_tcp_ping_avg(static_cast<float>(boost::accumulators::mean(accTCP)));
539 mpp.set_tcp_ping_var(static_cast<float>(boost::accumulators::variance(accTCP)));
540 }
541 mpp.set_tcp_packets(static_cast<int>(boost::accumulators::count(accTCP)));
542
543 sendMessage(mpp);
544
545 iInFlightTCPPings += 1;
546 }
547
message(unsigned int msgType,const QByteArray & qbaMsg)548 void ServerHandler::message(unsigned int msgType, const QByteArray &qbaMsg) {
549 const char *ptr = qbaMsg.constData();
550 if (msgType == MessageHandler::UDPTunnel) {
551 if (qbaMsg.length() < 1)
552 return;
553
554 MessageHandler::UDPMessageType umsgType = static_cast<MessageHandler::UDPMessageType>((ptr[0] >> 5) & 0x7);
555 unsigned int msgFlags = ptr[0] & 0x1f;
556 PacketDataStream pds(qbaMsg.constData() + 1, qbaMsg.size());
557
558 switch (umsgType) {
559 case MessageHandler::UDPVoiceCELTAlpha:
560 case MessageHandler::UDPVoiceCELTBeta:
561 case MessageHandler::UDPVoiceSpeex:
562 case MessageHandler::UDPVoiceOpus:
563 handleVoicePacket(msgFlags, pds, umsgType);
564 break;
565 default:
566 break;
567 }
568 } else if (msgType == MessageHandler::Ping) {
569 MumbleProto::Ping msg;
570 if (msg.ParseFromArray(qbaMsg.constData(), qbaMsg.size())) {
571 ConnectionPtr connection(cConnection);
572 if (!connection) return;
573
574 // Reset in-flight TCP ping counter to 0.
575 // We've received a ping. That means the
576 // connection is still OK.
577 iInFlightTCPPings = 0;
578
579 CryptState &cs = connection->csCrypt;
580 cs.uiRemoteGood = msg.good();
581 cs.uiRemoteLate = msg.late();
582 cs.uiRemoteLost = msg.lost();
583 cs.uiRemoteResync = msg.resync();
584 accTCP(static_cast<double>(tTimestamp.elapsed() - msg.timestamp()) / 1000.0);
585
586 if (((cs.uiRemoteGood == 0) || (cs.uiGood == 0)) && bUdp && (tTimestamp.elapsed() > 20000000ULL)) {
587 bUdp = false;
588 if (! NetworkConfig::TcpModeEnabled()) {
589 if ((cs.uiRemoteGood == 0) && (cs.uiGood == 0))
590 g.mw->msgBox(tr("UDP packets cannot be sent to or received from the server. Switching to TCP mode."));
591 else if (cs.uiRemoteGood == 0)
592 g.mw->msgBox(tr("UDP packets cannot be sent to the server. Switching to TCP mode."));
593 else
594 g.mw->msgBox(tr("UDP packets cannot be received from the server. Switching to TCP mode."));
595
596 database->setUdp(qbaDigest, false);
597 }
598 } else if (!bUdp && (cs.uiRemoteGood > 3) && (cs.uiGood > 3)) {
599 bUdp = true;
600 if (! NetworkConfig::TcpModeEnabled()) {
601 g.mw->msgBox(tr("UDP packets can be sent to and received from the server. Switching back to UDP mode."));
602
603 database->setUdp(qbaDigest, true);
604 }
605 }
606 }
607 } else {
608 ServerHandlerMessageEvent *shme=new ServerHandlerMessageEvent(qbaMsg, msgType, false);
609 QApplication::postEvent(g.mw, shme);
610 }
611 }
612
disconnect()613 void ServerHandler::disconnect() {
614 // Actual TCP object is in a different thread, so signal it
615 QByteArray qbaBuffer;
616 ServerHandlerMessageEvent *shme=new ServerHandlerMessageEvent(qbaBuffer, 0, false);
617 QApplication::postEvent(this, shme);
618 }
619
serverConnectionClosed(QAbstractSocket::SocketError err,const QString & reason)620 void ServerHandler::serverConnectionClosed(QAbstractSocket::SocketError err, const QString &reason) {
621 Connection *c = cConnection.get();
622 if (! c)
623 return;
624 if (c->bDisconnectedEmitted)
625 return;
626 c->bDisconnectedEmitted = true;
627
628 AudioOutputPtr ao = g.ao;
629 if (ao)
630 ao->wipe();
631
632 // Try next server in the list if possible.
633 // Otherwise, emit disconnect and exit with
634 // a normal status code.
635 if (!qlAddresses.isEmpty()) {
636 if (err == QAbstractSocket::ConnectionRefusedError || err == QAbstractSocket::SocketTimeoutError) {
637 qWarning("ServerHandler: connection attempt to %s:%i failed: %s (%li); trying next server....",
638 qPrintable(saTargetServer.host.toString()), static_cast<int>(saTargetServer.port),
639 qPrintable(reason), static_cast<long>(err));
640 exit(-2);
641 return;
642 }
643 }
644
645 emit disconnected(err, reason);
646
647 exit(0);
648 }
649
serverConnectionTimeoutOnConnect()650 void ServerHandler::serverConnectionTimeoutOnConnect() {
651 ConnectionPtr connection(cConnection);
652 if (connection)
653 connection->disconnectSocket(true);
654
655 serverConnectionClosed(QAbstractSocket::SocketTimeoutError, tr("Connection timed out"));
656 }
657
serverConnectionStateChanged(QAbstractSocket::SocketState state)658 void ServerHandler::serverConnectionStateChanged(QAbstractSocket::SocketState state) {
659 if (state == QAbstractSocket::ConnectingState) {
660 // Start timer for connection timeout during connect after resolving is completed
661 tConnectionTimeoutTimer = new QTimer();
662 connect(tConnectionTimeoutTimer, SIGNAL(timeout()), this, SLOT(serverConnectionTimeoutOnConnect()));
663 tConnectionTimeoutTimer->setSingleShot(true);
664 tConnectionTimeoutTimer->start(g.s.iConnectionTimeoutDurationMsec);
665 } else if (state == QAbstractSocket::ConnectedState) {
666 // Start TLS handshake
667 qtsSock->startClientEncryption();
668 }
669 }
670
serverConnectionConnected()671 void ServerHandler::serverConnectionConnected() {
672 ConnectionPtr connection(cConnection);
673 if (!connection) return;
674
675 iInFlightTCPPings = 0;
676
677 tConnectionTimeoutTimer->stop();
678
679 if (g.s.bQoS)
680 connection->setToS();
681
682 qscCert = connection->peerCertificateChain();
683 qscCipher = connection->sessionCipher();
684
685 if (! qscCert.isEmpty()) {
686 const QSslCertificate &qsc = qscCert.last();
687 qbaDigest = sha1(qsc.publicKey().toDer());
688 bUdp = database->getUdp(qbaDigest);
689 } else {
690 // Shouldn't reach this
691 qCritical("Server must have a certificate. Dropping connection");
692 disconnect();
693 return;
694 }
695
696 MumbleProto::Version mpv;
697 mpv.set_release(u8(QLatin1String(MUMBLE_RELEASE)));
698
699 unsigned int version = MumbleVersion::getRaw();
700 if (version) {
701 mpv.set_version(version);
702 }
703
704 if (!g.s.bHideOS) {
705 mpv.set_os(u8(OSInfo::getOS()));
706 mpv.set_os_version(u8(OSInfo::getOSDisplayableVersion()));
707 }
708
709 sendMessage(mpv);
710
711 MumbleProto::Authenticate mpa;
712 mpa.set_username(u8(qsUserName));
713 mpa.set_password(u8(qsPassword));
714
715 QStringList tokens = database->getTokens(qbaDigest);
716 foreach(const QString &qs, tokens)
717 mpa.add_tokens(u8(qs));
718
719 QMap<int, CELTCodec *>::const_iterator i;
720 for (i=g.qmCodecs.constBegin(); i != g.qmCodecs.constEnd(); ++i)
721 mpa.add_celt_versions(i.key());
722 #ifdef USE_OPUS
723 mpa.set_opus(true);
724 #else
725 mpa.set_opus(false);
726 #endif
727 sendMessage(mpa);
728
729 {
730 QMutexLocker qml(&qmUdp);
731
732 qhaRemote = connection->peerAddress();
733 qhaLocal = connection->localAddress();
734 usResolvedPort = connection->peerPort();
735 if (qhaLocal.isNull()) {
736 qFatal("ServerHandler: qhaLocal is unexpectedly a null addr");
737 }
738
739 qusUdp = new QUdpSocket(this);
740 if (! qusUdp) {
741 qFatal("ServerHandler: qusUdp is unexpectedly a null addr");
742 }
743 if (g.s.bUdpForceTcpAddr) {
744 qusUdp->bind(qhaLocal, 0);
745 } else {
746 if (qhaRemote.protocol() == QAbstractSocket::IPv6Protocol) {
747 qusUdp->bind(QHostAddress(QHostAddress::AnyIPv6), 0);
748 } else {
749 qusUdp->bind(QHostAddress(QHostAddress::Any), 0);
750 }
751 }
752
753 connect(qusUdp, SIGNAL(readyRead()), this, SLOT(udpReady()));
754
755 if (g.s.bQoS) {
756
757 #if defined(Q_OS_UNIX)
758 int val = 0xe0;
759 if (setsockopt(static_cast<int>(qusUdp->socketDescriptor()), IPPROTO_IP, IP_TOS, &val, sizeof(val))) {
760 val = 0x80;
761 if (setsockopt(static_cast<int>(qusUdp->socketDescriptor()), IPPROTO_IP, IP_TOS, &val, sizeof(val)))
762 qWarning("ServerHandler: Failed to set TOS for UDP Socket");
763 }
764 #if defined(SO_PRIORITY)
765 socklen_t optlen = sizeof(val);
766 if (getsockopt(static_cast<int>(qusUdp->socketDescriptor()), SOL_SOCKET, SO_PRIORITY, &val, &optlen) == 0) {
767 if (val == 0) {
768 val = 6;
769 setsockopt(static_cast<int>(qusUdp->socketDescriptor()), SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
770 }
771 }
772 #endif
773 #elif defined(Q_OS_WIN)
774 if (hQoS != NULL) {
775 struct sockaddr_in addr;
776 memset(&addr, 0, sizeof(addr));
777 addr.sin_family = AF_INET;
778 addr.sin_port = htons(usPort);
779 addr.sin_addr.s_addr = htonl(qhaRemote.toIPv4Address());
780
781 dwFlowUDP = 0;
782 if (! QOSAddSocketToFlow(hQoS, qusUdp->socketDescriptor(), reinterpret_cast<sockaddr *>(&addr), QOSTrafficTypeVoice, QOS_NON_ADAPTIVE_FLOW, reinterpret_cast<PQOS_FLOWID>(&dwFlowUDP)))
783 qWarning("ServerHandler: Failed to add UDP to QOS");
784 }
785 #endif
786 }
787 }
788
789 emit connected();
790 }
791
setConnectionInfo(const QString & host,unsigned short port,const QString & username,const QString & pw)792 void ServerHandler::setConnectionInfo(const QString &host, unsigned short port, const QString &username, const QString &pw) {
793 qsHostName = host;
794 usPort = port;
795 qsUserName = username;
796 qsPassword = pw;
797 }
798
getConnectionInfo(QString & host,unsigned short & port,QString & username,QString & pw) const799 void ServerHandler::getConnectionInfo(QString &host, unsigned short &port, QString &username, QString &pw) const {
800 host = qsHostName;
801 port = usPort;
802 username = qsUserName;
803 pw = qsPassword;
804 }
805
isStrong() const806 bool ServerHandler::isStrong() const {
807 return bStrong;
808 }
809
requestUserStats(unsigned int uiSession,bool statsOnly)810 void ServerHandler::requestUserStats(unsigned int uiSession, bool statsOnly) {
811 MumbleProto::UserStats mpus;
812 mpus.set_session(uiSession);
813 mpus.set_stats_only(statsOnly);
814 sendMessage(mpus);
815 }
816
joinChannel(unsigned int uiSession,unsigned int channel)817 void ServerHandler::joinChannel(unsigned int uiSession, unsigned int channel) {
818 MumbleProto::UserState mpus;
819 mpus.set_session(uiSession);
820 mpus.set_channel_id(channel);
821 sendMessage(mpus);
822 }
823
createChannel(unsigned int parent_id,const QString & name,const QString & description,unsigned int position,bool temporary,unsigned int maxUsers)824 void ServerHandler::createChannel(unsigned int parent_id, const QString &name, const QString &description, unsigned int position, bool temporary, unsigned int maxUsers) {
825 MumbleProto::ChannelState mpcs;
826 mpcs.set_parent(parent_id);
827 mpcs.set_name(u8(name));
828 mpcs.set_description(u8(description));
829 mpcs.set_position(position);
830 mpcs.set_temporary(temporary);
831 mpcs.set_max_users(maxUsers);
832 sendMessage(mpcs);
833 }
834
requestBanList()835 void ServerHandler::requestBanList() {
836 MumbleProto::BanList mpbl;
837 mpbl.set_query(true);
838 sendMessage(mpbl);
839 }
840
requestUserList()841 void ServerHandler::requestUserList() {
842 MumbleProto::UserList mpul;
843 sendMessage(mpul);
844 }
845
requestACL(unsigned int channel)846 void ServerHandler::requestACL(unsigned int channel) {
847 MumbleProto::ACL mpacl;
848 mpacl.set_channel_id(channel);
849 mpacl.set_query(true);
850 sendMessage(mpacl);
851 }
852
registerUser(unsigned int uiSession)853 void ServerHandler::registerUser(unsigned int uiSession) {
854 MumbleProto::UserState mpus;
855 mpus.set_session(uiSession);
856 mpus.set_user_id(0);
857 sendMessage(mpus);
858 }
859
kickBanUser(unsigned int uiSession,const QString & reason,bool ban)860 void ServerHandler::kickBanUser(unsigned int uiSession, const QString &reason, bool ban) {
861 MumbleProto::UserRemove mpur;
862 mpur.set_session(uiSession);
863 mpur.set_reason(u8(reason));
864 mpur.set_ban(ban);
865 sendMessage(mpur);
866 }
867
sendUserTextMessage(unsigned int uiSession,const QString & message_)868 void ServerHandler::sendUserTextMessage(unsigned int uiSession, const QString &message_) {
869 MumbleProto::TextMessage mptm;
870 mptm.add_session(uiSession);
871 mptm.set_message(u8(message_));
872 sendMessage(mptm);
873 }
874
sendChannelTextMessage(unsigned int channel,const QString & message_,bool tree)875 void ServerHandler::sendChannelTextMessage(unsigned int channel, const QString &message_, bool tree) {
876 MumbleProto::TextMessage mptm;
877 if (tree) {
878 mptm.add_tree_id(channel);
879 } else {
880 mptm.add_channel_id(channel);
881
882 if (message_ == QString::fromUtf8(g.ccHappyEaster + 10)) g.bHappyEaster = true;
883 }
884 mptm.set_message(u8(message_));
885 sendMessage(mptm);
886 }
887
setUserComment(unsigned int uiSession,const QString & comment)888 void ServerHandler::setUserComment(unsigned int uiSession, const QString &comment) {
889 MumbleProto::UserState mpus;
890 mpus.set_session(uiSession);
891 mpus.set_comment(u8(comment));
892 sendMessage(mpus);
893 }
894
setUserTexture(unsigned int uiSession,const QByteArray & qba)895 void ServerHandler::setUserTexture(unsigned int uiSession, const QByteArray &qba) {
896 QByteArray texture;
897
898 if ((uiVersion >= 0x010202) || qba.isEmpty()) {
899 texture = qba;
900 } else {
901 QByteArray raw = qba;
902
903 QBuffer qb(& raw);
904 qb.open(QIODevice::ReadOnly);
905
906 QImageReader qir;
907 qir.setDecideFormatFromContent(false);
908
909 QByteArray fmt;
910 if (!RichTextImage::isValidImage(qba, fmt)) {
911 return;
912 }
913
914 qir.setFormat(fmt);
915 qir.setDevice(&qb);
916
917 QSize sz = qir.size();
918 const int TEX_MAX_WIDTH = 600;
919 const int TEX_MAX_HEIGHT = 60;
920 const int TEX_RGBA_SIZE = TEX_MAX_WIDTH*TEX_MAX_HEIGHT*4;
921 sz.scale(TEX_MAX_WIDTH, TEX_MAX_HEIGHT, Qt::KeepAspectRatio);
922 qir.setScaledSize(sz);
923
924 QImage tex = qir.read();
925 if (tex.isNull()) {
926 return;
927 }
928
929 raw = QByteArray(TEX_RGBA_SIZE, 0);
930 QImage img(reinterpret_cast<unsigned char *>(raw.data()), TEX_MAX_WIDTH, TEX_MAX_HEIGHT, QImage::Format_ARGB32);
931
932 QPainter imgp(&img);
933 imgp.setRenderHint(QPainter::Antialiasing);
934 imgp.setRenderHint(QPainter::TextAntialiasing);
935 imgp.setCompositionMode(QPainter::CompositionMode_SourceOver);
936 imgp.drawImage(0, 0, tex);
937
938 texture = qCompress(QByteArray(reinterpret_cast<const char *>(img.bits()), TEX_RGBA_SIZE));
939 }
940
941 MumbleProto::UserState mpus;
942 mpus.set_session(uiSession);
943 mpus.set_texture(blob(texture));
944 sendMessage(mpus);
945
946 if (! texture.isEmpty()) {
947 database->setBlob(sha1(texture), texture);
948 }
949 }
950
setTokens(const QStringList & tokens)951 void ServerHandler::setTokens(const QStringList &tokens) {
952 MumbleProto::Authenticate msg;
953 foreach(const QString &qs, tokens)
954 msg.add_tokens(u8(qs));
955 sendMessage(msg);
956 }
957
removeChannel(unsigned int channel)958 void ServerHandler::removeChannel(unsigned int channel) {
959 MumbleProto::ChannelRemove mpcr;
960 mpcr.set_channel_id(channel);
961 sendMessage(mpcr);
962 }
963
addChannelLink(unsigned int channel,unsigned int link)964 void ServerHandler::addChannelLink(unsigned int channel, unsigned int link) {
965 MumbleProto::ChannelState mpcs;
966 mpcs.set_channel_id(channel);
967 mpcs.add_links_add(link);
968 sendMessage(mpcs);
969 }
970
removeChannelLink(unsigned int channel,unsigned int link)971 void ServerHandler::removeChannelLink(unsigned int channel, unsigned int link) {
972 MumbleProto::ChannelState mpcs;
973 mpcs.set_channel_id(channel);
974 mpcs.add_links_remove(link);
975 sendMessage(mpcs);
976 }
977
requestChannelPermissions(unsigned int channel)978 void ServerHandler::requestChannelPermissions(unsigned int channel) {
979 MumbleProto::PermissionQuery mppq;
980 mppq.set_channel_id(channel);
981 sendMessage(mppq);
982 }
983
setSelfMuteDeafState(bool mute,bool deaf)984 void ServerHandler::setSelfMuteDeafState(bool mute, bool deaf) {
985 MumbleProto::UserState mpus;
986 mpus.set_self_mute(mute);
987 mpus.set_self_deaf(deaf);
988 sendMessage(mpus);
989 }
990
announceRecordingState(bool recording)991 void ServerHandler::announceRecordingState(bool recording) {
992 MumbleProto::UserState mpus;
993 mpus.set_recording(recording);
994 sendMessage(mpus);
995 }
996
getServerURL(bool withPassword) const997 QUrl ServerHandler::getServerURL(bool withPassword) const {
998 QUrl url;
999
1000 url.setScheme(QLatin1String("mumble"));
1001 url.setHost(qsHostName);
1002 if (usPort != DEFAULT_MUMBLE_PORT) {
1003 url.setPort(usPort);
1004 }
1005
1006 url.setUserName(qsUserName);
1007
1008 if (withPassword && !qsPassword.isEmpty()) {
1009 url.setPassword(qsPassword);
1010 }
1011
1012 return url;
1013 }
1014