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