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.
38 #include "messagehandler.h"
42 #include "voicetarget.h"
46 #define MAX_USERNAME 128
48 #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."
51 extern channel_t *defaultChan;
52 extern int iCodecAlpha, iCodecBeta;
53 extern bool_t bPreferAlpha, bOpus;
55 static bool_t fake_celt_support;
57 static void sendServerReject(client_t *client, const char *reason, MumbleProto__Reject__RejectType type)
59 message_t *msg = Msg_create(Reject);
60 msg->payload.reject->reason = strdup(reason);
61 msg->payload.reject->type = type;
62 msg->payload.reject->has_type = true;
63 Client_send_message(client, msg);
65 Log_info_client(client, "Server reject reason: %s", reason);
68 static void sendPermissionDenied(client_t *client, const char *reason)
70 message_t *msg = Msg_create(PermissionDenied);
71 msg->payload.permissionDenied->has_type = true;
72 msg->payload.permissionDenied->type = MUMBLE_PROTO__PERMISSION_DENIED__DENY_TYPE__Text;
73 msg->payload.permissionDenied->reason = strdup(reason);
74 Client_send_message(client, msg);
77 static void addTokens(client_t *client, message_t *msg)
80 if (client->tokencount + msg->payload.authenticate->n_tokens < MAX_TOKENS) {
81 /* Check lengths first */
82 for (i = 0; i < msg->payload.authenticate->n_tokens; i++) {
83 if (strlen(msg->payload.authenticate->tokens[i]) > MAX_TOKENSIZE - 1) {
84 sendPermissionDenied(client, "Too long token");
89 for (i = 0; i < msg->payload.authenticate->n_tokens; i++) {
90 Log_debug("Adding token '%s' to client '%s'", msg->payload.authenticate->tokens[i], client->username);
91 Client_token_add(client, msg->payload.authenticate->tokens[i]);
95 sendPermissionDenied(client, "Too many tokens");
98 void Mh_handle_message(client_t *client, message_t *msg)
100 message_t *sendmsg = NULL;
101 channel_t *ch_itr = NULL;
102 client_t *client_itr, *target;
104 if (!client->authenticated && !(msg->messageType == Authenticate ||
105 msg->messageType == Version)) {
109 switch (msg->messageType) {
115 case PermissionQuery:
118 Timer_restart(&client->idleTime);
121 switch (msg->messageType) {
123 Log_debug("Authenticate message received");
125 if (IS_AUTH(client) || !msg->payload.authenticate->username) {
126 /* Authenticate message might be sent when a tokens are changed by the user.*/
127 Client_token_free(client); /* Clear the token list */
128 if (msg->payload.authenticate->n_tokens > 0) {
129 Log_debug("Tokens in auth message from '%s'. n_tokens = %d", client->username,
130 msg->payload.authenticate->n_tokens);
131 addTokens(client, msg);
136 if (SSLi_getSHA1Hash(client->ssl, client->hash) && Ban_isBanned(client)) {
138 SSLi_hash2hex(client->hash, hexhash);
139 Log_info("Client with hash '%s' is banned. Disconnecting", hexhash);
143 client->authenticated = true;
146 while (Client_iterate(&client_itr) != NULL) {
147 if (!IS_AUTH(client_itr))
149 if (client_itr->username && strncmp(client_itr->username, msg->payload.authenticate->username, MAX_USERNAME) == 0) {
151 sprintf(buf, "Username already in use");
152 Log_debug("Username already in use");
153 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__UsernameInUse);
157 if (strlen(getStrConf(PASSPHRASE)) > 0) {
158 if (!msg->payload.authenticate->password ||
159 (msg->payload.authenticate->password &&
160 strncmp(getStrConf(PASSPHRASE), msg->payload.authenticate->password, MAX_TEXT) != 0)) {
162 sprintf(buf, "Wrong server password");
163 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__WrongServerPW);
164 Log_debug("Wrong server password: '%s'", msg->payload.authenticate->password != NULL ?
165 msg->payload.authenticate->password : "(null)");
169 if (strlen(msg->payload.authenticate->username) == 0 ||
170 strlen(msg->payload.authenticate->username) >= MAX_USERNAME) { /* XXX - other invalid names? */
172 sprintf(buf, "Invalid username");
173 Log_debug("Invalid username");
174 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__InvalidUsername);
178 if (Client_count() >= getIntConf(MAX_CLIENTS)) {
180 snprintf(buf, 64, "Server is full (max %d users)", getIntConf(MAX_CLIENTS));
181 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__ServerFull);
186 client->username = strdup(msg->payload.authenticate->username);
189 if (msg->payload.authenticate->n_tokens > 0)
190 addTokens(client, msg);
192 /* Check if admin PW among tokens */
193 if (strlen(getStrConf(ADMIN_PASSPHRASE)) > 0 &&
194 Client_token_match(client, getStrConf(ADMIN_PASSPHRASE))) {
195 client->isAdmin = true;
196 Log_info_client(client, "User provided admin password");
199 /* Setup UDP encryption */
200 CryptState_init(&client->cryptState);
201 CryptState_genKey(&client->cryptState);
202 sendmsg = Msg_create(CryptSetup);
203 sendmsg->payload.cryptSetup->has_key = true;
204 sendmsg->payload.cryptSetup->key.data = client->cryptState.raw_key;
205 sendmsg->payload.cryptSetup->key.len = AES_BLOCK_SIZE;
206 sendmsg->payload.cryptSetup->has_server_nonce = true;
207 sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.encrypt_iv;
208 sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
209 sendmsg->payload.cryptSetup->has_client_nonce = true;
210 sendmsg->payload.cryptSetup->client_nonce.data = client->cryptState.decrypt_iv;
211 sendmsg->payload.cryptSetup->client_nonce.len = AES_BLOCK_SIZE;
212 Client_send_message(client, sendmsg);
215 Chan_userJoin(defaultChan, client); /* Join default channel */
218 Log_debug("Client %d has %d CELT codecs", client->sessionId,
219 msg->payload.authenticate->n_celt_versions);
220 if (msg->payload.authenticate->n_celt_versions > 0) {
223 client->codec_count = msg->payload.authenticate->n_celt_versions;
225 for (i = 0; i < client->codec_count; i++)
226 Client_codec_add(client, msg->payload.authenticate->celt_versions[i]);
228 while (Client_codec_iterate(client, &codec_itr) != NULL)
229 Log_debug("Client %d CELT codec ver 0x%x", client->sessionId, codec_itr->codec);
232 Client_codec_add(client, (int32_t)0x8000000b);
233 client->codec_count = 1;
234 fake_celt_support = true;
236 if (msg->payload.authenticate->opus)
237 client->bOpus = true;
239 recheckCodecVersions(client);
241 sendmsg = Msg_create(CodecVersion);
242 sendmsg->payload.codecVersion->alpha = iCodecAlpha;
243 sendmsg->payload.codecVersion->beta = iCodecBeta;
244 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
245 sendmsg->payload.codecVersion->has_opus = true;
246 sendmsg->payload.codecVersion->opus = bOpus;
247 Client_send_message(client, sendmsg);
249 if (!bOpus && client->bOpus && fake_celt_support) {
250 Client_textmessage(client, NO_CELT_MESSAGE);
253 /* Iterate channels and send channel info */
255 while (Chan_iterate(&ch_itr) != NULL) {
256 sendmsg = Msg_create(ChannelState);
257 sendmsg->payload.channelState->has_channel_id = true;
258 sendmsg->payload.channelState->channel_id = ch_itr->id;
259 if (ch_itr->id != 0) {
260 sendmsg->payload.channelState->has_parent = true;
261 sendmsg->payload.channelState->parent = ch_itr->parent->id;
263 sendmsg->payload.channelState->name = strdup(ch_itr->name);
265 sendmsg->payload.channelState->description = strdup(ch_itr->desc);
266 if (ch_itr->position != 0) {
267 sendmsg->payload.channelState->has_position = true;
268 sendmsg->payload.channelState->position = ch_itr->position;
270 Log_debug("Send channel info: %s", sendmsg->payload.channelState->name);
271 Client_send_message(client, sendmsg);
274 /* Iterate channels and send channel links info */
276 while (Chan_iterate(&ch_itr) != NULL) {
277 if (ch_itr->linkcount > 0) { /* Has links */
282 sendmsg = Msg_create(ChannelState);
283 sendmsg->payload.channelState->has_channel_id = true;
284 sendmsg->payload.channelState->channel_id = ch_itr->id;
285 sendmsg->payload.channelState->n_links = ch_itr->linkcount;
287 links = (uint32_t *)malloc(ch_itr->linkcount * sizeof(uint32_t));
289 Log_fatal("Out of memory");
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 = malloc(strlen(client->username) + 32);
503 Log_fatal("Out of memory");
504 tree_id = malloc(sizeof(uint32_t));
506 Log_fatal("Out of memory");
508 sendmsg = Msg_create(TextMessage);
509 sendmsg->payload.textMessage->message = message;
510 sendmsg->payload.textMessage->n_tree_id = 1;
511 sendmsg->payload.textMessage->tree_id = tree_id;
512 if (client->recording)
513 sprintf(message, "User %s started recording", client->username);
515 sprintf(message, "User %s stopped recording", client->username);
516 Client_send_message_except_ver(NULL, sendmsg, ~0x010203);
519 if (msg->payload.userState->has_channel_id) {
522 channelJoinResult_t result = Chan_userJoin_id_test(msg->payload.userState->channel_id, target);
524 if (result.CHJOIN_NOENTER || result.CHJOIN_NOTFOUND)
527 if (result.CHJOIN_WRONGPW) {
528 if (target == client && !client->isAdmin) {
529 sendPermissionDenied(client, "Wrong channel password");
532 /* Tricky one: if user hasn't the password, but is moved to the channel by admin then let
533 * the user in. Also let admin user in regardless of channel password.
534 * Take no action on other errors.
536 else if (!client->isAdmin)
540 leave_id = Chan_userJoin_id(msg->payload.userState->channel_id, target);
542 Log_debug("Removing channel ID %d", leave_id);
543 sendmsg = Msg_create(ChannelRemove);
544 sendmsg->payload.channelRemove->channel_id = leave_id;
547 if (result.CHJOIN_SILENT) {
548 if (!target->isSuppressed) {
549 msg->payload.userState->has_suppress = true;
550 msg->payload.userState->suppress = true;
551 target->isSuppressed = true;
554 else if (target->isSuppressed) {
555 msg->payload.userState->has_suppress = true;
556 msg->payload.userState->suppress = false;
557 target->isSuppressed = false;
560 if (msg->payload.userState->has_plugin_context) {
562 free(client->context);
563 client->context = malloc(msg->payload.userState->plugin_context.len);
564 if (client->context == NULL)
565 Log_fatal("Out of memory");
566 memcpy(client->context, msg->payload.userState->plugin_context.data,
567 msg->payload.userState->plugin_context.len);
569 break; /* Don't inform other users about this state */
574 Client_send_message_except(NULL, msg);
576 /* Need to send remove channel message _after_ UserState message */
578 Client_send_message_except(NULL, sendmsg);
582 if (!getBoolConf(ALLOW_TEXTMESSAGE))
584 msg->payload.textMessage->has_actor = true;
585 msg->payload.textMessage->actor = client->sessionId;
587 /* XXX - HTML is allowed and can't be turned off */
588 if (msg->payload.textMessage->n_tree_id > 0) {
589 sendPermissionDenied(client, "Tree message not supported");
593 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
596 for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
599 Chan_iterate(&ch_itr);
600 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
601 if (ch_itr != NULL) {
603 list_iterate(itr, &ch_itr->clients) {
605 c = list_get_entry(itr, client_t, chan_node);
606 if (c != client && !c->deaf && !c->self_deaf) {
608 Client_send_message(c, msg);
609 Log_debug("Text message to session ID %d", c->sessionId);
615 if (msg->payload.textMessage->n_session > 0) { /* To user */
618 for (i = 0; i < msg->payload.textMessage->n_session; i++) {
620 while (Client_iterate(&itr) != NULL) {
623 if (itr->sessionId == msg->payload.textMessage->session[i]) {
624 if (!itr->deaf && !itr->self_deaf) {
626 Client_send_message(itr, msg);
627 Log_debug("Text message to session ID %d", itr->sessionId);
633 Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
640 int i, j, count, targetId = msg->payload.voiceTarget->id;
641 struct _MumbleProto__VoiceTarget__Target *target;
643 if (!targetId || targetId >= 0x1f)
645 Voicetarget_add_id(client, targetId);
646 count = msg->payload.voiceTarget->n_targets;
649 for (i = 0; i < count; i++) {
650 target = msg->payload.voiceTarget->targets[i];
651 for (j = 0; j < target->n_session; j++)
652 Voicetarget_add_session(client, targetId, target->session[j]);
653 if (target->has_channel_id) {
654 bool_t linked = false, children = false;
655 if (target->has_links)
656 linked = target->links;
657 if (target->has_children)
658 children = target->children;
659 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
665 Log_debug("Version message received");
666 if (msg->payload.version->has_version) {
667 client->version = msg->payload.version->version;
668 Log_debug("Client version 0x%x", client->version);
670 if (msg->payload.version->release) {
671 if (client->release) free(client->release);
672 client->release = strdup(msg->payload.version->release);
673 Log_debug("Client release %s", client->release);
675 if (msg->payload.version->os) {
676 if (client->os) free(client->os);
677 client->os = strdup(msg->payload.version->os);
678 Log_debug("Client OS %s", client->os);
680 if (msg->payload.version->os_version) {
681 if (client->os_version) free(client->os_version);
682 client->os_version = strdup(msg->payload.version->os_version);
683 Log_debug("Client OS version %s", client->os_version);
686 case PermissionQuery:
687 Msg_inc_ref(msg); /* Re-use message */
688 msg->payload.permissionQuery->has_permissions = true;
691 msg->payload.permissionQuery->permissions = PERM_ADMIN;
693 msg->payload.permissionQuery->permissions = PERM_DEFAULT;
695 if (!getBoolConf(ALLOW_TEXTMESSAGE))
696 msg->payload.permissionQuery->permissions &= ~PERM_TEXTMESSAGE;
697 if (!getBoolConf(ENABLE_BAN))
698 msg->payload.permissionQuery->permissions &= ~PERM_BAN;
700 Client_send_message(client, msg);
703 client->bUDP = false;
704 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
708 channel_t *ch_itr, *parent, *newchan;
710 /* Don't allow any changes to existing channels */
711 if (msg->payload.channelState->has_channel_id) {
712 sendPermissionDenied(client, "Not supported by uMurmur");
715 /* Must have parent */
716 if (!msg->payload.channelState->has_parent) {
717 sendPermissionDenied(client, "Not supported by uMurmur");
721 if (msg->payload.channelState->name == NULL) {
722 sendPermissionDenied(client, "Not supported by uMurmur");
725 /* Must be temporary channel */
726 if (msg->payload.channelState->temporary != true) {
727 sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
730 /* Check channel name is OK */
731 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
732 sendPermissionDenied(client, "Channel name too long");
736 parent = Chan_fromId(msg->payload.channelState->parent);
740 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
741 if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
742 sendPermissionDenied(client, "Channel already exists");
749 /* Disallow temporary channels as siblings to temporary channels */
750 if (parent->temporary) {
751 sendPermissionDenied(client, "Parent channel is temporary channel");
755 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
756 * I don't know why so I don't do that here...
759 /* Create the channel */
760 newchan = Chan_createChannel(msg->payload.channelState->name,
761 msg->payload.channelState->description);
762 newchan->temporary = true;
763 if (msg->payload.channelState->has_position)
764 newchan->position = msg->payload.channelState->position;
765 Chan_addChannel(parent, newchan);
766 msg->payload.channelState->has_channel_id = true;
767 msg->payload.channelState->channel_id = newchan->id;
769 Client_send_message_except(NULL, msg);
771 /* Join the creating user */
772 sendmsg = Msg_create(UserState);
773 sendmsg->payload.userState->has_session = true;
774 sendmsg->payload.userState->session = client->sessionId;
775 sendmsg->payload.userState->has_channel_id = true;
776 sendmsg->payload.userState->channel_id = newchan->id;
778 if (client->isSuppressed) {
779 sendmsg->payload.userState->has_suppress = true;
780 sendmsg->payload.userState->suppress = false;
781 client->isSuppressed = false;
784 Client_send_message_except(NULL, sendmsg);
786 leave_id = Chan_userJoin(newchan, client);
788 Log_debug("Removing channel ID %d", leave_id);
789 sendmsg = Msg_create(ChannelRemove);
790 sendmsg->payload.channelRemove->channel_id = leave_id;
791 Client_send_message_except(NULL, sendmsg);
798 client_t *target = NULL;
799 codec_t *codec_itr = NULL;
801 bool_t details = true;
803 if (msg->payload.userStats->has_stats_only)
804 details = !msg->payload.userStats->stats_only;
806 if (!msg->payload.userStats->has_session)
807 sendPermissionDenied(client, "Not supported by uMurmur");
808 while (Client_iterate(&target) != NULL) {
809 if (!IS_AUTH(target))
811 if (target->sessionId == msg->payload.userStats->session)
814 if (!target) /* Not found */
818 * Differences from Murmur:
819 * o Ignoring certificates intentionally
820 * o Ignoring channel local determining
823 sendmsg = Msg_create(UserStats);
824 sendmsg->payload.userStats->session = msg->payload.userStats->session;
825 sendmsg->payload.userStats->from_client->has_good = true;
826 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
827 sendmsg->payload.userStats->from_client->has_late = true;
828 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
829 sendmsg->payload.userStats->from_client->has_lost = true;
830 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
831 sendmsg->payload.userStats->from_client->has_resync = true;
832 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
834 sendmsg->payload.userStats->from_server->has_good = true;
835 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
836 sendmsg->payload.userStats->from_server->has_late = true;
837 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
838 sendmsg->payload.userStats->from_server->has_lost = true;
839 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
840 sendmsg->payload.userStats->from_server->has_resync = true;
841 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
843 sendmsg->payload.userStats->has_udp_packets = true;
844 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
845 sendmsg->payload.userStats->has_udp_ping_avg = true;
846 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
847 sendmsg->payload.userStats->has_udp_ping_var = true;
848 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
850 sendmsg->payload.userStats->has_tcp_ping_avg = true;
851 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
852 sendmsg->payload.userStats->has_tcp_ping_var = true;
853 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
854 sendmsg->payload.userStats->has_tcp_packets = true;
855 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
859 sendmsg->payload.userStats->version->has_version = true;
860 sendmsg->payload.userStats->version->version = target->version;
862 sendmsg->payload.userStats->version->release = strdup(target->release);
864 sendmsg->payload.userStats->version->os = strdup(target->os);
865 if (target->os_version)
866 sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
868 sendmsg->payload.userStats->n_celt_versions = target->codec_count;
869 sendmsg->payload.userStats->celt_versions = malloc(sizeof(int32_t) * target->codec_count);
870 if (!sendmsg->payload.userStats->celt_versions)
871 Log_fatal("Out of memory");
873 while (Client_codec_iterate(target, &codec_itr) != NULL)
874 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
876 sendmsg->payload.userStats->has_opus = true;
877 sendmsg->payload.userStats->opus = target->bOpus;
880 sendmsg->payload.userStats->has_address = true;
881 sendmsg->payload.userStats->address.data = malloc(sizeof(uint8_t) * 16);
882 if (!sendmsg->payload.userStats->address.data)
883 Log_fatal("Out of memory");
884 memset(sendmsg->payload.userStats->address.data, 0, 16);
885 /* ipv4 representation as ipv6 address. Supposedly correct. */
886 memset(&sendmsg->payload.userStats->address.data[10], 0xff, 2); /* IPv4 */
887 if(target->remote_tcp.ss_family == AF_INET)
888 memcpy(&sendmsg->payload.userStats->address.data[12], &((struct sockaddr_in*)&target->remote_tcp)->sin_addr, 4);
890 memcpy(&sendmsg->payload.userStats->address.data[0], &((struct sockaddr_in6*)&target->remote_tcp)->sin6_addr, 16);
891 sendmsg->payload.userStats->address.len = 16;
894 sendmsg->payload.userStats->has_bandwidth = true;
895 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
898 sendmsg->payload.userStats->has_onlinesecs = true;
899 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;
901 sendmsg->payload.userStats->has_idlesecs = true;
902 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;
903 Client_send_message(client, sendmsg);
908 /* Only admin can issue this */
909 if (!client->isAdmin) {
910 sendPermissionDenied(client, "Permission denied");
913 while (Client_iterate(&target) != NULL) {
914 if (target->sessionId == msg->payload.userRemove->session)
917 if (target == NULL) {
918 Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
921 msg->payload.userRemove->session = target->sessionId;
922 msg->payload.userRemove->has_actor = true;
923 msg->payload.userRemove->actor = client->sessionId;
925 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
926 if (!getBoolConf(ENABLE_BAN))
927 sendPermissionDenied(client, "Permission denied");
929 Ban_UserBan(target, msg->payload.userRemove->reason);
931 Log_info_client(target, "User kicked. Reason: '%s'",
932 strlen(msg->payload.userRemove->reason) == 0 ? "N/A" : msg->payload.userRemove->reason);
937 Client_send_message_except(NULL, msg);
938 Client_close(target);
941 /* Only admin can issue this */
942 if (!client->isAdmin) {
943 sendPermissionDenied(client, "Permission denied");
946 if (!getBoolConf(ENABLE_BAN)) {
947 sendPermissionDenied(client, "Permission denied");
950 if (msg->payload.banList->has_query && msg->payload.banList->query) {
951 /* Create banlist message and add banentrys */
952 sendmsg = Ban_getBanList();
953 Client_send_message(client, sendmsg);
955 /* Clear banlist and set the new one */
957 Ban_putBanList(msg, msg->payload.banList->n_bans);
961 /* Permission denied for all these messages. Not implemented. */
964 case ContextActionAdd:
968 sendPermissionDenied(client, "Not supported by uMurmur");
972 Log_warn("Message %d not handled", msg->messageType);
981 Client_close(client);