Commit 0d676dc9b9030a7d06a57ec953c8b56ad1bd8978

Authored by Wiebe Cazemier
1 parent 243c873f

Connect handling, mostly

client.cpp
... ... @@ -74,7 +74,10 @@ bool Client::bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn)
74 74 while ((encodedByte & 128) != 0);
75 75 packet_length += remaining_length_i;
76 76  
77   - // TODO: unauth client can't send many bytes
  77 + if (!authenticated && packet_length >= 1024*1024)
  78 + {
  79 + throw ProtocolError("An unauthenticated client sends a packet of 1 MB or bigger? Probably it's just random bytes.");
  80 + }
78 81  
79 82 if (packet_length <= getBufBytesUsed())
80 83 {
... ... @@ -99,6 +102,13 @@ bool Client::bufferToMqttPackets(std::vector&lt;MqttPacket&gt; &amp;packetQueueIn)
99 102 // TODO: reset buffer to normal size after a while of not needing it, or not needing the extra space.
100 103 }
101 104  
  105 +void Client::setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen)
  106 +{
  107 + this->clientid = clientId;
  108 + this->username = username;
  109 + this->connectPacketSeen = connectPacketSeen;
  110 +}
  111 +
102 112  
103 113  
104 114  
... ...
client.h
... ... @@ -7,6 +7,7 @@
7 7  
8 8 #include "threaddata.h"
9 9 #include "mqttpacket.h"
  10 +#include "exceptions.h"
10 11  
11 12 #define CLIENT_BUFFER_SIZE 1024
12 13 #define MQTT_HEADER_LENGH 2
... ... @@ -26,7 +27,9 @@ class Client
26 27 int ri = 0;
27 28  
28 29 bool authenticated = false;
  30 + bool connectPacketSeen = false;
29 31 std::string clientid;
  32 + std::string username;
30 33  
31 34 ThreadData_p threadData;
32 35  
... ... @@ -55,6 +58,11 @@ public:
55 58 int getFd() { return fd;}
56 59 bool readFdIntoBuffer();
57 60 bool bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn);
  61 + void setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen);
  62 + void setAuthenticated(bool value) { authenticated = value;}
  63 + bool getAuthenticated() { return authenticated; }
  64 + bool hasConnectPacketSeen() { return connectPacketSeen; }
  65 +
58 66  
59 67 };
60 68  
... ...
mqttpacket.cpp
... ... @@ -7,24 +7,25 @@ MqttPacket::MqttPacket(char *buf, size_t len, size_t fixed_header_length, Client
7 7 sender(sender)
8 8 {
9 9 unsigned char _packetType = buf[0] >> 4;
10   - packetType = (PacketType)_packetType; // TODO: veryify some other things and set to invalid if doesn't match
  10 + packetType = (PacketType)_packetType;
  11 + pos += fixed_header_length;
11 12  
12 13 std::memcpy(&bites[0], buf, len);
13 14 }
14 15  
15 16 void MqttPacket::handle()
16 17 {
17   - pos += fixed_header_length;
18   -
19 18 if (packetType == PacketType::CONNECT)
20 19 handleConnect();
21 20 }
22 21  
23 22 void MqttPacket::handleConnect()
24 23 {
  24 + if (sender->hasConnectPacketSeen())
  25 + throw ProtocolError("Client already sent a CONNECT.");
  26 +
25 27 // TODO: Do all packets have a variable header?
26   - variable_header_length = (bites[fixed_header_length] << 8) | (bites[fixed_header_length+1]);
27   - pos += 2;
  28 + variable_header_length = readTwoBytesToUInt16();
28 29  
29 30 if (variable_header_length == 4)
30 31 {
... ... @@ -36,12 +37,54 @@ void MqttPacket::handleConnect()
36 37 if (magic_marker == "MQTT" && protocol_level == 0x04)
37 38 {
38 39 protocolVersion = ProtocolVersion::Mqtt311;
  40 +
  41 + char flagByte = readByte();
  42 + bool reserved = !!(flagByte & 0b00000001);
  43 +
  44 + if (reserved)
  45 + throw ProtocolError("Protocol demands reserved flag in CONNECT is 0");
  46 +
  47 +
  48 + bool user_name_flag = !!(flagByte & 0b10000000);
  49 + bool password_flag = !!(flagByte & 0b01000000);
  50 + bool will_retain = !!(flagByte & 0b00100000);
  51 + char will_qos = (flagByte & 0b00011000) >> 3;
  52 + bool will_flag = !!(flagByte & 0b00000100);
  53 + bool clean_session = !!(flagByte & 0b00000010);
  54 +
  55 + uint16_t keep_alive = readTwoBytesToUInt16();
  56 +
  57 + uint16_t client_id_length = readTwoBytesToUInt16();
  58 + std::string client_id(readBytes(client_id_length), client_id_length);
  59 +
  60 + std::string username;
  61 + std::string password;
  62 +
  63 + if (will_flag)
  64 + {
  65 +
  66 + }
  67 + if (user_name_flag)
  68 + {
  69 + uint16_t user_name_length = readTwoBytesToUInt16();
  70 + username = std::string(readBytes(user_name_length), user_name_length);
  71 + }
  72 + if (password_flag)
  73 + {
  74 + uint16_t password_length = readTwoBytesToUInt16();
  75 + password = std::string(readBytes(password_length), password_length);
  76 + }
  77 +
  78 + sender->setClientProperties(clientid, username, true);
  79 +
39 80 }
40 81 }
41 82 else if (variable_header_length == 6)
42 83 {
43   - throw new ProtocolError("Only MQTT 3.1.1 implemented.");
  84 + throw ProtocolError("Only MQTT 3.1.1 implemented.");
44 85 }
  86 +
  87 + throw ProtocolError("Unprogrammed sequence in CONNECT.");
45 88 }
46 89  
47 90 char *MqttPacket::readBytes(size_t length)
... ... @@ -59,11 +102,20 @@ char MqttPacket::readByte()
59 102 if (pos + 1 > bites.size())
60 103 throw ProtocolError("Invalid packet: header specifies invalid length.");
61 104  
62   - char b = bites[pos];
63   - pos++;
  105 + char b = bites[pos++];
64 106 return b;
65 107 }
66 108  
  109 +uint16_t MqttPacket::readTwoBytesToUInt16()
  110 +{
  111 + if (pos + 2 > bites.size())
  112 + throw ProtocolError("Invalid packet: header specifies invalid length.");
  113 +
  114 + uint16_t i = bites[pos] << 8 | bites[pos+1];
  115 + pos += 2;
  116 + return i;
  117 +}
  118 +
67 119  
68 120  
69 121 std::string MqttPacket::getClientId()
... ...
mqttpacket.h
... ... @@ -34,6 +34,7 @@ public:
34 34 void handleConnect();
35 35 char *readBytes(size_t length);
36 36 char readByte();
  37 + uint16_t readTwoBytesToUInt16();
37 38 };
38 39  
39 40 #endif // MQTTPACKET_H
... ...