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