Use Client_find_by_session() instead of a few open-coded loops.
[umurmur.git] / src / messagehandler.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 #include <string.h>
32 #include <stdlib.h>
33
34 #include "log.h"
35 #include "memory.h"
36 #include "list.h"
37 #include "client.h"
38 #include "messages.h"
39 #include "messagehandler.h"
40 #include "crypt.h"
41 #include "channel.h"
42 #include "conf.h"
43 #include "voicetarget.h"
44 #include "ban.h"
45
46 #define MAX_TEXT 512
47 #define MAX_USERNAME 128
48
49 #define NO_CELT_MESSAGE "<strong>WARNING:</strong> Your client doesn't support the CELT codec, you won't be able to talk to or hear most clients. Please make sure your client was built with CELT support."
50
51
52 extern channel_t *defaultChan;
53 extern int iCodecAlpha, iCodecBeta;
54 extern bool_t bPreferAlpha, bOpus;
55
56 static bool_t fake_celt_support;
57
58 static void sendServerReject(client_t *client, const char *reason, MumbleProto__Reject__RejectType type)
59 {
60         message_t *msg = Msg_create(Reject);
61         msg->payload.reject->reason = strdup(reason);
62         msg->payload.reject->type = type;
63         msg->payload.reject->has_type = true;
64         Client_send_message(client, msg);
65
66         Log_info_client(client, "Server reject reason: %s", reason);
67 }
68
69 static void sendPermissionDenied(client_t *client, const char *reason)
70 {
71         message_t *msg = Msg_create(PermissionDenied);
72         msg->payload.permissionDenied->has_type = true;
73         msg->payload.permissionDenied->type = MUMBLE_PROTO__PERMISSION_DENIED__DENY_TYPE__Text;
74         msg->payload.permissionDenied->reason = strdup(reason);
75         Client_send_message(client, msg);
76 }
77
78 static void addTokens(client_t *client, message_t *msg)
79 {
80         int i;
81         if (client->tokencount + msg->payload.authenticate->n_tokens < MAX_TOKENS) {
82                 /* Check lengths first */
83                 for (i = 0; i < msg->payload.authenticate->n_tokens; i++) {
84                         if (strlen(msg->payload.authenticate->tokens[i]) > MAX_TOKENSIZE - 1) {
85                                 sendPermissionDenied(client, "Too long token");
86                                 return;
87                         }
88                 }
89
90                 for (i = 0; i < msg->payload.authenticate->n_tokens; i++) {
91                         Log_debug("Adding token '%s' to client '%s'", msg->payload.authenticate->tokens[i], client->username);
92                         Client_token_add(client, msg->payload.authenticate->tokens[i]);
93                 }
94         }
95         else
96                 sendPermissionDenied(client, "Too many tokens");
97 }
98
99 void Mh_handle_message(client_t *client, message_t *msg)
100 {
101         message_t *sendmsg = NULL;
102         channel_t *ch_itr = NULL;
103         client_t *client_itr, *target;
104
105         if (!client->authenticated && !(msg->messageType == Authenticate ||
106                                                                         msg->messageType == Version)) {
107                 goto out;
108         }
109
110         switch (msg->messageType) {
111         case UDPTunnel:
112         case Ping:
113         case CryptSetup:
114         case VoiceTarget:
115         case UserStats:
116         case PermissionQuery:
117                 break;
118         default:
119                 Timer_restart(&client->idleTime);
120         }
121
122         switch (msg->messageType) {
123         case Authenticate:
124                 Log_debug("Authenticate message received");
125
126                 if (IS_AUTH(client) || !msg->payload.authenticate->username) {
127                         /* Authenticate message might be sent when a tokens are changed by the user.*/
128                         Client_token_free(client); /* Clear the token list */
129                         if (msg->payload.authenticate->n_tokens > 0) {
130                                 Log_debug("Tokens in auth message from '%s'. n_tokens = %d", client->username,
131                                           msg->payload.authenticate->n_tokens);
132                                 addTokens(client, msg);
133                         }
134                         break;
135                 }
136
137                 if (SSLi_getSHA1Hash(client->ssl, client->hash) && Ban_isBanned(client)) {
138                         char hexhash[41];
139                         SSLi_hash2hex(client->hash, hexhash);
140                         Log_info("Client with hash '%s' is banned. Disconnecting", hexhash);
141                         goto disconnect;
142                 }
143
144                 client->authenticated = true;
145
146                 client_itr = NULL;
147                 while (Client_iterate(&client_itr) != NULL) {
148                         if (!IS_AUTH(client_itr))
149                                 continue;
150                         if (client_itr->username && strncmp(client_itr->username, msg->payload.authenticate->username, MAX_USERNAME) == 0) {
151                                 char buf[64];
152                                 sprintf(buf, "Username already in use");
153                                 Log_debug("Username already in use");
154                                 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__UsernameInUse);
155                                 goto disconnect;
156                         }
157                 }
158                 if (strlen(getStrConf(PASSPHRASE)) > 0) {
159                         if (!msg->payload.authenticate->password ||
160                                 (msg->payload.authenticate->password &&
161                                  strncmp(getStrConf(PASSPHRASE), msg->payload.authenticate->password, MAX_TEXT) != 0)) {
162                                 char buf[64];
163                                 sprintf(buf, "Wrong server password");
164                                 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__WrongServerPW);
165                                 Log_debug("Wrong server password: '%s'", msg->payload.authenticate->password != NULL ?
166                                                   msg->payload.authenticate->password : "(null)");
167                                 goto disconnect;
168                         }
169                 }
170                 if (strlen(msg->payload.authenticate->username) == 0 ||
171                         strlen(msg->payload.authenticate->username) >= MAX_USERNAME) { /* XXX - other invalid names? */
172                         char buf[64];
173                         sprintf(buf, "Invalid username");
174                         Log_debug("Invalid username");
175                         sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__InvalidUsername);
176                         goto disconnect;
177                 }
178
179                 if (Client_count() >= getIntConf(MAX_CLIENTS)) {
180                         char buf[64];
181                         snprintf(buf, 64, "Server is full (max %d users)", getIntConf(MAX_CLIENTS));
182                         sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__ServerFull);
183                         goto disconnect;
184                 }
185
186                 /* Name */
187                 client->username = strdup(msg->payload.authenticate->username);
188
189                 /* Tokens */
190                 if (msg->payload.authenticate->n_tokens > 0)
191                         addTokens(client, msg);
192
193                 /* Check if admin PW among tokens */
194                 if (strlen(getStrConf(ADMIN_PASSPHRASE)) > 0 &&
195                     Client_token_match(client, getStrConf(ADMIN_PASSPHRASE))) {
196                         client->isAdmin = true;
197                         Log_info_client(client, "User provided admin password");
198                 }
199
200                 /* Setup UDP encryption */
201                 CryptState_init(&client->cryptState);
202                 CryptState_genKey(&client->cryptState);
203                 sendmsg = Msg_create(CryptSetup);
204                 sendmsg->payload.cryptSetup->has_key = true;
205                 sendmsg->payload.cryptSetup->key.data = client->cryptState.raw_key;
206                 sendmsg->payload.cryptSetup->key.len = AES_BLOCK_SIZE;
207                 sendmsg->payload.cryptSetup->has_server_nonce = true;
208                 sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.encrypt_iv;
209                 sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
210                 sendmsg->payload.cryptSetup->has_client_nonce = true;
211                 sendmsg->payload.cryptSetup->client_nonce.data = client->cryptState.decrypt_iv;
212                 sendmsg->payload.cryptSetup->client_nonce.len = AES_BLOCK_SIZE;
213                 Client_send_message(client, sendmsg);
214
215                 /* Channel stuff */
216                 Chan_userJoin(defaultChan, client); /* Join default channel */
217
218                 /* Codec version */
219                 Log_debug("Client %d has %d CELT codecs", client->sessionId,
220                                   msg->payload.authenticate->n_celt_versions);
221                 if (msg->payload.authenticate->n_celt_versions > 0) {
222                         int i;
223                         codec_t *codec_itr;
224                         client->codec_count = msg->payload.authenticate->n_celt_versions;
225
226                         for (i = 0; i < client->codec_count; i++)
227                         Client_codec_add(client, msg->payload.authenticate->celt_versions[i]);
228                         codec_itr = NULL;
229                         while (Client_codec_iterate(client, &codec_itr) != NULL)
230                                 Log_debug("Client %d CELT codec ver 0x%x", client->sessionId, codec_itr->codec);
231
232                 } else {
233                         Client_codec_add(client, (int32_t)0x8000000b);
234                         client->codec_count = 1;
235                         fake_celt_support = true;
236                 }
237                 if (msg->payload.authenticate->opus)
238                         client->bOpus = true;
239
240                 recheckCodecVersions(client);
241
242                 sendmsg = Msg_create(CodecVersion);
243                 sendmsg->payload.codecVersion->alpha = iCodecAlpha;
244                 sendmsg->payload.codecVersion->beta = iCodecBeta;
245                 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
246                 sendmsg->payload.codecVersion->has_opus = true;
247                 sendmsg->payload.codecVersion->opus = bOpus;
248                 Client_send_message(client, sendmsg);
249
250                 if (!bOpus && client->bOpus && fake_celt_support) {
251                         Client_textmessage(client, NO_CELT_MESSAGE);
252                 }
253
254                 /* Iterate channels and send channel info */
255                 ch_itr = NULL;
256                 while (Chan_iterate(&ch_itr) != NULL) {
257                         sendmsg = Msg_create(ChannelState);
258                         sendmsg->payload.channelState->has_channel_id = true;
259                         sendmsg->payload.channelState->channel_id = ch_itr->id;
260                         if (ch_itr->id != 0) {
261                                 sendmsg->payload.channelState->has_parent = true;
262                                 sendmsg->payload.channelState->parent = ch_itr->parent->id;
263                         }
264                         sendmsg->payload.channelState->name = strdup(ch_itr->name);
265                         if (ch_itr->desc)
266                                 sendmsg->payload.channelState->description = strdup(ch_itr->desc);
267                         if (ch_itr->position != 0) {
268                                 sendmsg->payload.channelState->has_position = true;
269                                 sendmsg->payload.channelState->position = ch_itr->position;
270                         }
271                         Log_debug("Send channel info: %s", sendmsg->payload.channelState->name);
272                         Client_send_message(client, sendmsg);
273                 }
274
275                 /* Iterate channels and send channel links info */
276                 ch_itr = NULL;
277                 while (Chan_iterate(&ch_itr) != NULL) {
278                         if (ch_itr->linkcount > 0) { /* Has links */
279                                 uint32_t *links;
280                                 int i = 0;
281                                 struct dlist *itr;
282
283                                 sendmsg = Msg_create(ChannelState);
284                                 sendmsg->payload.channelState->has_channel_id = true;
285                                 sendmsg->payload.channelState->channel_id = ch_itr->id;
286                                 sendmsg->payload.channelState->n_links = ch_itr->linkcount;
287
288                                 links = (uint32_t*)Memory_safeMalloc(
289                                         ch_itr->linkcount,
290                                         sizeof(uint32_t));
291                                 list_iterate(itr, &ch_itr->channel_links) { /* Iterate links */
292                                         channellist_t *chl;
293                                         channel_t *ch;
294                                         chl = list_get_entry(itr, channellist_t, node);
295                                         ch = chl->chan;
296                                         links[i++] = ch->id;
297                                 }
298                                 sendmsg->payload.channelState->links = links;
299                                 Client_send_message(client, sendmsg);
300                         }
301                 }
302
303                 /* Send user state for connecting user to other users */
304                 sendmsg = Msg_create(UserState);
305                 sendmsg->payload.userState->has_session = true;
306                 sendmsg->payload.userState->session = client->sessionId;
307                 sendmsg->payload.userState->name = strdup(client->username);
308                 sendmsg->payload.userState->has_channel_id = true;
309                 sendmsg->payload.userState->channel_id = client->channel->id;
310
311                 if (defaultChan->silent) {
312                         sendmsg->payload.userState->has_suppress = true;
313                         sendmsg->payload.userState->suppress = true;
314                 }
315
316                 Client_send_message_except(client, sendmsg);
317
318                 client_itr = NULL;
319                 while (Client_iterate(&client_itr) != NULL) {
320                         if (!IS_AUTH(client_itr))
321                                 continue;
322                         sendmsg = Msg_create(UserState);
323                         sendmsg->payload.userState->has_session = true;
324                         sendmsg->payload.userState->session = client_itr->sessionId;
325                         sendmsg->payload.userState->name = strdup(client_itr->username);
326                         sendmsg->payload.userState->has_channel_id = true;
327                         sendmsg->payload.userState->channel_id = client_itr->channel->id;
328                         sendmsg->payload.userState->has_suppress = client_itr->channel->silent;
329                         sendmsg->payload.userState->suppress = client_itr->channel->silent;
330
331                         client_itr->isSuppressed = client_itr->channel->silent;
332
333                         if (client_itr->self_deaf) {
334                                 sendmsg->payload.userState->has_self_deaf = true;
335                                 sendmsg->payload.userState->self_deaf = true;
336                         }
337                         if (client_itr->self_mute) {
338                                 sendmsg->payload.userState->has_self_mute = true;
339                                 sendmsg->payload.userState->self_mute = true;
340                         }
341                         if (client_itr->deaf) {
342                                 sendmsg->payload.userState->has_deaf = true;
343                                 sendmsg->payload.userState->deaf = true;
344                         }
345                         if (client_itr->mute) {
346                                 sendmsg->payload.userState->has_mute = true;
347                                 sendmsg->payload.userState->mute = true;
348                         }
349                         if (client_itr->recording) {
350                                 sendmsg->payload.userState->has_recording = true;
351                                 sendmsg->payload.userState->recording = true;
352                         }
353                         Client_send_message(client, sendmsg);
354                 }
355
356                 /* Sync message */
357                 sendmsg = Msg_create(ServerSync);
358                 sendmsg->payload.serverSync->has_session = true;
359                 sendmsg->payload.serverSync->session = client->sessionId;
360                 sendmsg->payload.serverSync->welcome_text = strdup(getStrConf(WELCOMETEXT));
361                 sendmsg->payload.serverSync->has_max_bandwidth = true;
362                 sendmsg->payload.serverSync->max_bandwidth = getIntConf(MAX_BANDWIDTH);
363                 Client_send_message(client, sendmsg);
364
365                 /* Server config message */
366                 sendmsg = Msg_create(ServerConfig);
367                 sendmsg->payload.serverConfig->has_allow_html = true;
368                 sendmsg->payload.serverConfig->allow_html = true; /* Support this? */
369                 sendmsg->payload.serverConfig->has_message_length = true;
370                 sendmsg->payload.serverConfig->message_length = MAX_TEXT; /* Hardcoded */
371                 sendmsg->payload.serverConfig->has_image_message_length = true;
372                 sendmsg->payload.serverConfig->image_message_length = 0; /* XXX */
373                 Client_send_message(client, sendmsg);
374
375                 Log_info_client(client, "User %s authenticated", client->username);
376                 break;
377
378         case Ping:
379                 if (msg->payload.ping->has_good)
380                         client->cryptState.uiRemoteGood = msg->payload.ping->good;
381                 if (msg->payload.ping->has_late)
382                         client->cryptState.uiRemoteLate = msg->payload.ping->late;
383                 if (msg->payload.ping->has_lost)
384                         client->cryptState.uiRemoteLost = msg->payload.ping->lost;
385                 if (msg->payload.ping->has_resync)
386                         client->cryptState.uiRemoteResync = msg->payload.ping->resync;
387
388                 Log_debug("Ping <-: %d %d %d %d",
389                                   client->cryptState.uiRemoteGood, client->cryptState.uiRemoteLate,
390                                   client->cryptState.uiRemoteLost, client->cryptState.uiRemoteResync
391                         );
392
393                 client->UDPPingAvg = msg->payload.ping->udp_ping_avg;
394                 client->UDPPingVar = msg->payload.ping->udp_ping_var;
395                 client->TCPPingAvg = msg->payload.ping->tcp_ping_avg;
396                 client->TCPPingVar = msg->payload.ping->tcp_ping_var;
397                 client->UDPPackets = msg->payload.ping->udp_packets;
398                 client->TCPPackets = msg->payload.ping->tcp_packets;
399
400                 sendmsg = Msg_create(Ping);
401
402                 sendmsg->payload.ping->timestamp = msg->payload.ping->timestamp;
403                 sendmsg->payload.ping->has_timestamp = true;
404                 sendmsg->payload.ping->good = client->cryptState.uiGood;
405                 sendmsg->payload.ping->has_good = true;
406                 sendmsg->payload.ping->late = client->cryptState.uiLate;
407                 sendmsg->payload.ping->has_late = true;
408                 sendmsg->payload.ping->lost = client->cryptState.uiLost;
409                 sendmsg->payload.ping->has_lost = true;
410                 sendmsg->payload.ping->resync = client->cryptState.uiResync;
411                 sendmsg->payload.ping->has_resync = true;
412
413                 Client_send_message(client, sendmsg);
414                 Log_debug("Ping ->: %d %d %d %d",
415                                   client->cryptState.uiGood, client->cryptState.uiLate,
416                                   client->cryptState.uiLost, client->cryptState.uiResync);
417
418                 break;
419         case CryptSetup:
420                 Log_debug("Voice channel crypt resync requested");
421                 if (!msg->payload.cryptSetup->has_client_nonce) {
422                         sendmsg = Msg_create(CryptSetup);
423                         sendmsg->payload.cryptSetup->has_server_nonce = true;
424                         sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.decrypt_iv;
425                         sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
426                         Client_send_message(client, sendmsg);
427                 } else {
428                         memcpy(client->cryptState.decrypt_iv, msg->payload.cryptSetup->client_nonce.data, AES_BLOCK_SIZE);
429                         client->cryptState.uiResync++;
430                 }
431                 break;
432         case UserState:
433                 target = NULL;
434                 /* Only allow state changes for for the self user unless an admin is issuing */
435                 if (msg->payload.userState->has_session &&
436                     msg->payload.userState->session != client->sessionId && !client->isAdmin) {
437                         sendPermissionDenied(client, "Permission denied");
438                         break;
439                 }
440                 if (msg->payload.userState->has_session && msg->payload.userState->session != client->sessionId) {
441                         target = Client_find_by_session(msg->payload.userState->session);
442
443                         if (target == NULL) {
444                                 Log_warn("Client with sessionID %d not found", msg->payload.userState->session);
445                                 break;
446                         }
447                 }
448
449                 if (msg->payload.userState->has_user_id || msg->payload.userState->has_suppress ||
450                     msg->payload.userState->has_priority_speaker || msg->payload.userState->has_texture) {
451                         sendPermissionDenied(client, "Not supported by uMurmur");
452                         break;
453                 }
454
455                 if (target == NULL)
456                         target = client;
457
458                 msg->payload.userState->has_session = true;
459                 msg->payload.userState->session = target->sessionId;
460                 msg->payload.userState->has_actor = true;
461                 msg->payload.userState->actor = client->sessionId;
462
463                 if (msg->payload.userState->has_deaf) {
464                         target->deaf = msg->payload.userState->deaf;
465                         if (target->deaf) {
466                                 msg->payload.userState->has_mute = true;
467                                 msg->payload.userState->mute = true;
468                         }
469                 }
470                 if (msg->payload.userState->has_mute) {
471                         target->mute = msg->payload.userState->mute;
472                         if (!target->mute) {
473                                 msg->payload.userState->has_deaf = true;
474                                 msg->payload.userState->deaf = false;
475                                 target->deaf = false;
476                         }
477                 }
478                 if (msg->payload.userState->has_self_deaf) {
479                         client->self_deaf = msg->payload.userState->self_deaf;
480                         if (client->self_deaf) {
481                                 msg->payload.userState->has_self_mute = true;
482                                 msg->payload.userState->self_mute = true;
483                         }
484                 }
485                 if (msg->payload.userState->has_self_mute) {
486                         client->self_mute = msg->payload.userState->self_mute;
487                         if (!client->self_mute) {
488                                 msg->payload.userState->has_self_deaf = true;
489                                 msg->payload.userState->self_deaf = false;
490                                 client->self_deaf = false;
491                         }
492                 }
493                 if (msg->payload.userState->has_recording &&
494                         msg->payload.userState->recording != client->recording) {
495                         client->recording = msg->payload.userState->recording;
496                         char *message;
497                         uint32_t *tree_id;
498
499                         message = Memory_safeMalloc(1, strlen(client->username) + 32);
500                         tree_id = Memory_safeMalloc(1, sizeof(uint32_t));
501                         *tree_id = 0;
502                         sendmsg = Msg_create(TextMessage);
503                         sendmsg->payload.textMessage->message = message;
504                         sendmsg->payload.textMessage->n_tree_id = 1;
505                         sendmsg->payload.textMessage->tree_id = tree_id;
506                         if (client->recording)
507                                 sprintf(message, "User %s started recording", client->username);
508                         else
509                                 sprintf(message, "User %s stopped recording", client->username);
510                         Client_send_message_except_ver(NULL, sendmsg, ~0x010203);
511                         sendmsg = NULL;
512                 }
513                 if (msg->payload.userState->has_channel_id) {
514                         int leave_id;
515
516                         channelJoinResult_t result = Chan_userJoin_id_test(msg->payload.userState->channel_id, target);
517
518                         if (result.CHJOIN_NOENTER || result.CHJOIN_NOTFOUND)
519                                 break;
520
521                         if (result.CHJOIN_WRONGPW) {
522                                 if (target == client && !client->isAdmin) {
523                                         sendPermissionDenied(client, "Wrong channel password");
524                                         break;
525                                 }
526                                 /* Tricky one: if user hasn't the password, but is moved to the channel by admin then let
527                                  * the user in. Also let admin user in regardless of channel password.
528                                  * Take no action on other errors.
529                                  */
530                                 else if (!client->isAdmin)
531                                         break;
532                         }
533
534                         leave_id = Chan_userJoin_id(msg->payload.userState->channel_id, target);
535                         if (leave_id > 0) {
536                                 Log_debug("Removing channel ID %d", leave_id);
537                                 sendmsg = Msg_create(ChannelRemove);
538                                 sendmsg->payload.channelRemove->channel_id = leave_id;
539                         }
540
541                         if (result.CHJOIN_SILENT) {
542                                 if (!target->isSuppressed) {
543                                 msg->payload.userState->has_suppress = true;
544                                 msg->payload.userState->suppress = true;
545                                 target->isSuppressed = true;
546                                 }
547                         }
548                         else if (target->isSuppressed) {
549                                 msg->payload.userState->has_suppress = true;
550                                 msg->payload.userState->suppress = false;
551                                 target->isSuppressed = false;
552                         }
553                 }
554                 if (msg->payload.userState->has_plugin_context) {
555                         free(client->context);
556                         client->context = Memory_safeMalloc(1, msg->payload.userState->plugin_context.len);
557                         memcpy(client->context, msg->payload.userState->plugin_context.data,
558                                    msg->payload.userState->plugin_context.len);
559
560                         break; /* Don't inform other users about this state */
561                 }
562                 /* Re-use message */
563                 Msg_inc_ref(msg);
564
565                 Client_send_message_except(NULL, msg);
566
567                 /* Need to send remove channel message _after_ UserState message */
568                 if (sendmsg != NULL)
569                         Client_send_message_except(NULL, sendmsg);
570                 break;
571
572         case TextMessage:
573                 if (!getBoolConf(ALLOW_TEXTMESSAGE))
574                         break;
575                 msg->payload.textMessage->has_actor = true;
576                 msg->payload.textMessage->actor = client->sessionId;
577
578                 /* XXX - HTML is allowed and can't be turned off */
579                 if (msg->payload.textMessage->n_tree_id > 0) {
580                         sendPermissionDenied(client, "Tree message not supported");
581                         break;
582                 }
583
584                 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
585                         int i;
586                         channel_t *ch_itr;
587                         for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
588                                 ch_itr = NULL;
589                                 do {
590                                         Chan_iterate(&ch_itr);
591                                 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
592                                 if (ch_itr != NULL) {
593                                         struct dlist *itr;
594                                         list_iterate(itr, &ch_itr->clients) {
595                                                 client_t *c;
596                                                 c = list_get_entry(itr, client_t, chan_node);
597                                                 if (c != client && !c->deaf && !c->self_deaf) {
598                                                         Msg_inc_ref(msg);
599                                                         Client_send_message(c, msg);
600                                                         Log_debug("Text message to session ID %d", c->sessionId);
601                                                 }
602                                         }
603                                 }
604                         } /* for */
605                 }
606                 if (msg->payload.textMessage->n_session > 0) { /* To user */
607                         int i;
608                         client_t *itr;
609                         for (i = 0; i < msg->payload.textMessage->n_session; i++) {
610                                 itr = Client_find_by_session(msg->payload.textMessage->session[i]);
611
612                                 if (itr == NULL)
613                                         Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
614                                 else if (IS_AUTH(itr) && !itr->deaf && !itr->self_deaf) {
615                                         Msg_inc_ref(msg);
616                                         Client_send_message(itr, msg);
617                                         Log_debug("Text message to session ID %d", itr->sessionId);
618                                 }
619                         } /* for */
620                 }
621                 break;
622
623         case VoiceTarget:
624         {
625                 int i, j, count, targetId = msg->payload.voiceTarget->id;
626                 struct _MumbleProto__VoiceTarget__Target *target;
627
628                 if (!targetId || targetId >= 0x1f)
629                         break;
630                 Voicetarget_add_id(client, targetId);
631                 count = msg->payload.voiceTarget->n_targets;
632                 if (!count)
633                         break;
634                 for (i = 0; i < count; i++) {
635                         target = msg->payload.voiceTarget->targets[i];
636                         for (j = 0; j < target->n_session; j++)
637                                 Voicetarget_add_session(client, targetId, target->session[j]);
638                         if (target->has_channel_id) {
639                                 bool_t linked = false, children = false;
640                                 if (target->has_links)
641                                         linked = target->links;
642                                 if (target->has_children)
643                                         children = target->children;
644                                 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
645                         }
646                 }
647                 break;
648         }
649         case Version:
650                 Log_debug("Version message received");
651                 if (msg->payload.version->has_version) {
652                         client->version = msg->payload.version->version;
653                         Log_debug("Client version 0x%x", client->version);
654                 }
655                 if (msg->payload.version->release) {
656                         free(client->release);
657                         client->release = strdup(msg->payload.version->release);
658                         Log_debug("Client release %s", client->release);
659                 }
660                 if (msg->payload.version->os) {
661                         free(client->os);
662                         client->os = strdup(msg->payload.version->os);
663                         Log_debug("Client OS %s", client->os);
664                 }
665                 if (msg->payload.version->os_version) {
666                         free(client->os_version);
667                         client->os_version = strdup(msg->payload.version->os_version);
668                         Log_debug("Client OS version %s", client->os_version);
669                 }
670                 break;
671         case PermissionQuery:
672                 Msg_inc_ref(msg); /* Re-use message */
673                 msg->payload.permissionQuery->has_permissions = true;
674
675                 if (client->isAdmin)
676                         msg->payload.permissionQuery->permissions = PERM_ADMIN;
677                 else
678                         msg->payload.permissionQuery->permissions = PERM_DEFAULT;
679
680                 if (!getBoolConf(ALLOW_TEXTMESSAGE))
681                         msg->payload.permissionQuery->permissions &= ~PERM_TEXTMESSAGE;
682                 if (!getBoolConf(ENABLE_BAN))
683                         msg->payload.permissionQuery->permissions &= ~PERM_BAN;
684
685                 Client_send_message(client, msg);
686                 break;
687         case UDPTunnel:
688                 client->bUDP = false;
689                 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
690             break;
691         case ChannelState:
692         {
693                 channel_t *ch_itr, *parent, *newchan;
694                 int leave_id;
695                 /* Don't allow any changes to existing channels */
696                 if (msg->payload.channelState->has_channel_id) {
697                         sendPermissionDenied(client, "Not supported by uMurmur");
698                         break;
699                 }
700                 /* Must have parent */
701                 if (!msg->payload.channelState->has_parent) {
702                         sendPermissionDenied(client, "Not supported by uMurmur");
703                         break;
704                 }
705                 /* Must have name */
706                 if (msg->payload.channelState->name == NULL) {
707                         sendPermissionDenied(client, "Not supported by uMurmur");
708                         break;
709                 }
710                 /* Must be temporary channel */
711                 if (msg->payload.channelState->temporary != true) {
712                         sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
713                         break;
714                 }
715                 /* Check channel name is OK */
716                 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
717                         sendPermissionDenied(client, "Channel name too long");
718                         break;
719                 }
720
721                 parent = Chan_fromId(msg->payload.channelState->parent);
722                 if (parent == NULL)
723                         break;
724                 ch_itr = NULL;
725                 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
726                         if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
727                                 sendPermissionDenied(client, "Channel already exists");
728                                 break;
729                         }
730                 }
731                 if (ch_itr != NULL)
732                         break;
733
734                 /* Disallow temporary channels as siblings to temporary channels */
735                 if (parent->temporary) {
736                         sendPermissionDenied(client, "Parent channel is temporary channel");
737                         break;
738                 }
739
740                 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
741                  * I don't know why so I don't do that here...
742                  */
743
744                 /* Create the channel */
745                 newchan = Chan_createChannel(msg->payload.channelState->name,
746                                                                          msg->payload.channelState->description);
747                 newchan->temporary = true;
748                 if (msg->payload.channelState->has_position)
749                         newchan->position = msg->payload.channelState->position;
750                 Chan_addChannel(parent, newchan);
751                 msg->payload.channelState->has_channel_id = true;
752                 msg->payload.channelState->channel_id = newchan->id;
753                 Msg_inc_ref(msg);
754                 Client_send_message_except(NULL, msg);
755
756                 /* Join the creating user */
757                 sendmsg = Msg_create(UserState);
758                 sendmsg->payload.userState->has_session = true;
759                 sendmsg->payload.userState->session = client->sessionId;
760                 sendmsg->payload.userState->has_channel_id = true;
761                 sendmsg->payload.userState->channel_id = newchan->id;
762
763                 if (client->isSuppressed) {
764                         sendmsg->payload.userState->has_suppress = true;
765                         sendmsg->payload.userState->suppress = false;
766                         client->isSuppressed = false;
767                 }
768
769                 Client_send_message_except(NULL, sendmsg);
770
771                 leave_id = Chan_userJoin(newchan, client);
772                 if (leave_id > 0) {
773                         Log_debug("Removing channel ID %d", leave_id);
774                         sendmsg = Msg_create(ChannelRemove);
775                         sendmsg->payload.channelRemove->channel_id = leave_id;
776                         Client_send_message_except(NULL, sendmsg);
777                 }
778         }
779         break;
780
781         case UserStats:
782         {
783                 client_t *target = NULL;
784                 codec_t *codec_itr = NULL;
785                 int i;
786                 bool_t details = true;
787
788                 if (msg->payload.userStats->has_stats_only)
789                         details = !msg->payload.userStats->stats_only;
790
791                 if (!msg->payload.userStats->has_session)
792                         sendPermissionDenied(client, "Not supported by uMurmur");
793
794                 target = Client_find_by_session(msg->payload.userStats->session);
795
796                 if (!target) /* Not found */
797                         break;
798
799                 if (!IS_AUTH(target)) /* Not authenticated. */
800                         break;
801
802                 /*
803                  * Differences from Murmur:
804                  * o Ignoring certificates intentionally
805                  * o Ignoring channel local determining
806                  */
807
808                 sendmsg = Msg_create(UserStats);
809                 sendmsg->payload.userStats->session = msg->payload.userStats->session;
810                 sendmsg->payload.userStats->from_client->has_good = true;
811                 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
812                 sendmsg->payload.userStats->from_client->has_late = true;
813                 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
814                 sendmsg->payload.userStats->from_client->has_lost = true;
815                 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
816                 sendmsg->payload.userStats->from_client->has_resync = true;
817                 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
818
819                 sendmsg->payload.userStats->from_server->has_good = true;
820                 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
821                 sendmsg->payload.userStats->from_server->has_late = true;
822                 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
823                 sendmsg->payload.userStats->from_server->has_lost = true;
824                 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
825                 sendmsg->payload.userStats->from_server->has_resync = true;
826                 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
827
828                 sendmsg->payload.userStats->has_udp_packets = true;
829                 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
830                 sendmsg->payload.userStats->has_udp_ping_avg = true;
831                 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
832                 sendmsg->payload.userStats->has_udp_ping_var = true;
833                 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
834
835                 sendmsg->payload.userStats->has_tcp_ping_avg = true;
836                 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
837                 sendmsg->payload.userStats->has_tcp_ping_var = true;
838                 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
839                 sendmsg->payload.userStats->has_tcp_packets = true;
840                 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
841
842                 if (details) {
843
844                         sendmsg->payload.userStats->version->has_version = true;
845                         sendmsg->payload.userStats->version->version = target->version;
846                         if (target->release)
847                                 sendmsg->payload.userStats->version->release = strdup(target->release);
848                         if (target->os)
849                                 sendmsg->payload.userStats->version->os = strdup(target->os);
850                         if (target->os_version)
851                                 sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
852
853                         sendmsg->payload.userStats->n_celt_versions = target->codec_count;
854                         sendmsg->payload.userStats->celt_versions
855                                 = Memory_safeMalloc(target->codec_count, sizeof(int32_t));
856                         i = 0;
857                         while (Client_codec_iterate(target, &codec_itr) != NULL)
858                                 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
859
860                         sendmsg->payload.userStats->has_opus = true;
861                         sendmsg->payload.userStats->opus = target->bOpus;
862
863                         /* Address */
864                         if (getBoolConf(SHOW_ADDRESSES)) {
865                                 sendmsg->payload.userStats->has_address = true;
866                                 sendmsg->payload.userStats->address.data
867                                         = Memory_safeMalloc(16, sizeof(uint8_t));
868                                 memset(sendmsg->payload.userStats->address.data, 0, 16);
869                                 /* ipv4 representation as ipv6 address. Supposedly correct. */
870                                 memset(&sendmsg->payload.userStats->address.data[10], 0xff, 2); /* IPv4 */
871                                 if(target->remote_tcp.ss_family == AF_INET)
872                                         memcpy(&sendmsg->payload.userStats->address.data[12], &((struct sockaddr_in*)&target->remote_tcp)->sin_addr, 4);
873                                 else
874                                         memcpy(&sendmsg->payload.userStats->address.data[0], &((struct sockaddr_in6*)&target->remote_tcp)->sin6_addr, 16);
875                                 sendmsg->payload.userStats->address.len = 16;
876                         } else {
877                                 sendmsg->payload.userStats->has_address = false;
878                         }
879                 }
880                 /* BW */
881                 sendmsg->payload.userStats->has_bandwidth = true;
882                 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
883
884                 /* Onlinesecs */
885                 sendmsg->payload.userStats->has_onlinesecs = true;
886                 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;
887                 /* Idlesecs */
888                 sendmsg->payload.userStats->has_idlesecs = true;
889                 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;
890                 Client_send_message(client, sendmsg);
891         }
892         break;
893         case UserRemove:
894                 target = NULL;
895                 /* Only admin can issue this */
896                 if (!client->isAdmin) {
897                         sendPermissionDenied(client, "Permission denied");
898                         break;
899                 }
900
901                 target = Client_find_by_session(msg->payload.userRemove->session);
902
903                 if (target == NULL) {
904                         Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
905                         break;
906                 }
907                 msg->payload.userRemove->session = target->sessionId;
908                 msg->payload.userRemove->has_actor = true;
909                 msg->payload.userRemove->actor = client->sessionId;
910
911                 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
912                         if (!getBoolConf(ENABLE_BAN))
913                                 sendPermissionDenied(client, "Permission denied");
914                         else
915                                 Ban_UserBan(target, msg->payload.userRemove->reason);
916                 } else {
917                         Log_info_client(target, "User kicked. Reason: '%s'",
918                                         strlen(msg->payload.userRemove->reason) == 0 ? "N/A" : msg->payload.userRemove->reason);
919                 }
920                 /* Re-use message */
921                 Msg_inc_ref(msg);
922
923                 Client_send_message_except(NULL, msg);
924                 Client_close(target);
925                 break;
926         case BanList:
927                 /* Only admin can issue this */
928                 if (!client->isAdmin) {
929                         sendPermissionDenied(client, "Permission denied");
930                         break;
931                 }
932                 if (!getBoolConf(ENABLE_BAN)) {
933                         sendPermissionDenied(client, "Permission denied");
934                         break;
935                 }
936                 if (msg->payload.banList->has_query && msg->payload.banList->query) {
937                         /* Create banlist message and add banentrys */
938                         sendmsg = Ban_getBanList();
939                         Client_send_message(client, sendmsg);
940                 } else {
941                         /* Clear banlist and set the new one */
942                         Ban_clearBanList();
943                         Ban_putBanList(msg, msg->payload.banList->n_bans);
944                 }
945                 break;
946
947                 /* Permission denied for all these messages. Not implemented. */
948         case ChannelRemove:
949         case ContextAction:
950         case ContextActionAdd:
951         case ACL:
952         case UserList:
953         case QueryUsers:
954                 sendPermissionDenied(client, "Not supported by uMurmur");
955                 break;
956
957         default:
958                 Log_warn("Message %d not handled", msg->messageType);
959                 break;
960         }
961 out:
962         Msg_free(msg);
963         return;
964
965 disconnect:
966         Msg_free(msg);
967         Client_close(client);
968 }
969