1 /* Copyright (C) 2009, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2009, 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.
32 #include <openssl/aes.h>
42 extern channel_t *defaultChan;
44 static void sendServerReject(client_t *client, const char *reason, rejectType_t type)
46 message_t *msg = Msg_create(ServerReject);
47 msg->sessionId = client->sessionId;
48 strcpy(msg->payload.serverReject.reason, reason);
49 msg->payload.serverReject.type = type;
50 Client_send_message(client, msg);
53 static void sendPermissionDenied(client_t *client, const char *reason)
55 message_t *msg = Msg_create(PermissionDenied);
56 msg->sessionId = client->sessionId;
57 strncpy(msg->payload.permissionDenied.reason, reason, MAX_TEXT);
58 Client_send_message(client, msg);
61 void Mh_handle_message(client_t *client, message_t *msg)
64 channel_t *ch_itr = NULL;
67 switch (msg->messageType) {
68 case ServerAuthenticate:
70 * 1. Check stuff, Serverreject if not ok
71 * 2. Setup UDP encryption -> MessageCryptSetup
73 * 4. MessageChannelAdd + MessageChannelDescUpdate for all channels
74 * 5. (MessageChannelLink)
75 * 6. MessageServerJoin
76 * 7. MessagePlayerMove
77 * 8. MessageServerJoin for all connected users
78 * 9. PlayerDeaf/PlayerMute/PlayerSelfMuteDeaf for all users it applies to
79 * 10. MessageServerSync
81 if (msg->payload.serverAuthenticate.version != MESSAGE_STREAM_VERSION) {
83 sprintf(buf, "Wrong version of mumble protocol (client: %d, server: %d)",
84 msg->payload.serverAuthenticate.version, MESSAGE_STREAM_VERSION);
85 sendServerReject(client, buf, WrongVersion);
90 while (Client_iterate(&client_itr) != NULL) {
91 if (!IS_AUTH(client_itr))
93 if (strncmp(client_itr->playerName, msg->payload.serverAuthenticate.userName, MAX_TEXT) == 0) {
95 sprintf(buf, "Username already in use");
96 sendServerReject(client, buf, UsernameInUse);
101 if (strncmp(getStrConf(PASSPHRASE), msg->payload.serverAuthenticate.password, MAX_TEXT) != 0) {
103 sprintf(buf, "Wrong server password");
104 sendServerReject(client, buf, WrongServerPW);
108 if (strlen(msg->payload.serverAuthenticate.userName) == 0) { /* XXX - other invalid names? */
110 sprintf(buf, "Invalid username");
111 sendServerReject(client, buf, InvalidUsername);
115 if (Client_count() >= getIntConf(MAX_CLIENTS)) {
117 sprintf(buf, "Server is full (max %d users)", getIntConf(MAX_CLIENTS));
118 sendServerReject(client, buf, ServerFull);
122 /* Name & password */
123 strncpy(client->playerName, msg->payload.serverAuthenticate.userName, MAX_TEXT);
124 client->playerId = client->sessionId;
126 client->authenticated = true;
128 /* XXX - Kick ghost */
130 /* Setup UDP encryption */
131 CryptState_init(&client->cryptState);
132 CryptState_genKey(&client->cryptState);
133 sendmsg = Msg_create(CryptSetup);
134 sendmsg->sessionId = client->sessionId;
135 memcpy(sendmsg->payload.cryptSetup.key, client->cryptState.raw_key, AES_BLOCK_SIZE);
136 memcpy(sendmsg->payload.cryptSetup.serverNonce, client->cryptState.encrypt_iv, AES_BLOCK_SIZE);
137 memcpy(sendmsg->payload.cryptSetup.clientNonce, client->cryptState.decrypt_iv, AES_BLOCK_SIZE);
138 Client_send_message(client, sendmsg);
141 Chan_playerJoin(defaultChan, client); /* Join default channel */
143 /* Iterate channels and send channel info */
145 Chan_iterate(&ch_itr);
147 sendmsg = Msg_create(ChannelAdd);
148 sendmsg->sessionId = 0;
149 sendmsg->payload.channelAdd.id = ch_itr->id;
151 sendmsg->payload.channelAdd.parentId = -1;
153 sendmsg->payload.channelAdd.parentId = ch_itr->parent->id;
154 strcpy(sendmsg->payload.channelAdd.name, ch_itr->name);
155 Client_send_message(client, sendmsg);
157 sendmsg = Msg_create(ChannelDescUpdate);
158 sendmsg->sessionId = 0;
159 sendmsg->payload.channelDescUpdate.id = ch_itr->id;
160 strcpy(sendmsg->payload.channelDescUpdate.desc, ch_itr->desc);
161 Client_send_message(client, sendmsg);
163 Chan_iterate(&ch_itr);
164 } while (ch_itr != NULL);
166 /* Not supporting channel link for now */
168 /* Server join for connecting user */
169 sendmsg = Msg_create(ServerJoin);
170 sendmsg->sessionId = client->sessionId;
171 sendmsg->payload.serverJoin.id = client->playerId;
172 strcpy(sendmsg->payload.serverJoin.playerName, client->playerName);
173 Client_send_message_except(client, sendmsg);
175 /* Player move for connecting user */
176 if (((channel_t *)client->channel)->id != 0) {
177 sendmsg = Msg_create(PlayerMove);
178 sendmsg->sessionId = client->sessionId;
179 sendmsg->payload.playerMove.victim = client->playerId;
180 sendmsg->payload.playerMove.channel = ((channel_t *)client->channel)->id;
181 Client_send_message_except(client, sendmsg);
184 while (Client_iterate(&client_itr) != NULL) {
185 if (!IS_AUTH(client_itr))
187 sendmsg = Msg_create(ServerJoin);
188 sendmsg->sessionId = client_itr->sessionId;
189 sendmsg->payload.serverJoin.id = client_itr->playerId;
190 strncpy(sendmsg->payload.serverJoin.playerName, client_itr->playerName, MAX_TEXT);
191 Client_send_message(client, sendmsg);
193 sendmsg = Msg_create(PlayerMove);
194 sendmsg->sessionId = client_itr->sessionId;
195 sendmsg->payload.playerMove.victim = client_itr->playerId;
196 sendmsg->payload.playerMove.channel = ((channel_t *)client_itr->channel)->id;
197 Client_send_message(client, sendmsg);
200 sendmsg = Msg_create(ServerSync);
201 sendmsg->sessionId = client->sessionId;
202 strcpy(sendmsg->payload.serverSync.welcomeText, getStrConf(WELCOMETEXT));
203 sendmsg->payload.serverSync.maxBandwidth = getIntConf(MAX_BANDWIDTH);
204 Client_send_message(client, sendmsg);
206 Log_info("Player %s authenticated", client->playerName);
211 client->cryptState.uiRemoteGood = msg->payload.pingStats.good;
212 client->cryptState.uiRemoteLate = msg->payload.pingStats.late;
213 client->cryptState.uiRemoteLost = msg->payload.pingStats.lost;
214 client->cryptState.uiRemoteResync = msg->payload.pingStats.resync;
216 Log_debug("Pingstats <-: %d %d %d %d",
217 client->cryptState.uiRemoteGood, client->cryptState.uiRemoteLate,
218 client->cryptState.uiRemoteLost, client->cryptState.uiRemoteResync);
220 /* Ignoring the double values since they don't seem to be used */
221 sendmsg = Msg_create(PingStats);
222 sendmsg->sessionId = client->sessionId;
223 sendmsg->payload.pingStats.timestamp = msg->payload.pingStats.timestamp;
225 sendmsg->payload.pingStats.good = client->cryptState.uiGood;
226 sendmsg->payload.pingStats.late = client->cryptState.uiLate;
227 sendmsg->payload.pingStats.lost = client->cryptState.uiLost;
228 sendmsg->payload.pingStats.resync = client->cryptState.uiResync;
230 Client_send_message(client, sendmsg);
231 Log_debug("Pingstats ->: %d %d %d %d",
232 client->cryptState.uiGood, client->cryptState.uiLate,
233 client->cryptState.uiLost, client->cryptState.uiResync);
237 sendmsg = Msg_create(Ping);
238 sendmsg->sessionId = client->sessionId;
239 sendmsg->payload.ping.timestamp = msg->payload.ping.timestamp;
240 Client_send_message(client, sendmsg);
243 Log_debug("Voice channel crypt resync requested");
244 if (msg->payload.cryptSync.empty) {
245 sendmsg = Msg_create(CryptSync);
246 sendmsg->sessionId = msg->sessionId;
247 sendmsg->payload.cryptSync.empty = false;
248 memcpy(sendmsg->payload.cryptSync.nonce, client->cryptState.decrypt_iv, AES_BLOCK_SIZE);
249 Client_send_message(client, sendmsg);
251 memcpy(client->cryptState.decrypt_iv, msg->payload.cryptSync.nonce, AES_BLOCK_SIZE);
252 client->cryptState.uiResync++;
256 if (msg->payload.playerMute.victim != client->playerId) {
257 sendPermissionDenied(client, "Permission denied");
259 Log_debug("Player ID %d muted", msg->payload.playerMute.victim);
260 client->mute = msg->payload.playerMute.bMute;
264 if (msg->payload.playerDeaf.victim != client->playerId) {
265 sendPermissionDenied(client, "Permission denied");
267 Log_debug("Player ID %d deaf", msg->payload.playerDeaf.victim);
268 client->deaf = msg->payload.playerDeaf.bDeaf;
272 if (msg->payload.textMessage.bTree)
273 sendPermissionDenied(client, "Tree message not supported");
274 else if (msg->payload.textMessage.channel != -1) { /* To channel */
275 channel_t *ch_itr = NULL;
277 Chan_iterate(&ch_itr);
278 } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage.channel);
280 Log_warn("Channel id %d not found - ignoring.", msg->payload.textMessage.channel);
283 list_iterate(itr, &ch_itr->clients) {
285 c = list_get_entry(itr, client_t, chan_node);
286 if (c != client && !c->deaf) {
288 Client_send_message(c, msg);
289 Log_debug("Text message to player ID %d", c->playerId);
293 } else { /* To player */
294 client_t *itr = NULL;
295 while (Client_iterate(&itr) != NULL) {
298 if (itr->playerId == msg->payload.textMessage.victim) {
301 Client_send_message(itr, msg);
307 Log_warn("TextMessage: Player ID %d not found", msg->payload.textMessage.victim);
310 case PlayerSelfMuteDeaf:
311 client->deaf = msg->payload.playerSelfMuteDeaf.bDeaf;
312 client->mute = msg->payload.playerSelfMuteDeaf.bMute;
313 Log_debug("Player ID %d %s and %s", client->playerId, client->deaf ? "deaf": "not deaf",
314 client->mute ? "mute" : "not mute");
317 Msg_inc_ref(msg); /* Re-use message */
318 Client_send_message_except(NULL, msg);
319 Chan_playerJoin_id(msg->payload.playerMove.channel, client);
322 /* Permission denied for all these messages. Not implemented. */
325 case ChannelDescUpdate:
327 case ContextAddAction:
336 sendPermissionDenied(client, "Not supported by uMurmur");
339 case PlayerTexture: /* Ignore */
343 Log_warn("Message %d not handled", msg->messageType);
350 Client_close(client);