1 /* Copyright (C) 2009-2014, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2014, Thorvald Natvig <thorvald@natvig.com>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
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.
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.
39 #include "messagehandler.h"
43 #include "voicetarget.h"
47 #define MAX_USERNAME 128
49 #define NO_CELT_MESSAGE "<strong>WARNING:</strong> Your client doesn't support the CELT codec, you won't be able to talk to or hear most clients. Please make sure your client was built with CELT support."
52 extern channel_t *defaultChan;
53 extern int iCodecAlpha, iCodecBeta;
54 extern bool_t bPreferAlpha, bOpus;
56 static bool_t fake_celt_support;
58 static void sendServerReject(client_t *client, const char *reason, MumbleProto__Reject__RejectType type)
60 message_t *msg = Msg_create(Reject);
61 msg->payload.reject->reason = strdup(reason);
62 msg->payload.reject->type = type;
63 msg->payload.reject->has_type = true;
64 Client_send_message(client, msg);
66 Log_info_client(client, "Server reject reason: %s", reason);
69 static void sendPermissionDenied(client_t *client, const char *reason)
71 message_t *msg = Msg_create(PermissionDenied);
72 msg->payload.permissionDenied->has_type = true;
73 msg->payload.permissionDenied->type = MUMBLE_PROTO__PERMISSION_DENIED__DENY_TYPE__Text;
74 msg->payload.permissionDenied->reason = strdup(reason);
75 Client_send_message(client, msg);
78 static void addTokens(client_t *client, message_t *msg)
81 if (client->tokencount + msg->payload.authenticate->n_tokens < MAX_TOKENS) {
82 /* Check lengths first */
83 for (i = 0; i < msg->payload.authenticate->n_tokens; i++) {
84 if (strlen(msg->payload.authenticate->tokens[i]) > MAX_TOKENSIZE - 1) {
85 sendPermissionDenied(client, "Too long token");
90 for (i = 0; i < msg->payload.authenticate->n_tokens; i++) {
91 Log_debug("Adding token '%s' to client '%s'", msg->payload.authenticate->tokens[i], client->username);
92 Client_token_add(client, msg->payload.authenticate->tokens[i]);
96 sendPermissionDenied(client, "Too many tokens");
99 void Mh_handle_message(client_t *client, message_t *msg)
101 message_t *sendmsg = NULL;
102 channel_t *ch_itr = NULL;
103 client_t *client_itr, *target;
105 if (!client->authenticated && !(msg->messageType == Authenticate ||
106 msg->messageType == Version)) {
110 switch (msg->messageType) {
116 case PermissionQuery:
119 Timer_restart(&client->idleTime);
122 switch (msg->messageType) {
124 Log_debug("Authenticate message received");
126 if (IS_AUTH(client) || !msg->payload.authenticate->username) {
127 /* Authenticate message might be sent when a tokens are changed by the user.*/
128 Client_token_free(client); /* Clear the token list */
129 if (msg->payload.authenticate->n_tokens > 0) {
130 Log_debug("Tokens in auth message from '%s'. n_tokens = %d", client->username,
131 msg->payload.authenticate->n_tokens);
132 addTokens(client, msg);
137 if (SSLi_getSHA1Hash(client->ssl, client->hash) && Ban_isBanned(client)) {
139 SSLi_hash2hex(client->hash, hexhash);
140 Log_info("Client with hash '%s' is banned. Disconnecting", hexhash);
144 client->authenticated = true;
147 while (Client_iterate(&client_itr) != NULL) {
148 if (!IS_AUTH(client_itr))
150 if (client_itr->username && strncmp(client_itr->username, msg->payload.authenticate->username, MAX_USERNAME) == 0) {
152 sprintf(buf, "Username already in use");
153 Log_debug("Username already in use");
154 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__UsernameInUse);
158 if (strlen(getStrConf(PASSPHRASE)) > 0) {
159 if (!msg->payload.authenticate->password ||
160 (msg->payload.authenticate->password &&
161 strncmp(getStrConf(PASSPHRASE), msg->payload.authenticate->password, MAX_TEXT) != 0)) {
163 sprintf(buf, "Wrong server password");
164 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__WrongServerPW);
165 Log_debug("Wrong server password: '%s'", msg->payload.authenticate->password != NULL ?
166 msg->payload.authenticate->password : "(null)");
170 if (strlen(msg->payload.authenticate->username) == 0 ||
171 strlen(msg->payload.authenticate->username) >= MAX_USERNAME) { /* XXX - other invalid names? */
173 sprintf(buf, "Invalid username");
174 Log_debug("Invalid username");
175 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__InvalidUsername);
179 if (Client_count() >= getIntConf(MAX_CLIENTS)) {
181 snprintf(buf, 64, "Server is full (max %d users)", getIntConf(MAX_CLIENTS));
182 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__ServerFull);
187 client->username = strdup(msg->payload.authenticate->username);
190 if (msg->payload.authenticate->n_tokens > 0)
191 addTokens(client, msg);
193 /* Check if admin PW among tokens */
194 if (strlen(getStrConf(ADMIN_PASSPHRASE)) > 0 &&
195 Client_token_match(client, getStrConf(ADMIN_PASSPHRASE))) {
196 client->isAdmin = true;
197 Log_info_client(client, "User provided admin password");
200 /* Setup UDP encryption */
201 CryptState_init(&client->cryptState);
202 CryptState_genKey(&client->cryptState);
203 sendmsg = Msg_create(CryptSetup);
204 sendmsg->payload.cryptSetup->has_key = true;
205 sendmsg->payload.cryptSetup->key.data = client->cryptState.raw_key;
206 sendmsg->payload.cryptSetup->key.len = AES_BLOCK_SIZE;
207 sendmsg->payload.cryptSetup->has_server_nonce = true;
208 sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.encrypt_iv;
209 sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
210 sendmsg->payload.cryptSetup->has_client_nonce = true;
211 sendmsg->payload.cryptSetup->client_nonce.data = client->cryptState.decrypt_iv;
212 sendmsg->payload.cryptSetup->client_nonce.len = AES_BLOCK_SIZE;
213 Client_send_message(client, sendmsg);
216 Chan_userJoin(defaultChan, client); /* Join default channel */
219 Log_debug("Client %d has %d CELT codecs", client->sessionId,
220 msg->payload.authenticate->n_celt_versions);
221 if (msg->payload.authenticate->n_celt_versions > 0) {
224 client->codec_count = msg->payload.authenticate->n_celt_versions;
226 for (i = 0; i < client->codec_count; i++)
227 Client_codec_add(client, msg->payload.authenticate->celt_versions[i]);
229 while (Client_codec_iterate(client, &codec_itr) != NULL)
230 Log_debug("Client %d CELT codec ver 0x%x", client->sessionId, codec_itr->codec);
233 Client_codec_add(client, (int32_t)0x8000000b);
234 client->codec_count = 1;
235 fake_celt_support = true;
237 if (msg->payload.authenticate->opus)
238 client->bOpus = true;
240 recheckCodecVersions(client);
242 sendmsg = Msg_create(CodecVersion);
243 sendmsg->payload.codecVersion->alpha = iCodecAlpha;
244 sendmsg->payload.codecVersion->beta = iCodecBeta;
245 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
246 sendmsg->payload.codecVersion->has_opus = true;
247 sendmsg->payload.codecVersion->opus = bOpus;
248 Client_send_message(client, sendmsg);
250 if (!bOpus && client->bOpus && fake_celt_support) {
251 Client_textmessage(client, NO_CELT_MESSAGE);
254 /* Iterate channels and send channel info */
256 while (Chan_iterate(&ch_itr) != NULL) {
257 sendmsg = Msg_create(ChannelState);
258 sendmsg->payload.channelState->has_channel_id = true;
259 sendmsg->payload.channelState->channel_id = ch_itr->id;
260 if (ch_itr->id != 0) {
261 sendmsg->payload.channelState->has_parent = true;
262 sendmsg->payload.channelState->parent = ch_itr->parent->id;
264 sendmsg->payload.channelState->name = strdup(ch_itr->name);
266 sendmsg->payload.channelState->description = strdup(ch_itr->desc);
267 if (ch_itr->position != 0) {
268 sendmsg->payload.channelState->has_position = true;
269 sendmsg->payload.channelState->position = ch_itr->position;
271 Log_debug("Send channel info: %s", sendmsg->payload.channelState->name);
272 Client_send_message(client, sendmsg);
275 /* Iterate channels and send channel links info */
277 while (Chan_iterate(&ch_itr) != NULL) {
278 if (ch_itr->linkcount > 0) { /* Has links */
283 sendmsg = Msg_create(ChannelState);
284 sendmsg->payload.channelState->has_channel_id = true;
285 sendmsg->payload.channelState->channel_id = ch_itr->id;
286 sendmsg->payload.channelState->n_links = ch_itr->linkcount;
288 links = (uint32_t*)Memory_safeMalloc(
291 list_iterate(itr, &ch_itr->channel_links) { /* Iterate links */
294 chl = list_get_entry(itr, channellist_t, node);
298 sendmsg->payload.channelState->links = links;
299 Client_send_message(client, sendmsg);
303 /* Send user state for connecting user to other users */
304 sendmsg = Msg_create(UserState);
305 sendmsg->payload.userState->has_session = true;
306 sendmsg->payload.userState->session = client->sessionId;
307 sendmsg->payload.userState->name = strdup(client->username);
308 sendmsg->payload.userState->has_channel_id = true;
309 sendmsg->payload.userState->channel_id = ((channel_t *)client->channel)->id;
311 if (defaultChan->silent) {
312 sendmsg->payload.userState->has_suppress = true;
313 sendmsg->payload.userState->suppress = true;
316 Client_send_message_except(client, sendmsg);
319 while (Client_iterate(&client_itr) != NULL) {
320 if (!IS_AUTH(client_itr))
322 sendmsg = Msg_create(UserState);
323 sendmsg->payload.userState->has_session = true;
324 sendmsg->payload.userState->session = client_itr->sessionId;
325 sendmsg->payload.userState->name = strdup(client_itr->username);
326 sendmsg->payload.userState->has_channel_id = true;
327 sendmsg->payload.userState->channel_id = ((channel_t *)client_itr->channel)->id;
328 sendmsg->payload.userState->has_suppress = ((channel_t *)client_itr->channel)->silent;
329 sendmsg->payload.userState->suppress = ((channel_t *)client_itr->channel)->silent;
331 client_itr->isSuppressed = ((channel_t *)client_itr->channel)->silent;
333 if (client_itr->self_deaf) {
334 sendmsg->payload.userState->has_self_deaf = true;
335 sendmsg->payload.userState->self_deaf = true;
337 if (client_itr->self_mute) {
338 sendmsg->payload.userState->has_self_mute = true;
339 sendmsg->payload.userState->self_mute = true;
341 if (client_itr->deaf) {
342 sendmsg->payload.userState->has_deaf = true;
343 sendmsg->payload.userState->deaf = true;
345 if (client_itr->mute) {
346 sendmsg->payload.userState->has_mute = true;
347 sendmsg->payload.userState->mute = true;
349 if (client_itr->recording) {
350 sendmsg->payload.userState->has_recording = true;
351 sendmsg->payload.userState->recording = true;
353 Client_send_message(client, sendmsg);
357 sendmsg = Msg_create(ServerSync);
358 sendmsg->payload.serverSync->has_session = true;
359 sendmsg->payload.serverSync->session = client->sessionId;
360 sendmsg->payload.serverSync->welcome_text = strdup(getStrConf(WELCOMETEXT));
361 sendmsg->payload.serverSync->has_max_bandwidth = true;
362 sendmsg->payload.serverSync->max_bandwidth = getIntConf(MAX_BANDWIDTH);
363 Client_send_message(client, sendmsg);
365 /* Server config message */
366 sendmsg = Msg_create(ServerConfig);
367 sendmsg->payload.serverConfig->has_allow_html = true;
368 sendmsg->payload.serverConfig->allow_html = true; /* Support this? */
369 sendmsg->payload.serverConfig->has_message_length = true;
370 sendmsg->payload.serverConfig->message_length = MAX_TEXT; /* Hardcoded */
371 sendmsg->payload.serverConfig->has_image_message_length = true;
372 sendmsg->payload.serverConfig->image_message_length = 0; /* XXX */
373 Client_send_message(client, sendmsg);
375 Log_info_client(client, "User %s authenticated", client->username);
379 if (msg->payload.ping->has_good)
380 client->cryptState.uiRemoteGood = msg->payload.ping->good;
381 if (msg->payload.ping->has_late)
382 client->cryptState.uiRemoteLate = msg->payload.ping->late;
383 if (msg->payload.ping->has_lost)
384 client->cryptState.uiRemoteLost = msg->payload.ping->lost;
385 if (msg->payload.ping->has_resync)
386 client->cryptState.uiRemoteResync = msg->payload.ping->resync;
388 Log_debug("Ping <-: %d %d %d %d",
389 client->cryptState.uiRemoteGood, client->cryptState.uiRemoteLate,
390 client->cryptState.uiRemoteLost, client->cryptState.uiRemoteResync
393 client->UDPPingAvg = msg->payload.ping->udp_ping_avg;
394 client->UDPPingVar = msg->payload.ping->udp_ping_var;
395 client->TCPPingAvg = msg->payload.ping->tcp_ping_avg;
396 client->TCPPingVar = msg->payload.ping->tcp_ping_var;
397 client->UDPPackets = msg->payload.ping->udp_packets;
398 client->TCPPackets = msg->payload.ping->tcp_packets;
400 sendmsg = Msg_create(Ping);
402 sendmsg->payload.ping->timestamp = msg->payload.ping->timestamp;
403 sendmsg->payload.ping->has_timestamp = true;
404 sendmsg->payload.ping->good = client->cryptState.uiGood;
405 sendmsg->payload.ping->has_good = true;
406 sendmsg->payload.ping->late = client->cryptState.uiLate;
407 sendmsg->payload.ping->has_late = true;
408 sendmsg->payload.ping->lost = client->cryptState.uiLost;
409 sendmsg->payload.ping->has_lost = true;
410 sendmsg->payload.ping->resync = client->cryptState.uiResync;
411 sendmsg->payload.ping->has_resync = true;
413 Client_send_message(client, sendmsg);
414 Log_debug("Ping ->: %d %d %d %d",
415 client->cryptState.uiGood, client->cryptState.uiLate,
416 client->cryptState.uiLost, client->cryptState.uiResync);
420 Log_debug("Voice channel crypt resync requested");
421 if (!msg->payload.cryptSetup->has_client_nonce) {
422 sendmsg = Msg_create(CryptSetup);
423 sendmsg->payload.cryptSetup->has_server_nonce = true;
424 sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.decrypt_iv;
425 sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
426 Client_send_message(client, sendmsg);
428 memcpy(client->cryptState.decrypt_iv, msg->payload.cryptSetup->client_nonce.data, AES_BLOCK_SIZE);
429 client->cryptState.uiResync++;
434 /* Only allow state changes for for the self user unless an admin is issuing */
435 if (msg->payload.userState->has_session &&
436 msg->payload.userState->session != client->sessionId && !client->isAdmin) {
437 sendPermissionDenied(client, "Permission denied");
440 if (msg->payload.userState->has_session && msg->payload.userState->session != client->sessionId) {
441 while (Client_iterate(&target) != NULL) {
442 if (target->sessionId == msg->payload.userState->session)
445 if (target == NULL) {
446 Log_warn("Client with sessionID %d not found", msg->payload.userState->session);
451 if (msg->payload.userState->has_user_id || msg->payload.userState->has_suppress ||
452 msg->payload.userState->has_priority_speaker || msg->payload.userState->has_texture) {
453 sendPermissionDenied(client, "Not supported by uMurmur");
460 msg->payload.userState->has_session = true;
461 msg->payload.userState->session = target->sessionId;
462 msg->payload.userState->has_actor = true;
463 msg->payload.userState->actor = client->sessionId;
465 if (msg->payload.userState->has_deaf) {
466 target->deaf = msg->payload.userState->deaf;
468 msg->payload.userState->has_mute = true;
469 msg->payload.userState->mute = true;
472 if (msg->payload.userState->has_mute) {
473 target->mute = msg->payload.userState->mute;
475 msg->payload.userState->has_deaf = true;
476 msg->payload.userState->deaf = false;
477 target->deaf = false;
480 if (msg->payload.userState->has_self_deaf) {
481 client->self_deaf = msg->payload.userState->self_deaf;
482 if (client->self_deaf) {
483 msg->payload.userState->has_self_mute = true;
484 msg->payload.userState->self_mute = true;
487 if (msg->payload.userState->has_self_mute) {
488 client->self_mute = msg->payload.userState->self_mute;
489 if (!client->self_mute) {
490 msg->payload.userState->has_self_deaf = true;
491 msg->payload.userState->self_deaf = false;
492 client->self_deaf = false;
495 if (msg->payload.userState->has_recording &&
496 msg->payload.userState->recording != client->recording) {
497 client->recording = msg->payload.userState->recording;
501 message = Memory_safeMalloc(1, strlen(client->username) + 32);
502 tree_id = Memory_safeMalloc(1, sizeof(uint32_t));
504 sendmsg = Msg_create(TextMessage);
505 sendmsg->payload.textMessage->message = message;
506 sendmsg->payload.textMessage->n_tree_id = 1;
507 sendmsg->payload.textMessage->tree_id = tree_id;
508 if (client->recording)
509 sprintf(message, "User %s started recording", client->username);
511 sprintf(message, "User %s stopped recording", client->username);
512 Client_send_message_except_ver(NULL, sendmsg, ~0x010203);
515 if (msg->payload.userState->has_channel_id) {
518 channelJoinResult_t result = Chan_userJoin_id_test(msg->payload.userState->channel_id, target);
520 if (result.CHJOIN_NOENTER || result.CHJOIN_NOTFOUND)
523 if (result.CHJOIN_WRONGPW) {
524 if (target == client && !client->isAdmin) {
525 sendPermissionDenied(client, "Wrong channel password");
528 /* Tricky one: if user hasn't the password, but is moved to the channel by admin then let
529 * the user in. Also let admin user in regardless of channel password.
530 * Take no action on other errors.
532 else if (!client->isAdmin)
536 leave_id = Chan_userJoin_id(msg->payload.userState->channel_id, target);
538 Log_debug("Removing channel ID %d", leave_id);
539 sendmsg = Msg_create(ChannelRemove);
540 sendmsg->payload.channelRemove->channel_id = leave_id;
543 if (result.CHJOIN_SILENT) {
544 if (!target->isSuppressed) {
545 msg->payload.userState->has_suppress = true;
546 msg->payload.userState->suppress = true;
547 target->isSuppressed = true;
550 else if (target->isSuppressed) {
551 msg->payload.userState->has_suppress = true;
552 msg->payload.userState->suppress = false;
553 target->isSuppressed = false;
556 if (msg->payload.userState->has_plugin_context) {
558 free(client->context);
559 client->context = Memory_safeMalloc(1, msg->payload.userState->plugin_context.len);
560 memcpy(client->context, msg->payload.userState->plugin_context.data,
561 msg->payload.userState->plugin_context.len);
563 break; /* Don't inform other users about this state */
568 Client_send_message_except(NULL, msg);
570 /* Need to send remove channel message _after_ UserState message */
572 Client_send_message_except(NULL, sendmsg);
576 if (!getBoolConf(ALLOW_TEXTMESSAGE))
578 msg->payload.textMessage->has_actor = true;
579 msg->payload.textMessage->actor = client->sessionId;
581 /* XXX - HTML is allowed and can't be turned off */
582 if (msg->payload.textMessage->n_tree_id > 0) {
583 sendPermissionDenied(client, "Tree message not supported");
587 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
590 for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
593 Chan_iterate(&ch_itr);
594 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
595 if (ch_itr != NULL) {
597 list_iterate(itr, &ch_itr->clients) {
599 c = list_get_entry(itr, client_t, chan_node);
600 if (c != client && !c->deaf && !c->self_deaf) {
602 Client_send_message(c, msg);
603 Log_debug("Text message to session ID %d", c->sessionId);
609 if (msg->payload.textMessage->n_session > 0) { /* To user */
612 for (i = 0; i < msg->payload.textMessage->n_session; i++) {
614 while (Client_iterate(&itr) != NULL) {
617 if (itr->sessionId == msg->payload.textMessage->session[i]) {
618 if (!itr->deaf && !itr->self_deaf) {
620 Client_send_message(itr, msg);
621 Log_debug("Text message to session ID %d", itr->sessionId);
627 Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
634 int i, j, count, targetId = msg->payload.voiceTarget->id;
635 struct _MumbleProto__VoiceTarget__Target *target;
637 if (!targetId || targetId >= 0x1f)
639 Voicetarget_add_id(client, targetId);
640 count = msg->payload.voiceTarget->n_targets;
643 for (i = 0; i < count; i++) {
644 target = msg->payload.voiceTarget->targets[i];
645 for (j = 0; j < target->n_session; j++)
646 Voicetarget_add_session(client, targetId, target->session[j]);
647 if (target->has_channel_id) {
648 bool_t linked = false, children = false;
649 if (target->has_links)
650 linked = target->links;
651 if (target->has_children)
652 children = target->children;
653 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
659 Log_debug("Version message received");
660 if (msg->payload.version->has_version) {
661 client->version = msg->payload.version->version;
662 Log_debug("Client version 0x%x", client->version);
664 if (msg->payload.version->release) {
665 if (client->release) free(client->release);
666 client->release = strdup(msg->payload.version->release);
667 Log_debug("Client release %s", client->release);
669 if (msg->payload.version->os) {
670 if (client->os) free(client->os);
671 client->os = strdup(msg->payload.version->os);
672 Log_debug("Client OS %s", client->os);
674 if (msg->payload.version->os_version) {
675 if (client->os_version) free(client->os_version);
676 client->os_version = strdup(msg->payload.version->os_version);
677 Log_debug("Client OS version %s", client->os_version);
680 case PermissionQuery:
681 Msg_inc_ref(msg); /* Re-use message */
682 msg->payload.permissionQuery->has_permissions = true;
685 msg->payload.permissionQuery->permissions = PERM_ADMIN;
687 msg->payload.permissionQuery->permissions = PERM_DEFAULT;
689 if (!getBoolConf(ALLOW_TEXTMESSAGE))
690 msg->payload.permissionQuery->permissions &= ~PERM_TEXTMESSAGE;
691 if (!getBoolConf(ENABLE_BAN))
692 msg->payload.permissionQuery->permissions &= ~PERM_BAN;
694 Client_send_message(client, msg);
697 client->bUDP = false;
698 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
702 channel_t *ch_itr, *parent, *newchan;
704 /* Don't allow any changes to existing channels */
705 if (msg->payload.channelState->has_channel_id) {
706 sendPermissionDenied(client, "Not supported by uMurmur");
709 /* Must have parent */
710 if (!msg->payload.channelState->has_parent) {
711 sendPermissionDenied(client, "Not supported by uMurmur");
715 if (msg->payload.channelState->name == NULL) {
716 sendPermissionDenied(client, "Not supported by uMurmur");
719 /* Must be temporary channel */
720 if (msg->payload.channelState->temporary != true) {
721 sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
724 /* Check channel name is OK */
725 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
726 sendPermissionDenied(client, "Channel name too long");
730 parent = Chan_fromId(msg->payload.channelState->parent);
734 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
735 if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
736 sendPermissionDenied(client, "Channel already exists");
743 /* Disallow temporary channels as siblings to temporary channels */
744 if (parent->temporary) {
745 sendPermissionDenied(client, "Parent channel is temporary channel");
749 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
750 * I don't know why so I don't do that here...
753 /* Create the channel */
754 newchan = Chan_createChannel(msg->payload.channelState->name,
755 msg->payload.channelState->description);
756 newchan->temporary = true;
757 if (msg->payload.channelState->has_position)
758 newchan->position = msg->payload.channelState->position;
759 Chan_addChannel(parent, newchan);
760 msg->payload.channelState->has_channel_id = true;
761 msg->payload.channelState->channel_id = newchan->id;
763 Client_send_message_except(NULL, msg);
765 /* Join the creating user */
766 sendmsg = Msg_create(UserState);
767 sendmsg->payload.userState->has_session = true;
768 sendmsg->payload.userState->session = client->sessionId;
769 sendmsg->payload.userState->has_channel_id = true;
770 sendmsg->payload.userState->channel_id = newchan->id;
772 if (client->isSuppressed) {
773 sendmsg->payload.userState->has_suppress = true;
774 sendmsg->payload.userState->suppress = false;
775 client->isSuppressed = false;
778 Client_send_message_except(NULL, sendmsg);
780 leave_id = Chan_userJoin(newchan, client);
782 Log_debug("Removing channel ID %d", leave_id);
783 sendmsg = Msg_create(ChannelRemove);
784 sendmsg->payload.channelRemove->channel_id = leave_id;
785 Client_send_message_except(NULL, sendmsg);
792 client_t *target = NULL;
793 codec_t *codec_itr = NULL;
795 bool_t details = true;
797 if (msg->payload.userStats->has_stats_only)
798 details = !msg->payload.userStats->stats_only;
800 if (!msg->payload.userStats->has_session)
801 sendPermissionDenied(client, "Not supported by uMurmur");
802 while (Client_iterate(&target) != NULL) {
803 if (!IS_AUTH(target))
805 if (target->sessionId == msg->payload.userStats->session)
808 if (!target) /* Not found */
812 * Differences from Murmur:
813 * o Ignoring certificates intentionally
814 * o Ignoring channel local determining
817 sendmsg = Msg_create(UserStats);
818 sendmsg->payload.userStats->session = msg->payload.userStats->session;
819 sendmsg->payload.userStats->from_client->has_good = true;
820 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
821 sendmsg->payload.userStats->from_client->has_late = true;
822 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
823 sendmsg->payload.userStats->from_client->has_lost = true;
824 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
825 sendmsg->payload.userStats->from_client->has_resync = true;
826 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
828 sendmsg->payload.userStats->from_server->has_good = true;
829 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
830 sendmsg->payload.userStats->from_server->has_late = true;
831 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
832 sendmsg->payload.userStats->from_server->has_lost = true;
833 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
834 sendmsg->payload.userStats->from_server->has_resync = true;
835 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
837 sendmsg->payload.userStats->has_udp_packets = true;
838 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
839 sendmsg->payload.userStats->has_udp_ping_avg = true;
840 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
841 sendmsg->payload.userStats->has_udp_ping_var = true;
842 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
844 sendmsg->payload.userStats->has_tcp_ping_avg = true;
845 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
846 sendmsg->payload.userStats->has_tcp_ping_var = true;
847 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
848 sendmsg->payload.userStats->has_tcp_packets = true;
849 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
853 sendmsg->payload.userStats->version->has_version = true;
854 sendmsg->payload.userStats->version->version = target->version;
856 sendmsg->payload.userStats->version->release = strdup(target->release);
858 sendmsg->payload.userStats->version->os = strdup(target->os);
859 if (target->os_version)
860 sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
862 sendmsg->payload.userStats->n_celt_versions = target->codec_count;
863 sendmsg->payload.userStats->celt_versions
864 = Memory_safeMalloc(target->codec_count, sizeof(int32_t));
866 while (Client_codec_iterate(target, &codec_itr) != NULL)
867 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
869 sendmsg->payload.userStats->has_opus = true;
870 sendmsg->payload.userStats->opus = target->bOpus;
873 if (getBoolConf(SHOW_ADDRESSES)) {
874 sendmsg->payload.userStats->has_address = true;
875 sendmsg->payload.userStats->address.data
876 = Memory_safeMalloc(16, sizeof(uint8_t));
877 memset(sendmsg->payload.userStats->address.data, 0, 16);
878 /* ipv4 representation as ipv6 address. Supposedly correct. */
879 memset(&sendmsg->payload.userStats->address.data[10], 0xff, 2); /* IPv4 */
880 if(target->remote_tcp.ss_family == AF_INET)
881 memcpy(&sendmsg->payload.userStats->address.data[12], &((struct sockaddr_in*)&target->remote_tcp)->sin_addr, 4);
883 memcpy(&sendmsg->payload.userStats->address.data[0], &((struct sockaddr_in6*)&target->remote_tcp)->sin6_addr, 16);
884 sendmsg->payload.userStats->address.len = 16;
886 sendmsg->payload.userStats->has_address = false;
890 sendmsg->payload.userStats->has_bandwidth = true;
891 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
894 sendmsg->payload.userStats->has_onlinesecs = true;
895 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;
897 sendmsg->payload.userStats->has_idlesecs = true;
898 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;
899 Client_send_message(client, sendmsg);
904 /* Only admin can issue this */
905 if (!client->isAdmin) {
906 sendPermissionDenied(client, "Permission denied");
909 while (Client_iterate(&target) != NULL) {
910 if (target->sessionId == msg->payload.userRemove->session)
913 if (target == NULL) {
914 Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
917 msg->payload.userRemove->session = target->sessionId;
918 msg->payload.userRemove->has_actor = true;
919 msg->payload.userRemove->actor = client->sessionId;
921 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
922 if (!getBoolConf(ENABLE_BAN))
923 sendPermissionDenied(client, "Permission denied");
925 Ban_UserBan(target, msg->payload.userRemove->reason);
927 Log_info_client(target, "User kicked. Reason: '%s'",
928 strlen(msg->payload.userRemove->reason) == 0 ? "N/A" : msg->payload.userRemove->reason);
933 Client_send_message_except(NULL, msg);
934 Client_close(target);
937 /* Only admin can issue this */
938 if (!client->isAdmin) {
939 sendPermissionDenied(client, "Permission denied");
942 if (!getBoolConf(ENABLE_BAN)) {
943 sendPermissionDenied(client, "Permission denied");
946 if (msg->payload.banList->has_query && msg->payload.banList->query) {
947 /* Create banlist message and add banentrys */
948 sendmsg = Ban_getBanList();
949 Client_send_message(client, sendmsg);
951 /* Clear banlist and set the new one */
953 Ban_putBanList(msg, msg->payload.banList->n_bans);
957 /* Permission denied for all these messages. Not implemented. */
960 case ContextActionAdd:
964 sendPermissionDenied(client, "Not supported by uMurmur");
968 Log_warn("Message %d not handled", msg->messageType);
977 Client_close(client);