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 target = Client_find_by_session(msg->payload.userState->session);
443 if (target == NULL) {
444 Log_warn("Client with sessionID %d not found", msg->payload.userState->session);
449 if (msg->payload.userState->has_user_id || msg->payload.userState->has_suppress ||
450 msg->payload.userState->has_priority_speaker || msg->payload.userState->has_texture) {
451 sendPermissionDenied(client, "Not supported by uMurmur");
458 msg->payload.userState->has_session = true;
459 msg->payload.userState->session = target->sessionId;
460 msg->payload.userState->has_actor = true;
461 msg->payload.userState->actor = client->sessionId;
463 if (msg->payload.userState->has_deaf) {
464 target->deaf = msg->payload.userState->deaf;
466 msg->payload.userState->has_mute = true;
467 msg->payload.userState->mute = true;
470 if (msg->payload.userState->has_mute) {
471 target->mute = msg->payload.userState->mute;
473 msg->payload.userState->has_deaf = true;
474 msg->payload.userState->deaf = false;
475 target->deaf = false;
478 if (msg->payload.userState->has_self_deaf) {
479 client->self_deaf = msg->payload.userState->self_deaf;
480 if (client->self_deaf) {
481 msg->payload.userState->has_self_mute = true;
482 msg->payload.userState->self_mute = true;
485 if (msg->payload.userState->has_self_mute) {
486 client->self_mute = msg->payload.userState->self_mute;
487 if (!client->self_mute) {
488 msg->payload.userState->has_self_deaf = true;
489 msg->payload.userState->self_deaf = false;
490 client->self_deaf = false;
493 if (msg->payload.userState->has_recording &&
494 msg->payload.userState->recording != client->recording) {
495 client->recording = msg->payload.userState->recording;
499 message = Memory_safeMalloc(1, strlen(client->username) + 32);
500 tree_id = Memory_safeMalloc(1, sizeof(uint32_t));
502 sendmsg = Msg_create(TextMessage);
503 sendmsg->payload.textMessage->message = message;
504 sendmsg->payload.textMessage->n_tree_id = 1;
505 sendmsg->payload.textMessage->tree_id = tree_id;
506 if (client->recording)
507 sprintf(message, "User %s started recording", client->username);
509 sprintf(message, "User %s stopped recording", client->username);
510 Client_send_message_except_ver(NULL, sendmsg, ~0x010203);
513 if (msg->payload.userState->has_channel_id) {
516 channelJoinResult_t result = Chan_userJoin_id_test(msg->payload.userState->channel_id, target);
518 if (result.CHJOIN_NOENTER || result.CHJOIN_NOTFOUND)
521 if (result.CHJOIN_WRONGPW) {
522 if (target == client && !client->isAdmin) {
523 sendPermissionDenied(client, "Wrong channel password");
526 /* Tricky one: if user hasn't the password, but is moved to the channel by admin then let
527 * the user in. Also let admin user in regardless of channel password.
528 * Take no action on other errors.
530 else if (!client->isAdmin)
534 leave_id = Chan_userJoin_id(msg->payload.userState->channel_id, target);
536 Log_debug("Removing channel ID %d", leave_id);
537 sendmsg = Msg_create(ChannelRemove);
538 sendmsg->payload.channelRemove->channel_id = leave_id;
541 if (result.CHJOIN_SILENT) {
542 if (!target->isSuppressed) {
543 msg->payload.userState->has_suppress = true;
544 msg->payload.userState->suppress = true;
545 target->isSuppressed = true;
548 else if (target->isSuppressed) {
549 msg->payload.userState->has_suppress = true;
550 msg->payload.userState->suppress = false;
551 target->isSuppressed = false;
554 if (msg->payload.userState->has_plugin_context) {
555 free(client->context);
556 client->context = Memory_safeMalloc(1, msg->payload.userState->plugin_context.len);
557 memcpy(client->context, msg->payload.userState->plugin_context.data,
558 msg->payload.userState->plugin_context.len);
560 break; /* Don't inform other users about this state */
565 Client_send_message_except(NULL, msg);
567 /* Need to send remove channel message _after_ UserState message */
569 Client_send_message_except(NULL, sendmsg);
573 if (!getBoolConf(ALLOW_TEXTMESSAGE))
575 msg->payload.textMessage->has_actor = true;
576 msg->payload.textMessage->actor = client->sessionId;
578 /* XXX - HTML is allowed and can't be turned off */
579 if (msg->payload.textMessage->n_tree_id > 0) {
580 sendPermissionDenied(client, "Tree message not supported");
584 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
587 for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
590 Chan_iterate(&ch_itr);
591 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
592 if (ch_itr != NULL) {
594 list_iterate(itr, &ch_itr->clients) {
596 c = list_get_entry(itr, client_t, chan_node);
597 if (c != client && !c->deaf && !c->self_deaf) {
599 Client_send_message(c, msg);
600 Log_debug("Text message to session ID %d", c->sessionId);
606 if (msg->payload.textMessage->n_session > 0) { /* To user */
609 for (i = 0; i < msg->payload.textMessage->n_session; i++) {
610 itr = Client_find_by_session(msg->payload.textMessage->session[i]);
613 Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
614 else if (IS_AUTH(itr) && !itr->deaf && !itr->self_deaf) {
616 Client_send_message(itr, msg);
617 Log_debug("Text message to session ID %d", itr->sessionId);
625 int i, j, count, targetId = msg->payload.voiceTarget->id;
626 struct _MumbleProto__VoiceTarget__Target *target;
628 if (!targetId || targetId >= 0x1f)
630 Voicetarget_add_id(client, targetId);
631 count = msg->payload.voiceTarget->n_targets;
634 for (i = 0; i < count; i++) {
635 target = msg->payload.voiceTarget->targets[i];
636 for (j = 0; j < target->n_session; j++)
637 Voicetarget_add_session(client, targetId, target->session[j]);
638 if (target->has_channel_id) {
639 bool_t linked = false, children = false;
640 if (target->has_links)
641 linked = target->links;
642 if (target->has_children)
643 children = target->children;
644 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
650 Log_debug("Version message received");
651 if (msg->payload.version->has_version) {
652 client->version = msg->payload.version->version;
653 Log_debug("Client version 0x%x", client->version);
655 if (msg->payload.version->release) {
656 free(client->release);
657 client->release = strdup(msg->payload.version->release);
658 Log_debug("Client release %s", client->release);
660 if (msg->payload.version->os) {
662 client->os = strdup(msg->payload.version->os);
663 Log_debug("Client OS %s", client->os);
665 if (msg->payload.version->os_version) {
666 free(client->os_version);
667 client->os_version = strdup(msg->payload.version->os_version);
668 Log_debug("Client OS version %s", client->os_version);
671 case PermissionQuery:
672 Msg_inc_ref(msg); /* Re-use message */
673 msg->payload.permissionQuery->has_permissions = true;
676 msg->payload.permissionQuery->permissions = PERM_ADMIN;
678 msg->payload.permissionQuery->permissions = PERM_DEFAULT;
680 if (!getBoolConf(ALLOW_TEXTMESSAGE))
681 msg->payload.permissionQuery->permissions &= ~PERM_TEXTMESSAGE;
682 if (!getBoolConf(ENABLE_BAN))
683 msg->payload.permissionQuery->permissions &= ~PERM_BAN;
685 Client_send_message(client, msg);
688 client->bUDP = false;
689 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
693 channel_t *ch_itr, *parent, *newchan;
695 /* Don't allow any changes to existing channels */
696 if (msg->payload.channelState->has_channel_id) {
697 sendPermissionDenied(client, "Not supported by uMurmur");
700 /* Must have parent */
701 if (!msg->payload.channelState->has_parent) {
702 sendPermissionDenied(client, "Not supported by uMurmur");
706 if (msg->payload.channelState->name == NULL) {
707 sendPermissionDenied(client, "Not supported by uMurmur");
710 /* Must be temporary channel */
711 if (msg->payload.channelState->temporary != true) {
712 sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
715 /* Check channel name is OK */
716 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
717 sendPermissionDenied(client, "Channel name too long");
721 parent = Chan_fromId(msg->payload.channelState->parent);
725 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
726 if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
727 sendPermissionDenied(client, "Channel already exists");
734 /* Disallow temporary channels as siblings to temporary channels */
735 if (parent->temporary) {
736 sendPermissionDenied(client, "Parent channel is temporary channel");
740 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
741 * I don't know why so I don't do that here...
744 /* Create the channel */
745 newchan = Chan_createChannel(msg->payload.channelState->name,
746 msg->payload.channelState->description);
747 newchan->temporary = true;
748 if (msg->payload.channelState->has_position)
749 newchan->position = msg->payload.channelState->position;
750 Chan_addChannel(parent, newchan);
751 msg->payload.channelState->has_channel_id = true;
752 msg->payload.channelState->channel_id = newchan->id;
754 Client_send_message_except(NULL, msg);
756 /* Join the creating user */
757 sendmsg = Msg_create(UserState);
758 sendmsg->payload.userState->has_session = true;
759 sendmsg->payload.userState->session = client->sessionId;
760 sendmsg->payload.userState->has_channel_id = true;
761 sendmsg->payload.userState->channel_id = newchan->id;
763 if (client->isSuppressed) {
764 sendmsg->payload.userState->has_suppress = true;
765 sendmsg->payload.userState->suppress = false;
766 client->isSuppressed = false;
769 Client_send_message_except(NULL, sendmsg);
771 leave_id = Chan_userJoin(newchan, client);
773 Log_debug("Removing channel ID %d", leave_id);
774 sendmsg = Msg_create(ChannelRemove);
775 sendmsg->payload.channelRemove->channel_id = leave_id;
776 Client_send_message_except(NULL, sendmsg);
783 client_t *target = NULL;
784 codec_t *codec_itr = NULL;
786 bool_t details = true;
788 if (msg->payload.userStats->has_stats_only)
789 details = !msg->payload.userStats->stats_only;
791 if (!msg->payload.userStats->has_session)
792 sendPermissionDenied(client, "Not supported by uMurmur");
794 target = Client_find_by_session(msg->payload.userStats->session);
796 if (!target) /* Not found */
799 if (!IS_AUTH(target)) /* Not authenticated. */
803 * Differences from Murmur:
804 * o Ignoring certificates intentionally
805 * o Ignoring channel local determining
808 sendmsg = Msg_create(UserStats);
809 sendmsg->payload.userStats->session = msg->payload.userStats->session;
810 sendmsg->payload.userStats->from_client->has_good = true;
811 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
812 sendmsg->payload.userStats->from_client->has_late = true;
813 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
814 sendmsg->payload.userStats->from_client->has_lost = true;
815 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
816 sendmsg->payload.userStats->from_client->has_resync = true;
817 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
819 sendmsg->payload.userStats->from_server->has_good = true;
820 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
821 sendmsg->payload.userStats->from_server->has_late = true;
822 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
823 sendmsg->payload.userStats->from_server->has_lost = true;
824 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
825 sendmsg->payload.userStats->from_server->has_resync = true;
826 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
828 sendmsg->payload.userStats->has_udp_packets = true;
829 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
830 sendmsg->payload.userStats->has_udp_ping_avg = true;
831 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
832 sendmsg->payload.userStats->has_udp_ping_var = true;
833 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
835 sendmsg->payload.userStats->has_tcp_ping_avg = true;
836 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
837 sendmsg->payload.userStats->has_tcp_ping_var = true;
838 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
839 sendmsg->payload.userStats->has_tcp_packets = true;
840 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
844 sendmsg->payload.userStats->version->has_version = true;
845 sendmsg->payload.userStats->version->version = target->version;
847 sendmsg->payload.userStats->version->release = strdup(target->release);
849 sendmsg->payload.userStats->version->os = strdup(target->os);
850 if (target->os_version)
851 sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
853 sendmsg->payload.userStats->n_celt_versions = target->codec_count;
854 sendmsg->payload.userStats->celt_versions
855 = Memory_safeMalloc(target->codec_count, sizeof(int32_t));
857 while (Client_codec_iterate(target, &codec_itr) != NULL)
858 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
860 sendmsg->payload.userStats->has_opus = true;
861 sendmsg->payload.userStats->opus = target->bOpus;
864 if (getBoolConf(SHOW_ADDRESSES)) {
865 sendmsg->payload.userStats->has_address = true;
866 sendmsg->payload.userStats->address.data
867 = Memory_safeMalloc(16, sizeof(uint8_t));
868 memset(sendmsg->payload.userStats->address.data, 0, 16);
869 /* ipv4 representation as ipv6 address. Supposedly correct. */
870 memset(&sendmsg->payload.userStats->address.data[10], 0xff, 2); /* IPv4 */
871 if(target->remote_tcp.ss_family == AF_INET)
872 memcpy(&sendmsg->payload.userStats->address.data[12], &((struct sockaddr_in*)&target->remote_tcp)->sin_addr, 4);
874 memcpy(&sendmsg->payload.userStats->address.data[0], &((struct sockaddr_in6*)&target->remote_tcp)->sin6_addr, 16);
875 sendmsg->payload.userStats->address.len = 16;
877 sendmsg->payload.userStats->has_address = false;
881 sendmsg->payload.userStats->has_bandwidth = true;
882 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
885 sendmsg->payload.userStats->has_onlinesecs = true;
886 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;
888 sendmsg->payload.userStats->has_idlesecs = true;
889 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;
890 Client_send_message(client, sendmsg);
895 /* Only admin can issue this */
896 if (!client->isAdmin) {
897 sendPermissionDenied(client, "Permission denied");
901 target = Client_find_by_session(msg->payload.userRemove->session);
903 if (target == NULL) {
904 Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
907 msg->payload.userRemove->session = target->sessionId;
908 msg->payload.userRemove->has_actor = true;
909 msg->payload.userRemove->actor = client->sessionId;
911 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
912 if (!getBoolConf(ENABLE_BAN))
913 sendPermissionDenied(client, "Permission denied");
915 Ban_UserBan(target, msg->payload.userRemove->reason);
917 Log_info_client(target, "User kicked. Reason: '%s'",
918 strlen(msg->payload.userRemove->reason) == 0 ? "N/A" : msg->payload.userRemove->reason);
923 Client_send_message_except(NULL, msg);
924 Client_close(target);
927 /* Only admin can issue this */
928 if (!client->isAdmin) {
929 sendPermissionDenied(client, "Permission denied");
932 if (!getBoolConf(ENABLE_BAN)) {
933 sendPermissionDenied(client, "Permission denied");
936 if (msg->payload.banList->has_query && msg->payload.banList->query) {
937 /* Create banlist message and add banentrys */
938 sendmsg = Ban_getBanList();
939 Client_send_message(client, sendmsg);
941 /* Clear banlist and set the new one */
943 Ban_putBanList(msg, msg->payload.banList->n_bans);
947 /* Permission denied for all these messages. Not implemented. */
950 case ContextActionAdd:
954 sendPermissionDenied(client, "Not supported by uMurmur");
958 Log_warn("Message %d not handled", msg->messageType);
967 Client_close(client);