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