Handle admin via token. Handle user mute/deafen. Handle kick and partly ban.
[umurmur.git] / src / messagehandler.c
1 /* Copyright (C) 2009-2011, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
10    - Redistributions of source code must retain the above copyright notice,
11      this list of conditions and the following disclaimer.
12    - Redistributions in binary form must reproduce the above copyright notice,
13      this list of conditions and the following disclaimer in the documentation
14      and/or other materials provided with the distribution.
15    - Neither the name of the Developers nor the names of its contributors may
16      be used to endorse or promote products derived from this software without
17      specific prior written permission.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #include <string.h>
32 #include <stdlib.h>
33
34 #include "log.h"
35 #include "list.h"
36 #include "client.h"
37 #include "messages.h"
38 #include "messagehandler.h"
39 #include "crypt.h"
40 #include "channel.h"
41 #include "conf.h"
42 #include "voicetarget.h"
43
44 #define MAX_TEXT 512
45 #define MAX_USERNAME 128
46
47 extern channel_t *defaultChan;
48 extern int iCodecAlpha, iCodecBeta;
49 extern bool_t bPreferAlpha;
50
51 static void sendServerReject(client_t *client, const char *reason, MumbleProto__Reject__RejectType type)
52 {
53         message_t *msg = Msg_create(Reject);
54         msg->payload.reject->reason = strdup(reason);
55         msg->payload.reject->type = type;
56         msg->payload.reject->has_type = true;
57         Client_send_message(client, msg);
58         
59         Log_info_client(client, "Server reject reason: %s", reason);
60 }
61
62 static void sendPermissionDenied(client_t *client, const char *reason)
63 {
64         message_t *msg = Msg_create(PermissionDenied);
65         msg->payload.permissionDenied->has_type = true;
66         msg->payload.permissionDenied->type = MUMBLE_PROTO__PERMISSION_DENIED__DENY_TYPE__Text;
67         msg->payload.permissionDenied->reason = strdup(reason);
68         Client_send_message(client, msg);
69 }
70
71 static void addTokens(client_t *client, message_t *msg)
72 {
73         int i;
74         if (client->tokencount + msg->payload.authenticate->n_tokens < MAX_TOKENS) {
75                 /* Check lengths first */
76                 for (i = 0; i < msg->payload.authenticate->n_tokens; i++) {
77                         if (strlen(msg->payload.authenticate->tokens[i]) > MAX_TOKENSIZE - 1) {
78                                 sendPermissionDenied(client, "Too long token");
79                                 return;
80                         }
81                 }
82                 
83                 for (i = 0; i < msg->payload.authenticate->n_tokens; i++) {
84                         Log_debug("Adding token '%s' to client '%s'", msg->payload.authenticate->tokens[i], client->username);
85                         Client_token_add(client, msg->payload.authenticate->tokens[i]);
86                 }
87         }
88         else
89                 sendPermissionDenied(client, "Too many tokens");
90 }
91
92 void Mh_handle_message(client_t *client, message_t *msg)
93 {
94         message_t *sendmsg = NULL;
95         channel_t *ch_itr = NULL;
96         client_t *client_itr, *target;
97
98         if (!client->authenticated && !(msg->messageType == Authenticate ||
99                                                                         msg->messageType == Version)) {
100                 goto out;
101         }
102         
103         switch (msg->messageType) {
104         case UDPTunnel:
105         case Ping:
106         case CryptSetup:
107         case VoiceTarget:
108         case UserStats:
109         case PermissionQuery:
110                 break;
111         default:
112                 Timer_restart(&client->idleTime);
113         }
114         
115         switch (msg->messageType) {
116         case Authenticate:
117                 Log_debug("Authenticate message received");
118                 
119                 if (IS_AUTH(client) || !msg->payload.authenticate->username) {
120                         /* Authenticate message might be sent when a tokens are changed by the user.*/
121                         Client_token_free(client); /* Clear the token list */
122                         if (msg->payload.authenticate->n_tokens > 0) {
123                                 Log_debug("Tokens in auth message from '%s'. n_tokens = %d", client->username,
124                                           msg->payload.authenticate->n_tokens);
125                                 addTokens(client, msg);
126                                 
127                                 /* Check if admin PW among tokens */
128                                 if (strlen(getStrConf(ADMIN_PASSPHRASE)) > 0 &&
129                                     Client_token_match(client, getStrConf(ADMIN_PASSPHRASE))) {
130                                         client->isAdmin = true;
131                                         Log_info("User is admin");
132                                 }                               
133                         }
134                         break;
135                 }
136                 
137                 client->authenticated = true;
138                 SSLi_getSHA1Hash(client->ssl, client->hash);
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("User is admin");
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_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                 }
429                 if (msg->payload.userState->has_mute) {
430                         target->mute = msg->payload.userState->mute;
431                         if (!target->mute) {
432                                 msg->payload.userState->has_deaf = true;
433                                 msg->payload.userState->deaf = false;
434                                 client->deaf = false;
435                         }
436                 }
437                 if (msg->payload.userState->has_self_deaf) {
438                         client->deaf = msg->payload.userState->self_deaf;
439                 }
440                 if (msg->payload.userState->has_self_mute) {
441                         client->mute = msg->payload.userState->self_mute;
442                         if (!client->mute) {
443                                 msg->payload.userState->has_self_deaf = true;
444                                 msg->payload.userState->self_deaf = false;
445                                 client->deaf = false;
446                         }
447                 }
448                 if (msg->payload.userState->has_recording &&
449                         msg->payload.userState->recording != client->recording) {
450                         client->recording = msg->payload.userState->recording;
451                         char *message;
452                         uint32_t *tree_id;
453                         
454                         message = malloc(strlen(client->username) + 32);
455                         if (!message)
456                                 Log_fatal("Out of memory");
457                         tree_id = malloc(sizeof(uint32_t));
458                         if (!tree_id)
459                                 Log_fatal("Out of memory");
460                         *tree_id = 0;
461                         sendmsg = Msg_create(TextMessage);
462                         sendmsg->payload.textMessage->message = message;
463                         sendmsg->payload.textMessage->n_tree_id = 1;
464                         sendmsg->payload.textMessage->tree_id = tree_id;
465                         if (client->recording)
466                                 sprintf(message, "User %s started recording", client->username);
467                         else
468                                 sprintf(message, "User %s stopped recording", client->username);
469                         Client_send_message_except_ver(NULL, sendmsg, ~0x010203);
470                         sendmsg = NULL;
471                 }
472                 if (msg->payload.userState->has_channel_id) {
473                         int leave_id;
474                         channelJoinResult_t chjoin_rc = Chan_userJoin_id_test(msg->payload.userState->channel_id, client);
475                         
476                         if (chjoin_rc != CHJOIN_OK) {
477                                 if (chjoin_rc == CHJOIN_WRONGPW) {
478                                         sendPermissionDenied(client, "Wrong channel password");
479                                 }
480                                 break;
481                         }
482                         
483                         leave_id = Chan_userJoin_id(msg->payload.userState->channel_id, client);
484                         if (leave_id > 0) {
485                                 Log_debug("Removing channel ID %d", leave_id);
486                                 sendmsg = Msg_create(ChannelRemove);
487                                 sendmsg->payload.channelRemove->channel_id = leave_id;
488                         }
489                 }
490                 if (msg->payload.userState->has_plugin_context) {
491                         if (client->context)
492                                 free(client->context);
493                         client->context = malloc(msg->payload.userState->plugin_context.len);
494                         if (client->context == NULL)
495                                 Log_fatal("Out of memory");
496                         memcpy(client->context, msg->payload.userState->plugin_context.data,
497                                    msg->payload.userState->plugin_context.len);
498                         
499                         break; /* Don't inform other users about this state */
500                 }
501                 /* Re-use message */
502                 Msg_inc_ref(msg);
503                                 
504                 Client_send_message_except(NULL, msg);
505
506                 /* Need to send remove channel message _after_ UserState message */
507                 if (sendmsg != NULL)
508                         Client_send_message_except(NULL, sendmsg);
509                 break;
510                 
511         case TextMessage:
512                 msg->payload.textMessage->has_actor = true;
513                 msg->payload.textMessage->actor = client->sessionId;
514
515                 /* XXX - HTML is allowed and can't be turned off */
516                 if (msg->payload.textMessage->n_tree_id > 0) {
517                         sendPermissionDenied(client, "Tree message not supported");
518                         break;
519                 }
520                         
521                 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
522                         int i;
523                         channel_t *ch_itr;
524                         for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
525                                 ch_itr = NULL;
526                                 do {
527                                         Chan_iterate(&ch_itr);
528                                 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
529                                 if (ch_itr != NULL) {
530                                         struct dlist *itr;
531                                         list_iterate(itr, &ch_itr->clients) {
532                                                 client_t *c;
533                                                 c = list_get_entry(itr, client_t, chan_node);
534                                                 if (c != client && !c->deaf) {
535                                                         Msg_inc_ref(msg);
536                                                         Client_send_message(c, msg);
537                                                         Log_debug("Text message to session ID %d", c->sessionId);
538                                                 }
539                                         }
540                                 }
541                         } /* for */
542                 }
543                 if (msg->payload.textMessage->n_session > 0) { /* To user */
544                         int i;
545                         client_t *itr;
546                         for (i = 0; i < msg->payload.textMessage->n_session; i++) {
547                                 itr = NULL;
548                                 while (Client_iterate(&itr) != NULL) {
549                                         if (!IS_AUTH(itr))
550                                                 continue;
551                                         if (itr->sessionId == msg->payload.textMessage->session[i]) {
552                                                 if (!itr->deaf) {
553                                                         Msg_inc_ref(msg);
554                                                         Client_send_message(itr, msg);
555                                                         Log_debug("Text message to session ID %d", itr->sessionId);
556                                                 }
557                                                 break;
558                                         }
559                                 }
560                                 if (itr == NULL)
561                                         Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
562                         } /* for */
563                 }
564                 break;
565
566         case VoiceTarget:
567         {
568                 int i, j, count, targetId = msg->payload.voiceTarget->id;
569                 struct _MumbleProto__VoiceTarget__Target *target;
570
571                 if (!targetId || targetId >= 0x1f)
572                         break;
573                 Voicetarget_add_id(client, targetId);
574                 count = msg->payload.voiceTarget->n_targets;
575                 if (!count)
576                         break;
577                 for (i = 0; i < count; i++) {
578                         target = msg->payload.voiceTarget->targets[i];
579                         for (j = 0; j < target->n_session; j++)
580                                 Voicetarget_add_session(client, targetId, target->session[j]);
581                         if (target->has_channel_id) {
582                                 bool_t linked = false, children = false;
583                                 if (target->has_links)
584                                         linked = target->links;
585                                 if (target->has_children)
586                                         children = target->children;
587                                 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
588                         }
589                 }
590                 break;
591         }
592         case Version:
593                 Log_debug("Version message received");
594                 if (msg->payload.version->has_version) {
595                         client->version = msg->payload.version->version;
596                         Log_debug("Client version 0x%x", client->version);
597                 }
598                 if (msg->payload.version->release) {
599                         if (client->release) free(client->release);
600                         client->release = strdup(msg->payload.version->release);
601                         Log_debug("Client release %s", client->release);
602                 }
603                 if (msg->payload.version->os) {
604                         if (client->os) free(client->os);                       
605                         client->os = strdup(msg->payload.version->os);
606                         Log_debug("Client OS %s", client->os);
607                 }
608                 if (msg->payload.version->os_version) {
609                         if (client->os_version) free(client->os_version);                       
610                         client->os_version = strdup(msg->payload.version->os_version);
611                         Log_debug("Client OS version %s", client->os_version);
612                 }
613                 break;
614         case PermissionQuery:
615                 Msg_inc_ref(msg); /* Re-use message */
616                 msg->payload.permissionQuery->has_permissions = true;
617                 if (client->isAdmin)
618                         msg->payload.permissionQuery->permissions = PERM_ADMIN;
619                 else
620                         msg->payload.permissionQuery->permissions = PERM_DEFAULT;
621                 
622                 Client_send_message(client, msg);
623                 break;
624         case UDPTunnel:
625                 client->bUDP = false;
626                 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
627             break;
628         case ChannelState:
629         {
630                 channel_t *ch_itr, *parent, *newchan;
631                 int leave_id;           
632                 /* Don't allow any changes to existing channels */
633                 if (msg->payload.channelState->has_channel_id) {
634                         sendPermissionDenied(client, "Not supported by uMurmur");
635                         break;
636                 }
637                 /* Must have parent */
638                 if (!msg->payload.channelState->has_parent) {
639                         sendPermissionDenied(client, "Not supported by uMurmur");
640                         break;
641                 }
642                 /* Must have name */
643                 if (msg->payload.channelState->name == NULL) {
644                         sendPermissionDenied(client, "Not supported by uMurmur");
645                         break;
646                 }
647                 /* Must be temporary channel */
648                 if (msg->payload.channelState->temporary != true) {
649                         sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
650                         break;
651                 }
652                 /* Check channel name is OK */
653                 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
654                         sendPermissionDenied(client, "Channel name too long");
655                         break;
656                 }
657                         
658                 parent = Chan_fromId(msg->payload.channelState->parent);
659                 if (parent == NULL)
660                         break;
661                 ch_itr = NULL;
662                 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
663                         if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
664                                 sendPermissionDenied(client, "Channel already exists");
665                                 break;
666                         }
667                 }
668                 if (ch_itr != NULL)
669                         break;
670                 
671                 /* Disallow temporary channels as siblings to temporary channels */
672                 if (parent->temporary) {
673                         sendPermissionDenied(client, "Parent channel is temporary channel");
674                         break;
675                 }
676                         
677                 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
678                  * I don't know why so I don't do that here...
679                  */
680
681                 /* Create the channel */
682                 newchan = Chan_createChannel(msg->payload.channelState->name,
683                                                                          msg->payload.channelState->description);
684                 newchan->temporary = true;
685                 Chan_addChannel(parent, newchan);
686                 msg->payload.channelState->has_channel_id = true;
687                 msg->payload.channelState->channel_id = newchan->id;
688                 Msg_inc_ref(msg);
689                 Client_send_message_except(NULL, msg);
690
691                 /* Join the creating user */
692                 sendmsg = Msg_create(UserState);
693                 sendmsg->payload.userState->has_session = true;
694                 sendmsg->payload.userState->session = client->sessionId;
695                 sendmsg->payload.userState->has_channel_id = true;
696                 sendmsg->payload.userState->channel_id = newchan->id;
697                 Client_send_message_except(NULL, sendmsg);
698                 
699                 leave_id = Chan_userJoin(newchan, client);
700                 if (leave_id > 0) {
701                         Log_debug("Removing channel ID %d", leave_id);
702                         sendmsg = Msg_create(ChannelRemove);
703                         sendmsg->payload.channelRemove->channel_id = leave_id;
704                         Client_send_message_except(NULL, sendmsg);
705                 }
706         }               
707         break;
708
709         case UserStats:
710         {
711                 client_t *target = NULL;
712                 codec_t *codec_itr = NULL;
713                 int i;
714                 bool_t details = true;
715                 
716                 if (msg->payload.userStats->has_stats_only)
717                         details = !msg->payload.userStats->stats_only;
718                 
719                 if (!msg->payload.userStats->has_session)
720                         sendPermissionDenied(client, "Not supported by uMurmur");
721                 while (Client_iterate(&target) != NULL) {
722                         if (!IS_AUTH(target))
723                                 continue;
724                         if (target->sessionId == msg->payload.userStats->session)
725                                 break;
726                 }
727                 if (!target) /* Not found */
728                         break;
729                 
730                 /*
731                  * Differences from Murmur:
732                  * o Ignoring certificates intentionally
733                  * o Ignoring channel local determining
734                  */
735                 
736                 sendmsg = Msg_create(UserStats);
737                 sendmsg->payload.userStats->session = msg->payload.userStats->session;
738                 sendmsg->payload.userStats->from_client->has_good = true;
739                 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
740                 sendmsg->payload.userStats->from_client->has_late = true;
741                 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
742                 sendmsg->payload.userStats->from_client->has_lost = true;
743                 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
744                 sendmsg->payload.userStats->from_client->has_resync = true;
745                 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
746                 
747                 sendmsg->payload.userStats->from_server->has_good = true;
748                 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
749                 sendmsg->payload.userStats->from_server->has_late = true;
750                 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
751                 sendmsg->payload.userStats->from_server->has_lost = true;
752                 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
753                 sendmsg->payload.userStats->from_server->has_resync = true;
754                 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
755
756                 sendmsg->payload.userStats->has_udp_packets = true;
757                 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
758                 sendmsg->payload.userStats->has_udp_ping_avg = true;
759                 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
760                 sendmsg->payload.userStats->has_udp_ping_var = true;
761                 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
762                 
763                 sendmsg->payload.userStats->has_tcp_ping_avg = true;
764                 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
765                 sendmsg->payload.userStats->has_tcp_ping_var = true;
766                 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
767                 sendmsg->payload.userStats->has_tcp_packets = true;
768                 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
769                 
770                 if (details) {
771
772                         sendmsg->payload.userStats->version->has_version = true;
773                         sendmsg->payload.userStats->version->version = target->version;
774                         sendmsg->payload.userStats->version->release = strdup(target->release);
775                         sendmsg->payload.userStats->version->os = strdup(target->os);
776                         sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
777                         
778                         sendmsg->payload.userStats->n_celt_versions = target->codec_count;
779                         sendmsg->payload.userStats->celt_versions = malloc(sizeof(int32_t) * target->codec_count);
780                         if (!sendmsg->payload.userStats->celt_versions)
781                                 Log_fatal("Out of memory");
782                         i = 0;
783                         while (Client_codec_iterate(target, &codec_itr) != NULL)
784                                 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
785
786                         /* Address */
787                         sendmsg->payload.userStats->has_address = true;
788                         sendmsg->payload.userStats->address.data = malloc(sizeof(uint8_t) * 16);
789                         if (!sendmsg->payload.userStats->address.data)
790                                 Log_fatal("Out of memory");
791                         memset(sendmsg->payload.userStats->address.data, 0, 16);
792                         /* ipv4 representation as ipv6 address. Supposedly correct. */
793                         memcpy(&sendmsg->payload.userStats->address.data[12], &target->remote_tcp.sin_addr, 4);
794                         sendmsg->payload.userStats->address.len = 16;
795                 }
796                 /* BW */
797                 sendmsg->payload.userStats->has_bandwidth = true;
798                 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
799                 
800                 /* Onlinesecs */
801                 sendmsg->payload.userStats->has_onlinesecs = true;
802                 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;               
803                 /* Idlesecs */
804                 sendmsg->payload.userStats->has_idlesecs = true;
805                 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;            
806                 Client_send_message(client, sendmsg);
807         }
808         break;
809         case UserRemove:
810                 target = NULL;
811                 /* Only admin can issue this */
812                 if (!client->isAdmin) {
813                         sendPermissionDenied(client, "Permission denied");
814                         break;
815                 }
816                 while (Client_iterate(&target) != NULL) {
817                         if (target->sessionId == msg->payload.userRemove->session)
818                                 break;
819                 }
820                 if (target == NULL) {
821                         Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
822                         break;
823                 }
824                 msg->payload.userRemove->session = target->sessionId;
825                 msg->payload.userRemove->has_actor = true;
826                 msg->payload.userRemove->actor = client->sessionId;
827
828                 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
829                         Log_info("User banned for %d seconds", getIntConf(BAN_LENGTH));
830                         /* Put reason, IP, hash, name etc in a list   --->  msg->payload.userRemove->reason */
831                 } else {
832                         Log_info("User kicked");
833                 }
834                 /* Re-use message */
835                 Msg_inc_ref(msg);
836                                 
837                 Client_send_message_except(NULL, msg);
838                 Client_close(target);
839                 break;
840                 
841                 /* Permission denied for all these messages. Not implemented. */
842         case ChannelRemove:
843         case ContextAction:
844         case ContextActionAdd:
845         case ACL:
846         case BanList:
847         case UserList:
848         case QueryUsers:
849                 sendPermissionDenied(client, "Not supported by uMurmur");
850                 break;
851                                 
852         default:
853                 Log_warn("Message %d not handled", msg->messageType);
854                 break;
855         }
856 out:
857         Msg_free(msg);
858         return;
859         
860 disconnect:
861         Msg_free(msg);
862         Client_close(client);
863 }
864