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