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