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