Mute/deaf fixes + simplify channel password logic.
[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                         if (client->self_deaf) {
451                                 msg->payload.userState->has_self_mute = true;
452                                 msg->payload.userState->self_mute = true;
453                         }
454                 }
455                 if (msg->payload.userState->has_self_mute) {
456                         client->self_mute = msg->payload.userState->self_mute;
457                         if (!client->self_mute) {
458                                 msg->payload.userState->has_self_deaf = true;
459                                 msg->payload.userState->self_deaf = false;
460                                 client->self_deaf = false;
461                         }
462                 }
463                 if (msg->payload.userState->has_recording &&
464                         msg->payload.userState->recording != client->recording) {
465                         client->recording = msg->payload.userState->recording;
466                         char *message;
467                         uint32_t *tree_id;
468                         
469                         message = malloc(strlen(client->username) + 32);
470                         if (!message)
471                                 Log_fatal("Out of memory");
472                         tree_id = malloc(sizeof(uint32_t));
473                         if (!tree_id)
474                                 Log_fatal("Out of memory");
475                         *tree_id = 0;
476                         sendmsg = Msg_create(TextMessage);
477                         sendmsg->payload.textMessage->message = message;
478                         sendmsg->payload.textMessage->n_tree_id = 1;
479                         sendmsg->payload.textMessage->tree_id = tree_id;
480                         if (client->recording)
481                                 sprintf(message, "User %s started recording", client->username);
482                         else
483                                 sprintf(message, "User %s stopped recording", client->username);
484                         Client_send_message_except_ver(NULL, sendmsg, ~0x010203);
485                         sendmsg = NULL;
486                 }
487                 if (msg->payload.userState->has_channel_id) {
488                         int leave_id;
489                         channelJoinResult_t chjoin_rc = Chan_userJoin_id_test(msg->payload.userState->channel_id, target);
490                         
491                         if (chjoin_rc != CHJOIN_OK) {
492                                 if (chjoin_rc == CHJOIN_WRONGPW) {
493                                         if (target == client && !client->isAdmin) {
494                                                 sendPermissionDenied(client, "Wrong channel password");
495                                                 break;
496                                         }
497                                         /* Tricky one: if user hasn't the password, but is moved to the channel by admin then let
498                                          * the user in. Also let admin user in regardless of channel password.
499                                          * Take no action on other errors.
500                                          */
501                                         else if (!client->isAdmin)
502                                                 break;
503                                 }
504                                 else break;
505                         }
506                         
507                         leave_id = Chan_userJoin_id(msg->payload.userState->channel_id, target);
508                         if (leave_id > 0) {
509                                 Log_debug("Removing channel ID %d", leave_id);
510                                 sendmsg = Msg_create(ChannelRemove);
511                                 sendmsg->payload.channelRemove->channel_id = leave_id;
512                         }
513                 }
514                 if (msg->payload.userState->has_plugin_context) {
515                         if (client->context)
516                                 free(client->context);
517                         client->context = malloc(msg->payload.userState->plugin_context.len);
518                         if (client->context == NULL)
519                                 Log_fatal("Out of memory");
520                         memcpy(client->context, msg->payload.userState->plugin_context.data,
521                                    msg->payload.userState->plugin_context.len);
522                         
523                         break; /* Don't inform other users about this state */
524                 }
525                 /* Re-use message */
526                 Msg_inc_ref(msg);
527                                 
528                 Client_send_message_except(NULL, msg);
529
530                 /* Need to send remove channel message _after_ UserState message */
531                 if (sendmsg != NULL)
532                         Client_send_message_except(NULL, sendmsg);
533                 break;
534                 
535         case TextMessage:
536                 if (!getBoolConf(ALLOW_TEXTMESSAGE))
537                         break;
538                 msg->payload.textMessage->has_actor = true;
539                 msg->payload.textMessage->actor = client->sessionId;
540
541                 /* XXX - HTML is allowed and can't be turned off */
542                 if (msg->payload.textMessage->n_tree_id > 0) {
543                         sendPermissionDenied(client, "Tree message not supported");
544                         break;
545                 }
546                         
547                 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
548                         int i;
549                         channel_t *ch_itr;
550                         for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
551                                 ch_itr = NULL;
552                                 do {
553                                         Chan_iterate(&ch_itr);
554                                 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
555                                 if (ch_itr != NULL) {
556                                         struct dlist *itr;
557                                         list_iterate(itr, &ch_itr->clients) {
558                                                 client_t *c;
559                                                 c = list_get_entry(itr, client_t, chan_node);
560                                                 if (c != client && !c->deaf && !c->self_deaf) {
561                                                         Msg_inc_ref(msg);
562                                                         Client_send_message(c, msg);
563                                                         Log_debug("Text message to session ID %d", c->sessionId);
564                                                 }
565                                         }
566                                 }
567                         } /* for */
568                 }
569                 if (msg->payload.textMessage->n_session > 0) { /* To user */
570                         int i;
571                         client_t *itr;
572                         for (i = 0; i < msg->payload.textMessage->n_session; i++) {
573                                 itr = NULL;
574                                 while (Client_iterate(&itr) != NULL) {
575                                         if (!IS_AUTH(itr))
576                                                 continue;
577                                         if (itr->sessionId == msg->payload.textMessage->session[i]) {
578                                                 if (!itr->deaf && !itr->self_deaf) {
579                                                         Msg_inc_ref(msg);
580                                                         Client_send_message(itr, msg);
581                                                         Log_debug("Text message to session ID %d", itr->sessionId);
582                                                 }
583                                                 break;
584                                         }
585                                 }
586                                 if (itr == NULL)
587                                         Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
588                         } /* for */
589                 }
590                 break;
591
592         case VoiceTarget:
593         {
594                 int i, j, count, targetId = msg->payload.voiceTarget->id;
595                 struct _MumbleProto__VoiceTarget__Target *target;
596
597                 if (!targetId || targetId >= 0x1f)
598                         break;
599                 Voicetarget_add_id(client, targetId);
600                 count = msg->payload.voiceTarget->n_targets;
601                 if (!count)
602                         break;
603                 for (i = 0; i < count; i++) {
604                         target = msg->payload.voiceTarget->targets[i];
605                         for (j = 0; j < target->n_session; j++)
606                                 Voicetarget_add_session(client, targetId, target->session[j]);
607                         if (target->has_channel_id) {
608                                 bool_t linked = false, children = false;
609                                 if (target->has_links)
610                                         linked = target->links;
611                                 if (target->has_children)
612                                         children = target->children;
613                                 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
614                         }
615                 }
616                 break;
617         }
618         case Version:
619                 Log_debug("Version message received");
620                 if (msg->payload.version->has_version) {
621                         client->version = msg->payload.version->version;
622                         Log_debug("Client version 0x%x", client->version);
623                 }
624                 if (msg->payload.version->release) {
625                         if (client->release) free(client->release);
626                         client->release = strdup(msg->payload.version->release);
627                         Log_debug("Client release %s", client->release);
628                 }
629                 if (msg->payload.version->os) {
630                         if (client->os) free(client->os);                       
631                         client->os = strdup(msg->payload.version->os);
632                         Log_debug("Client OS %s", client->os);
633                 }
634                 if (msg->payload.version->os_version) {
635                         if (client->os_version) free(client->os_version);                       
636                         client->os_version = strdup(msg->payload.version->os_version);
637                         Log_debug("Client OS version %s", client->os_version);
638                 }
639                 break;
640         case PermissionQuery:
641                 Msg_inc_ref(msg); /* Re-use message */
642                 msg->payload.permissionQuery->has_permissions = true;
643                 
644                 if (client->isAdmin)
645                         msg->payload.permissionQuery->permissions = PERM_ADMIN;
646                 else
647                         msg->payload.permissionQuery->permissions = PERM_DEFAULT;
648                 
649                 if (!getBoolConf(ALLOW_TEXTMESSAGE))
650                         msg->payload.permissionQuery->permissions &= ~PERM_TEXTMESSAGE;
651                 if (!getBoolConf(ENABLE_BAN))
652                         msg->payload.permissionQuery->permissions &= ~PERM_BAN;
653                 
654                 Client_send_message(client, msg);
655                 break;
656         case UDPTunnel:
657                 client->bUDP = false;
658                 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
659             break;
660         case ChannelState:
661         {
662                 channel_t *ch_itr, *parent, *newchan;
663                 int leave_id;           
664                 /* Don't allow any changes to existing channels */
665                 if (msg->payload.channelState->has_channel_id) {
666                         sendPermissionDenied(client, "Not supported by uMurmur");
667                         break;
668                 }
669                 /* Must have parent */
670                 if (!msg->payload.channelState->has_parent) {
671                         sendPermissionDenied(client, "Not supported by uMurmur");
672                         break;
673                 }
674                 /* Must have name */
675                 if (msg->payload.channelState->name == NULL) {
676                         sendPermissionDenied(client, "Not supported by uMurmur");
677                         break;
678                 }
679                 /* Must be temporary channel */
680                 if (msg->payload.channelState->temporary != true) {
681                         sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
682                         break;
683                 }
684                 /* Check channel name is OK */
685                 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
686                         sendPermissionDenied(client, "Channel name too long");
687                         break;
688                 }
689                         
690                 parent = Chan_fromId(msg->payload.channelState->parent);
691                 if (parent == NULL)
692                         break;
693                 ch_itr = NULL;
694                 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
695                         if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
696                                 sendPermissionDenied(client, "Channel already exists");
697                                 break;
698                         }
699                 }
700                 if (ch_itr != NULL)
701                         break;
702                 
703                 /* Disallow temporary channels as siblings to temporary channels */
704                 if (parent->temporary) {
705                         sendPermissionDenied(client, "Parent channel is temporary channel");
706                         break;
707                 }
708                         
709                 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
710                  * I don't know why so I don't do that here...
711                  */
712
713                 /* Create the channel */
714                 newchan = Chan_createChannel(msg->payload.channelState->name,
715                                                                          msg->payload.channelState->description);
716                 newchan->temporary = true;
717                 Chan_addChannel(parent, newchan);
718                 msg->payload.channelState->has_channel_id = true;
719                 msg->payload.channelState->channel_id = newchan->id;
720                 Msg_inc_ref(msg);
721                 Client_send_message_except(NULL, msg);
722
723                 /* Join the creating user */
724                 sendmsg = Msg_create(UserState);
725                 sendmsg->payload.userState->has_session = true;
726                 sendmsg->payload.userState->session = client->sessionId;
727                 sendmsg->payload.userState->has_channel_id = true;
728                 sendmsg->payload.userState->channel_id = newchan->id;
729                 Client_send_message_except(NULL, sendmsg);
730                 
731                 leave_id = Chan_userJoin(newchan, client);
732                 if (leave_id > 0) {
733                         Log_debug("Removing channel ID %d", leave_id);
734                         sendmsg = Msg_create(ChannelRemove);
735                         sendmsg->payload.channelRemove->channel_id = leave_id;
736                         Client_send_message_except(NULL, sendmsg);
737                 }
738         }               
739         break;
740
741         case UserStats:
742         {
743                 client_t *target = NULL;
744                 codec_t *codec_itr = NULL;
745                 int i;
746                 bool_t details = true;
747                 
748                 if (msg->payload.userStats->has_stats_only)
749                         details = !msg->payload.userStats->stats_only;
750                 
751                 if (!msg->payload.userStats->has_session)
752                         sendPermissionDenied(client, "Not supported by uMurmur");
753                 while (Client_iterate(&target) != NULL) {
754                         if (!IS_AUTH(target))
755                                 continue;
756                         if (target->sessionId == msg->payload.userStats->session)
757                                 break;
758                 }
759                 if (!target) /* Not found */
760                         break;
761                 
762                 /*
763                  * Differences from Murmur:
764                  * o Ignoring certificates intentionally
765                  * o Ignoring channel local determining
766                  */
767                 
768                 sendmsg = Msg_create(UserStats);
769                 sendmsg->payload.userStats->session = msg->payload.userStats->session;
770                 sendmsg->payload.userStats->from_client->has_good = true;
771                 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
772                 sendmsg->payload.userStats->from_client->has_late = true;
773                 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
774                 sendmsg->payload.userStats->from_client->has_lost = true;
775                 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
776                 sendmsg->payload.userStats->from_client->has_resync = true;
777                 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
778                 
779                 sendmsg->payload.userStats->from_server->has_good = true;
780                 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
781                 sendmsg->payload.userStats->from_server->has_late = true;
782                 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
783                 sendmsg->payload.userStats->from_server->has_lost = true;
784                 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
785                 sendmsg->payload.userStats->from_server->has_resync = true;
786                 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
787
788                 sendmsg->payload.userStats->has_udp_packets = true;
789                 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
790                 sendmsg->payload.userStats->has_udp_ping_avg = true;
791                 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
792                 sendmsg->payload.userStats->has_udp_ping_var = true;
793                 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
794                 
795                 sendmsg->payload.userStats->has_tcp_ping_avg = true;
796                 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
797                 sendmsg->payload.userStats->has_tcp_ping_var = true;
798                 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
799                 sendmsg->payload.userStats->has_tcp_packets = true;
800                 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
801                 
802                 if (details) {
803
804                         sendmsg->payload.userStats->version->has_version = true;
805                         sendmsg->payload.userStats->version->version = target->version;
806                         sendmsg->payload.userStats->version->release = strdup(target->release);
807                         sendmsg->payload.userStats->version->os = strdup(target->os);
808                         sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
809                         
810                         sendmsg->payload.userStats->n_celt_versions = target->codec_count;
811                         sendmsg->payload.userStats->celt_versions = malloc(sizeof(int32_t) * target->codec_count);
812                         if (!sendmsg->payload.userStats->celt_versions)
813                                 Log_fatal("Out of memory");
814                         i = 0;
815                         while (Client_codec_iterate(target, &codec_itr) != NULL)
816                                 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
817
818                         /* Address */
819                         sendmsg->payload.userStats->has_address = true;
820                         sendmsg->payload.userStats->address.data = malloc(sizeof(uint8_t) * 16);
821                         if (!sendmsg->payload.userStats->address.data)
822                                 Log_fatal("Out of memory");
823                         memset(sendmsg->payload.userStats->address.data, 0, 16);
824                         /* ipv4 representation as ipv6 address. Supposedly correct. */
825                         memcpy(&sendmsg->payload.userStats->address.data[12], &target->remote_tcp.sin_addr, 4);
826                         memset(&sendmsg->payload.userStats->address.data[10], 0xff, 2); /* IPv4 */
827                         sendmsg->payload.userStats->address.len = 16;
828                 }
829                 /* BW */
830                 sendmsg->payload.userStats->has_bandwidth = true;
831                 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
832                 
833                 /* Onlinesecs */
834                 sendmsg->payload.userStats->has_onlinesecs = true;
835                 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;               
836                 /* Idlesecs */
837                 sendmsg->payload.userStats->has_idlesecs = true;
838                 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;            
839                 Client_send_message(client, sendmsg);
840         }
841         break;
842         case UserRemove:
843                 target = NULL;
844                 /* Only admin can issue this */
845                 if (!client->isAdmin) {
846                         sendPermissionDenied(client, "Permission denied");
847                         break;
848                 }
849                 while (Client_iterate(&target) != NULL) {
850                         if (target->sessionId == msg->payload.userRemove->session)
851                                 break;
852                 }
853                 if (target == NULL) {
854                         Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
855                         break;
856                 }
857                 msg->payload.userRemove->session = target->sessionId;
858                 msg->payload.userRemove->has_actor = true;
859                 msg->payload.userRemove->actor = client->sessionId;
860
861                 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
862                         if (!getBoolConf(ENABLE_BAN))
863                                 sendPermissionDenied(client, "Permission denied");
864                         else
865                                 Ban_UserBan(target, msg->payload.userRemove->reason);
866                 } else {
867                         Log_info_client(target, "User kicked. Reason: '%s'",
868                                         strlen(msg->payload.userRemove->reason) == 0 ? "N/A" : msg->payload.userRemove->reason);
869                 }
870                 /* Re-use message */
871                 Msg_inc_ref(msg);
872                                 
873                 Client_send_message_except(NULL, msg);
874                 Client_close(target);
875                 break;
876         case BanList:
877                 /* Only admin can issue this */
878                 if (!client->isAdmin) {
879                         sendPermissionDenied(client, "Permission denied");
880                         break;
881                 }
882                 if (!getBoolConf(ENABLE_BAN)) {
883                         sendPermissionDenied(client, "Permission denied");
884                         break;
885                 }
886                 if (msg->payload.banList->has_query && msg->payload.banList->query) {
887                         /* Create banlist message and add banentrys */
888                         sendmsg = Ban_getBanList();
889                         Client_send_message(client, sendmsg);
890                 } else {
891                         /* Clear banlist and set the new one */
892                         Ban_clearBanList();
893                         Ban_putBanList(msg, msg->payload.banList->n_bans);
894                 }
895                 break;
896                 
897                 /* Permission denied for all these messages. Not implemented. */
898         case ChannelRemove:
899         case ContextAction:
900         case ContextActionAdd:
901         case ACL:
902         case UserList:
903         case QueryUsers:
904                 sendPermissionDenied(client, "Not supported by uMurmur");
905                 break;
906                                 
907         default:
908                 Log_warn("Message %d not handled", msg->messageType);
909                 break;
910         }
911 out:
912         Msg_free(msg);
913         return;
914         
915 disconnect:
916         Msg_free(msg);
917         Client_close(client);
918 }
919