Add initial support for Opus
[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, bOpus;
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                 if (msg->payload.authenticate->opus)
231                         client->bOpus = true;
232                 
233                 recheckCodecVersions(client);
234                 
235                 sendmsg = Msg_create(CodecVersion);
236                 sendmsg->payload.codecVersion->alpha = iCodecAlpha;
237                 sendmsg->payload.codecVersion->beta = iCodecBeta;
238                 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
239                 Client_send_message(client, sendmsg);
240                 
241                 /* Iterate channels and send channel info */
242                 ch_itr = NULL;
243                 while (Chan_iterate(&ch_itr) != NULL) {
244                         sendmsg = Msg_create(ChannelState);
245                         sendmsg->payload.channelState->has_channel_id = true;
246                         sendmsg->payload.channelState->channel_id = ch_itr->id;
247                         if (ch_itr->id != 0) {
248                                 sendmsg->payload.channelState->has_parent = true;
249                                 sendmsg->payload.channelState->parent = ch_itr->parent->id;
250                         }
251                         sendmsg->payload.channelState->name = strdup(ch_itr->name);
252                         if (ch_itr->desc)
253                                 sendmsg->payload.channelState->description = strdup(ch_itr->desc);
254                         Log_debug("Send channel info: %s", sendmsg->payload.channelState->name);
255                         Client_send_message(client, sendmsg);                   
256                 }
257
258                 /* Iterate channels and send channel links info */
259                 ch_itr = NULL;
260                 while (Chan_iterate(&ch_itr) != NULL) {
261                         if (ch_itr->linkcount > 0) { /* Has links */
262                                 uint32_t *links;
263                                 int i = 0;
264                                 struct dlist *itr;
265                                 
266                                 sendmsg = Msg_create(ChannelState);
267                                 sendmsg->payload.channelState->has_channel_id = true;
268                                 sendmsg->payload.channelState->channel_id = ch_itr->id;
269                                 sendmsg->payload.channelState->n_links = ch_itr->linkcount;
270                                 
271                                 links = (uint32_t *)malloc(ch_itr->linkcount * sizeof(uint32_t));
272                                 list_iterate(itr, &ch_itr->channel_links) { /* Iterate links */
273                                         channel_t *ch;
274                                         ch = list_get_entry(itr, channel_t, link_node);
275                                         links[i++] = ch->id;
276                                 }
277                                 sendmsg->payload.channelState->links = links;
278                                 Client_send_message(client, sendmsg);
279                         }
280                 }
281                 
282                 /* Send user state for connecting user to other users */
283                 sendmsg = Msg_create(UserState);
284                 sendmsg->payload.userState->has_session = true;
285                 sendmsg->payload.userState->session = client->sessionId;
286                 sendmsg->payload.userState->name = strdup(client->username);
287                 sendmsg->payload.userState->has_channel_id = true;
288                 sendmsg->payload.userState->channel_id = ((channel_t *)client->channel)->id;
289
290                 Client_send_message_except(client, sendmsg);
291
292                 client_itr = NULL;
293                 while (Client_iterate(&client_itr) != NULL) {
294                         if (!IS_AUTH(client_itr))
295                                 continue;
296                         sendmsg = Msg_create(UserState);
297                         sendmsg->payload.userState->has_session = true;
298                         sendmsg->payload.userState->session = client_itr->sessionId;
299                         sendmsg->payload.userState->name = strdup(client_itr->username);
300                         sendmsg->payload.userState->has_channel_id = true;
301                         sendmsg->payload.userState->channel_id = ((channel_t *)client_itr->channel)->id;
302
303                         if (client_itr->self_deaf) {
304                                 sendmsg->payload.userState->has_self_deaf = true;
305                                 sendmsg->payload.userState->self_deaf = true;
306                         }
307                         if (client_itr->self_mute) {
308                                 sendmsg->payload.userState->has_self_mute = true;
309                                 sendmsg->payload.userState->self_mute = true;
310                         }
311                         if (client_itr->deaf) {
312                                 sendmsg->payload.userState->has_deaf = true;
313                                 sendmsg->payload.userState->deaf = true;
314                         }
315                         if (client_itr->mute) {
316                                 sendmsg->payload.userState->has_mute = true;
317                                 sendmsg->payload.userState->mute = true;
318                         }
319                         if (client_itr->recording) {
320                                 sendmsg->payload.userState->has_recording = true;
321                                 sendmsg->payload.userState->recording = true;
322                         }
323                         Client_send_message(client, sendmsg);
324                 }
325
326                 /* Sync message */
327                 sendmsg = Msg_create(ServerSync);
328                 sendmsg->payload.serverSync->has_session = true;
329                 sendmsg->payload.serverSync->session = client->sessionId;
330                 sendmsg->payload.serverSync->welcome_text = strdup(getStrConf(WELCOMETEXT));
331                 sendmsg->payload.serverSync->has_max_bandwidth = true;
332                 sendmsg->payload.serverSync->max_bandwidth = getIntConf(MAX_BANDWIDTH);
333                 Client_send_message(client, sendmsg);
334
335                 /* Server config message */
336                 sendmsg = Msg_create(ServerConfig);             
337                 sendmsg->payload.serverConfig->has_allow_html = true;
338                 sendmsg->payload.serverConfig->allow_html = true; /* Support this? */
339                 sendmsg->payload.serverConfig->has_message_length = true;
340                 sendmsg->payload.serverConfig->message_length = MAX_TEXT; /* Hardcoded */
341                 sendmsg->payload.serverConfig->has_image_message_length = true;
342                 sendmsg->payload.serverConfig->image_message_length = 0; /* XXX */
343                 Client_send_message(client, sendmsg);
344
345                 Log_info_client(client, "User %s authenticated", client->username);
346                 break;
347                 
348         case Ping:
349                 if (msg->payload.ping->has_good)
350                         client->cryptState.uiRemoteGood = msg->payload.ping->good;
351                 if (msg->payload.ping->has_late)
352                         client->cryptState.uiRemoteLate = msg->payload.ping->late;
353                 if (msg->payload.ping->has_lost)
354                         client->cryptState.uiRemoteLost = msg->payload.ping->lost;
355                 if (msg->payload.ping->has_resync)
356                         client->cryptState.uiRemoteResync = msg->payload.ping->resync;
357
358                 Log_debug("Ping <-: %d %d %d %d",
359                                   client->cryptState.uiRemoteGood, client->cryptState.uiRemoteLate,
360                                   client->cryptState.uiRemoteLost, client->cryptState.uiRemoteResync
361                         );
362                 
363                 client->UDPPingAvg = msg->payload.ping->udp_ping_avg;
364                 client->UDPPingVar = msg->payload.ping->udp_ping_var;
365                 client->TCPPingAvg = msg->payload.ping->tcp_ping_avg;
366                 client->TCPPingVar = msg->payload.ping->tcp_ping_var;
367                 client->UDPPackets = msg->payload.ping->udp_packets;
368                 client->TCPPackets = msg->payload.ping->tcp_packets;
369                 
370                 sendmsg = Msg_create(Ping);
371
372                 sendmsg->payload.ping->timestamp = msg->payload.ping->timestamp;
373                 sendmsg->payload.ping->has_timestamp = true;
374                 sendmsg->payload.ping->good = client->cryptState.uiGood;
375                 sendmsg->payload.ping->has_good = true;
376                 sendmsg->payload.ping->late = client->cryptState.uiLate;
377                 sendmsg->payload.ping->has_late = true;
378                 sendmsg->payload.ping->lost = client->cryptState.uiLost;
379                 sendmsg->payload.ping->has_lost = true;
380                 sendmsg->payload.ping->resync = client->cryptState.uiResync;
381                 sendmsg->payload.ping->has_resync = true;
382
383                 Client_send_message(client, sendmsg);
384                 Log_debug("Ping ->: %d %d %d %d",
385                                   client->cryptState.uiGood, client->cryptState.uiLate,
386                                   client->cryptState.uiLost, client->cryptState.uiResync);
387
388                 break;
389         case CryptSetup:
390                 Log_debug("Voice channel crypt resync requested");
391                 if (!msg->payload.cryptSetup->has_client_nonce) {
392                         sendmsg = Msg_create(CryptSetup);
393                         sendmsg->payload.cryptSetup->has_server_nonce = true;
394                         sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.decrypt_iv;
395                         sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
396                         Client_send_message(client, sendmsg);
397                 } else {
398                         memcpy(client->cryptState.decrypt_iv, msg->payload.cryptSetup->client_nonce.data, AES_BLOCK_SIZE);
399                         client->cryptState.uiResync++;
400                 }
401                 break;
402         case UserState:
403                 target = NULL;
404                 /* Only allow state changes for for the self user unless an admin is issuing */
405                 if (msg->payload.userState->has_session &&
406                     msg->payload.userState->session != client->sessionId && !client->isAdmin) {
407                         sendPermissionDenied(client, "Permission denied");
408                         break;
409                 }
410                 if (msg->payload.userState->has_session && msg->payload.userState->session != client->sessionId) {
411                         while (Client_iterate(&target) != NULL) {
412                                 if (target->sessionId == msg->payload.userState->session)
413                                         break;
414                         }
415                         if (target == NULL) {
416                                 Log_warn("Client with sessionID %d not found", msg->payload.userState->session);
417                                 break;
418                         }
419                 }
420
421                 if (msg->payload.userState->has_user_id || msg->payload.userState->has_suppress ||
422                     msg->payload.userState->has_priority_speaker || msg->payload.userState->has_texture) {
423                         sendPermissionDenied(client, "Not supported by uMurmur");
424                         break;
425                 }
426
427                 if (target == NULL)
428                         target = client;
429                 
430                 msg->payload.userState->has_session = true;
431                 msg->payload.userState->session = target->sessionId;
432                 msg->payload.userState->has_actor = true;
433                 msg->payload.userState->actor = client->sessionId;
434
435                 if (msg->payload.userState->has_deaf) {
436                         target->deaf = msg->payload.userState->deaf;
437                         if (target->deaf) {
438                                 msg->payload.userState->has_mute = true;
439                                 msg->payload.userState->mute = true;
440                         }
441                 }
442                 if (msg->payload.userState->has_mute) {
443                         target->mute = msg->payload.userState->mute;
444                         if (!target->mute) {
445                                 msg->payload.userState->has_deaf = true;
446                                 msg->payload.userState->deaf = false;
447                                 target->deaf = false;
448                         }
449                 }
450                 if (msg->payload.userState->has_self_deaf) {
451                         client->self_deaf = msg->payload.userState->self_deaf;
452                         if (client->self_deaf) {
453                                 msg->payload.userState->has_self_mute = true;
454                                 msg->payload.userState->self_mute = true;
455                         }
456                 }
457                 if (msg->payload.userState->has_self_mute) {
458                         client->self_mute = msg->payload.userState->self_mute;
459                         if (!client->self_mute) {
460                                 msg->payload.userState->has_self_deaf = true;
461                                 msg->payload.userState->self_deaf = false;
462                                 client->self_deaf = false;
463                         }
464                 }
465                 if (msg->payload.userState->has_recording &&
466                         msg->payload.userState->recording != client->recording) {
467                         client->recording = msg->payload.userState->recording;
468                         char *message;
469                         uint32_t *tree_id;
470                         
471                         message = malloc(strlen(client->username) + 32);
472                         if (!message)
473                                 Log_fatal("Out of memory");
474                         tree_id = malloc(sizeof(uint32_t));
475                         if (!tree_id)
476                                 Log_fatal("Out of memory");
477                         *tree_id = 0;
478                         sendmsg = Msg_create(TextMessage);
479                         sendmsg->payload.textMessage->message = message;
480                         sendmsg->payload.textMessage->n_tree_id = 1;
481                         sendmsg->payload.textMessage->tree_id = tree_id;
482                         if (client->recording)
483                                 sprintf(message, "User %s started recording", client->username);
484                         else
485                                 sprintf(message, "User %s stopped recording", client->username);
486                         Client_send_message_except_ver(NULL, sendmsg, ~0x010203);
487                         sendmsg = NULL;
488                 }
489                 if (msg->payload.userState->has_channel_id) {
490                         int leave_id;
491                         channelJoinResult_t chjoin_rc = Chan_userJoin_id_test(msg->payload.userState->channel_id, target);
492                         
493                         if (chjoin_rc != CHJOIN_OK) {
494                                 if (chjoin_rc == CHJOIN_WRONGPW) {
495                                         if (target == client && !client->isAdmin) {
496                                                 sendPermissionDenied(client, "Wrong channel password");
497                                                 break;
498                                         }
499                                         /* Tricky one: if user hasn't the password, but is moved to the channel by admin then let
500                                          * the user in. Also let admin user in regardless of channel password.
501                                          * Take no action on other errors.
502                                          */
503                                         else if (!client->isAdmin)
504                                                 break;
505                                 }
506                                 else break;
507                         }
508                         
509                         leave_id = Chan_userJoin_id(msg->payload.userState->channel_id, target);
510                         if (leave_id > 0) {
511                                 Log_debug("Removing channel ID %d", leave_id);
512                                 sendmsg = Msg_create(ChannelRemove);
513                                 sendmsg->payload.channelRemove->channel_id = leave_id;
514                         }
515                 }
516                 if (msg->payload.userState->has_plugin_context) {
517                         if (client->context)
518                                 free(client->context);
519                         client->context = malloc(msg->payload.userState->plugin_context.len);
520                         if (client->context == NULL)
521                                 Log_fatal("Out of memory");
522                         memcpy(client->context, msg->payload.userState->plugin_context.data,
523                                    msg->payload.userState->plugin_context.len);
524                         
525                         break; /* Don't inform other users about this state */
526                 }
527                 /* Re-use message */
528                 Msg_inc_ref(msg);
529                                 
530                 Client_send_message_except(NULL, msg);
531
532                 /* Need to send remove channel message _after_ UserState message */
533                 if (sendmsg != NULL)
534                         Client_send_message_except(NULL, sendmsg);
535                 break;
536                 
537         case TextMessage:
538                 if (!getBoolConf(ALLOW_TEXTMESSAGE))
539                         break;
540                 msg->payload.textMessage->has_actor = true;
541                 msg->payload.textMessage->actor = client->sessionId;
542
543                 /* XXX - HTML is allowed and can't be turned off */
544                 if (msg->payload.textMessage->n_tree_id > 0) {
545                         sendPermissionDenied(client, "Tree message not supported");
546                         break;
547                 }
548                         
549                 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
550                         int i;
551                         channel_t *ch_itr;
552                         for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
553                                 ch_itr = NULL;
554                                 do {
555                                         Chan_iterate(&ch_itr);
556                                 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
557                                 if (ch_itr != NULL) {
558                                         struct dlist *itr;
559                                         list_iterate(itr, &ch_itr->clients) {
560                                                 client_t *c;
561                                                 c = list_get_entry(itr, client_t, chan_node);
562                                                 if (c != client && !c->deaf && !c->self_deaf) {
563                                                         Msg_inc_ref(msg);
564                                                         Client_send_message(c, msg);
565                                                         Log_debug("Text message to session ID %d", c->sessionId);
566                                                 }
567                                         }
568                                 }
569                         } /* for */
570                 }
571                 if (msg->payload.textMessage->n_session > 0) { /* To user */
572                         int i;
573                         client_t *itr;
574                         for (i = 0; i < msg->payload.textMessage->n_session; i++) {
575                                 itr = NULL;
576                                 while (Client_iterate(&itr) != NULL) {
577                                         if (!IS_AUTH(itr))
578                                                 continue;
579                                         if (itr->sessionId == msg->payload.textMessage->session[i]) {
580                                                 if (!itr->deaf && !itr->self_deaf) {
581                                                         Msg_inc_ref(msg);
582                                                         Client_send_message(itr, msg);
583                                                         Log_debug("Text message to session ID %d", itr->sessionId);
584                                                 }
585                                                 break;
586                                         }
587                                 }
588                                 if (itr == NULL)
589                                         Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
590                         } /* for */
591                 }
592                 break;
593
594         case VoiceTarget:
595         {
596                 int i, j, count, targetId = msg->payload.voiceTarget->id;
597                 struct _MumbleProto__VoiceTarget__Target *target;
598
599                 if (!targetId || targetId >= 0x1f)
600                         break;
601                 Voicetarget_add_id(client, targetId);
602                 count = msg->payload.voiceTarget->n_targets;
603                 if (!count)
604                         break;
605                 for (i = 0; i < count; i++) {
606                         target = msg->payload.voiceTarget->targets[i];
607                         for (j = 0; j < target->n_session; j++)
608                                 Voicetarget_add_session(client, targetId, target->session[j]);
609                         if (target->has_channel_id) {
610                                 bool_t linked = false, children = false;
611                                 if (target->has_links)
612                                         linked = target->links;
613                                 if (target->has_children)
614                                         children = target->children;
615                                 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
616                         }
617                 }
618                 break;
619         }
620         case Version:
621                 Log_debug("Version message received");
622                 if (msg->payload.version->has_version) {
623                         client->version = msg->payload.version->version;
624                         Log_debug("Client version 0x%x", client->version);
625                 }
626                 if (msg->payload.version->release) {
627                         if (client->release) free(client->release);
628                         client->release = strdup(msg->payload.version->release);
629                         Log_debug("Client release %s", client->release);
630                 }
631                 if (msg->payload.version->os) {
632                         if (client->os) free(client->os);                       
633                         client->os = strdup(msg->payload.version->os);
634                         Log_debug("Client OS %s", client->os);
635                 }
636                 if (msg->payload.version->os_version) {
637                         if (client->os_version) free(client->os_version);                       
638                         client->os_version = strdup(msg->payload.version->os_version);
639                         Log_debug("Client OS version %s", client->os_version);
640                 }
641                 break;
642         case PermissionQuery:
643                 Msg_inc_ref(msg); /* Re-use message */
644                 msg->payload.permissionQuery->has_permissions = true;
645                 
646                 if (client->isAdmin)
647                         msg->payload.permissionQuery->permissions = PERM_ADMIN;
648                 else
649                         msg->payload.permissionQuery->permissions = PERM_DEFAULT;
650                 
651                 if (!getBoolConf(ALLOW_TEXTMESSAGE))
652                         msg->payload.permissionQuery->permissions &= ~PERM_TEXTMESSAGE;
653                 if (!getBoolConf(ENABLE_BAN))
654                         msg->payload.permissionQuery->permissions &= ~PERM_BAN;
655                 
656                 Client_send_message(client, msg);
657                 break;
658         case UDPTunnel:
659                 client->bUDP = false;
660                 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
661             break;
662         case ChannelState:
663         {
664                 channel_t *ch_itr, *parent, *newchan;
665                 int leave_id;           
666                 /* Don't allow any changes to existing channels */
667                 if (msg->payload.channelState->has_channel_id) {
668                         sendPermissionDenied(client, "Not supported by uMurmur");
669                         break;
670                 }
671                 /* Must have parent */
672                 if (!msg->payload.channelState->has_parent) {
673                         sendPermissionDenied(client, "Not supported by uMurmur");
674                         break;
675                 }
676                 /* Must have name */
677                 if (msg->payload.channelState->name == NULL) {
678                         sendPermissionDenied(client, "Not supported by uMurmur");
679                         break;
680                 }
681                 /* Must be temporary channel */
682                 if (msg->payload.channelState->temporary != true) {
683                         sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
684                         break;
685                 }
686                 /* Check channel name is OK */
687                 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
688                         sendPermissionDenied(client, "Channel name too long");
689                         break;
690                 }
691                         
692                 parent = Chan_fromId(msg->payload.channelState->parent);
693                 if (parent == NULL)
694                         break;
695                 ch_itr = NULL;
696                 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
697                         if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
698                                 sendPermissionDenied(client, "Channel already exists");
699                                 break;
700                         }
701                 }
702                 if (ch_itr != NULL)
703                         break;
704                 
705                 /* Disallow temporary channels as siblings to temporary channels */
706                 if (parent->temporary) {
707                         sendPermissionDenied(client, "Parent channel is temporary channel");
708                         break;
709                 }
710                         
711                 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
712                  * I don't know why so I don't do that here...
713                  */
714
715                 /* Create the channel */
716                 newchan = Chan_createChannel(msg->payload.channelState->name,
717                                                                          msg->payload.channelState->description);
718                 newchan->temporary = true;
719                 Chan_addChannel(parent, newchan);
720                 msg->payload.channelState->has_channel_id = true;
721                 msg->payload.channelState->channel_id = newchan->id;
722                 Msg_inc_ref(msg);
723                 Client_send_message_except(NULL, msg);
724
725                 /* Join the creating user */
726                 sendmsg = Msg_create(UserState);
727                 sendmsg->payload.userState->has_session = true;
728                 sendmsg->payload.userState->session = client->sessionId;
729                 sendmsg->payload.userState->has_channel_id = true;
730                 sendmsg->payload.userState->channel_id = newchan->id;
731                 Client_send_message_except(NULL, sendmsg);
732                 
733                 leave_id = Chan_userJoin(newchan, client);
734                 if (leave_id > 0) {
735                         Log_debug("Removing channel ID %d", leave_id);
736                         sendmsg = Msg_create(ChannelRemove);
737                         sendmsg->payload.channelRemove->channel_id = leave_id;
738                         Client_send_message_except(NULL, sendmsg);
739                 }
740         }               
741         break;
742
743         case UserStats:
744         {
745                 client_t *target = NULL;
746                 codec_t *codec_itr = NULL;
747                 int i;
748                 bool_t details = true;
749                 
750                 if (msg->payload.userStats->has_stats_only)
751                         details = !msg->payload.userStats->stats_only;
752                 
753                 if (!msg->payload.userStats->has_session)
754                         sendPermissionDenied(client, "Not supported by uMurmur");
755                 while (Client_iterate(&target) != NULL) {
756                         if (!IS_AUTH(target))
757                                 continue;
758                         if (target->sessionId == msg->payload.userStats->session)
759                                 break;
760                 }
761                 if (!target) /* Not found */
762                         break;
763                 
764                 /*
765                  * Differences from Murmur:
766                  * o Ignoring certificates intentionally
767                  * o Ignoring channel local determining
768                  */
769                 
770                 sendmsg = Msg_create(UserStats);
771                 sendmsg->payload.userStats->session = msg->payload.userStats->session;
772                 sendmsg->payload.userStats->from_client->has_good = true;
773                 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
774                 sendmsg->payload.userStats->from_client->has_late = true;
775                 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
776                 sendmsg->payload.userStats->from_client->has_lost = true;
777                 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
778                 sendmsg->payload.userStats->from_client->has_resync = true;
779                 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
780                 
781                 sendmsg->payload.userStats->from_server->has_good = true;
782                 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
783                 sendmsg->payload.userStats->from_server->has_late = true;
784                 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
785                 sendmsg->payload.userStats->from_server->has_lost = true;
786                 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
787                 sendmsg->payload.userStats->from_server->has_resync = true;
788                 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
789
790                 sendmsg->payload.userStats->has_udp_packets = true;
791                 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
792                 sendmsg->payload.userStats->has_udp_ping_avg = true;
793                 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
794                 sendmsg->payload.userStats->has_udp_ping_var = true;
795                 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
796                 
797                 sendmsg->payload.userStats->has_tcp_ping_avg = true;
798                 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
799                 sendmsg->payload.userStats->has_tcp_ping_var = true;
800                 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
801                 sendmsg->payload.userStats->has_tcp_packets = true;
802                 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
803                 
804                 if (details) {
805
806                         sendmsg->payload.userStats->version->has_version = true;
807                         sendmsg->payload.userStats->version->version = target->version;
808                         sendmsg->payload.userStats->version->release = strdup(target->release);
809                         sendmsg->payload.userStats->version->os = strdup(target->os);
810                         sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
811                         
812                         sendmsg->payload.userStats->n_celt_versions = target->codec_count;
813                         sendmsg->payload.userStats->celt_versions = malloc(sizeof(int32_t) * target->codec_count);
814                         if (!sendmsg->payload.userStats->celt_versions)
815                                 Log_fatal("Out of memory");
816                         i = 0;
817                         while (Client_codec_iterate(target, &codec_itr) != NULL)
818                                 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
819
820                         sendmsg->payload.userStats->opus = target->bOpus;
821
822                         /* Address */
823                         sendmsg->payload.userStats->has_address = true;
824                         sendmsg->payload.userStats->address.data = malloc(sizeof(uint8_t) * 16);
825                         if (!sendmsg->payload.userStats->address.data)
826                                 Log_fatal("Out of memory");
827                         memset(sendmsg->payload.userStats->address.data, 0, 16);
828                         /* ipv4 representation as ipv6 address. Supposedly correct. */
829                         memcpy(&sendmsg->payload.userStats->address.data[12], &target->remote_tcp.sin_addr, 4);
830                         memset(&sendmsg->payload.userStats->address.data[10], 0xff, 2); /* IPv4 */
831                         sendmsg->payload.userStats->address.len = 16;
832                 }
833                 /* BW */
834                 sendmsg->payload.userStats->has_bandwidth = true;
835                 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
836                 
837                 /* Onlinesecs */
838                 sendmsg->payload.userStats->has_onlinesecs = true;
839                 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;               
840                 /* Idlesecs */
841                 sendmsg->payload.userStats->has_idlesecs = true;
842                 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;            
843                 Client_send_message(client, sendmsg);
844         }
845         break;
846         case UserRemove:
847                 target = NULL;
848                 /* Only admin can issue this */
849                 if (!client->isAdmin) {
850                         sendPermissionDenied(client, "Permission denied");
851                         break;
852                 }
853                 while (Client_iterate(&target) != NULL) {
854                         if (target->sessionId == msg->payload.userRemove->session)
855                                 break;
856                 }
857                 if (target == NULL) {
858                         Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
859                         break;
860                 }
861                 msg->payload.userRemove->session = target->sessionId;
862                 msg->payload.userRemove->has_actor = true;
863                 msg->payload.userRemove->actor = client->sessionId;
864
865                 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
866                         if (!getBoolConf(ENABLE_BAN))
867                                 sendPermissionDenied(client, "Permission denied");
868                         else
869                                 Ban_UserBan(target, msg->payload.userRemove->reason);
870                 } else {
871                         Log_info_client(target, "User kicked. Reason: '%s'",
872                                         strlen(msg->payload.userRemove->reason) == 0 ? "N/A" : msg->payload.userRemove->reason);
873                 }
874                 /* Re-use message */
875                 Msg_inc_ref(msg);
876                                 
877                 Client_send_message_except(NULL, msg);
878                 Client_close(target);
879                 break;
880         case BanList:
881                 /* Only admin can issue this */
882                 if (!client->isAdmin) {
883                         sendPermissionDenied(client, "Permission denied");
884                         break;
885                 }
886                 if (!getBoolConf(ENABLE_BAN)) {
887                         sendPermissionDenied(client, "Permission denied");
888                         break;
889                 }
890                 if (msg->payload.banList->has_query && msg->payload.banList->query) {
891                         /* Create banlist message and add banentrys */
892                         sendmsg = Ban_getBanList();
893                         Client_send_message(client, sendmsg);
894                 } else {
895                         /* Clear banlist and set the new one */
896                         Ban_clearBanList();
897                         Ban_putBanList(msg, msg->payload.banList->n_bans);
898                 }
899                 break;
900                 
901                 /* Permission denied for all these messages. Not implemented. */
902         case ChannelRemove:
903         case ContextAction:
904         case ContextActionAdd:
905         case ACL:
906         case UserList:
907         case QueryUsers:
908                 sendPermissionDenied(client, "Not supported by uMurmur");
909                 break;
910                                 
911         default:
912                 Log_warn("Message %d not handled", msg->messageType);
913                 break;
914         }
915 out:
916         Msg_free(msg);
917         return;
918         
919 disconnect:
920         Msg_free(msg);
921         Client_close(client);
922 }
923