Admin user role first shot + ban and kick.
[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                         break;
128                 }
129                 
130                 SSLi_getSHA1Hash(client->ssl, client->hash);
131                 if (Ban_isBanned(client))
132                         goto disconnect;
133                 
134                 client->authenticated = true;
135                 
136                 client_itr = NULL;
137                 while (Client_iterate(&client_itr) != NULL) {
138                         if (!IS_AUTH(client_itr))
139                                 continue;
140                         if (client_itr->username && strncmp(client_itr->username, msg->payload.authenticate->username, MAX_USERNAME) == 0) {
141                                 char buf[64];
142                                 sprintf(buf, "Username already in use");
143                                 Log_debug("Username already in use");
144                                 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__UsernameInUse);
145                                 goto disconnect;
146                         }                               
147                 }
148                 if (strlen(getStrConf(PASSPHRASE)) > 0) {
149                         if (!msg->payload.authenticate->password ||
150                                 (msg->payload.authenticate->password &&
151                                  strncmp(getStrConf(PASSPHRASE), msg->payload.authenticate->password, MAX_TEXT) != 0)) {
152                                 char buf[64];
153                                 sprintf(buf, "Wrong server password");
154                                 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__WrongServerPW);
155                                 Log_debug("Wrong server password: '%s'", msg->payload.authenticate->password != NULL ?
156                                                   msg->payload.authenticate->password : "(null)");
157                                 goto disconnect;
158                         }
159                 }                               
160                 if (strlen(msg->payload.authenticate->username) == 0 ||
161                         strlen(msg->payload.authenticate->username) >= MAX_USERNAME) { /* XXX - other invalid names? */
162                         char buf[64];
163                         sprintf(buf, "Invalid username");
164                         Log_debug("Invalid username");
165                         sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__InvalidUsername);
166                         goto disconnect;
167                 }                               
168
169                 if (Client_count() >= getIntConf(MAX_CLIENTS)) {
170                         char buf[64];
171                         snprintf(buf, 64, "Server is full (max %d users)", getIntConf(MAX_CLIENTS));
172                         sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__ServerFull);
173                         goto disconnect;
174                 }
175                 
176                 /* Name */
177                 client->username = strdup(msg->payload.authenticate->username);                         
178
179                 /* Tokens */
180                 if (msg->payload.authenticate->n_tokens > 0)
181                         addTokens(client, msg);
182                 
183                 /* Check if admin PW among tokens */
184                 if (strlen(getStrConf(ADMIN_PASSPHRASE)) > 0 &&
185                     Client_token_match(client, getStrConf(ADMIN_PASSPHRASE))) {
186                         client->isAdmin = true;
187                         Log_info("User is admin");
188                 }
189                 
190                 /* Setup UDP encryption */
191                 CryptState_init(&client->cryptState);
192                 CryptState_genKey(&client->cryptState);
193                 sendmsg = Msg_create(CryptSetup);
194                 sendmsg->payload.cryptSetup->has_key = true;
195                 sendmsg->payload.cryptSetup->key.data = client->cryptState.raw_key;
196                 sendmsg->payload.cryptSetup->key.len = AES_BLOCK_SIZE;
197                 sendmsg->payload.cryptSetup->has_server_nonce = true;
198                 sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.encrypt_iv;
199                 sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
200                 sendmsg->payload.cryptSetup->has_client_nonce = true;
201                 sendmsg->payload.cryptSetup->client_nonce.data = client->cryptState.decrypt_iv;
202                 sendmsg->payload.cryptSetup->client_nonce.len = AES_BLOCK_SIZE;
203                 Client_send_message(client, sendmsg);
204
205                 /* Channel stuff */
206                 Chan_userJoin(defaultChan, client); /* Join default channel */
207
208                 /* Codec version */             
209                 Log_debug("Client %d has %d CELT codecs", client->sessionId,
210                                   msg->payload.authenticate->n_celt_versions);
211                 if (msg->payload.authenticate->n_celt_versions > 0) {
212                         int i;
213                         codec_t *codec_itr;
214                         client->codec_count = msg->payload.authenticate->n_celt_versions;
215                         
216                         for (i = 0; i < client->codec_count; i++)
217                         Client_codec_add(client, msg->payload.authenticate->celt_versions[i]);
218                         codec_itr = NULL;
219                         while (Client_codec_iterate(client, &codec_itr) != NULL)
220                                 Log_debug("Client %d CELT codec ver 0x%x", client->sessionId, codec_itr->codec);
221                                 
222                 } else {
223                         Client_codec_add(client, (int32_t)0x8000000a);
224                         client->codec_count = 1;
225                 }
226                 
227                 recheckCodecVersions();
228                 
229                 sendmsg = Msg_create(CodecVersion);
230                 sendmsg->payload.codecVersion->alpha = iCodecAlpha;
231                 sendmsg->payload.codecVersion->beta = iCodecBeta;
232                 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
233                 Client_send_message(client, sendmsg);
234                 
235                 /* Iterate channels and send channel info */
236                 ch_itr = NULL;
237                 while (Chan_iterate(&ch_itr) != NULL) {
238                         sendmsg = Msg_create(ChannelState);
239                         sendmsg->payload.channelState->has_channel_id = true;
240                         sendmsg->payload.channelState->channel_id = ch_itr->id;
241                         if (ch_itr->id != 0) {
242                                 sendmsg->payload.channelState->has_parent = true;
243                                 sendmsg->payload.channelState->parent = ch_itr->parent->id;
244                         }
245                         sendmsg->payload.channelState->name = strdup(ch_itr->name);
246                         if (ch_itr->desc)
247                                 sendmsg->payload.channelState->description = strdup(ch_itr->desc);
248                         Log_debug("Send channel info: %s", sendmsg->payload.channelState->name);
249                         Client_send_message(client, sendmsg);                   
250                 }
251
252                 /* Iterate channels and send channel links info */
253                 ch_itr = NULL;
254                 while (Chan_iterate(&ch_itr) != NULL) {
255                         if (ch_itr->linkcount > 0) { /* Has links */
256                                 uint32_t *links;
257                                 int i = 0;
258                                 struct dlist *itr;
259                                 
260                                 sendmsg = Msg_create(ChannelState);
261                                 sendmsg->payload.channelState->has_channel_id = true;
262                                 sendmsg->payload.channelState->channel_id = ch_itr->id;
263                                 sendmsg->payload.channelState->n_links = ch_itr->linkcount;
264                                 
265                                 links = (uint32_t *)malloc(ch_itr->linkcount * sizeof(uint32_t));
266                                 list_iterate(itr, &ch_itr->channel_links) { /* Iterate links */
267                                         channel_t *ch;
268                                         ch = list_get_entry(itr, channel_t, link_node);
269                                         links[i++] = ch->id;
270                                 }
271                                 sendmsg->payload.channelState->links = links;
272                                 Client_send_message(client, sendmsg);
273                         }
274                 }
275                 
276                 /* Send user state for connecting user to other users */
277                 sendmsg = Msg_create(UserState);
278                 sendmsg->payload.userState->has_session = true;
279                 sendmsg->payload.userState->session = client->sessionId;
280                 sendmsg->payload.userState->name = strdup(client->username);
281                 sendmsg->payload.userState->has_channel_id = true;
282                 sendmsg->payload.userState->channel_id = ((channel_t *)client->channel)->id;
283
284                 Client_send_message_except(client, sendmsg);
285
286                 client_itr = NULL;
287                 while (Client_iterate(&client_itr) != NULL) {
288                         if (!IS_AUTH(client_itr))
289                                 continue;
290                         sendmsg = Msg_create(UserState);
291                         sendmsg->payload.userState->has_session = true;
292                         sendmsg->payload.userState->session = client_itr->sessionId;
293                         sendmsg->payload.userState->name = strdup(client_itr->username);
294                         sendmsg->payload.userState->has_channel_id = true;
295                         sendmsg->payload.userState->channel_id = ((channel_t *)client_itr->channel)->id;
296
297                         /* Only self_mute/deaf supported */
298                         if (client_itr->deaf) {
299                                 sendmsg->payload.userState->has_self_deaf = true;
300                                 sendmsg->payload.userState->self_deaf = true;
301                         }
302                         if (client_itr->mute) {
303                                 sendmsg->payload.userState->has_self_mute = true;
304                                 sendmsg->payload.userState->self_mute = true;
305                         }
306                         if (client_itr->recording) {
307                                 sendmsg->payload.userState->has_recording = true;
308                                 sendmsg->payload.userState->recording = true;
309                         }
310                         Client_send_message(client, sendmsg);
311                 }
312
313                 /* Sync message */
314                 sendmsg = Msg_create(ServerSync);
315                 sendmsg->payload.serverSync->has_session = true;
316                 sendmsg->payload.serverSync->session = client->sessionId;
317                 sendmsg->payload.serverSync->welcome_text = strdup(getStrConf(WELCOMETEXT));
318                 sendmsg->payload.serverSync->has_max_bandwidth = true;
319                 sendmsg->payload.serverSync->max_bandwidth = getIntConf(MAX_BANDWIDTH);
320                 Client_send_message(client, sendmsg);
321
322                 /* Server config message */
323                 sendmsg = Msg_create(ServerConfig);             
324                 sendmsg->payload.serverConfig->has_allow_html = true;
325                 sendmsg->payload.serverConfig->allow_html = true; /* Support this? */
326                 sendmsg->payload.serverConfig->has_message_length = true;
327                 sendmsg->payload.serverConfig->message_length = MAX_TEXT; /* Hardcoded */
328                 sendmsg->payload.serverConfig->has_image_message_length = true;
329                 sendmsg->payload.serverConfig->image_message_length = 0; /* XXX */
330                 Client_send_message(client, sendmsg);
331
332                 Log_info_client(client, "User %s authenticated", client->username);
333                 break;
334                 
335         case Ping:
336                 if (msg->payload.ping->has_good)
337                         client->cryptState.uiRemoteGood = msg->payload.ping->good;
338                 if (msg->payload.ping->has_late)
339                         client->cryptState.uiRemoteLate = msg->payload.ping->late;
340                 if (msg->payload.ping->has_lost)
341                         client->cryptState.uiRemoteLost = msg->payload.ping->lost;
342                 if (msg->payload.ping->has_resync)
343                         client->cryptState.uiRemoteResync = msg->payload.ping->resync;
344
345                 Log_debug("Ping <-: %d %d %d %d",
346                                   client->cryptState.uiRemoteGood, client->cryptState.uiRemoteLate,
347                                   client->cryptState.uiRemoteLost, client->cryptState.uiRemoteResync
348                         );
349                 
350                 client->UDPPingAvg = msg->payload.ping->udp_ping_avg;
351                 client->UDPPingVar = msg->payload.ping->udp_ping_var;
352                 client->TCPPingAvg = msg->payload.ping->tcp_ping_avg;
353                 client->TCPPingVar = msg->payload.ping->tcp_ping_var;
354                 client->UDPPackets = msg->payload.ping->udp_packets;
355                 client->TCPPackets = msg->payload.ping->tcp_packets;
356                 
357                 sendmsg = Msg_create(Ping);
358
359                 sendmsg->payload.ping->timestamp = msg->payload.ping->timestamp;
360                 sendmsg->payload.ping->has_timestamp = true;
361                 sendmsg->payload.ping->good = client->cryptState.uiGood;
362                 sendmsg->payload.ping->has_good = true;
363                 sendmsg->payload.ping->late = client->cryptState.uiLate;
364                 sendmsg->payload.ping->has_late = true;
365                 sendmsg->payload.ping->lost = client->cryptState.uiLost;
366                 sendmsg->payload.ping->has_lost = true;
367                 sendmsg->payload.ping->resync = client->cryptState.uiResync;
368                 sendmsg->payload.ping->has_resync = true;
369
370                 Client_send_message(client, sendmsg);
371                 Log_debug("Ping ->: %d %d %d %d",
372                                   client->cryptState.uiGood, client->cryptState.uiLate,
373                                   client->cryptState.uiLost, client->cryptState.uiResync);
374
375                 break;
376         case CryptSetup:
377                 Log_debug("Voice channel crypt resync requested");
378                 if (!msg->payload.cryptSetup->has_client_nonce) {
379                         sendmsg = Msg_create(CryptSetup);
380                         sendmsg->payload.cryptSetup->has_server_nonce = true;
381                         sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.decrypt_iv;
382                         sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
383                         Client_send_message(client, sendmsg);
384                 } else {
385                         memcpy(client->cryptState.decrypt_iv, msg->payload.cryptSetup->client_nonce.data, AES_BLOCK_SIZE);
386                         client->cryptState.uiResync++;
387                 }
388                 break;
389         case UserState:
390                 target = NULL;
391                 /* Only allow state changes for for the self user unless an admin is issuing */
392                 if (msg->payload.userState->has_session &&
393                     msg->payload.userState->session != client->sessionId && !client->isAdmin) {
394                         sendPermissionDenied(client, "Permission denied");
395                         break;
396                 }
397                 if (msg->payload.userState->has_session && msg->payload.userState->session != client->sessionId) {
398                         while (Client_iterate(&target) != NULL) {
399                                 if (target->sessionId == msg->payload.userState->session)
400                                         break;
401                         }
402                         if (target == NULL) {
403                                 Log_warn("Client with sessionID %d not found", msg->payload.userState->session);
404                                 break;
405                         }
406                 }
407
408                 if (msg->payload.userState->has_user_id || msg->payload.userState->has_suppress ||
409                         msg->payload.userState->has_texture) {
410                         sendPermissionDenied(client, "Not supported by uMurmur");
411                         break;
412                 }
413
414                 if (target == NULL)
415                         target = client;
416                 
417                 msg->payload.userState->has_session = true;
418                 msg->payload.userState->session = target->sessionId;
419                 msg->payload.userState->has_actor = true;
420                 msg->payload.userState->actor = client->sessionId;
421
422                 if (msg->payload.userState->has_deaf) {
423                         target->deaf = msg->payload.userState->deaf;
424                 }
425                 if (msg->payload.userState->has_mute) {
426                         target->mute = msg->payload.userState->mute;
427                         if (!target->mute) {
428                                 msg->payload.userState->has_deaf = true;
429                                 msg->payload.userState->deaf = false;
430                                 client->deaf = false;
431                         }
432                 }
433                 if (msg->payload.userState->has_self_deaf) {
434                         client->deaf = msg->payload.userState->self_deaf;
435                 }
436                 if (msg->payload.userState->has_self_mute) {
437                         client->mute = msg->payload.userState->self_mute;
438                         if (!client->mute) {
439                                 msg->payload.userState->has_self_deaf = true;
440                                 msg->payload.userState->self_deaf = false;
441                                 client->deaf = false;
442                         }
443                 }
444                 if (msg->payload.userState->has_recording &&
445                         msg->payload.userState->recording != client->recording) {
446                         client->recording = msg->payload.userState->recording;
447                         char *message;
448                         uint32_t *tree_id;
449                         
450                         message = malloc(strlen(client->username) + 32);
451                         if (!message)
452                                 Log_fatal("Out of memory");
453                         tree_id = malloc(sizeof(uint32_t));
454                         if (!tree_id)
455                                 Log_fatal("Out of memory");
456                         *tree_id = 0;
457                         sendmsg = Msg_create(TextMessage);
458                         sendmsg->payload.textMessage->message = message;
459                         sendmsg->payload.textMessage->n_tree_id = 1;
460                         sendmsg->payload.textMessage->tree_id = tree_id;
461                         if (client->recording)
462                                 sprintf(message, "User %s started recording", client->username);
463                         else
464                                 sprintf(message, "User %s stopped recording", client->username);
465                         Client_send_message_except_ver(NULL, sendmsg, ~0x010203);
466                         sendmsg = NULL;
467                 }
468                 if (msg->payload.userState->has_channel_id) {
469                         int leave_id;
470                         channelJoinResult_t chjoin_rc = Chan_userJoin_id_test(msg->payload.userState->channel_id, client);
471                         
472                         if (chjoin_rc != CHJOIN_OK) {
473                                 if (chjoin_rc == CHJOIN_WRONGPW) {
474                                         sendPermissionDenied(client, "Wrong channel password");
475                                 }
476                                 break;
477                         }
478                         
479                         leave_id = Chan_userJoin_id(msg->payload.userState->channel_id, client);
480                         if (leave_id > 0) {
481                                 Log_debug("Removing channel ID %d", leave_id);
482                                 sendmsg = Msg_create(ChannelRemove);
483                                 sendmsg->payload.channelRemove->channel_id = leave_id;
484                         }
485                 }
486                 if (msg->payload.userState->has_plugin_context) {
487                         if (client->context)
488                                 free(client->context);
489                         client->context = malloc(msg->payload.userState->plugin_context.len);
490                         if (client->context == NULL)
491                                 Log_fatal("Out of memory");
492                         memcpy(client->context, msg->payload.userState->plugin_context.data,
493                                    msg->payload.userState->plugin_context.len);
494                         
495                         break; /* Don't inform other users about this state */
496                 }
497                 /* Re-use message */
498                 Msg_inc_ref(msg);
499                                 
500                 Client_send_message_except(NULL, msg);
501
502                 /* Need to send remove channel message _after_ UserState message */
503                 if (sendmsg != NULL)
504                         Client_send_message_except(NULL, sendmsg);
505                 break;
506                 
507         case TextMessage:
508                 msg->payload.textMessage->has_actor = true;
509                 msg->payload.textMessage->actor = client->sessionId;
510
511                 /* XXX - HTML is allowed and can't be turned off */
512                 if (msg->payload.textMessage->n_tree_id > 0) {
513                         sendPermissionDenied(client, "Tree message not supported");
514                         break;
515                 }
516                         
517                 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
518                         int i;
519                         channel_t *ch_itr;
520                         for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
521                                 ch_itr = NULL;
522                                 do {
523                                         Chan_iterate(&ch_itr);
524                                 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
525                                 if (ch_itr != NULL) {
526                                         struct dlist *itr;
527                                         list_iterate(itr, &ch_itr->clients) {
528                                                 client_t *c;
529                                                 c = list_get_entry(itr, client_t, chan_node);
530                                                 if (c != client && !c->deaf) {
531                                                         Msg_inc_ref(msg);
532                                                         Client_send_message(c, msg);
533                                                         Log_debug("Text message to session ID %d", c->sessionId);
534                                                 }
535                                         }
536                                 }
537                         } /* for */
538                 }
539                 if (msg->payload.textMessage->n_session > 0) { /* To user */
540                         int i;
541                         client_t *itr;
542                         for (i = 0; i < msg->payload.textMessage->n_session; i++) {
543                                 itr = NULL;
544                                 while (Client_iterate(&itr) != NULL) {
545                                         if (!IS_AUTH(itr))
546                                                 continue;
547                                         if (itr->sessionId == msg->payload.textMessage->session[i]) {
548                                                 if (!itr->deaf) {
549                                                         Msg_inc_ref(msg);
550                                                         Client_send_message(itr, msg);
551                                                         Log_debug("Text message to session ID %d", itr->sessionId);
552                                                 }
553                                                 break;
554                                         }
555                                 }
556                                 if (itr == NULL)
557                                         Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
558                         } /* for */
559                 }
560                 break;
561
562         case VoiceTarget:
563         {
564                 int i, j, count, targetId = msg->payload.voiceTarget->id;
565                 struct _MumbleProto__VoiceTarget__Target *target;
566
567                 if (!targetId || targetId >= 0x1f)
568                         break;
569                 Voicetarget_add_id(client, targetId);
570                 count = msg->payload.voiceTarget->n_targets;
571                 if (!count)
572                         break;
573                 for (i = 0; i < count; i++) {
574                         target = msg->payload.voiceTarget->targets[i];
575                         for (j = 0; j < target->n_session; j++)
576                                 Voicetarget_add_session(client, targetId, target->session[j]);
577                         if (target->has_channel_id) {
578                                 bool_t linked = false, children = false;
579                                 if (target->has_links)
580                                         linked = target->links;
581                                 if (target->has_children)
582                                         children = target->children;
583                                 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
584                         }
585                 }
586                 break;
587         }
588         case Version:
589                 Log_debug("Version message received");
590                 if (msg->payload.version->has_version) {
591                         client->version = msg->payload.version->version;
592                         Log_debug("Client version 0x%x", client->version);
593                 }
594                 if (msg->payload.version->release) {
595                         if (client->release) free(client->release);
596                         client->release = strdup(msg->payload.version->release);
597                         Log_debug("Client release %s", client->release);
598                 }
599                 if (msg->payload.version->os) {
600                         if (client->os) free(client->os);                       
601                         client->os = strdup(msg->payload.version->os);
602                         Log_debug("Client OS %s", client->os);
603                 }
604                 if (msg->payload.version->os_version) {
605                         if (client->os_version) free(client->os_version);                       
606                         client->os_version = strdup(msg->payload.version->os_version);
607                         Log_debug("Client OS version %s", client->os_version);
608                 }
609                 break;
610         case PermissionQuery:
611                 Msg_inc_ref(msg); /* Re-use message */
612                 msg->payload.permissionQuery->has_permissions = true;
613                 if (client->isAdmin)
614                         msg->payload.permissionQuery->permissions = PERM_ADMIN;
615                 else
616                         msg->payload.permissionQuery->permissions = PERM_DEFAULT;
617                 
618                 Client_send_message(client, msg);
619                 break;
620         case UDPTunnel:
621                 client->bUDP = false;
622                 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
623             break;
624         case ChannelState:
625         {
626                 channel_t *ch_itr, *parent, *newchan;
627                 int leave_id;           
628                 /* Don't allow any changes to existing channels */
629                 if (msg->payload.channelState->has_channel_id) {
630                         sendPermissionDenied(client, "Not supported by uMurmur");
631                         break;
632                 }
633                 /* Must have parent */
634                 if (!msg->payload.channelState->has_parent) {
635                         sendPermissionDenied(client, "Not supported by uMurmur");
636                         break;
637                 }
638                 /* Must have name */
639                 if (msg->payload.channelState->name == NULL) {
640                         sendPermissionDenied(client, "Not supported by uMurmur");
641                         break;
642                 }
643                 /* Must be temporary channel */
644                 if (msg->payload.channelState->temporary != true) {
645                         sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
646                         break;
647                 }
648                 /* Check channel name is OK */
649                 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
650                         sendPermissionDenied(client, "Channel name too long");
651                         break;
652                 }
653                         
654                 parent = Chan_fromId(msg->payload.channelState->parent);
655                 if (parent == NULL)
656                         break;
657                 ch_itr = NULL;
658                 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
659                         if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
660                                 sendPermissionDenied(client, "Channel already exists");
661                                 break;
662                         }
663                 }
664                 if (ch_itr != NULL)
665                         break;
666                 
667                 /* Disallow temporary channels as siblings to temporary channels */
668                 if (parent->temporary) {
669                         sendPermissionDenied(client, "Parent channel is temporary channel");
670                         break;
671                 }
672                         
673                 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
674                  * I don't know why so I don't do that here...
675                  */
676
677                 /* Create the channel */
678                 newchan = Chan_createChannel(msg->payload.channelState->name,
679                                                                          msg->payload.channelState->description);
680                 newchan->temporary = true;
681                 Chan_addChannel(parent, newchan);
682                 msg->payload.channelState->has_channel_id = true;
683                 msg->payload.channelState->channel_id = newchan->id;
684                 Msg_inc_ref(msg);
685                 Client_send_message_except(NULL, msg);
686
687                 /* Join the creating user */
688                 sendmsg = Msg_create(UserState);
689                 sendmsg->payload.userState->has_session = true;
690                 sendmsg->payload.userState->session = client->sessionId;
691                 sendmsg->payload.userState->has_channel_id = true;
692                 sendmsg->payload.userState->channel_id = newchan->id;
693                 Client_send_message_except(NULL, sendmsg);
694                 
695                 leave_id = Chan_userJoin(newchan, client);
696                 if (leave_id > 0) {
697                         Log_debug("Removing channel ID %d", leave_id);
698                         sendmsg = Msg_create(ChannelRemove);
699                         sendmsg->payload.channelRemove->channel_id = leave_id;
700                         Client_send_message_except(NULL, sendmsg);
701                 }
702         }               
703         break;
704
705         case UserStats:
706         {
707                 client_t *target = NULL;
708                 codec_t *codec_itr = NULL;
709                 int i;
710                 bool_t details = true;
711                 
712                 if (msg->payload.userStats->has_stats_only)
713                         details = !msg->payload.userStats->stats_only;
714                 
715                 if (!msg->payload.userStats->has_session)
716                         sendPermissionDenied(client, "Not supported by uMurmur");
717                 while (Client_iterate(&target) != NULL) {
718                         if (!IS_AUTH(target))
719                                 continue;
720                         if (target->sessionId == msg->payload.userStats->session)
721                                 break;
722                 }
723                 if (!target) /* Not found */
724                         break;
725                 
726                 /*
727                  * Differences from Murmur:
728                  * o Ignoring certificates intentionally
729                  * o Ignoring channel local determining
730                  */
731                 
732                 sendmsg = Msg_create(UserStats);
733                 sendmsg->payload.userStats->session = msg->payload.userStats->session;
734                 sendmsg->payload.userStats->from_client->has_good = true;
735                 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
736                 sendmsg->payload.userStats->from_client->has_late = true;
737                 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
738                 sendmsg->payload.userStats->from_client->has_lost = true;
739                 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
740                 sendmsg->payload.userStats->from_client->has_resync = true;
741                 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
742                 
743                 sendmsg->payload.userStats->from_server->has_good = true;
744                 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
745                 sendmsg->payload.userStats->from_server->has_late = true;
746                 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
747                 sendmsg->payload.userStats->from_server->has_lost = true;
748                 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
749                 sendmsg->payload.userStats->from_server->has_resync = true;
750                 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
751
752                 sendmsg->payload.userStats->has_udp_packets = true;
753                 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
754                 sendmsg->payload.userStats->has_udp_ping_avg = true;
755                 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
756                 sendmsg->payload.userStats->has_udp_ping_var = true;
757                 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
758                 
759                 sendmsg->payload.userStats->has_tcp_ping_avg = true;
760                 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
761                 sendmsg->payload.userStats->has_tcp_ping_var = true;
762                 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
763                 sendmsg->payload.userStats->has_tcp_packets = true;
764                 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
765                 
766                 if (details) {
767
768                         sendmsg->payload.userStats->version->has_version = true;
769                         sendmsg->payload.userStats->version->version = target->version;
770                         sendmsg->payload.userStats->version->release = strdup(target->release);
771                         sendmsg->payload.userStats->version->os = strdup(target->os);
772                         sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
773                         
774                         sendmsg->payload.userStats->n_celt_versions = target->codec_count;
775                         sendmsg->payload.userStats->celt_versions = malloc(sizeof(int32_t) * target->codec_count);
776                         if (!sendmsg->payload.userStats->celt_versions)
777                                 Log_fatal("Out of memory");
778                         i = 0;
779                         while (Client_codec_iterate(target, &codec_itr) != NULL)
780                                 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
781
782                         /* Address */
783                         sendmsg->payload.userStats->has_address = true;
784                         sendmsg->payload.userStats->address.data = malloc(sizeof(uint8_t) * 16);
785                         if (!sendmsg->payload.userStats->address.data)
786                                 Log_fatal("Out of memory");
787                         memset(sendmsg->payload.userStats->address.data, 0, 16);
788                         /* ipv4 representation as ipv6 address. Supposedly correct. */
789                         memcpy(&sendmsg->payload.userStats->address.data[12], &target->remote_tcp.sin_addr, 4);
790                         sendmsg->payload.userStats->address.len = 16;
791                 }
792                 /* BW */
793                 sendmsg->payload.userStats->has_bandwidth = true;
794                 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
795                 
796                 /* Onlinesecs */
797                 sendmsg->payload.userStats->has_onlinesecs = true;
798                 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;               
799                 /* Idlesecs */
800                 sendmsg->payload.userStats->has_idlesecs = true;
801                 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;            
802                 Client_send_message(client, sendmsg);
803         }
804         break;
805         case UserRemove:
806                 target = NULL;
807                 /* Only admin can issue this */
808                 if (!client->isAdmin) {
809                         sendPermissionDenied(client, "Permission denied");
810                         break;
811                 }
812                 while (Client_iterate(&target) != NULL) {
813                         if (target->sessionId == msg->payload.userRemove->session)
814                                 break;
815                 }
816                 if (target == NULL) {
817                         Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
818                         break;
819                 }
820                 msg->payload.userRemove->session = target->sessionId;
821                 msg->payload.userRemove->has_actor = true;
822                 msg->payload.userRemove->actor = client->sessionId;
823
824                 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
825                         Ban_UserBan(target, msg->payload.userRemove->reason);
826                 } else {
827                         Log_info("User kicked");
828                 }
829                 /* Re-use message */
830                 Msg_inc_ref(msg);
831                                 
832                 Client_send_message_except(NULL, msg);
833                 Client_close(target);
834                 break;
835                 
836                 /* Permission denied for all these messages. Not implemented. */
837         case ChannelRemove:
838         case ContextAction:
839         case ContextActionAdd:
840         case ACL:
841         case BanList:
842         case UserList:
843         case QueryUsers:
844                 sendPermissionDenied(client, "Not supported by uMurmur");
845                 break;
846                                 
847         default:
848                 Log_warn("Message %d not handled", msg->messageType);
849                 break;
850         }
851 out:
852         Msg_free(msg);
853         return;
854         
855 disconnect:
856         Msg_free(msg);
857         Client_close(client);
858 }
859