1 /* Copyright (C) 2009-2012, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2012, 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 extern channel_t *defaultChan;
49 extern int iCodecAlpha, iCodecBeta;
50 extern bool_t bPreferAlpha;
52 static void sendServerReject(client_t *client, const char *reason, MumbleProto__Reject__RejectType type)
54 message_t *msg = Msg_create(Reject);
55 msg->payload.reject->reason = strdup(reason);
56 msg->payload.reject->type = type;
57 msg->payload.reject->has_type = true;
58 Client_send_message(client, msg);
60 Log_info_client(client, "Server reject reason: %s", reason);
63 static void sendPermissionDenied(client_t *client, const char *reason)
65 message_t *msg = Msg_create(PermissionDenied);
66 msg->payload.permissionDenied->has_type = true;
67 msg->payload.permissionDenied->type = MUMBLE_PROTO__PERMISSION_DENIED__DENY_TYPE__Text;
68 msg->payload.permissionDenied->reason = strdup(reason);
69 Client_send_message(client, msg);
72 static void addTokens(client_t *client, message_t *msg)
75 if (client->tokencount + msg->payload.authenticate->n_tokens < MAX_TOKENS) {
76 /* Check lengths first */
77 for (i = 0; i < msg->payload.authenticate->n_tokens; i++) {
78 if (strlen(msg->payload.authenticate->tokens[i]) > MAX_TOKENSIZE - 1) {
79 sendPermissionDenied(client, "Too long token");
84 for (i = 0; i < msg->payload.authenticate->n_tokens; i++) {
85 Log_debug("Adding token '%s' to client '%s'", msg->payload.authenticate->tokens[i], client->username);
86 Client_token_add(client, msg->payload.authenticate->tokens[i]);
90 sendPermissionDenied(client, "Too many tokens");
93 void Mh_handle_message(client_t *client, message_t *msg)
95 message_t *sendmsg = NULL;
96 channel_t *ch_itr = NULL;
97 client_t *client_itr, *target;
99 if (!client->authenticated && !(msg->messageType == Authenticate ||
100 msg->messageType == Version)) {
104 switch (msg->messageType) {
110 case PermissionQuery:
113 Timer_restart(&client->idleTime);
116 switch (msg->messageType) {
118 Log_debug("Authenticate message received");
120 if (IS_AUTH(client) || !msg->payload.authenticate->username) {
121 /* Authenticate message might be sent when a tokens are changed by the user.*/
122 Client_token_free(client); /* Clear the token list */
123 if (msg->payload.authenticate->n_tokens > 0) {
124 Log_debug("Tokens in auth message from '%s'. n_tokens = %d", client->username,
125 msg->payload.authenticate->n_tokens);
126 addTokens(client, msg);
131 if (SSLi_getSHA1Hash(client->ssl, client->hash) && Ban_isBanned(client)) {
133 SSLi_hash2hex(client->hash, hexhash);
134 Log_info("Client with hash '%s' is banned. Disconnecting", hexhash);
138 client->authenticated = true;
141 while (Client_iterate(&client_itr) != NULL) {
142 if (!IS_AUTH(client_itr))
144 if (client_itr->username && strncmp(client_itr->username, msg->payload.authenticate->username, MAX_USERNAME) == 0) {
146 sprintf(buf, "Username already in use");
147 Log_debug("Username already in use");
148 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__UsernameInUse);
152 if (strlen(getStrConf(PASSPHRASE)) > 0) {
153 if (!msg->payload.authenticate->password ||
154 (msg->payload.authenticate->password &&
155 strncmp(getStrConf(PASSPHRASE), msg->payload.authenticate->password, MAX_TEXT) != 0)) {
157 sprintf(buf, "Wrong server password");
158 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__WrongServerPW);
159 Log_debug("Wrong server password: '%s'", msg->payload.authenticate->password != NULL ?
160 msg->payload.authenticate->password : "(null)");
164 if (strlen(msg->payload.authenticate->username) == 0 ||
165 strlen(msg->payload.authenticate->username) >= MAX_USERNAME) { /* XXX - other invalid names? */
167 sprintf(buf, "Invalid username");
168 Log_debug("Invalid username");
169 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__InvalidUsername);
173 if (Client_count() >= getIntConf(MAX_CLIENTS)) {
175 snprintf(buf, 64, "Server is full (max %d users)", getIntConf(MAX_CLIENTS));
176 sendServerReject(client, buf, MUMBLE_PROTO__REJECT__REJECT_TYPE__ServerFull);
181 client->username = strdup(msg->payload.authenticate->username);
184 if (msg->payload.authenticate->n_tokens > 0)
185 addTokens(client, msg);
187 /* Check if admin PW among tokens */
188 if (strlen(getStrConf(ADMIN_PASSPHRASE)) > 0 &&
189 Client_token_match(client, getStrConf(ADMIN_PASSPHRASE))) {
190 client->isAdmin = true;
191 Log_info_client(client, "User provided admin password");
194 /* Setup UDP encryption */
195 CryptState_init(&client->cryptState);
196 CryptState_genKey(&client->cryptState);
197 sendmsg = Msg_create(CryptSetup);
198 sendmsg->payload.cryptSetup->has_key = true;
199 sendmsg->payload.cryptSetup->key.data = client->cryptState.raw_key;
200 sendmsg->payload.cryptSetup->key.len = AES_BLOCK_SIZE;
201 sendmsg->payload.cryptSetup->has_server_nonce = true;
202 sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.encrypt_iv;
203 sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
204 sendmsg->payload.cryptSetup->has_client_nonce = true;
205 sendmsg->payload.cryptSetup->client_nonce.data = client->cryptState.decrypt_iv;
206 sendmsg->payload.cryptSetup->client_nonce.len = AES_BLOCK_SIZE;
207 Client_send_message(client, sendmsg);
210 Chan_userJoin(defaultChan, client); /* Join default channel */
213 Log_debug("Client %d has %d CELT codecs", client->sessionId,
214 msg->payload.authenticate->n_celt_versions);
215 if (msg->payload.authenticate->n_celt_versions > 0) {
218 client->codec_count = msg->payload.authenticate->n_celt_versions;
220 for (i = 0; i < client->codec_count; i++)
221 Client_codec_add(client, msg->payload.authenticate->celt_versions[i]);
223 while (Client_codec_iterate(client, &codec_itr) != NULL)
224 Log_debug("Client %d CELT codec ver 0x%x", client->sessionId, codec_itr->codec);
227 Client_codec_add(client, (int32_t)0x8000000a);
228 client->codec_count = 1;
231 recheckCodecVersions();
233 sendmsg = Msg_create(CodecVersion);
234 sendmsg->payload.codecVersion->alpha = iCodecAlpha;
235 sendmsg->payload.codecVersion->beta = iCodecBeta;
236 sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
237 Client_send_message(client, sendmsg);
239 /* Iterate channels and send channel info */
241 while (Chan_iterate(&ch_itr) != NULL) {
242 sendmsg = Msg_create(ChannelState);
243 sendmsg->payload.channelState->has_channel_id = true;
244 sendmsg->payload.channelState->channel_id = ch_itr->id;
245 if (ch_itr->id != 0) {
246 sendmsg->payload.channelState->has_parent = true;
247 sendmsg->payload.channelState->parent = ch_itr->parent->id;
249 sendmsg->payload.channelState->name = strdup(ch_itr->name);
251 sendmsg->payload.channelState->description = strdup(ch_itr->desc);
252 Log_debug("Send channel info: %s", sendmsg->payload.channelState->name);
253 Client_send_message(client, sendmsg);
256 /* Iterate channels and send channel links info */
258 while (Chan_iterate(&ch_itr) != NULL) {
259 if (ch_itr->linkcount > 0) { /* Has links */
264 sendmsg = Msg_create(ChannelState);
265 sendmsg->payload.channelState->has_channel_id = true;
266 sendmsg->payload.channelState->channel_id = ch_itr->id;
267 sendmsg->payload.channelState->n_links = ch_itr->linkcount;
269 links = (uint32_t *)malloc(ch_itr->linkcount * sizeof(uint32_t));
270 list_iterate(itr, &ch_itr->channel_links) { /* Iterate links */
272 ch = list_get_entry(itr, channel_t, link_node);
275 sendmsg->payload.channelState->links = links;
276 Client_send_message(client, sendmsg);
280 /* Send user state for connecting user to other users */
281 sendmsg = Msg_create(UserState);
282 sendmsg->payload.userState->has_session = true;
283 sendmsg->payload.userState->session = client->sessionId;
284 sendmsg->payload.userState->name = strdup(client->username);
285 sendmsg->payload.userState->has_channel_id = true;
286 sendmsg->payload.userState->channel_id = ((channel_t *)client->channel)->id;
288 Client_send_message_except(client, sendmsg);
291 while (Client_iterate(&client_itr) != NULL) {
292 if (!IS_AUTH(client_itr))
294 sendmsg = Msg_create(UserState);
295 sendmsg->payload.userState->has_session = true;
296 sendmsg->payload.userState->session = client_itr->sessionId;
297 sendmsg->payload.userState->name = strdup(client_itr->username);
298 sendmsg->payload.userState->has_channel_id = true;
299 sendmsg->payload.userState->channel_id = ((channel_t *)client_itr->channel)->id;
301 if (client_itr->self_deaf) {
302 sendmsg->payload.userState->has_self_deaf = true;
303 sendmsg->payload.userState->self_deaf = true;
305 if (client_itr->self_mute) {
306 sendmsg->payload.userState->has_self_mute = true;
307 sendmsg->payload.userState->self_mute = true;
309 if (client_itr->deaf) {
310 sendmsg->payload.userState->has_deaf = true;
311 sendmsg->payload.userState->deaf = true;
313 if (client_itr->mute) {
314 sendmsg->payload.userState->has_mute = true;
315 sendmsg->payload.userState->mute = true;
317 if (client_itr->recording) {
318 sendmsg->payload.userState->has_recording = true;
319 sendmsg->payload.userState->recording = true;
321 Client_send_message(client, sendmsg);
325 sendmsg = Msg_create(ServerSync);
326 sendmsg->payload.serverSync->has_session = true;
327 sendmsg->payload.serverSync->session = client->sessionId;
328 sendmsg->payload.serverSync->welcome_text = strdup(getStrConf(WELCOMETEXT));
329 sendmsg->payload.serverSync->has_max_bandwidth = true;
330 sendmsg->payload.serverSync->max_bandwidth = getIntConf(MAX_BANDWIDTH);
331 Client_send_message(client, sendmsg);
333 /* Server config message */
334 sendmsg = Msg_create(ServerConfig);
335 sendmsg->payload.serverConfig->has_allow_html = true;
336 sendmsg->payload.serverConfig->allow_html = true; /* Support this? */
337 sendmsg->payload.serverConfig->has_message_length = true;
338 sendmsg->payload.serverConfig->message_length = MAX_TEXT; /* Hardcoded */
339 sendmsg->payload.serverConfig->has_image_message_length = true;
340 sendmsg->payload.serverConfig->image_message_length = 0; /* XXX */
341 Client_send_message(client, sendmsg);
343 Log_info_client(client, "User %s authenticated", client->username);
347 if (msg->payload.ping->has_good)
348 client->cryptState.uiRemoteGood = msg->payload.ping->good;
349 if (msg->payload.ping->has_late)
350 client->cryptState.uiRemoteLate = msg->payload.ping->late;
351 if (msg->payload.ping->has_lost)
352 client->cryptState.uiRemoteLost = msg->payload.ping->lost;
353 if (msg->payload.ping->has_resync)
354 client->cryptState.uiRemoteResync = msg->payload.ping->resync;
356 Log_debug("Ping <-: %d %d %d %d",
357 client->cryptState.uiRemoteGood, client->cryptState.uiRemoteLate,
358 client->cryptState.uiRemoteLost, client->cryptState.uiRemoteResync
361 client->UDPPingAvg = msg->payload.ping->udp_ping_avg;
362 client->UDPPingVar = msg->payload.ping->udp_ping_var;
363 client->TCPPingAvg = msg->payload.ping->tcp_ping_avg;
364 client->TCPPingVar = msg->payload.ping->tcp_ping_var;
365 client->UDPPackets = msg->payload.ping->udp_packets;
366 client->TCPPackets = msg->payload.ping->tcp_packets;
368 sendmsg = Msg_create(Ping);
370 sendmsg->payload.ping->timestamp = msg->payload.ping->timestamp;
371 sendmsg->payload.ping->has_timestamp = true;
372 sendmsg->payload.ping->good = client->cryptState.uiGood;
373 sendmsg->payload.ping->has_good = true;
374 sendmsg->payload.ping->late = client->cryptState.uiLate;
375 sendmsg->payload.ping->has_late = true;
376 sendmsg->payload.ping->lost = client->cryptState.uiLost;
377 sendmsg->payload.ping->has_lost = true;
378 sendmsg->payload.ping->resync = client->cryptState.uiResync;
379 sendmsg->payload.ping->has_resync = true;
381 Client_send_message(client, sendmsg);
382 Log_debug("Ping ->: %d %d %d %d",
383 client->cryptState.uiGood, client->cryptState.uiLate,
384 client->cryptState.uiLost, client->cryptState.uiResync);
388 Log_debug("Voice channel crypt resync requested");
389 if (!msg->payload.cryptSetup->has_client_nonce) {
390 sendmsg = Msg_create(CryptSetup);
391 sendmsg->payload.cryptSetup->has_server_nonce = true;
392 sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.decrypt_iv;
393 sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
394 Client_send_message(client, sendmsg);
396 memcpy(client->cryptState.decrypt_iv, msg->payload.cryptSetup->client_nonce.data, AES_BLOCK_SIZE);
397 client->cryptState.uiResync++;
402 /* Only allow state changes for for the self user unless an admin is issuing */
403 if (msg->payload.userState->has_session &&
404 msg->payload.userState->session != client->sessionId && !client->isAdmin) {
405 sendPermissionDenied(client, "Permission denied");
408 if (msg->payload.userState->has_session && msg->payload.userState->session != client->sessionId) {
409 while (Client_iterate(&target) != NULL) {
410 if (target->sessionId == msg->payload.userState->session)
413 if (target == NULL) {
414 Log_warn("Client with sessionID %d not found", msg->payload.userState->session);
419 if (msg->payload.userState->has_user_id || msg->payload.userState->has_suppress ||
420 msg->payload.userState->has_priority_speaker || msg->payload.userState->has_texture) {
421 sendPermissionDenied(client, "Not supported by uMurmur");
428 msg->payload.userState->has_session = true;
429 msg->payload.userState->session = target->sessionId;
430 msg->payload.userState->has_actor = true;
431 msg->payload.userState->actor = client->sessionId;
433 if (msg->payload.userState->has_deaf) {
434 target->deaf = msg->payload.userState->deaf;
436 msg->payload.userState->has_mute = true;
437 msg->payload.userState->mute = true;
440 if (msg->payload.userState->has_mute) {
441 target->mute = msg->payload.userState->mute;
443 msg->payload.userState->has_deaf = true;
444 msg->payload.userState->deaf = false;
445 target->deaf = false;
448 if (msg->payload.userState->has_self_deaf) {
449 client->self_deaf = msg->payload.userState->self_deaf;
451 if (msg->payload.userState->has_self_mute) {
452 client->self_mute = msg->payload.userState->self_mute;
453 if (!client->self_mute) {
454 msg->payload.userState->has_self_deaf = true;
455 msg->payload.userState->self_deaf = false;
456 client->self_deaf = false;
459 if (msg->payload.userState->has_recording &&
460 msg->payload.userState->recording != client->recording) {
461 client->recording = msg->payload.userState->recording;
465 message = malloc(strlen(client->username) + 32);
467 Log_fatal("Out of memory");
468 tree_id = malloc(sizeof(uint32_t));
470 Log_fatal("Out of memory");
472 sendmsg = Msg_create(TextMessage);
473 sendmsg->payload.textMessage->message = message;
474 sendmsg->payload.textMessage->n_tree_id = 1;
475 sendmsg->payload.textMessage->tree_id = tree_id;
476 if (client->recording)
477 sprintf(message, "User %s started recording", client->username);
479 sprintf(message, "User %s stopped recording", client->username);
480 Client_send_message_except_ver(NULL, sendmsg, ~0x010203);
483 if (msg->payload.userState->has_channel_id) {
485 channelJoinResult_t chjoin_rc = Chan_userJoin_id_test(msg->payload.userState->channel_id, target);
487 if (chjoin_rc != CHJOIN_OK) {
488 if (chjoin_rc == CHJOIN_WRONGPW && target == client && !client->isAdmin) {
489 sendPermissionDenied(client, "Wrong channel password");
492 /* Tricky one: if user hasn't the password, but is moved to the channel by admin then let
493 * the user in. Also let admin user in regardless of pchannel password.
494 * Take no action on other errors.
496 else if (!(chjoin_rc == CHJOIN_WRONGPW && (target != client || client->isAdmin)))
500 leave_id = Chan_userJoin_id(msg->payload.userState->channel_id, target);
502 Log_debug("Removing channel ID %d", leave_id);
503 sendmsg = Msg_create(ChannelRemove);
504 sendmsg->payload.channelRemove->channel_id = leave_id;
507 if (msg->payload.userState->has_plugin_context) {
509 free(client->context);
510 client->context = malloc(msg->payload.userState->plugin_context.len);
511 if (client->context == NULL)
512 Log_fatal("Out of memory");
513 memcpy(client->context, msg->payload.userState->plugin_context.data,
514 msg->payload.userState->plugin_context.len);
516 break; /* Don't inform other users about this state */
521 Client_send_message_except(NULL, msg);
523 /* Need to send remove channel message _after_ UserState message */
525 Client_send_message_except(NULL, sendmsg);
529 if (!getBoolConf(ALLOW_TEXTMESSAGE))
531 msg->payload.textMessage->has_actor = true;
532 msg->payload.textMessage->actor = client->sessionId;
534 /* XXX - HTML is allowed and can't be turned off */
535 if (msg->payload.textMessage->n_tree_id > 0) {
536 sendPermissionDenied(client, "Tree message not supported");
540 if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
543 for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
546 Chan_iterate(&ch_itr);
547 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
548 if (ch_itr != NULL) {
550 list_iterate(itr, &ch_itr->clients) {
552 c = list_get_entry(itr, client_t, chan_node);
553 if (c != client && !c->deaf) {
555 Client_send_message(c, msg);
556 Log_debug("Text message to session ID %d", c->sessionId);
562 if (msg->payload.textMessage->n_session > 0) { /* To user */
565 for (i = 0; i < msg->payload.textMessage->n_session; i++) {
567 while (Client_iterate(&itr) != NULL) {
570 if (itr->sessionId == msg->payload.textMessage->session[i]) {
573 Client_send_message(itr, msg);
574 Log_debug("Text message to session ID %d", itr->sessionId);
580 Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
587 int i, j, count, targetId = msg->payload.voiceTarget->id;
588 struct _MumbleProto__VoiceTarget__Target *target;
590 if (!targetId || targetId >= 0x1f)
592 Voicetarget_add_id(client, targetId);
593 count = msg->payload.voiceTarget->n_targets;
596 for (i = 0; i < count; i++) {
597 target = msg->payload.voiceTarget->targets[i];
598 for (j = 0; j < target->n_session; j++)
599 Voicetarget_add_session(client, targetId, target->session[j]);
600 if (target->has_channel_id) {
601 bool_t linked = false, children = false;
602 if (target->has_links)
603 linked = target->links;
604 if (target->has_children)
605 children = target->children;
606 Voicetarget_add_channel(client, targetId, target->channel_id, linked, children);
612 Log_debug("Version message received");
613 if (msg->payload.version->has_version) {
614 client->version = msg->payload.version->version;
615 Log_debug("Client version 0x%x", client->version);
617 if (msg->payload.version->release) {
618 if (client->release) free(client->release);
619 client->release = strdup(msg->payload.version->release);
620 Log_debug("Client release %s", client->release);
622 if (msg->payload.version->os) {
623 if (client->os) free(client->os);
624 client->os = strdup(msg->payload.version->os);
625 Log_debug("Client OS %s", client->os);
627 if (msg->payload.version->os_version) {
628 if (client->os_version) free(client->os_version);
629 client->os_version = strdup(msg->payload.version->os_version);
630 Log_debug("Client OS version %s", client->os_version);
633 case PermissionQuery:
634 Msg_inc_ref(msg); /* Re-use message */
635 msg->payload.permissionQuery->has_permissions = true;
638 msg->payload.permissionQuery->permissions = PERM_ADMIN;
640 msg->payload.permissionQuery->permissions = PERM_DEFAULT;
642 if (!getBoolConf(ALLOW_TEXTMESSAGE))
643 msg->payload.permissionQuery->permissions &= ~PERM_TEXTMESSAGE;
644 if (!getBoolConf(ENABLE_BAN))
645 msg->payload.permissionQuery->permissions &= ~PERM_BAN;
647 Client_send_message(client, msg);
650 client->bUDP = false;
651 Client_voiceMsg(client, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
655 channel_t *ch_itr, *parent, *newchan;
657 /* Don't allow any changes to existing channels */
658 if (msg->payload.channelState->has_channel_id) {
659 sendPermissionDenied(client, "Not supported by uMurmur");
662 /* Must have parent */
663 if (!msg->payload.channelState->has_parent) {
664 sendPermissionDenied(client, "Not supported by uMurmur");
668 if (msg->payload.channelState->name == NULL) {
669 sendPermissionDenied(client, "Not supported by uMurmur");
672 /* Must be temporary channel */
673 if (msg->payload.channelState->temporary != true) {
674 sendPermissionDenied(client, "Only temporary channels are supported by uMurmur");
677 /* Check channel name is OK */
678 if (strlen(msg->payload.channelState->name) > MAX_TEXT) {
679 sendPermissionDenied(client, "Channel name too long");
683 parent = Chan_fromId(msg->payload.channelState->parent);
687 while (Chan_iterate_siblings(parent, &ch_itr) != NULL) {
688 if (strcmp(ch_itr->name, msg->payload.channelState->name) == 0) {
689 sendPermissionDenied(client, "Channel already exists");
696 /* Disallow temporary channels as siblings to temporary channels */
697 if (parent->temporary) {
698 sendPermissionDenied(client, "Parent channel is temporary channel");
702 /* XXX - Murmur looks for "\\w" and sends perm denied if not found.
703 * I don't know why so I don't do that here...
706 /* Create the channel */
707 newchan = Chan_createChannel(msg->payload.channelState->name,
708 msg->payload.channelState->description);
709 newchan->temporary = true;
710 Chan_addChannel(parent, newchan);
711 msg->payload.channelState->has_channel_id = true;
712 msg->payload.channelState->channel_id = newchan->id;
714 Client_send_message_except(NULL, msg);
716 /* Join the creating user */
717 sendmsg = Msg_create(UserState);
718 sendmsg->payload.userState->has_session = true;
719 sendmsg->payload.userState->session = client->sessionId;
720 sendmsg->payload.userState->has_channel_id = true;
721 sendmsg->payload.userState->channel_id = newchan->id;
722 Client_send_message_except(NULL, sendmsg);
724 leave_id = Chan_userJoin(newchan, client);
726 Log_debug("Removing channel ID %d", leave_id);
727 sendmsg = Msg_create(ChannelRemove);
728 sendmsg->payload.channelRemove->channel_id = leave_id;
729 Client_send_message_except(NULL, sendmsg);
736 client_t *target = NULL;
737 codec_t *codec_itr = NULL;
739 bool_t details = true;
741 if (msg->payload.userStats->has_stats_only)
742 details = !msg->payload.userStats->stats_only;
744 if (!msg->payload.userStats->has_session)
745 sendPermissionDenied(client, "Not supported by uMurmur");
746 while (Client_iterate(&target) != NULL) {
747 if (!IS_AUTH(target))
749 if (target->sessionId == msg->payload.userStats->session)
752 if (!target) /* Not found */
756 * Differences from Murmur:
757 * o Ignoring certificates intentionally
758 * o Ignoring channel local determining
761 sendmsg = Msg_create(UserStats);
762 sendmsg->payload.userStats->session = msg->payload.userStats->session;
763 sendmsg->payload.userStats->from_client->has_good = true;
764 sendmsg->payload.userStats->from_client->good = target->cryptState.uiGood;
765 sendmsg->payload.userStats->from_client->has_late = true;
766 sendmsg->payload.userStats->from_client->late = target->cryptState.uiLate;
767 sendmsg->payload.userStats->from_client->has_lost = true;
768 sendmsg->payload.userStats->from_client->lost = target->cryptState.uiLost;
769 sendmsg->payload.userStats->from_client->has_resync = true;
770 sendmsg->payload.userStats->from_client->resync = target->cryptState.uiResync;
772 sendmsg->payload.userStats->from_server->has_good = true;
773 sendmsg->payload.userStats->from_server->good = target->cryptState.uiRemoteGood;
774 sendmsg->payload.userStats->from_server->has_late = true;
775 sendmsg->payload.userStats->from_server->late = target->cryptState.uiRemoteLate;
776 sendmsg->payload.userStats->from_server->has_lost = true;
777 sendmsg->payload.userStats->from_server->lost = target->cryptState.uiRemoteLost;
778 sendmsg->payload.userStats->from_server->has_resync = true;
779 sendmsg->payload.userStats->from_server->resync = target->cryptState.uiRemoteResync;
781 sendmsg->payload.userStats->has_udp_packets = true;
782 sendmsg->payload.userStats->udp_packets = target->UDPPackets;
783 sendmsg->payload.userStats->has_udp_ping_avg = true;
784 sendmsg->payload.userStats->udp_ping_avg = target->UDPPingAvg;
785 sendmsg->payload.userStats->has_udp_ping_var = true;
786 sendmsg->payload.userStats->udp_ping_var = target->UDPPingVar;
788 sendmsg->payload.userStats->has_tcp_ping_avg = true;
789 sendmsg->payload.userStats->tcp_ping_avg = target->TCPPingAvg;
790 sendmsg->payload.userStats->has_tcp_ping_var = true;
791 sendmsg->payload.userStats->tcp_ping_var = target->TCPPingVar;
792 sendmsg->payload.userStats->has_tcp_packets = true;
793 sendmsg->payload.userStats->tcp_packets = target->TCPPackets;
797 sendmsg->payload.userStats->version->has_version = true;
798 sendmsg->payload.userStats->version->version = target->version;
799 sendmsg->payload.userStats->version->release = strdup(target->release);
800 sendmsg->payload.userStats->version->os = strdup(target->os);
801 sendmsg->payload.userStats->version->os_version = strdup(target->os_version);
803 sendmsg->payload.userStats->n_celt_versions = target->codec_count;
804 sendmsg->payload.userStats->celt_versions = malloc(sizeof(int32_t) * target->codec_count);
805 if (!sendmsg->payload.userStats->celt_versions)
806 Log_fatal("Out of memory");
808 while (Client_codec_iterate(target, &codec_itr) != NULL)
809 sendmsg->payload.userStats->celt_versions[i++] = codec_itr->codec;
812 sendmsg->payload.userStats->has_address = true;
813 sendmsg->payload.userStats->address.data = malloc(sizeof(uint8_t) * 16);
814 if (!sendmsg->payload.userStats->address.data)
815 Log_fatal("Out of memory");
816 memset(sendmsg->payload.userStats->address.data, 0, 16);
817 /* ipv4 representation as ipv6 address. Supposedly correct. */
818 memcpy(&sendmsg->payload.userStats->address.data[12], &target->remote_tcp.sin_addr, 4);
819 memset(&sendmsg->payload.userStats->address.data[10], 0xff, 2); /* IPv4 */
820 sendmsg->payload.userStats->address.len = 16;
823 sendmsg->payload.userStats->has_bandwidth = true;
824 sendmsg->payload.userStats->bandwidth = target->availableBandwidth;
827 sendmsg->payload.userStats->has_onlinesecs = true;
828 sendmsg->payload.userStats->onlinesecs = Timer_elapsed(&target->connectTime) / 1000000LL;
830 sendmsg->payload.userStats->has_idlesecs = true;
831 sendmsg->payload.userStats->idlesecs = Timer_elapsed(&target->idleTime) / 1000000LL;
832 Client_send_message(client, sendmsg);
837 /* Only admin can issue this */
838 if (!client->isAdmin) {
839 sendPermissionDenied(client, "Permission denied");
842 while (Client_iterate(&target) != NULL) {
843 if (target->sessionId == msg->payload.userRemove->session)
846 if (target == NULL) {
847 Log_warn("Client with sessionId %d not found", msg->payload.userRemove->session);
850 msg->payload.userRemove->session = target->sessionId;
851 msg->payload.userRemove->has_actor = true;
852 msg->payload.userRemove->actor = client->sessionId;
854 if (msg->payload.userRemove->has_ban && msg->payload.userRemove->ban) {
855 if (!getBoolConf(ENABLE_BAN))
856 sendPermissionDenied(client, "Permission denied");
858 Ban_UserBan(target, msg->payload.userRemove->reason);
860 Log_info_client(target, "User kicked. Reason: '%s'",
861 strlen(msg->payload.userRemove->reason) == 0 ? "N/A" : msg->payload.userRemove->reason);
866 Client_send_message_except(NULL, msg);
867 Client_close(target);
870 /* Only admin can issue this */
871 if (!client->isAdmin) {
872 sendPermissionDenied(client, "Permission denied");
875 if (!getBoolConf(ENABLE_BAN)) {
876 sendPermissionDenied(client, "Permission denied");
879 if (msg->payload.banList->has_query && msg->payload.banList->query) {
880 /* Create banlist message and add banentrys */
881 sendmsg = Ban_getBanList();
882 Client_send_message(client, sendmsg);
884 /* Clear banlist and set the new one */
886 Ban_putBanList(msg, msg->payload.banList->n_bans);
890 /* Permission denied for all these messages. Not implemented. */
893 case ContextActionAdd:
897 sendPermissionDenied(client, "Not supported by uMurmur");
901 Log_warn("Message %d not handled", msg->messageType);
910 Client_close(client);