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 = 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 = client_itr->channel->id;
328 sendmsg->payload.userState->has_suppress = client_itr->channel->silent;
329 sendmsg->payload.userState->suppress = client_itr->channel->silent;
331 client_itr->isSuppressed = 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) {
557 free(client->context);
558 client->context = Memory_safeMalloc(1, msg->payload.userState->plugin_context.len);
559 memcpy(client->context, msg->payload.userState->plugin_context.data,
560 msg->payload.userState->plugin_context.len);
562 break; /* Don't inform other users about this state */
567 Client_send_message_except(NULL, msg);
569 /* Need to send remove channel message _after_ UserState message */
571 Client_send_message_except(NULL, sendmsg);
575 if (!getBoolConf(ALLOW_TEXTMESSAGE))
577 msg->payload.textMessage->has_actor = true;
578 msg->payload.textMessage->actor = client->sessionId;
580 /* XXX - HTML is allowed and can't be turned off */
581 if (msg->payload.textMessage->n_tree_id > 0) {
582 sendPermissionDenied(client, "Tree message not supported");
586 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
589 for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
592 Chan_iterate(&ch_itr);
593 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
594 if (ch_itr != NULL) {
596 list_iterate(itr, &ch_itr->clients) {
598 c = list_get_entry(itr, client_t, chan_node);
599 if (c != client && !c->deaf && !c->self_deaf) {
601 Client_send_message(c, msg);
602 Log_debug("Text message to session ID %d", c->sessionId);
608 if (msg->payload.textMessage->n_session > 0) { /* To user */
611 for (i = 0; i < msg->payload.textMessage->n_session; i++) {
613 while (Client_iterate(&itr) != NULL) {
616 if (itr->sessionId == msg->payload.textMessage->session[i]) {
617 if (!itr->deaf && !itr->self_deaf) {
619 Client_send_message(itr, msg);
620 Log_debug("Text message to session ID %d", itr->sessionId);
626 Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
633 int i, j, count, targetId = msg->payload.voiceTarget->id;
634 struct _MumbleProto__VoiceTarget__Target *target;
636 if (!targetId || targetId >= 0x1f)
638 Voicetarget_add_id(client, targetId);
639 count = msg->payload.voiceTarget->n_targets;
642 for (i = 0; i < count; i++) {
643 target = msg->payload.voiceTarget->targets[i];
644 for (j = 0; j < target->n_session; j++)
645 Voicetarget_add_session(client, targetId, target->session[j]);
646 if (target->has_channel_id) {
647 bool_t linked = false, children = false;
648 if (target->has_links)
649 linked = target->links;
650 if (target->has_children)
651 children = target->children;
652 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
658 Log_debug("Version message received");
659 if (msg->payload.version->has_version) {
660 client->version = msg->payload.version->version;
661 Log_debug("Client version 0x%x", client->version);
663 if (msg->payload.version->release) {
664 free(client->release);
665 client->release = strdup(msg->payload.version->release);
666 Log_debug("Client release %s", client->release);
668 if (msg->payload.version->os) {
670 client->os = strdup(msg->payload.version->os);
671 Log_debug("Client OS %s", client->os);
673 if (msg->payload.version->os_version) {
674 free(client->os_version);
675 client->os_version = strdup(msg->payload.version->os_version);
676 Log_debug("Client OS version %s", client->os_version);
679 case PermissionQuery:
680 Msg_inc_ref(msg); /* Re-use message */
681 msg->payload.permissionQuery->has_permissions = true;
684 msg->payload.permissionQuery->permissions = PERM_ADMIN;
686 msg->payload.permissionQuery->permissions = PERM_DEFAULT;
688 if (!getBoolConf(ALLOW_TEXTMESSAGE))
689 msg->payload.permissionQuery->permissions &= ~PERM_TEXTMESSAGE;
690 if (!getBoolConf(ENABLE_BAN))
691 msg->payload.permissionQuery->permissions &= ~PERM_BAN;
693 Client_send_message(client, msg);
696 client->bUDP = false;
697 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
701 channel_t *ch_itr, *parent, *newchan;
703 /* Don't allow any changes to existing channels */
704 if (msg->payload.channelState->has_channel_id) {
705 sendPermissionDenied(client, "Not supported by uMurmur");
708 /* Must have parent */
709 if (!msg->payload.channelState->has_parent) {
710 sendPermissionDenied(client, "Not supported by uMurmur");
714 if (msg->payload.channelState->name == NULL) {
715 sendPermissionDenied(client, "Not supported by uMurmur");
718 /* Must be temporary channel */
719 if (msg->payload.channelState->temporary != true) {
720 sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
723 /* Check channel name is OK */
724 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
725 sendPermissionDenied(client, "Channel name too long");
729 parent = Chan_fromId(msg->payload.channelState->parent);
733 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
734 if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
735 sendPermissionDenied(client, "Channel already exists");
742 /* Disallow temporary channels as siblings to temporary channels */
743 if (parent->temporary) {
744 sendPermissionDenied(client, "Parent channel is temporary channel");
748 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
749 * I don't know why so I don't do that here...
752 /* Create the channel */
753 newchan = Chan_createChannel(msg->payload.channelState->name,
754 msg->payload.channelState->description);
755 newchan->temporary = true;
756 if (msg->payload.channelState->has_position)
757 newchan->position = msg->payload.channelState->position;
758 Chan_addChannel(parent, newchan);
759 msg->payload.channelState->has_channel_id = true;
760 msg->payload.channelState->channel_id = newchan->id;
762 Client_send_message_except(NULL, msg);
764 /* Join the creating user */
765 sendmsg = Msg_create(UserState);
766 sendmsg->payload.userState->has_session = true;
767 sendmsg->payload.userState->session = client->sessionId;
768 sendmsg->payload.userState->has_channel_id = true;
769 sendmsg->payload.userState->channel_id = newchan->id;
771 if (client->isSuppressed) {
772 sendmsg->payload.userState->has_suppress = true;
773 sendmsg->payload.userState->suppress = false;
774 client->isSuppressed = false;
777 Client_send_message_except(NULL, sendmsg);
779 leave_id = Chan_userJoin(newchan, client);
781 Log_debug("Removing channel ID %d", leave_id);
782 sendmsg = Msg_create(ChannelRemove);
783 sendmsg->payload.channelRemove->channel_id = leave_id;
784 Client_send_message_except(NULL, sendmsg);
791 client_t *target = NULL;
792 codec_t *codec_itr = NULL;
794 bool_t details = true;
796 if (msg->payload.userStats->has_stats_only)
797 details = !msg->payload.userStats->stats_only;
799 if (!msg->payload.userStats->has_session)
800 sendPermissionDenied(client, "Not supported by uMurmur");
801 while (Client_iterate(&target) != NULL) {
802 if (!IS_AUTH(target))
804 if (target->sessionId == msg->payload.userStats->session)
807 if (!target) /* Not found */
811 * Differences from Murmur:
812 * o Ignoring certificates intentionally
813 * o Ignoring channel local determining
816 sendmsg = Msg_create(UserStats);
817 sendmsg->payload.userStats->session = msg->payload.userStats->session;
818 sendmsg->payload.userStats->from_client->has_good = true;
819 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
820 sendmsg->payload.userStats->from_client->has_late = true;
821 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
822 sendmsg->payload.userStats->from_client->has_lost = true;
823 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
824 sendmsg->payload.userStats->from_client->has_resync = true;
825 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
827 sendmsg->payload.userStats->from_server->has_good = true;
828 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
829 sendmsg->payload.userStats->from_server->has_late = true;
830 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
831 sendmsg->payload.userStats->from_server->has_lost = true;
832 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
833 sendmsg->payload.userStats->from_server->has_resync = true;
834 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
836 sendmsg->payload.userStats->has_udp_packets = true;
837 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
838 sendmsg->payload.userStats->has_udp_ping_avg = true;
839 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
840 sendmsg->payload.userStats->has_udp_ping_var = true;
841 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
843 sendmsg->payload.userStats->has_tcp_ping_avg = true;
844 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
845 sendmsg->payload.userStats->has_tcp_ping_var = true;
846 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
847 sendmsg->payload.userStats->has_tcp_packets = true;
848 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
852 sendmsg->payload.userStats->version->has_version = true;
853 sendmsg->payload.userStats->version->version = target->version;
855 sendmsg->payload.userStats->version->release = strdup(target->release);
857 sendmsg->payload.userStats->version->os = strdup(target->os);
858 if (target->os_version)
859 sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
861 sendmsg->payload.userStats->n_celt_versions = target->codec_count;
862 sendmsg->payload.userStats->celt_versions
863 = Memory_safeMalloc(target->codec_count, sizeof(int32_t));
865 while (Client_codec_iterate(target, &codec_itr) != NULL)
866 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
868 sendmsg->payload.userStats->has_opus = true;
869 sendmsg->payload.userStats->opus = target->bOpus;
872 if (getBoolConf(SHOW_ADDRESSES)) {
873 sendmsg->payload.userStats->has_address = true;
874 sendmsg->payload.userStats->address.data
875 = Memory_safeMalloc(16, sizeof(uint8_t));
876 memset(sendmsg->payload.userStats->address.data, 0, 16);
877 /* ipv4 representation as ipv6 address. Supposedly correct. */
878 memset(&sendmsg->payload.userStats->address.data[10], 0xff, 2); /* IPv4 */
879 if(target->remote_tcp.ss_family == AF_INET)
880 memcpy(&sendmsg->payload.userStats->address.data[12], &((struct sockaddr_in*)&target->remote_tcp)->sin_addr, 4);
882 memcpy(&sendmsg->payload.userStats->address.data[0], &((struct sockaddr_in6*)&target->remote_tcp)->sin6_addr, 16);
883 sendmsg->payload.userStats->address.len = 16;
885 sendmsg->payload.userStats->has_address = false;
889 sendmsg->payload.userStats->has_bandwidth = true;
890 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
893 sendmsg->payload.userStats->has_onlinesecs = true;
894 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;
896 sendmsg->payload.userStats->has_idlesecs = true;
897 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;
898 Client_send_message(client, sendmsg);
903 /* Only admin can issue this */
904 if (!client->isAdmin) {
905 sendPermissionDenied(client, "Permission denied");
908 while (Client_iterate(&target) != NULL) {
909 if (target->sessionId == msg->payload.userRemove->session)
912 if (target == NULL) {
913 Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
916 msg->payload.userRemove->session = target->sessionId;
917 msg->payload.userRemove->has_actor = true;
918 msg->payload.userRemove->actor = client->sessionId;
920 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
921 if (!getBoolConf(ENABLE_BAN))
922 sendPermissionDenied(client, "Permission denied");
924 Ban_UserBan(target, msg->payload.userRemove->reason);
926 Log_info_client(target, "User kicked. Reason: '%s'",
927 strlen(msg->payload.userRemove->reason) == 0 ? "N/A" : msg->payload.userRemove->reason);
932 Client_send_message_except(NULL, msg);
933 Client_close(target);
936 /* Only admin can issue this */
937 if (!client->isAdmin) {
938 sendPermissionDenied(client, "Permission denied");
941 if (!getBoolConf(ENABLE_BAN)) {
942 sendPermissionDenied(client, "Permission denied");
945 if (msg->payload.banList->has_query && msg->payload.banList->query) {
946 /* Create banlist message and add banentrys */
947 sendmsg = Ban_getBanList();
948 Client_send_message(client, sendmsg);
950 /* Clear banlist and set the new one */
952 Ban_putBanList(msg, msg->payload.banList->n_bans);
956 /* Permission denied for all these messages. Not implemented. */
959 case ContextActionAdd:
963 sendPermissionDenied(client, "Not supported by uMurmur");
967 Log_warn("Message %d not handled", msg->messageType);
976 Client_close(client);