1 /* Ricochet - https://ricochet.im/
2  * Copyright (C) 2014, John Brooks <john.brooks@dereferenced.net>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *    * Redistributions of source code must retain the above copyright
9  *      notice, this list of conditions and the following disclaimer.
10  *
11  *    * Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following disclaimer
13  *      in the documentation and/or other materials provided with the
14  *      distribution.
15  *
16  *    * Neither the names of the copyright owners nor the names of its
17  *      contributors may be used to endorse or promote products derived from
18  *      this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "Connection_p.h"
34 #include "ControlChannel.h"
35 #include "utils/Useful.h"
36 #include <QTcpSocket>
37 #include <QTimer>
38 #include <QtEndian>
39 #include <QDebug>
40 
41 using namespace Protocol;
42 
Connection(QTcpSocket * socket,Direction direction)43 Connection::Connection(QTcpSocket *socket, Direction direction)
44     : QObject()
45     , d(new ConnectionPrivate(this))
46 {
47     d->setSocket(socket, direction);
48 }
49 
ConnectionPrivate(Connection * qq)50 ConnectionPrivate::ConnectionPrivate(Connection *qq)
51     : QObject(qq)
52     , q(qq)
53     , socket(0)
54     , direction(Connection::ClientSide)
55     , purpose(Connection::Purpose::Unknown)
56     , wasClosed(false)
57     , handshakeDone(false)
58     , nextOutboundChannelId(-1)
59 {
60     ageTimer.start();
61 
62     QTimer *timeout = new QTimer(this);
63     timeout->setSingleShot(true);
64     timeout->setInterval(UnknownPurposeTimeout * 1000);
65     connect(timeout, &QTimer::timeout, this,
66         [this,timeout]() {
67             if (purpose == Connection::Purpose::Unknown) {
68                 qDebug() << "Closing connection" << q << "with unknown purpose after timeout";
69                 q->close();
70             }
71             timeout->deleteLater();
72         }
73     );
74     timeout->start();
75 }
76 
~Connection()77 Connection::~Connection()
78 {
79     qDebug() << this << "Destroying connection";
80 
81     // When we call closeImmediately, the list of channels will be cleared.
82     // In the normal case, they will all use deleteLater to be freed at the
83     // next event loop. Since the connection is being destructed immediately,
84     // and we want to be certain that channels don't outlive it, copy the
85     // list before it's cleared and delete them immediately afterwards.
86     auto channels = d->channels;
87     d->closeImmediately();
88 
89     // These would be deleted by QObject ownership as well, but we want to
90     // give them a chance to destruct before the connection d pointer is reset.
91     foreach (Channel *c, channels)
92         delete c;
93 
94     // Reset d pointer, so we'll crash nicely if anything tries to call
95     // into Connection after this.
96     d = 0;
97 }
98 
~ConnectionPrivate()99 ConnectionPrivate::~ConnectionPrivate()
100 {
101     // Reset q pointer, for the same reason as above
102     q = 0;
103 }
104 
direction() const105 Connection::Direction Connection::direction() const
106 {
107     return d->direction;
108 }
109 
isConnected() const110 bool Connection::isConnected() const
111 {
112     bool re = d->socket && d->socket->state() == QAbstractSocket::ConnectedState;
113     if (d->wasClosed) {
114         Q_ASSERT(!re);
115     }
116     return re;
117 }
118 
serverHostname() const119 QString Connection::serverHostname() const
120 {
121     QString hostname;
122     if (direction() == ClientSide)
123         hostname = d->socket->peerName();
124     else if (direction() == ServerSide)
125         hostname = d->socket->property("localHostname").toString();
126 
127     if (!hostname.endsWith(QStringLiteral(".onion"))) {
128         BUG() << "Connection does not have a valid server hostname:" << hostname;
129         return QString();
130     }
131 
132     return hostname;
133 }
134 
age() const135 int Connection::age() const
136 {
137     return qRound(d->ageTimer.elapsed() / 1000.0);
138 }
139 
setSocket(QTcpSocket * s,Connection::Direction d)140 void ConnectionPrivate::setSocket(QTcpSocket *s, Connection::Direction d)
141 {
142     if (socket) {
143         BUG() << "Connection already has a socket";
144         return;
145     }
146 
147     socket = s;
148     direction = d;
149     connect(socket, &QAbstractSocket::disconnected, this, &ConnectionPrivate::socketDisconnected);
150     connect(socket, &QIODevice::readyRead, this, &ConnectionPrivate::socketReadable);
151 
152     socket->setParent(q);
153 
154     if (socket->state() != QAbstractSocket::ConnectedState) {
155         BUG() << "Connection created with socket in a non-connected state" << socket->state();
156     }
157 
158     Channel *control = new ControlChannel(direction == Connection::ClientSide ? Channel::Outbound : Channel::Inbound, q);
159     // Closing the control channel must also close the connection
160     connect(control, &Channel::invalidated, q, &Connection::close);
161     insertChannel(control);
162 
163     if (!control->isOpened() || control->identifier() != 0 || q->channel(0) != control) {
164         BUG() << "Control channel on new connection is not set up properly";
165         q->close();
166         return;
167     }
168 
169     if (direction == Connection::ClientSide) {
170         // The server side is implicitly authenticated (by the transport) as the correct service, so grant that
171         QString serverName = q->serverHostname();
172         if (serverName.isEmpty()) {
173             BUG() << "Server side of connection doesn't have an authenticated name, aborting";
174             q->close();
175             return;
176         }
177 
178         q->grantAuthentication(Connection::HiddenServiceAuth, serverName);
179 
180         // Send the introduction version handshake message
181         char intro[] = { 0x49, 0x4D, 0x02, ProtocolVersion, 0 };
182         if (socket->write(intro, sizeof(intro)) < (int)sizeof(intro)) {
183             qDebug() << "Failed writing introduction message to socket";
184             q->close();
185             return;
186         }
187     }
188 }
189 
close()190 void Connection::close()
191 {
192     if (isConnected()) {
193         Q_ASSERT(!d->wasClosed);
194         qDebug() << "Disconnecting socket for connection" << this;
195         d->socket->disconnectFromHost();
196 
197         // If not fully closed in 5 seconds, abort
198         QTimer *timeout = new QTimer(this);
199         timeout->setSingleShot(true);
200         connect(timeout, &QTimer::timeout, d, &ConnectionPrivate::closeImmediately);
201         timeout->start(5000);
202     }
203 }
204 
closeImmediately()205 void ConnectionPrivate::closeImmediately()
206 {
207     if (socket)
208         socket->abort();
209 
210     if (!wasClosed) {
211         BUG() << "Socket was forcefully closed but never emitted closed signal";
212         wasClosed = true;
213         emit q->closed();
214     }
215 
216     if (!channels.isEmpty()) {
217         foreach (Channel *c, channels)
218             qDebug() << "Open channel:" << c << c->type() << c->connection();
219         BUG() << "Channels remain open after forcefully closing connection socket";
220     }
221 }
222 
socketDisconnected()223 void ConnectionPrivate::socketDisconnected()
224 {
225     qDebug() << "Connection" << this << "disconnected";
226     closeAllChannels();
227 
228     if (!wasClosed) {
229         wasClosed = true;
230         emit q->closed();
231     }
232 }
233 
socketReadable()234 void ConnectionPrivate::socketReadable()
235 {
236     if (!handshakeDone) {
237         qint64 available = socket->bytesAvailable();
238 
239         if (direction == Connection::ClientSide && available >= 1) {
240             // Expecting a single byte in response with the chosen version
241             uchar version = ProtocolVersionFailed;
242             if (socket->read(reinterpret_cast<char*>(&version), 1) < 1) {
243                 qDebug() << "Connection socket error" << socket->error() << "during read:" << socket->errorString();
244                 socket->abort();
245                 return;
246             }
247 
248             handshakeDone = true;
249             if (version == 0) {
250                 qDebug() << "Server in outbound connection is using the version 1.0 protocol";
251                 emit q->oldVersionNegotiated(socket);
252                 q->close();
253                 return;
254             } else if (version != ProtocolVersion) {
255                 qDebug() << "Version negotiation failed on outbound connection";
256                 emit q->versionNegotiationFailed();
257                 socket->abort();
258                 return;
259             } else
260                 emit q->ready();
261         } else if (direction == Connection::ServerSide && available >= 3) {
262             // Expecting at least 3 bytes
263             uchar intro[3] = { 0 };
264             qint64 re = socket->peek(reinterpret_cast<char*>(intro), sizeof(intro));
265             if (re < (int)sizeof(intro)) {
266                 qDebug() << "Connection socket error" << socket->error() << "during read:" << socket->errorString();
267                 socket->abort();
268                 return;
269             }
270 
271             quint8 nVersions = intro[2];
272             if (intro[0] != 0x49 || intro[1] != 0x4D || nVersions == 0) {
273                 qDebug() << "Invalid introduction sequence on inbound connection";
274                 socket->abort();
275                 return;
276             }
277 
278             if (available < (qint64)sizeof(intro) + nVersions)
279                 return;
280 
281             // Discard intro header
282             re = socket->read(reinterpret_cast<char*>(intro), sizeof(intro));
283 
284             QByteArray versions(nVersions, 0);
285             re = socket->read(versions.data(), versions.size());
286             if (re != versions.size()) {
287                 qDebug() << "Connection socket error" << socket->error() << "during read:" << socket->errorString();
288                 socket->abort();
289                 return;
290             }
291 
292             quint8 selectedVersion = ProtocolVersionFailed;
293             foreach (quint8 v, versions) {
294                 if (v == ProtocolVersion) {
295                     selectedVersion = v;
296                     break;
297                 }
298             }
299 
300             re = socket->write(reinterpret_cast<char*>(&selectedVersion), 1);
301             if (re != 1) {
302                 qDebug() << "Connection socket error" << socket->error() << "during write:" << socket->errorString();
303                 socket->abort();
304                 return;
305             }
306 
307             handshakeDone = true;
308             if (selectedVersion != ProtocolVersion) {
309                 qDebug() << "Version negotiation failed on inbound connection";
310                 emit q->versionNegotiationFailed();
311                 // Close gracefully to allow the response to write
312                 q->close();
313                 return;
314             } else
315                 emit q->ready();
316         } else {
317             return;
318         }
319     }
320 
321     qint64 available;
322     while ((available = socket->bytesAvailable()) >= PacketHeaderSize) {
323         uchar header[PacketHeaderSize];
324         // Peek at the header first, to read the size of the packet and make sure
325         // the entire thing is available within the buffer.
326         qint64 re = socket->peek(reinterpret_cast<char*>(header), PacketHeaderSize);
327         if (re < 0) {
328             qDebug() << "Connection socket error" << socket->error() << "during read:" << socket->errorString();
329             socket->abort();
330             return;
331         } else if (re < PacketHeaderSize) {
332             BUG() << "Socket had" << available << "bytes available but peek only returned" << re;
333             return;
334         }
335 
336         Q_STATIC_ASSERT(PacketHeaderSize == 4);
337         quint16 packetSize = qFromBigEndian<quint16>(header);
338         quint16 channelId = qFromBigEndian<quint16>(&header[2]);
339 
340         if (packetSize < PacketHeaderSize) {
341             qWarning() << "Corrupted data from connection (packet size is too small); disconnecting";
342             socket->abort();
343             return;
344         }
345 
346         if (packetSize > available)
347             break;
348 
349         // Read header out of the buffer and discard
350         re = socket->read(reinterpret_cast<char*>(header), PacketHeaderSize);
351         if (re != PacketHeaderSize) {
352             if (re < 0) {
353                 qDebug() << "Connection socket error" << socket->error() << "during read:" << socket->errorString();
354             } else {
355                 // Because of QTcpSocket buffering, we can expect that up to 'available' bytes
356                 // will read. Treat anything less as an error condition.
357                 BUG() << "Socket read was unexpectedly small;" << available << "bytes should've been available but we read" << re;
358             }
359             socket->abort();
360             return;
361         }
362 
363         // Read data
364         QByteArray data(packetSize - PacketHeaderSize, 0);
365         re = (data.size() == 0) ? 0 : socket->read(data.data(), data.size());
366         if (re != data.size()) {
367             if (re < 0) {
368                 qDebug() << "Connection socket error" << socket->error() << "during read:" << socket->errorString();
369             } else {
370                 // As above
371                 BUG() << "Socket read was unexpectedly small;" << available << "bytes should've been available but we read" << re;
372             }
373             socket->abort();
374             return;
375         }
376 
377         Channel *channel = q->channel(channelId);
378         if (!channel) {
379             // XXX We should sanity-check and rate limit these responses better
380             if (data.isEmpty()) {
381                 qDebug() << "Ignoring channel close message for non-existent channel" << channelId;
382             } else {
383                 qDebug() << "Ignoring" << data.size() << "byte packet for non-existent channel" << channelId;
384                 // Send channel close message
385                 writePacket(channelId, QByteArray());
386             }
387             continue;
388         }
389 
390         if (channel->connection() != q) {
391             // If this fails, something is extremely broken. It may be dangerous to continue
392             // processing any data at all. Crash gracefully.
393             BUG() << "Channel" << channelId << "found on connection" << this << "but its connection is"
394                   << channel->connection();
395             qFatal("Connection mismatch while handling packet");
396             return;
397         }
398 
399         if (data.isEmpty()) {
400             channel->closeChannel();
401         } else {
402             channel->receivePacket(data);
403         }
404     }
405 }
406 
writePacket(Channel * channel,const QByteArray & data)407 bool ConnectionPrivate::writePacket(Channel *channel, const QByteArray &data)
408 {
409     if (channel->connection() != q) {
410         // As above, dangerously broken, crash the process to avoid damage
411         BUG() << "Writing packet for channel" << channel->identifier() << "on connection" << this
412               << "but its connection is" << channel->connection();
413         qFatal("Connection mismatch while writing packet");
414         return false;
415     }
416 
417     return writePacket(channel->identifier(), data);
418 }
419 
writePacket(int channelId,const QByteArray & data)420 bool ConnectionPrivate::writePacket(int channelId, const QByteArray &data)
421 {
422     if (channelId < 0 || channelId > UINT16_MAX) {
423         BUG() << "Cannot write packet for channel with invalid identifier" << channelId;
424         return false;
425     }
426 
427     if (data.size() > PacketMaxDataSize) {
428         BUG() << "Cannot write oversized packet of" << data.size() << "bytes to channel" << channelId;
429         return false;
430     }
431 
432     if (!q->isConnected()) {
433         qDebug() << "Cannot write packet to closed connection";
434         return false;
435     }
436 
437     Q_STATIC_ASSERT(PacketHeaderSize + PacketMaxDataSize <= UINT16_MAX);
438     Q_STATIC_ASSERT(PacketHeaderSize == 4);
439     uchar header[PacketHeaderSize] = { 0 };
440     qToBigEndian(static_cast<quint16>(PacketHeaderSize + data.size()), header);
441     qToBigEndian(static_cast<quint16>(channelId), &header[2]);
442 
443     qint64 re = socket->write(reinterpret_cast<char*>(header), PacketHeaderSize);
444     if (re != PacketHeaderSize) {
445         qDebug() << "Connection socket error" << socket->error() << "during write:" << socket->errorString();
446         socket->abort();
447         return false;
448     }
449 
450     re = socket->write(data);
451     if (re != data.size()) {
452         qDebug() << "Connection socket error" << socket->error() << "during write:" << socket->errorString();
453         socket->abort();
454         return false;
455     }
456 
457     return true;
458 }
459 
availableOutboundChannelId()460 int ConnectionPrivate::availableOutboundChannelId()
461 {
462     // Server opens even-nubmered channels, client opens odd-numbered
463     bool evenNumbered = (direction == Connection::ServerSide);
464     const int minId = evenNumbered ? 2 : 1;
465     const int maxId = evenNumbered ? (UINT16_MAX-1) : UINT16_MAX;
466 
467     if (nextOutboundChannelId < minId || nextOutboundChannelId > maxId)
468         nextOutboundChannelId = minId;
469 
470     // Find an unused id, trying a maximum of 100 times, using a random step to avoid collision
471     for (int i = 0; i < 100 && channels.contains(nextOutboundChannelId); i++) {
472         nextOutboundChannelId += 1 + (qrand() % 200);
473         if (evenNumbered)
474             nextOutboundChannelId += nextOutboundChannelId % 2;
475         if (nextOutboundChannelId > maxId)
476             nextOutboundChannelId = minId;
477     }
478 
479     if (channels.contains(nextOutboundChannelId)) {
480         // Abort the connection if we still couldn't find an id, because it's probably a nasty bug
481         BUG() << "Can't find an available outbound channel ID for connection; aborting connection";
482         socket->abort();
483         return -1;
484     }
485 
486     if (nextOutboundChannelId < minId || nextOutboundChannelId > maxId) {
487         BUG() << "Selected a channel id that isn't within range";
488         return -1;
489     }
490 
491     if (evenNumbered == bool(nextOutboundChannelId % 2)) {
492         BUG() << "Selected a channel id that isn't valid for this side of the connection";
493         return -1;
494     }
495 
496     int re = nextOutboundChannelId;
497     nextOutboundChannelId += 2;
498     return re;
499 }
500 
isValidAvailableChannelId(int id,Connection::Direction side)501 bool ConnectionPrivate::isValidAvailableChannelId(int id, Connection::Direction side)
502 {
503     if (id < 1 || id > UINT16_MAX)
504         return false;
505 
506     bool evenNumbered = bool(id % 2);
507     if (evenNumbered == (side == Connection::ServerSide))
508         return false;
509 
510     if (channels.contains(id))
511         return false;
512 
513     return true;
514 }
515 
insertChannel(Channel * channel)516 bool ConnectionPrivate::insertChannel(Channel *channel)
517 {
518     if (channel->connection() != q) {
519         BUG() << "Connection tried to insert a channel assigned to a different connection";
520         return false;
521     }
522 
523     if (channel->identifier() < 0) {
524         BUG() << "Connection tried to insert a channel without a valid identifier";
525         return false;
526     }
527 
528     if (channels.contains(channel->identifier())) {
529         BUG() << "Connection tried to insert a channel with a duplicate id" << channel->identifier()
530               << "- we have" << channels.value(channel->identifier()) << "and inserted" << channel;
531         return false;
532     }
533 
534     if (channel->parent() != q) {
535         BUG() << "Connection inserted a channel without expected parent object. Fixing.";
536         channel->setParent(q);
537     }
538 
539     channels.insert(channel->identifier(), channel);
540     return true;
541 }
542 
removeChannel(Channel * channel)543 void ConnectionPrivate::removeChannel(Channel *channel)
544 {
545     if (channel->connection() != q) {
546         BUG() << "Connection tried to remove a channel assigned to a different connection";
547         return;
548     }
549 
550     // Out of caution, find the channel by pointer instead of identifier. This will make sure
551     // it's always removed from the list, even if the identifier was somehow reset or lost.
552     for (auto it = channels.begin(); it != channels.end(); ) {
553         if (*it == channel)
554             it = channels.erase(it);
555         else
556             it++;
557     }
558 }
559 
closeAllChannels()560 void ConnectionPrivate::closeAllChannels()
561 {
562     // Takes a copy, won't be broken by removeChannel calls
563     foreach (Channel *channel, channels)
564         channel->closeChannel();
565 
566     if (!channels.isEmpty())
567         BUG() << "Channels remain open on connection after calling closeAllChannels";
568 }
569 
channels()570 QHash<int,Channel*> Connection::channels()
571 {
572     return d->channels;
573 }
574 
channel(int identifier)575 Channel *Connection::channel(int identifier)
576 {
577     return d->channels.value(identifier);
578 }
579 
purpose() const580 Connection::Purpose Connection::purpose() const
581 {
582     return d->purpose;
583 }
584 
setPurpose(Purpose value)585 bool Connection::setPurpose(Purpose value)
586 {
587     if (d->purpose == value)
588         return true;
589 
590     switch (value) {
591         case Purpose::Unknown:
592             BUG() << "A connection can't reset to unknown purpose";
593             return false;
594         case Purpose::KnownContact:
595             if (!hasAuthenticated(HiddenServiceAuth)) {
596                 BUG() << "Connection purpose cannot be KnownContact without authenticating a service";
597                 return false;
598             }
599             break;
600         case Purpose::OutboundRequest:
601             if (d->direction != ClientSide) {
602                 BUG() << "Connection purpose cannot be OutboundRequest on an inbound connection";
603                 return false;
604             } else if (d->purpose != Purpose::Unknown) {
605                 BUG() << "Connection purpose cannot change from" << int(d->purpose) << "to OutboundRequest";
606                 return false;
607             }
608             break;
609         case Purpose::InboundRequest:
610             if (d->direction != ServerSide) {
611                 BUG() << "Connection purpose cannot be InboundRequest on an outbound connection";
612                 return false;
613             } else if (d->purpose != Purpose::Unknown) {
614                 BUG() << "Connection purpose cannot change from" << int(d->purpose) << "to InboundRequest";
615                 return false;
616             }
617             break;
618         default:
619             BUG() << "Purpose type" << int(value) << "is not defined";
620             return false;
621     }
622 
623     Purpose old = d->purpose;
624     d->purpose = value;
625     emit purposeChanged(d->purpose, old);
626     return true;
627 }
628 
hasAuthenticated(AuthenticationType type) const629 bool Connection::hasAuthenticated(AuthenticationType type) const
630 {
631     return d->authentication.contains(type);
632 }
633 
hasAuthenticatedAs(AuthenticationType type,const QString & identity) const634 bool Connection::hasAuthenticatedAs(AuthenticationType type, const QString &identity) const
635 {
636     auto it = d->authentication.find(type);
637     if (!identity.isEmpty() && it != d->authentication.end())
638         return *it == identity;
639     return false;
640 }
641 
authenticatedIdentity(AuthenticationType type) const642 QString Connection::authenticatedIdentity(AuthenticationType type) const
643 {
644     return d->authentication.value(type);
645 }
646 
grantAuthentication(AuthenticationType type,const QString & identity)647 void Connection::grantAuthentication(AuthenticationType type, const QString &identity)
648 {
649     if (hasAuthenticated(type)) {
650         BUG() << "Tried to redundantly grant" << type << "authentication to connection";
651         return;
652     }
653 
654     qDebug() << "Granting" << type << "authentication as" << identity << "to connection";
655 
656     d->authentication.insert(type, identity);
657     emit authenticated(type, identity);
658 }
659 
660