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