Removed null-pointer dereference in low mem.
[umurmur.git] / src / messages.c
1 /* Copyright (C) 2009-2014, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2014, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
10    - Redistributions of source code must retain the above copyright notice,
11      this list of conditions and the following disclaimer.
12    - Redistributions in binary form must reproduce the above copyright notice,
13      this list of conditions and the following disclaimer in the documentation
14      and/or other materials provided with the distribution.
15    - Neither the name of the Developers nor the names of its contributors may
16      be used to endorse or promote products derived from this software without
17      specific prior written permission.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <arpa/inet.h>
36
37 #include "messages.h"
38 #include "client.h"
39 #include "pds.h"
40 #include "log.h"
41 #include "memory.h"
42
43 #define PREAMBLE_SIZE 6
44
45 static message_t *Msg_create_nopayload(messageType_t messageType);
46
47 static void Msg_addPreamble(uint8_t *buffer, uint16_t type, uint32_t len)
48 {
49         buffer[1] = (type) & 0xff;
50         buffer[0] = (type >> 8) & 0xff;
51
52         buffer[5] = (len) & 0xff;
53         buffer[4] = (len >> 8) & 0xff;
54         buffer[3] = (len >> 16) & 0xff;
55         buffer[2] = (len >> 24) & 0xff;
56 }
57
58 static void Msg_getPreamble(uint8_t *buffer, int *type, int *len)
59 {
60         uint16_t msgType;
61         uint32_t msgLen;
62
63         msgType = buffer[1] | (buffer[0] << 8);
64         msgLen = buffer[5] | (buffer[4] << 8) | (buffer[3] << 16) | (buffer[2] << 24);
65         *type = (int)msgType;
66         *len = (int)msgLen;
67 }
68
69 #define MAX_MSGSIZE (BUFSIZE - PREAMBLE_SIZE)
70 int Msg_messageToNetwork(message_t *msg, uint8_t *buffer)
71 {
72         int len;
73         uint8_t *bufptr = buffer + PREAMBLE_SIZE;
74
75         Log_debug("To net: msg type %d", msg->messageType);
76         switch (msg->messageType) {
77         case Version:
78                 len = mumble_proto__version__get_packed_size(msg->payload.version);
79                 if (len > MAX_MSGSIZE) {
80                         Log_warn("Too big tx message. Discarding");
81                         break;
82                 }
83                 Msg_addPreamble(buffer, msg->messageType, len);
84                 mumble_proto__version__pack(msg->payload.version, bufptr);
85                 break;
86         case UDPTunnel: /* Non-standard handling of tunneled voice traffic. */
87                 if (msg->payload.UDPTunnel->packet.len > MAX_MSGSIZE) {
88                         Log_warn("Too big tx message. Discarding");
89                         break;
90                 }
91                 len = msg->payload.UDPTunnel->packet.len;
92                 Msg_addPreamble(buffer, msg->messageType, msg->payload.UDPTunnel->packet.len);
93                 memcpy(bufptr, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
94                 break;
95         case Authenticate:
96                 len = mumble_proto__authenticate__get_packed_size(msg->payload.authenticate);
97                 if (len > MAX_MSGSIZE) {
98                         Log_warn("Too big tx message. Discarding");
99                         break;
100                         }
101                 Msg_addPreamble(buffer, msg->messageType, len);
102                 mumble_proto__authenticate__pack(msg->payload.authenticate, bufptr);
103                 break;
104         case Ping:
105                 len = mumble_proto__ping__get_packed_size(msg->payload.ping);
106                 if (len > MAX_MSGSIZE) {
107                         Log_warn("Too big tx message. Discarding");
108                         break;
109                         }
110                 Msg_addPreamble(buffer, msg->messageType, len);
111                 mumble_proto__ping__pack(msg->payload.ping, bufptr);
112                 break;
113         case Reject:
114                 len = mumble_proto__reject__get_packed_size(msg->payload.reject);
115                 if (len > MAX_MSGSIZE) {
116                         Log_warn("Too big tx message. Discarding");
117                         break;
118                         }
119                 Msg_addPreamble(buffer, msg->messageType, len);
120                 mumble_proto__reject__pack(msg->payload.reject, bufptr);
121                 break;
122         case ServerSync:
123                 len = mumble_proto__server_sync__get_packed_size(msg->payload.serverSync);
124                 if (len > MAX_MSGSIZE) {
125                         Log_warn("Too big tx message. Discarding");
126                         break;
127                         }
128                 Msg_addPreamble(buffer, msg->messageType, len);
129                 mumble_proto__server_sync__pack(msg->payload.serverSync, bufptr);
130                 break;
131         case TextMessage:
132                 len = mumble_proto__text_message__get_packed_size(msg->payload.textMessage);
133                 if (len > MAX_MSGSIZE) {
134                         Log_warn("Too big tx message. Discarding");
135                         break;
136                         }
137                 Msg_addPreamble(buffer, msg->messageType, len);
138                 mumble_proto__text_message__pack(msg->payload.textMessage, bufptr);
139                 break;
140         case PermissionDenied:
141                 len = mumble_proto__permission_denied__get_packed_size(msg->payload.permissionDenied);
142                 if (len > MAX_MSGSIZE) {
143                         Log_warn("Too big tx message. Discarding");
144                         break;
145                         }
146                 Msg_addPreamble(buffer, msg->messageType, len);
147                 mumble_proto__permission_denied__pack(msg->payload.permissionDenied, bufptr);
148                 break;
149         case CryptSetup:
150                 len = mumble_proto__crypt_setup__get_packed_size(msg->payload.cryptSetup);
151                 if (len > MAX_MSGSIZE) {
152                         Log_warn("Too big tx message. Discarding");
153                         break;
154                         }
155                 Msg_addPreamble(buffer, msg->messageType, len);
156                 mumble_proto__crypt_setup__pack(msg->payload.cryptSetup, bufptr);
157                 break;
158         case UserList:
159                 len = mumble_proto__user_list__get_packed_size(msg->payload.userList);
160                 if (len > MAX_MSGSIZE) {
161                         Log_warn("Too big tx message. Discarding");
162                         break;
163                         }
164                 Msg_addPreamble(buffer, msg->messageType, len);
165                 mumble_proto__user_list__pack(msg->payload.userList, bufptr);
166                 break;
167         case UserState:
168                 len = mumble_proto__user_state__get_packed_size(msg->payload.userState);
169                 if (len > MAX_MSGSIZE) {
170                         Log_warn("Too big tx message. Discarding");
171                         break;
172                         }
173                 Msg_addPreamble(buffer, msg->messageType, len);
174                 mumble_proto__user_state__pack(msg->payload.userState, bufptr);
175                 break;
176         case UserRemove:
177                 len = mumble_proto__user_remove__get_packed_size(msg->payload.userRemove);
178                 if (len > MAX_MSGSIZE) {
179                         Log_warn("Too big tx message. Discarding");
180                         break;
181                         }
182                 Msg_addPreamble(buffer, msg->messageType, len);
183                 mumble_proto__user_remove__pack(msg->payload.userRemove, bufptr);
184                 break;
185         case ChannelState:
186                 len = mumble_proto__channel_state__get_packed_size(msg->payload.channelState);
187                 if (len > MAX_MSGSIZE) {
188                         Log_warn("Too big tx message. Discarding");
189                         break;
190                         }
191                 Msg_addPreamble(buffer, msg->messageType, len);
192                 mumble_proto__channel_state__pack(msg->payload.channelState, bufptr);
193                 break;
194         case VoiceTarget:
195                 len = mumble_proto__voice_target__get_packed_size(msg->payload.voiceTarget);
196                 if (len > MAX_MSGSIZE) {
197                         Log_warn("Too big tx message. Discarding");
198                         break;
199                         }
200                 Msg_addPreamble(buffer, msg->messageType, len);
201                 mumble_proto__voice_target__pack(msg->payload.voiceTarget, bufptr);
202                 break;
203         case CodecVersion:
204                 len = mumble_proto__codec_version__get_packed_size(msg->payload.codecVersion);
205                 if (len > MAX_MSGSIZE) {
206                         Log_warn("Too big tx message. Discarding");
207                         break;
208                         }
209                 Msg_addPreamble(buffer, msg->messageType, len);
210                 mumble_proto__codec_version__pack(msg->payload.codecVersion, bufptr);
211                 break;
212         case PermissionQuery:
213                 len = mumble_proto__permission_query__get_packed_size(msg->payload.permissionQuery);
214                 if (len > MAX_MSGSIZE) {
215                         Log_warn("Too big tx message. Discarding");
216                         break;
217                         }
218                 Msg_addPreamble(buffer, msg->messageType, len);
219                 mumble_proto__permission_query__pack(msg->payload.permissionQuery, bufptr);
220                 break;
221         case ChannelRemove:
222                 len = mumble_proto__channel_remove__get_packed_size(msg->payload.channelRemove);
223                 if (len > MAX_MSGSIZE) {
224                         Log_warn("Too big tx message. Discarding");
225                         break;
226                         }
227                 Msg_addPreamble(buffer, msg->messageType, len);
228                 mumble_proto__channel_remove__pack(msg->payload.channelRemove, bufptr);
229                 break;
230         case UserStats:
231         {
232                 len = mumble_proto__user_stats__get_packed_size(msg->payload.userStats);
233                 if (len > MAX_MSGSIZE) {
234                         Log_warn("Too big tx message. Discarding");
235                         break;
236                         }
237                 Msg_addPreamble(buffer, msg->messageType, len);
238                 mumble_proto__user_stats__pack(msg->payload.userStats, bufptr);
239                 break;
240         }
241         case ServerConfig:
242                 len = mumble_proto__server_config__get_packed_size(msg->payload.serverConfig);
243                 if (len > MAX_MSGSIZE) {
244                         Log_warn("Too big tx message. Discarding");
245                         break;
246                         }
247                 Msg_addPreamble(buffer, msg->messageType, len);
248                 mumble_proto__server_config__pack(msg->payload.serverConfig, bufptr);
249                 break;
250
251         case BanList:
252                 len = mumble_proto__ban_list__get_packed_size(msg->payload.banList);
253                 if (len > MAX_MSGSIZE) {
254                         Log_warn("Too big tx message. Discarding");
255                         break;
256                         }
257                 Msg_addPreamble(buffer, msg->messageType, len);
258                 Log_debug("Msg_MessageToNetwork: BanList size %d", len);
259                 mumble_proto__ban_list__pack(msg->payload.banList, bufptr);
260                 break;
261         default:
262                 Log_warn("Msg_MessageToNetwork: Unsupported message %d", msg->messageType);
263                 return 0;
264         }
265         return len + PREAMBLE_SIZE;
266 }
267
268 static message_t *Msg_create_nopayload(messageType_t messageType)
269 {
270         message_t *msg = Memory_safeMalloc(1, sizeof(message_t));
271
272         memset(msg, 0, sizeof(message_t));
273         msg->refcount = 1;
274         msg->messageType = messageType;
275         init_list_entry(&msg->node);
276         return msg;
277 }
278
279 message_t *Msg_create(messageType_t messageType)
280 {
281         message_t *msg = Msg_create_nopayload(messageType);
282         int i;
283
284         switch (messageType) {
285         case Version:
286                 msg->payload.version = Memory_safeMalloc(1, sizeof(MumbleProto__Version));
287                 mumble_proto__version__init(msg->payload.version);
288                 break;
289         case UDPTunnel:
290                 msg->payload.UDPTunnel = Memory_safeMalloc(1, sizeof(MumbleProto__UDPTunnel));
291                 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
292                 break;
293         case Authenticate:
294                 msg->payload.authenticate = Memory_safeMalloc(1, sizeof(MumbleProto__Authenticate));
295                 mumble_proto__authenticate__init(msg->payload.authenticate);
296                 break;
297         case Ping:
298                 msg->payload.ping = Memory_safeMalloc(1, sizeof(MumbleProto__Ping));
299                 mumble_proto__ping__init(msg->payload.ping);
300                 break;
301         case Reject:
302                 msg->payload.reject = Memory_safeMalloc(1, sizeof(MumbleProto__Reject));
303                 mumble_proto__reject__init(msg->payload.reject);
304                 break;
305         case ServerSync:
306                 msg->payload.serverSync = Memory_safeMalloc(1, sizeof(MumbleProto__ServerSync));
307                 mumble_proto__server_sync__init(msg->payload.serverSync);
308                 break;
309         case TextMessage:
310                 msg->payload.textMessage = Memory_safeMalloc(1, sizeof(MumbleProto__TextMessage));
311                 mumble_proto__text_message__init(msg->payload.textMessage);
312                 break;
313         case PermissionDenied:
314                 msg->payload.permissionDenied = Memory_safeMalloc(1, sizeof(MumbleProto__PermissionDenied));
315                 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
316                 break;
317         case CryptSetup:
318                 msg->payload.cryptSetup = Memory_safeMalloc(1, sizeof(MumbleProto__CryptSetup));
319                 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
320                 break;
321         case UserList:
322                 msg->payload.userList = Memory_safeMalloc(1, sizeof(MumbleProto__UserList));
323                 mumble_proto__user_list__init(msg->payload.userList);
324                 break;
325         case UserState:
326                 msg->payload.userState = Memory_safeMalloc(1, sizeof(MumbleProto__UserState));
327                 mumble_proto__user_state__init(msg->payload.userState);
328                 break;
329         case ChannelState:
330                 msg->payload.channelState = Memory_safeMalloc(1, sizeof(MumbleProto__ChannelState));
331                 mumble_proto__channel_state__init(msg->payload.channelState);
332                 break;
333         case UserRemove:
334                 msg->payload.userRemove = Memory_safeMalloc(1, sizeof(MumbleProto__UserRemove));
335                 mumble_proto__user_remove__init(msg->payload.userRemove);
336                 break;
337         case VoiceTarget:
338                 msg->payload.voiceTarget = Memory_safeMalloc(1, sizeof(MumbleProto__VoiceTarget));
339                 mumble_proto__voice_target__init(msg->payload.voiceTarget);
340                 break;
341         case CodecVersion:
342                 msg->payload.codecVersion = Memory_safeMalloc(1, sizeof(MumbleProto__CodecVersion));
343                 mumble_proto__codec_version__init(msg->payload.codecVersion);
344                 break;
345         case PermissionQuery:
346                 msg->payload.permissionQuery = Memory_safeMalloc(1, sizeof(MumbleProto__PermissionQuery));
347                 mumble_proto__permission_query__init(msg->payload.permissionQuery);
348                 break;
349         case ChannelRemove:
350                 msg->payload.channelRemove = Memory_safeMalloc(1, sizeof(MumbleProto__ChannelRemove));
351                 mumble_proto__channel_remove__init(msg->payload.channelRemove);
352                 break;
353         case UserStats:
354                 msg->payload.userStats = Memory_safeMalloc(1, sizeof(MumbleProto__UserStats));
355                 mumble_proto__user_stats__init(msg->payload.userStats);
356
357                 msg->payload.userStats->from_client = Memory_safeMalloc(1, sizeof(MumbleProto__UserStats__Stats));
358                 mumble_proto__user_stats__stats__init(msg->payload.userStats->from_client);
359
360                 msg->payload.userStats->from_server = Memory_safeMalloc(1, sizeof(MumbleProto__UserStats__Stats));
361                 mumble_proto__user_stats__stats__init(msg->payload.userStats->from_server);
362
363                 msg->payload.userStats->version = Memory_safeMalloc(1, sizeof(MumbleProto__Version));
364                 mumble_proto__version__init(msg->payload.userStats->version);
365
366                 break;
367         case ServerConfig:
368                 msg->payload.serverConfig = Memory_safeMalloc(1, sizeof(MumbleProto__ServerConfig));
369                 mumble_proto__server_config__init(msg->payload.serverConfig);
370                 break;
371
372         default:
373                 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
374                 break;
375         }
376
377         return msg;
378 }
379
380 message_t *Msg_banList_create(int n_bans)
381 {
382         message_t *msg = Msg_create_nopayload(BanList);
383         int i;
384
385         msg->payload.banList = Memory_safeMalloc(1, sizeof(MumbleProto__BanList));
386         memset(msg->payload.banList, 0, sizeof(MumbleProto__BanList));
387         mumble_proto__ban_list__init(msg->payload.banList);
388         msg->payload.banList->n_bans = n_bans;
389         msg->payload.banList->bans = Memory_safeMalloc(1, sizeof(MumbleProto__BanList__BanEntry *) * n_bans);
390         for (i = 0; i < n_bans; i++) {
391                 msg->payload.banList->bans[i] = Memory_safeMalloc(1, sizeof(MumbleProto__BanList__BanEntry));
392                 memset(msg->payload.banList->bans[i], 0, sizeof(MumbleProto__BanList__BanEntry));
393                 mumble_proto__ban_list__ban_entry__init(msg->payload.banList->bans[i]);
394         }
395         return msg;
396 }
397
398 void Msg_banList_addEntry(message_t *msg, int index, uint8_t *address, uint32_t mask,
399                           char *name, char *hash, char *reason, char *start, uint32_t duration)
400 {
401         MumbleProto__BanList__BanEntry *entry = msg->payload.banList->bans[index];
402
403         entry->address.data = Memory_safeMalloc(1, 16);
404         memcpy(entry->address.data, address, 16);
405         entry->address.len = 16;
406         entry->mask = mask;
407         entry->name = strdup(name);
408         entry->hash = strdup(hash);
409         entry->reason = strdup(reason);
410         entry->start = strdup(start);
411         if (!entry->name || !entry->hash || !entry->reason || !entry->start)
412                 Log_fatal("Out of memory");
413
414         if (duration > 0) {
415                 entry->duration = duration;
416                 entry->has_duration = true;
417         }
418         Log_debug("Msg_banList_addEntry: %s %s %s %s %s",
419                 entry->name, entry->hash, entry->address.data, entry->reason, entry->start);
420 }
421
422 void Msg_banList_getEntry(message_t *msg, int index, uint8_t **address, uint32_t *mask,
423                           char **name, char **hash, char **reason, char **start, uint32_t *duration)
424 {
425         MumbleProto__BanList__BanEntry *entry = msg->payload.banList->bans[index];
426
427         *address =  entry->address.data;
428         *mask = entry->mask;
429         *name = entry->name;
430         *hash = entry->hash;
431         *reason = entry->reason;
432         *start = entry->start;
433         if (entry->has_duration)
434                 *duration = entry->duration;
435         else
436                 *duration = 0;
437 }
438
439
440 void Msg_inc_ref(message_t *msg)
441 {
442         msg->refcount++;
443 }
444
445 void Msg_free(message_t *msg)
446 {
447         int i;
448
449         if (msg->refcount) msg->refcount--;
450         if (msg->refcount > 0)
451                 return;
452
453         switch (msg->messageType) {
454         case Version:
455                 if (msg->unpacked)
456                         mumble_proto__version__free_unpacked(msg->payload.version, NULL);
457                 else {
458                         if (msg->payload.version->release)
459                                 free(msg->payload.version->release);
460                         if (msg->payload.version->os)
461                                 free(msg->payload.version->os);
462                         if (msg->payload.version->os_version)
463                                 free(msg->payload.version->os_version);
464                         free(msg->payload.version);
465                 }
466                 break;
467         case UDPTunnel:
468                 if (msg->unpacked)
469                         mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
470                 else {
471                         free(msg->payload.UDPTunnel->packet.data);
472                         free(msg->payload.UDPTunnel);
473                 }
474                 break;
475         case Authenticate:
476                 if (msg->unpacked)
477                         mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
478                 else
479                         free(msg->payload.authenticate);
480                 break;
481         case Ping:
482                 if (msg->unpacked)
483                         mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
484                 else {
485                         free(msg->payload.ping);
486                 }
487                 break;
488         case Reject:
489                 if (msg->unpacked)
490                         mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
491                 else {
492                         free(msg->payload.reject->reason);
493                         free(msg->payload.reject);
494                 }
495                 break;
496         case ServerSync:
497                 if (msg->unpacked)
498                         mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
499                 else {
500                         free(msg->payload.serverSync->welcome_text);
501                         free(msg->payload.serverSync);
502                 }
503                 break;
504         case TextMessage:
505                 if (msg->unpacked)
506                         mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
507                 else {
508                         if (msg->payload.textMessage->message)
509                                 free(msg->payload.textMessage->message);
510                         if (msg->payload.textMessage->session)
511                                 free(msg->payload.textMessage->session);
512                         if (msg->payload.textMessage->channel_id)
513                                 free(msg->payload.textMessage->channel_id);
514                         if (msg->payload.textMessage->tree_id)
515                                 free(msg->payload.textMessage->tree_id);
516                         free(msg->payload.textMessage);
517                 }
518                 break;
519         case PermissionDenied:
520                 if (msg->unpacked)
521                         mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
522                 else {
523                         free(msg->payload.permissionDenied->reason);
524                         free(msg->payload.permissionDenied);
525                 }
526                 break;
527         case CryptSetup:
528                 if (msg->unpacked)
529                         mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
530                 else {
531                         free(msg->payload.cryptSetup);
532                 }
533                 break;
534         case UserList:
535                 if (msg->unpacked)
536                         mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
537                 else {
538                         free(msg->payload.userList);
539                 }
540                 break;
541         case UserState:
542                 if (msg->unpacked)
543                         mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
544                 else {
545                         free(msg->payload.userState->name);
546                         free(msg->payload.userState);
547                 }
548                 break;
549         case ChannelState:
550                 if (msg->unpacked)
551                         mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
552                 else {
553                         if (msg->payload.channelState->name)
554                                 free(msg->payload.channelState->name);
555                         if (msg->payload.channelState->description)
556                                 free(msg->payload.channelState->description);
557                         if (msg->payload.channelState->links)
558                                 free(msg->payload.channelState->links);
559                         free(msg->payload.channelState);
560                 }
561                 break;
562         case UserRemove:
563                 if (msg->unpacked)
564                         mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
565                 else {
566                         free(msg->payload.userRemove);
567                 }
568                 break;
569         case VoiceTarget:
570                 if (msg->unpacked)
571                         mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
572                 else {
573                         free(msg->payload.voiceTarget);
574                 }
575                 break;
576         case CodecVersion:
577                 if (msg->unpacked)
578                         mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
579                 else {
580                         free(msg->payload.codecVersion);
581                 }
582                 break;
583         case PermissionQuery:
584                 if (msg->unpacked)
585                         mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
586                 else {
587                         free(msg->payload.permissionQuery);
588                 }
589                 break;
590         case ChannelRemove:
591                 if (msg->unpacked)
592                         mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
593                 else {
594                         free(msg->payload.channelRemove);
595                 }
596                 break;
597         case UserStats:
598                 if (msg->unpacked)
599                         mumble_proto__user_stats__free_unpacked(msg->payload.userStats, NULL);
600                 else {
601                         if (msg->payload.userStats->from_client)
602                                 free(msg->payload.userStats->from_client);
603                         if (msg->payload.userStats->from_server)
604                                 free(msg->payload.userStats->from_server);
605                         if (msg->payload.userStats->version) {
606                                 if (msg->payload.userStats->version->release)
607                                         free(msg->payload.userStats->version->release);
608                                 if (msg->payload.userStats->version->os)
609                                         free(msg->payload.userStats->version->os);
610                                 if (msg->payload.userStats->version->os_version)
611                                         free(msg->payload.userStats->version->os_version);
612
613                                 free(msg->payload.userStats->version);
614                         }
615                         if (msg->payload.userStats->celt_versions)
616                                 free(msg->payload.userStats->celt_versions);
617                         if (msg->payload.userStats->certificates) {
618                                 if (msg->payload.userStats->certificates->data)
619                                         free(msg->payload.userStats->certificates->data);
620                                 free(msg->payload.userStats->certificates);
621                         }
622                         if (msg->payload.userStats->address.data)
623                                 free(msg->payload.userStats->address.data);
624
625                         free(msg->payload.userStats);
626                 }
627                 break;
628         case ServerConfig:
629                 if (msg->unpacked)
630                         mumble_proto__server_config__free_unpacked(msg->payload.serverConfig, NULL);
631                 else {
632                         free(msg->payload.serverConfig);
633                 }
634                 break;
635         case BanList:
636                 if (msg->unpacked)
637                         mumble_proto__ban_list__free_unpacked(msg->payload.banList, NULL);
638                 else {
639                         for (i = 0; i < msg->payload.banList->n_bans; i++) {
640                                 free(msg->payload.banList->bans[i]->address.data);
641                                 free(msg->payload.banList->bans[i]->name);
642                                 free(msg->payload.banList->bans[i]->hash);
643                                 free(msg->payload.banList->bans[i]->reason);
644                                 free(msg->payload.banList->bans[i]->start);
645                                 free(msg->payload.banList->bans[i]);
646                         }
647                         free(msg->payload.banList->bans);
648                         free(msg->payload.banList);
649                 }
650                 break;
651
652         default:
653                 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
654                 break;
655         }
656         free(msg);
657 }
658
659 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
660 {
661         message_t *msg = NULL;
662
663         msg = Msg_create_nopayload(UDPTunnel);
664         msg->unpacked = false;
665         msg->payload.UDPTunnel = Memory_safeMalloc(1, sizeof(struct _MumbleProto__UDPTunnel));
666         msg->payload.UDPTunnel->packet.data = Memory_safeMalloc(1, size);
667         memcpy(msg->payload.UDPTunnel->packet.data, data, size);
668         msg->payload.UDPTunnel->packet.len = size;
669         return msg;
670 }
671
672 message_t *Msg_networkToMessage(uint8_t *data, int size)
673 {
674         message_t *msg = NULL;
675         uint8_t *msgData = &data[6];
676         int messageType, msgLen;
677
678         Msg_getPreamble(data, &messageType, &msgLen);
679
680         Log_debug("Message type %d size %d", messageType, msgLen);
681         //dumpmsg(data, size);
682
683         switch (messageType) {
684         case Version:
685         {
686                 msg = Msg_create_nopayload(Version);
687                 msg->unpacked = true;
688                 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
689                 if (msg->payload.version == NULL)
690                         goto err_out;
691                 break;
692         }
693         case UDPTunnel: /* Non-standard handling of tunneled voice data */
694         {
695                 msg = Msg_CreateVoiceMsg(msgData, msgLen);
696                 break;
697         }
698         case Authenticate:
699         {
700                 msg = Msg_create_nopayload(Authenticate);
701                 msg->unpacked = true;
702                 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
703                 if (msg->payload.authenticate == NULL)
704                         goto err_out;
705                 break;
706         }
707         case Ping:
708         {
709                 msg = Msg_create_nopayload(Ping);
710                 msg->unpacked = true;
711                 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
712                 if (msg->payload.ping == NULL)
713                         goto err_out;
714                 break;
715         }
716         case Reject:
717         {
718                 msg = Msg_create_nopayload(Reject);
719                 msg->unpacked = true;
720                 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
721                 if (msg->payload.reject == NULL)
722                         goto err_out;
723                 break;
724         }
725         case ServerSync:
726         {
727                 msg = Msg_create_nopayload(ServerSync);
728                 msg->unpacked = true;
729                 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
730                 if (msg->payload.serverSync == NULL)
731                         goto err_out;
732                 break;
733         }
734         case TextMessage:
735         {
736                 msg = Msg_create_nopayload(TextMessage);
737                 msg->unpacked = true;
738                 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
739                 if (msg->payload.textMessage == NULL)
740                         goto err_out;
741                 break;
742         }
743         case PermissionDenied:
744         {
745                 msg = Msg_create_nopayload(PermissionDenied);
746                 msg->unpacked = true;
747                 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
748                 if (msg->payload.permissionDenied == NULL)
749                         goto err_out;
750                 break;
751         }
752         case CryptSetup:
753         {
754                 msg = Msg_create_nopayload(CryptSetup);
755                 msg->unpacked = true;
756                 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
757                 if (msg->payload.cryptSetup == NULL)
758                         goto err_out;
759                 break;
760         }
761         case UserList:
762         {
763                 msg = Msg_create_nopayload(UserList);
764                 msg->unpacked = true;
765                 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
766                 if (msg->payload.userList == NULL)
767                         goto err_out;
768                 break;
769         }
770         case UserState:
771         {
772                 msg = Msg_create_nopayload(UserState);
773                 msg->unpacked = true;
774                 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
775                 if (msg->payload.userState == NULL)
776                         goto err_out;
777                 break;
778         }
779         case ChannelState:
780         {
781                 msg = Msg_create_nopayload(ChannelState);
782                 msg->unpacked = true;
783                 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
784                 if (msg->payload.channelState == NULL)
785                         goto err_out;
786                 break;
787         }
788         case VoiceTarget:
789         {
790                 msg = Msg_create_nopayload(VoiceTarget);
791                 msg->unpacked = true;
792                 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
793                 if (msg->payload.voiceTarget == NULL)
794                         goto err_out;
795                 break;
796         }
797         case CodecVersion:
798         {
799                 msg = Msg_create_nopayload(CodecVersion);
800                 msg->unpacked = true;
801                 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
802                 if (msg->payload.codecVersion == NULL)
803                         goto err_out;
804                 break;
805         }
806         case PermissionQuery:
807         {
808                 msg = Msg_create_nopayload(PermissionQuery);
809                 msg->unpacked = true;
810                 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
811                 if (msg->payload.permissionQuery == NULL)
812                         goto err_out;
813                 break;
814         }
815         case ChannelRemove:
816         {
817                 msg = Msg_create_nopayload(ChannelRemove);
818                 msg->unpacked = true;
819                 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
820                 if (msg->payload.channelRemove == NULL)
821                         goto err_out;
822                 break;
823         }
824         case UserStats:
825         {
826                 msg = Msg_create_nopayload(UserStats);
827                 msg->unpacked = true;
828                 msg->payload.userStats = mumble_proto__user_stats__unpack(NULL, msgLen, msgData);
829                 if (msg->payload.userStats == NULL)
830                         goto err_out;
831                 break;
832         }
833         case UserRemove:
834         {
835                 msg = Msg_create_nopayload(UserRemove);
836                 msg->unpacked = true;
837                 msg->payload.userRemove = mumble_proto__user_remove__unpack(NULL, msgLen, msgData);
838                 if (msg->payload.userRemove == NULL)
839                         goto err_out;
840                 break;
841         }
842         case BanList:
843         {
844                 msg = Msg_create_nopayload(BanList);
845                 msg->unpacked = true;
846                 msg->payload.banList = mumble_proto__ban_list__unpack(NULL, msgLen, msgData);
847                 if (msg->payload.banList == NULL)
848                         goto err_out;
849                 break;
850         }
851
852         default:
853                 Log_warn("Msg_networkToMessage: Unsupported message %d", messageType);
854                 break;
855         }
856         return msg;
857
858 err_out:
859         free(msg);
860         return NULL;
861 }