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));
288 list_iterate(itr, &ch_itr->channel_links) { /* Iterate links */
291 chl = list_get_entry(itr, channellist_t, node);
295 sendmsg->payload.channelState->links = links;
296 Client_send_message(client, sendmsg);
300 /* Send user state for connecting user to other users */
301 sendmsg = Msg_create(UserState);
302 sendmsg->payload.userState->has_session = true;
303 sendmsg->payload.userState->session = client->sessionId;
304 sendmsg->payload.userState->name = strdup(client->username);
305 sendmsg->payload.userState->has_channel_id = true;
306 sendmsg->payload.userState->channel_id = ((channel_t *)client->channel)->id;
308 if (defaultChan->silent) {
309 sendmsg->payload.userState->has_suppress = true;
310 sendmsg->payload.userState->suppress = true;
313 Client_send_message_except(client, sendmsg);
316 while (Client_iterate(&client_itr) != NULL) {
317 if (!IS_AUTH(client_itr))
319 sendmsg = Msg_create(UserState);
320 sendmsg->payload.userState->has_session = true;
321 sendmsg->payload.userState->session = client_itr->sessionId;
322 sendmsg->payload.userState->name = strdup(client_itr->username);
323 sendmsg->payload.userState->has_channel_id = true;
324 sendmsg->payload.userState->channel_id = ((channel_t *)client_itr->channel)->id;
325 sendmsg->payload.userState->has_suppress = ((channel_t *)client_itr->channel)->silent;
326 sendmsg->payload.userState->suppress = ((channel_t *)client_itr->channel)->silent;
328 client_itr->isSuppressed = ((channel_t *)client_itr->channel)->silent;
330 if (client_itr->self_deaf) {
331 sendmsg->payload.userState->has_self_deaf = true;
332 sendmsg->payload.userState->self_deaf = true;
334 if (client_itr->self_mute) {
335 sendmsg->payload.userState->has_self_mute = true;
336 sendmsg->payload.userState->self_mute = true;
338 if (client_itr->deaf) {
339 sendmsg->payload.userState->has_deaf = true;
340 sendmsg->payload.userState->deaf = true;
342 if (client_itr->mute) {
343 sendmsg->payload.userState->has_mute = true;
344 sendmsg->payload.userState->mute = true;
346 if (client_itr->recording) {
347 sendmsg->payload.userState->has_recording = true;
348 sendmsg->payload.userState->recording = true;
350 Client_send_message(client, sendmsg);
354 sendmsg = Msg_create(ServerSync);
355 sendmsg->payload.serverSync->has_session = true;
356 sendmsg->payload.serverSync->session = client->sessionId;
357 sendmsg->payload.serverSync->welcome_text = strdup(getStrConf(WELCOMETEXT));
358 sendmsg->payload.serverSync->has_max_bandwidth = true;
359 sendmsg->payload.serverSync->max_bandwidth = getIntConf(MAX_BANDWIDTH);
360 Client_send_message(client, sendmsg);
362 /* Server config message */
363 sendmsg = Msg_create(ServerConfig);
364 sendmsg->payload.serverConfig->has_allow_html = true;
365 sendmsg->payload.serverConfig->allow_html = true; /* Support this? */
366 sendmsg->payload.serverConfig->has_message_length = true;
367 sendmsg->payload.serverConfig->message_length = MAX_TEXT; /* Hardcoded */
368 sendmsg->payload.serverConfig->has_image_message_length = true;
369 sendmsg->payload.serverConfig->image_message_length = 0; /* XXX */
370 Client_send_message(client, sendmsg);
372 Log_info_client(client, "User %s authenticated", client->username);
376 if (msg->payload.ping->has_good)
377 client->cryptState.uiRemoteGood = msg->payload.ping->good;
378 if (msg->payload.ping->has_late)
379 client->cryptState.uiRemoteLate = msg->payload.ping->late;
380 if (msg->payload.ping->has_lost)
381 client->cryptState.uiRemoteLost = msg->payload.ping->lost;
382 if (msg->payload.ping->has_resync)
383 client->cryptState.uiRemoteResync = msg->payload.ping->resync;
385 Log_debug("Ping <-: %d %d %d %d",
386 client->cryptState.uiRemoteGood, client->cryptState.uiRemoteLate,
387 client->cryptState.uiRemoteLost, client->cryptState.uiRemoteResync
390 client->UDPPingAvg = msg->payload.ping->udp_ping_avg;
391 client->UDPPingVar = msg->payload.ping->udp_ping_var;
392 client->TCPPingAvg = msg->payload.ping->tcp_ping_avg;
393 client->TCPPingVar = msg->payload.ping->tcp_ping_var;
394 client->UDPPackets = msg->payload.ping->udp_packets;
395 client->TCPPackets = msg->payload.ping->tcp_packets;
397 sendmsg = Msg_create(Ping);
399 sendmsg->payload.ping->timestamp = msg->payload.ping->timestamp;
400 sendmsg->payload.ping->has_timestamp = true;
401 sendmsg->payload.ping->good = client->cryptState.uiGood;
402 sendmsg->payload.ping->has_good = true;
403 sendmsg->payload.ping->late = client->cryptState.uiLate;
404 sendmsg->payload.ping->has_late = true;
405 sendmsg->payload.ping->lost = client->cryptState.uiLost;
406 sendmsg->payload.ping->has_lost = true;
407 sendmsg->payload.ping->resync = client->cryptState.uiResync;
408 sendmsg->payload.ping->has_resync = true;
410 Client_send_message(client, sendmsg);
411 Log_debug("Ping ->: %d %d %d %d",
412 client->cryptState.uiGood, client->cryptState.uiLate,
413 client->cryptState.uiLost, client->cryptState.uiResync);
417 Log_debug("Voice channel crypt resync requested");
418 if (!msg->payload.cryptSetup->has_client_nonce) {
419 sendmsg = Msg_create(CryptSetup);
420 sendmsg->payload.cryptSetup->has_server_nonce = true;
421 sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.decrypt_iv;
422 sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
423 Client_send_message(client, sendmsg);
425 memcpy(client->cryptState.decrypt_iv, msg->payload.cryptSetup->client_nonce.data, AES_BLOCK_SIZE);
426 client->cryptState.uiResync++;
431 /* Only allow state changes for for the self user unless an admin is issuing */
432 if (msg->payload.userState->has_session &&
433 msg->payload.userState->session != client->sessionId && !client->isAdmin) {
434 sendPermissionDenied(client, "Permission denied");
437 if (msg->payload.userState->has_session && msg->payload.userState->session != client->sessionId) {
438 while (Client_iterate(&target) != NULL) {
439 if (target->sessionId == msg->payload.userState->session)
442 if (target == NULL) {
443 Log_warn("Client with sessionID %d not found", msg->payload.userState->session);
448 if (msg->payload.userState->has_user_id || msg->payload.userState->has_suppress ||
449 msg->payload.userState->has_priority_speaker || msg->payload.userState->has_texture) {
450 sendPermissionDenied(client, "Not supported by uMurmur");
457 msg->payload.userState->has_session = true;
458 msg->payload.userState->session = target->sessionId;
459 msg->payload.userState->has_actor = true;
460 msg->payload.userState->actor = client->sessionId;
462 if (msg->payload.userState->has_deaf) {
463 target->deaf = msg->payload.userState->deaf;
465 msg->payload.userState->has_mute = true;
466 msg->payload.userState->mute = true;
469 if (msg->payload.userState->has_mute) {
470 target->mute = msg->payload.userState->mute;
472 msg->payload.userState->has_deaf = true;
473 msg->payload.userState->deaf = false;
474 target->deaf = false;
477 if (msg->payload.userState->has_self_deaf) {
478 client->self_deaf = msg->payload.userState->self_deaf;
479 if (client->self_deaf) {
480 msg->payload.userState->has_self_mute = true;
481 msg->payload.userState->self_mute = true;
484 if (msg->payload.userState->has_self_mute) {
485 client->self_mute = msg->payload.userState->self_mute;
486 if (!client->self_mute) {
487 msg->payload.userState->has_self_deaf = true;
488 msg->payload.userState->self_deaf = false;
489 client->self_deaf = false;
492 if (msg->payload.userState->has_recording &&
493 msg->payload.userState->recording != client->recording) {
494 client->recording = msg->payload.userState->recording;
498 message = malloc(strlen(client->username) + 32);
500 Log_fatal("Out of memory");
501 tree_id = malloc(sizeof(uint32_t));
503 Log_fatal("Out of memory");
505 sendmsg = Msg_create(TextMessage);
506 sendmsg->payload.textMessage->message = message;
507 sendmsg->payload.textMessage->n_tree_id = 1;
508 sendmsg->payload.textMessage->tree_id = tree_id;
509 if (client->recording)
510 sprintf(message, "User %s started recording", client->username);
512 sprintf(message, "User %s stopped recording", client->username);
513 Client_send_message_except_ver(NULL, sendmsg, ~0x010203);
516 if (msg->payload.userState->has_channel_id) {
519 channelJoinResult_t result = Chan_userJoin_id_test(msg->payload.userState->channel_id, target);
521 if (result.CHJOIN_NOENTER || result.CHJOIN_NOTFOUND)
524 if (result.CHJOIN_WRONGPW) {
525 if (target == client && !client->isAdmin) {
526 sendPermissionDenied(client, "Wrong channel password");
529 /* Tricky one: if user hasn't the password, but is moved to the channel by admin then let
530 * the user in. Also let admin user in regardless of channel password.
531 * Take no action on other errors.
533 else if (!client->isAdmin)
537 leave_id = Chan_userJoin_id(msg->payload.userState->channel_id, target);
539 Log_debug("Removing channel ID %d", leave_id);
540 sendmsg = Msg_create(ChannelRemove);
541 sendmsg->payload.channelRemove->channel_id = leave_id;
544 if (result.CHJOIN_SILENT) {
545 if (!target->isSuppressed) {
546 msg->payload.userState->has_suppress = true;
547 msg->payload.userState->suppress = true;
548 target->isSuppressed = true;
551 else if (target->isSuppressed) {
552 msg->payload.userState->has_suppress = true;
553 msg->payload.userState->suppress = false;
554 target->isSuppressed = false;
557 if (msg->payload.userState->has_plugin_context) {
559 free(client->context);
560 client->context = malloc(msg->payload.userState->plugin_context.len);
561 if (client->context == NULL)
562 Log_fatal("Out of memory");
563 memcpy(client->context, msg->payload.userState->plugin_context.data,
564 msg->payload.userState->plugin_context.len);
566 break; /* Don't inform other users about this state */
571 Client_send_message_except(NULL, msg);
573 /* Need to send remove channel message _after_ UserState message */
575 Client_send_message_except(NULL, sendmsg);
579 if (!getBoolConf(ALLOW_TEXTMESSAGE))
581 msg->payload.textMessage->has_actor = true;
582 msg->payload.textMessage->actor = client->sessionId;
584 /* XXX - HTML is allowed and can't be turned off */
585 if (msg->payload.textMessage->n_tree_id > 0) {
586 sendPermissionDenied(client, "Tree message not supported");
590 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
593 for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
596 Chan_iterate(&ch_itr);
597 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
598 if (ch_itr != NULL) {
600 list_iterate(itr, &ch_itr->clients) {
602 c = list_get_entry(itr, client_t, chan_node);
603 if (c != client && !c->deaf && !c->self_deaf) {
605 Client_send_message(c, msg);
606 Log_debug("Text message to session ID %d", c->sessionId);
612 if (msg->payload.textMessage->n_session > 0) { /* To user */
615 for (i = 0; i < msg->payload.textMessage->n_session; i++) {
617 while (Client_iterate(&itr) != NULL) {
620 if (itr->sessionId == msg->payload.textMessage->session[i]) {
621 if (!itr->deaf && !itr->self_deaf) {
623 Client_send_message(itr, msg);
624 Log_debug("Text message to session ID %d", itr->sessionId);
630 Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
637 int i, j, count, targetId = msg->payload.voiceTarget->id;
638 struct _MumbleProto__VoiceTarget__Target *target;
640 if (!targetId || targetId >= 0x1f)
642 Voicetarget_add_id(client, targetId);
643 count = msg->payload.voiceTarget->n_targets;
646 for (i = 0; i < count; i++) {
647 target = msg->payload.voiceTarget->targets[i];
648 for (j = 0; j < target->n_session; j++)
649 Voicetarget_add_session(client, targetId, target->session[j]);
650 if (target->has_channel_id) {
651 bool_t linked = false, children = false;
652 if (target->has_links)
653 linked = target->links;
654 if (target->has_children)
655 children = target->children;
656 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
662 Log_debug("Version message received");
663 if (msg->payload.version->has_version) {
664 client->version = msg->payload.version->version;
665 Log_debug("Client version 0x%x", client->version);
667 if (msg->payload.version->release) {
668 if (client->release) free(client->release);
669 client->release = strdup(msg->payload.version->release);
670 Log_debug("Client release %s", client->release);
672 if (msg->payload.version->os) {
673 if (client->os) free(client->os);
674 client->os = strdup(msg->payload.version->os);
675 Log_debug("Client OS %s", client->os);
677 if (msg->payload.version->os_version) {
678 if (client->os_version) free(client->os_version);
679 client->os_version = strdup(msg->payload.version->os_version);
680 Log_debug("Client OS version %s", client->os_version);
683 case PermissionQuery:
684 Msg_inc_ref(msg); /* Re-use message */
685 msg->payload.permissionQuery->has_permissions = true;
688 msg->payload.permissionQuery->permissions = PERM_ADMIN;
690 msg->payload.permissionQuery->permissions = PERM_DEFAULT;
692 if (!getBoolConf(ALLOW_TEXTMESSAGE))
693 msg->payload.permissionQuery->permissions &= ~PERM_TEXTMESSAGE;
694 if (!getBoolConf(ENABLE_BAN))
695 msg->payload.permissionQuery->permissions &= ~PERM_BAN;
697 Client_send_message(client, msg);
700 client->bUDP = false;
701 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
705 channel_t *ch_itr, *parent, *newchan;
707 /* Don't allow any changes to existing channels */
708 if (msg->payload.channelState->has_channel_id) {
709 sendPermissionDenied(client, "Not supported by uMurmur");
712 /* Must have parent */
713 if (!msg->payload.channelState->has_parent) {
714 sendPermissionDenied(client, "Not supported by uMurmur");
718 if (msg->payload.channelState->name == NULL) {
719 sendPermissionDenied(client, "Not supported by uMurmur");
722 /* Must be temporary channel */
723 if (msg->payload.channelState->temporary != true) {
724 sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
727 /* Check channel name is OK */
728 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
729 sendPermissionDenied(client, "Channel name too long");
733 parent = Chan_fromId(msg->payload.channelState->parent);
737 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
738 if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
739 sendPermissionDenied(client, "Channel already exists");
746 /* Disallow temporary channels as siblings to temporary channels */
747 if (parent->temporary) {
748 sendPermissionDenied(client, "Parent channel is temporary channel");
752 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
753 * I don't know why so I don't do that here...
756 /* Create the channel */
757 newchan = Chan_createChannel(msg->payload.channelState->name,
758 msg->payload.channelState->description);
759 newchan->temporary = true;
760 if (msg->payload.channelState->has_position)
761 newchan->position = msg->payload.channelState->position;
762 Chan_addChannel(parent, newchan);
763 msg->payload.channelState->has_channel_id = true;
764 msg->payload.channelState->channel_id = newchan->id;
766 Client_send_message_except(NULL, msg);
768 /* Join the creating user */
769 sendmsg = Msg_create(UserState);
770 sendmsg->payload.userState->has_session = true;
771 sendmsg->payload.userState->session = client->sessionId;
772 sendmsg->payload.userState->has_channel_id = true;
773 sendmsg->payload.userState->channel_id = newchan->id;
775 if (client->isSuppressed) {
776 sendmsg->payload.userState->has_suppress = true;
777 sendmsg->payload.userState->suppress = false;
778 client->isSuppressed = false;
781 Client_send_message_except(NULL, sendmsg);
783 leave_id = Chan_userJoin(newchan, client);
785 Log_debug("Removing channel ID %d", leave_id);
786 sendmsg = Msg_create(ChannelRemove);
787 sendmsg->payload.channelRemove->channel_id = leave_id;
788 Client_send_message_except(NULL, sendmsg);
795 client_t *target = NULL;
796 codec_t *codec_itr = NULL;
798 bool_t details = true;
800 if (msg->payload.userStats->has_stats_only)
801 details = !msg->payload.userStats->stats_only;
803 if (!msg->payload.userStats->has_session)
804 sendPermissionDenied(client, "Not supported by uMurmur");
805 while (Client_iterate(&target) != NULL) {
806 if (!IS_AUTH(target))
808 if (target->sessionId == msg->payload.userStats->session)
811 if (!target) /* Not found */
815 * Differences from Murmur:
816 * o Ignoring certificates intentionally
817 * o Ignoring channel local determining
820 sendmsg = Msg_create(UserStats);
821 sendmsg->payload.userStats->session = msg->payload.userStats->session;
822 sendmsg->payload.userStats->from_client->has_good = true;
823 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
824 sendmsg->payload.userStats->from_client->has_late = true;
825 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
826 sendmsg->payload.userStats->from_client->has_lost = true;
827 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
828 sendmsg->payload.userStats->from_client->has_resync = true;
829 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
831 sendmsg->payload.userStats->from_server->has_good = true;
832 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
833 sendmsg->payload.userStats->from_server->has_late = true;
834 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
835 sendmsg->payload.userStats->from_server->has_lost = true;
836 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
837 sendmsg->payload.userStats->from_server->has_resync = true;
838 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
840 sendmsg->payload.userStats->has_udp_packets = true;
841 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
842 sendmsg->payload.userStats->has_udp_ping_avg = true;
843 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
844 sendmsg->payload.userStats->has_udp_ping_var = true;
845 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
847 sendmsg->payload.userStats->has_tcp_ping_avg = true;
848 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
849 sendmsg->payload.userStats->has_tcp_ping_var = true;
850 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
851 sendmsg->payload.userStats->has_tcp_packets = true;
852 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
856 sendmsg->payload.userStats->version->has_version = true;
857 sendmsg->payload.userStats->version->version = target->version;
859 sendmsg->payload.userStats->version->release = strdup(target->release);
861 sendmsg->payload.userStats->version->os = strdup(target->os);
862 if (target->os_version)
863 sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
865 sendmsg->payload.userStats->n_celt_versions = target->codec_count;
866 sendmsg->payload.userStats->celt_versions = malloc(sizeof(int32_t) * target->codec_count);
867 if (!sendmsg->payload.userStats->celt_versions)
868 Log_fatal("Out of memory");
870 while (Client_codec_iterate(target, &codec_itr) != NULL)
871 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
873 sendmsg->payload.userStats->has_opus = true;
874 sendmsg->payload.userStats->opus = target->bOpus;
877 sendmsg->payload.userStats->has_address = true;
878 sendmsg->payload.userStats->address.data = malloc(sizeof(uint8_t) * 16);
879 if (!sendmsg->payload.userStats->address.data)
880 Log_fatal("Out of memory");
881 memset(sendmsg->payload.userStats->address.data, 0, 16);
882 /* ipv4 representation as ipv6 address. Supposedly correct. */
883 memset(&sendmsg->payload.userStats->address.data[10], 0xff, 2); /* IPv4 */
884 if(target->remote_tcp.ss_family == AF_INET)
885 memcpy(&sendmsg->payload.userStats->address.data[12], &((struct sockaddr_in*)&target->remote_tcp)->sin_addr, 4);
887 memcpy(&sendmsg->payload.userStats->address.data[0], &((struct sockaddr_in6*)&target->remote_tcp)->sin6_addr, 16);
888 sendmsg->payload.userStats->address.len = 16;
891 sendmsg->payload.userStats->has_bandwidth = true;
892 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
895 sendmsg->payload.userStats->has_onlinesecs = true;
896 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;
898 sendmsg->payload.userStats->has_idlesecs = true;
899 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;
900 Client_send_message(client, sendmsg);
905 /* Only admin can issue this */
906 if (!client->isAdmin) {
907 sendPermissionDenied(client, "Permission denied");
910 while (Client_iterate(&target) != NULL) {
911 if (target->sessionId == msg->payload.userRemove->session)
914 if (target == NULL) {
915 Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
918 msg->payload.userRemove->session = target->sessionId;
919 msg->payload.userRemove->has_actor = true;
920 msg->payload.userRemove->actor = client->sessionId;
922 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
923 if (!getBoolConf(ENABLE_BAN))
924 sendPermissionDenied(client, "Permission denied");
926 Ban_UserBan(target, msg->payload.userRemove->reason);
928 Log_info_client(target, "User kicked. Reason: '%s'",
929 strlen(msg->payload.userRemove->reason) == 0 ? "N/A" : msg->payload.userRemove->reason);
934 Client_send_message_except(NULL, msg);
935 Client_close(target);
938 /* Only admin can issue this */
939 if (!client->isAdmin) {
940 sendPermissionDenied(client, "Permission denied");
943 if (!getBoolConf(ENABLE_BAN)) {
944 sendPermissionDenied(client, "Permission denied");
947 if (msg->payload.banList->has_query && msg->payload.banList->query) {
948 /* Create banlist message and add banentrys */
949 sendmsg = Ban_getBanList();
950 Client_send_message(client, sendmsg);
952 /* Clear banlist and set the new one */
954 Ban_putBanList(msg, msg->payload.banList->n_bans);
958 /* Permission denied for all these messages. Not implemented. */
961 case ContextActionAdd:
965 sendPermissionDenied(client, "Not supported by uMurmur");
969 Log_warn("Message %d not handled", msg->messageType);
978 Client_close(client);