5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2014 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "serverincludes.h"
21 #include "server_internal.h"
23 static int silc_server_is_registered(SilcServer server,
24 SilcPacketStream sock,
25 SilcServerCommandContext cmd,
28 silc_server_command_send_status_reply(SilcServerCommandContext cmd,
33 silc_server_command_send_status_data(SilcServerCommandContext cmd,
38 const unsigned char *arg,
41 silc_server_command_pending_error_check(SilcServerCommandContext cmd,
42 SilcServerCommandReplyContext cmdr,
44 SILC_TASK_CALLBACK(silc_server_command_process_timeout);
46 /* Server command list. */
47 SilcServerCommand silc_command_list[] =
49 SILC_SERVER_CMD(whois, WHOIS, SILC_CF_LAG | SILC_CF_REG),
50 SILC_SERVER_CMD(whowas, WHOWAS, SILC_CF_LAG | SILC_CF_REG),
51 SILC_SERVER_CMD(identify, IDENTIFY, SILC_CF_LAG | SILC_CF_REG),
52 SILC_SERVER_CMD(nick, NICK, SILC_CF_LAG_STRICT | SILC_CF_REG),
53 SILC_SERVER_CMD(list, LIST, SILC_CF_LAG_STRICT | SILC_CF_REG),
54 SILC_SERVER_CMD(topic, TOPIC, SILC_CF_LAG | SILC_CF_REG),
55 SILC_SERVER_CMD(invite, INVITE, SILC_CF_LAG | SILC_CF_REG),
56 SILC_SERVER_CMD(quit, QUIT, SILC_CF_LAG | SILC_CF_REG),
57 SILC_SERVER_CMD(kill, KILL, SILC_CF_LAG_STRICT | SILC_CF_REG | SILC_CF_OPER),
58 SILC_SERVER_CMD(info, INFO, SILC_CF_LAG | SILC_CF_REG),
59 SILC_SERVER_CMD(stats, STATS, SILC_CF_LAG | SILC_CF_REG),
60 SILC_SERVER_CMD(ping, PING, SILC_CF_LAG | SILC_CF_REG),
61 SILC_SERVER_CMD(oper, OPER, SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
62 SILC_SERVER_CMD(join, JOIN, SILC_CF_LAG_STRICT | SILC_CF_REG),
63 SILC_SERVER_CMD(motd, MOTD, SILC_CF_LAG | SILC_CF_REG),
64 SILC_SERVER_CMD(umode, UMODE, SILC_CF_LAG | SILC_CF_REG),
65 SILC_SERVER_CMD(cmode, CMODE, SILC_CF_LAG_STRICT | SILC_CF_REG),
66 SILC_SERVER_CMD(cumode, CUMODE, SILC_CF_LAG | SILC_CF_REG),
67 SILC_SERVER_CMD(kick, KICK, SILC_CF_LAG_STRICT | SILC_CF_REG),
68 SILC_SERVER_CMD(ban, BAN, SILC_CF_LAG_STRICT | SILC_CF_REG),
69 SILC_SERVER_CMD(detach, DETACH, SILC_CF_LAG_STRICT | SILC_CF_REG),
70 SILC_SERVER_CMD(watch, WATCH, SILC_CF_LAG | SILC_CF_REG),
71 SILC_SERVER_CMD(silcoper, SILCOPER,
72 SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER),
73 SILC_SERVER_CMD(leave, LEAVE, SILC_CF_LAG_STRICT | SILC_CF_REG),
74 SILC_SERVER_CMD(users, USERS, SILC_CF_LAG | SILC_CF_REG),
75 SILC_SERVER_CMD(getkey, GETKEY, SILC_CF_LAG | SILC_CF_REG),
76 SILC_SERVER_CMD(service, SERVICE, SILC_CF_LAG_STRICT | SILC_CF_REG),
78 SILC_SERVER_CMD(connect, PRIV_CONNECT,
79 SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
80 SILC_SERVER_CMD(close, PRIV_CLOSE,
81 SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
82 SILC_SERVER_CMD(shutdown, PRIV_SHUTDOWN, SILC_CF_LAG | SILC_CF_REG |
88 /* Returns TRUE if the connection is registered. Unregistered connections
89 usually cannot send commands hence the check. */
91 static int silc_server_is_registered(SilcServer server,
92 SilcPacketStream sock,
93 SilcServerCommandContext cmd,
96 SilcIDListData idata = silc_packet_get_context(sock);
101 if (idata->status & SILC_IDLIST_STATUS_REGISTERED)
104 silc_server_command_send_status_reply(cmd, command,
105 SILC_STATUS_ERR_NOT_REGISTERED, 0);
109 /* Performs several checks to the command. It first checks whether this
110 command was called as pending command callback. If it was then it checks
111 whether error occurred in the command reply where the pending command
114 It also checks that the requested command includes correct amount
116 #define SILC_SERVER_COMMAND_CHECK(command, context, min, max) \
120 if (silc_server_command_pending_error_check(cmd, context2, command)) { \
121 SILC_LOG_DEBUG(("Error occurred in command reply, command not called")); \
122 silc_server_command_free(cmd); \
127 !silc_server_is_registered(cmd->server, cmd->sock, cmd, command)) { \
128 SILC_LOG_DEBUG(("Not registered, command not called")); \
129 silc_server_command_free(cmd); \
133 _argc = silc_argument_get_arg_num(cmd->args); \
135 SILC_LOG_DEBUG(("Not enough parameters in command")); \
136 silc_server_command_send_status_reply(cmd, command, \
137 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, \
139 silc_server_command_free(cmd); \
143 SILC_LOG_DEBUG(("Too many parameters in command")); \
144 silc_server_command_send_status_reply(cmd, command, \
145 SILC_STATUS_ERR_TOO_MANY_PARAMS, \
147 silc_server_command_free(cmd); \
152 /* Internal context to hold data when executed command with timeout. */
154 SilcServerCommandContext ctx;
155 SilcServerCommand *cmd;
156 } *SilcServerCommandTimeout;
158 /* Timeout callback to process commands with timeout for client. Client's
159 commands are always executed with timeout. */
161 SILC_TASK_CALLBACK(silc_server_command_process_timeout)
163 SilcServerCommandTimeout timeout = (SilcServerCommandTimeout)context;
164 SilcClientEntry client = silc_packet_get_context(timeout->ctx->sock);
167 SILC_LOG_DEBUG(("Client entry is invalid"));
168 silc_server_command_free(timeout->ctx);
173 /* Update access time */
174 client->last_command = time(NULL);
176 if (!(timeout->cmd->flags & SILC_CF_REG)) {
177 SILC_LOG_DEBUG(("Calling %s command",
178 silc_get_command_name(timeout->cmd->cmd)));
179 timeout->cmd->cb(timeout->ctx, NULL);
180 } else if (silc_server_is_registered(timeout->ctx->server,
183 timeout->cmd->cmd)) {
184 SILC_LOG_DEBUG(("Calling %s command",
185 silc_get_command_name(timeout->cmd->cmd)));
186 timeout->cmd->cb(timeout->ctx, NULL);
188 SILC_LOG_DEBUG(("Client is not registered"));
189 silc_server_command_free(timeout->ctx);
195 /* Processes received command packet. */
197 void silc_server_command_process(SilcServer server,
198 SilcPacketStream sock,
201 SilcIDListData idata = silc_packet_get_context(sock);
202 SilcServerCommandContext ctx;
203 SilcServerCommand *cmd;
209 /* Allocate command context. This must be free'd by the
210 command routine receiving it. */
211 ctx = silc_server_command_alloc();
214 ctx->server = server;
216 ctx->packet = packet; /* Save original packet */
217 silc_packet_stream_ref(sock);
219 /* Parse the command payload in the packet */
220 ctx->payload = silc_command_payload_parse(packet->buffer.data,
221 silc_buffer_len(&packet->buffer));
223 SILC_LOG_ERROR(("Bad command payload"));
224 silc_packet_free(packet);
225 silc_packet_stream_unref(ctx->sock);
229 ctx->args = silc_command_get_args(ctx->payload);
231 /* Get the command */
232 command = silc_command_get(ctx->payload);
233 for (cmd = silc_command_list; cmd->cb; cmd++)
234 if (cmd->cmd == command)
237 if (!cmd || !cmd->cb) {
238 SILC_LOG_DEBUG(("Unknown command %d", command));
239 silc_server_command_send_status_reply(ctx, command,
240 SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
241 silc_packet_free(packet);
242 silc_packet_stream_unref(ctx->sock);
247 /* Execute client's commands always with timeout. Normally they are
248 executed with zero (0) timeout but if client is sending command more
249 frequently than once in 2 seconds, then the timeout may be 0 to 2
251 if (idata->conn_type == SILC_CONN_CLIENT) {
252 SilcClientEntry client = silc_packet_get_context(sock);
253 SilcServerCommandTimeout timeout;
256 timeout = silc_calloc(1, sizeof(*timeout));
258 silc_server_command_send_status_reply(
260 SILC_STATUS_ERR_OPERATION_ALLOWED, 0);
261 silc_packet_free(packet);
262 silc_packet_stream_unref(ctx->sock);
269 if (client->last_command && (time(NULL) - client->last_command) < 2) {
270 client->fast_command++;
273 if (client->fast_command - 2 <= 0)
274 client->fast_command = 0;
276 client->fast_command -= 2;
280 if (!fast && ((cmd->flags & SILC_CF_LAG_STRICT) ||
281 (client->fast_command > 5 && cmd->flags & SILC_CF_LAG)))
282 silc_schedule_task_add_timeout(
284 silc_server_command_process_timeout, timeout,
285 (client->fast_command < 3 ? 0 :
286 2 - (time(NULL) - client->last_command)),
287 (client->fast_command < 3 ? 200000 : 0));
289 silc_schedule_task_add_timeout(server->schedule,
290 silc_server_command_process_timeout,
295 /* Execute for server */
297 if (!(cmd->flags & SILC_CF_REG)) {
298 SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
300 } else if (silc_server_is_registered(server, sock, ctx, cmd->cmd)) {
301 SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
304 SILC_LOG_DEBUG(("Server is not registered"));
305 silc_server_command_free(ctx);
309 /* Allocate Command Context */
311 SilcServerCommandContext silc_server_command_alloc()
313 SilcServerCommandContext ctx = silc_calloc(1, sizeof(*ctx));
319 /* Free's the command context allocated before executing the command */
321 void silc_server_command_free(SilcServerCommandContext ctx)
324 SILC_LOG_DEBUG(("Command context %p refcnt %d->%d", ctx, ctx->users + 1,
326 if (ctx->users < 1) {
328 silc_command_payload_free(ctx->payload);
330 silc_packet_free(ctx->packet);
332 silc_packet_stream_unref(ctx->sock);
337 /* Duplicate Command Context by adding reference counter. The context won't
338 be free'd untill it hits zero. */
340 SilcServerCommandContext
341 silc_server_command_dup(SilcServerCommandContext ctx)
344 SILC_LOG_DEBUG(("Command context %p refcnt %d->%d", ctx, ctx->users - 1,
349 /* Timeout for pending command. If reply to pending command never arrives
350 this is called to free resources. */
352 SILC_TASK_CALLBACK(silc_server_command_pending_timeout)
354 SilcServer server = app_context;
355 SilcServerCommandPending *reply = context;
356 SilcServerCommandReplyContext cmdr;
360 SILC_LOG_DEBUG(("Timeout pending command %p", reply));
362 /* Allocate temporary and bogus command reply context */
363 cmdr = silc_calloc(1, sizeof(*cmdr));
366 cmdr->server = server;
367 cmdr->ident = reply->ident;
369 /* Check for pending commands and mark to be exeucted */
371 silc_server_command_pending_check(server, reply->reply_cmd,
372 reply->ident, &cmdr->callbacks_count);
373 if (!cmdr->callbacks) {
378 /* Create bogus command reply with an error inside */
380 silc_command_reply_payload_encode_va(reply->reply_cmd ? reply->reply_cmd :
381 SILC_COMMAND_RESERVED,
382 SILC_STATUS_ERR_TIMEDOUT, 0,
384 cmdr->payload = silc_command_payload_parse(tmpreply->data,
385 silc_buffer_len(tmpreply));
386 silc_buffer_free(tmpreply);
388 /* Call all callbacks. Same as SILC_SERVER_PENDING_EXEC macro. */
389 for (i = 0; i < cmdr->callbacks_count; i++)
390 if (cmdr->callbacks[i].callback)
391 (*cmdr->callbacks[i].callback)(cmdr->callbacks[i].context, cmdr);
393 silc_server_command_pending_del(server, reply->reply_cmd, reply->ident);
394 silc_server_command_reply_free(cmdr);
397 /* Add new pending command to be executed when reply to a command has been
398 received. The `reply_cmd' is the command that will call the `callback'
399 with `context' when reply has been received. It can be SILC_COMMAND_NONE
400 to match any command with the `ident'. If `ident' is non-zero
401 the `callback' will be executed when received reply with command
402 identifier `ident'. If there already exists pending command for the
403 specified command, ident, callback and context this function has no
406 SilcBool silc_server_command_pending(SilcServer server,
407 SilcCommand reply_cmd,
409 SilcCommandCb callback,
412 return silc_server_command_pending_timed(server, reply_cmd, ident, callback,
416 /* Same as silc_server_command_pending with specific timeout for pending
417 commands. If the `timeout' is zero default timeout is used. */
419 SilcBool silc_server_command_pending_timed(SilcServer server,
420 SilcCommand reply_cmd,
422 SilcCommandCb callback,
426 SilcServerCommandPending *reply;
428 /* Check whether identical pending already exists for same command,
429 ident, callback and callback context. If it does then it would be
430 error to register it again. */
431 silc_dlist_start(server->pending_commands);
432 while ((reply = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
433 if (reply->reply_cmd == reply_cmd && reply->ident == ident &&
434 reply->callback == callback && reply->context == context)
438 reply = silc_calloc(1, sizeof(*reply));
441 reply->reply_cmd = reply_cmd;
442 reply->ident = ident;
443 reply->context = context;
444 reply->callback = callback;
446 silc_schedule_task_add_timeout(server->schedule,
447 silc_server_command_pending_timeout, reply,
448 timeout ? timeout : 12, 0);
449 silc_dlist_add(server->pending_commands, reply);
454 /* Deletes pending command by reply command type. */
456 void silc_server_command_pending_del(SilcServer server,
457 SilcCommand reply_cmd,
460 SilcServerCommandPending *r;
462 silc_dlist_start(server->pending_commands);
463 while ((r = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
464 if ((r->reply_cmd == reply_cmd || (r->reply_cmd == SILC_COMMAND_NONE &&
466 && r->ident == ident) {
467 silc_dlist_del(server->pending_commands, r);
469 silc_schedule_task_del(server->schedule, r->timeout);
475 /* Checks for pending commands and marks callbacks to be called from
476 the command reply function. Returns the pending callbacks if there were
477 any or NULL if there weren't. */
479 SilcServerCommandPendingCallbacks
480 silc_server_command_pending_check(SilcServer server,
483 SilcUInt32 *callbacks_count)
485 SilcServerCommandPending *r;
486 SilcServerCommandPendingCallbacks callbacks = NULL;
489 silc_dlist_start(server->pending_commands);
490 while ((r = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
491 if ((r->reply_cmd == command || r->reply_cmd == SILC_COMMAND_NONE)
492 && r->ident == ident) {
493 callbacks = silc_realloc(callbacks, sizeof(*callbacks) * (i + 1));
496 callbacks[i].context = r->context;
497 callbacks[i].callback = r->callback;
498 r->reply_check = TRUE;
503 *callbacks_count = i;
507 /* Sends simple status message as command reply packet */
510 silc_server_command_send_status_reply(SilcServerCommandContext cmd,
518 cmd->server->stat.commands_sent++;
520 SILC_LOG_DEBUG(("Sending command status %d", status));
523 silc_command_reply_payload_encode_va(command, status, error,
524 silc_command_get_ident(cmd->payload),
526 silc_server_packet_send(cmd->server, cmd->sock,
527 SILC_PACKET_COMMAND_REPLY, 0,
528 buffer->data, silc_buffer_len(buffer));
529 silc_buffer_free(buffer);
532 /* Sends command status reply with one extra argument. The argument
533 type must be sent as argument. */
536 silc_server_command_send_status_data(SilcServerCommandContext cmd,
541 const unsigned char *arg,
547 cmd->server->stat.commands_sent++;
549 SILC_LOG_DEBUG(("Sending command status %d", status));
552 silc_command_reply_payload_encode_va(command, status, 0,
553 silc_command_get_ident(cmd->payload),
554 1, arg_type, arg, arg_len);
555 silc_server_packet_send(cmd->server, cmd->sock,
556 SILC_PACKET_COMMAND_REPLY, 0,
557 buffer->data, silc_buffer_len(buffer));
558 silc_buffer_free(buffer);
562 silc_server_command_send_status_data2(SilcServerCommandContext cmd,
566 SilcUInt32 arg_type1,
567 const unsigned char *arg1,
569 SilcUInt32 arg_type2,
570 const unsigned char *arg2,
576 cmd->server->stat.commands_sent++;
578 SILC_LOG_DEBUG(("Sending command status %d", status));
581 silc_command_reply_payload_encode_va(command, status, 0,
582 silc_command_get_ident(cmd->payload),
583 2, arg_type1, arg1, arg_len1,
584 arg_type2, arg2, arg_len2);
585 silc_server_packet_send(cmd->server, cmd->sock,
586 SILC_PACKET_COMMAND_REPLY, 0,
587 buffer->data, silc_buffer_len(buffer));
588 silc_buffer_free(buffer);
591 /* This function can be called to check whether in the command reply
592 an error occurred. This function has no effect if this is called
593 when the command function was not called as pending command callback.
594 This returns TRUE if error had occurred. */
597 silc_server_command_pending_error_check(SilcServerCommandContext cmd,
598 SilcServerCommandReplyContext cmdr,
601 if (!cmd->pending || !cmdr)
604 if (!silc_command_get_status(cmdr->payload, NULL, NULL)) {
608 cmd->server->stat.commands_sent++;
610 /* Send the same command reply payload */
611 silc_command_set_command(cmdr->payload, silc_command_get(cmd->payload));
612 silc_command_set_ident(cmdr->payload,
613 silc_command_get_ident(cmd->payload));
614 buffer = silc_command_payload_encode_payload(cmdr->payload);
615 silc_server_packet_send(cmd->server, cmd->sock,
616 SILC_PACKET_COMMAND_REPLY, 0,
617 buffer->data, silc_buffer_len(buffer));
618 silc_buffer_free(buffer);
625 /* Server side of command WHOIS. */
627 SILC_SERVER_CMD_FUNC(whois)
629 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
630 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WHOIS, cmd, 1, 256);
631 silc_server_query_command(cmd->server, SILC_COMMAND_WHOIS, cmd, NULL);
632 silc_server_command_free(cmd);
635 /* Server side of command WHOWAS. */
637 SILC_SERVER_CMD_FUNC(whowas)
639 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
640 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WHOWAS, cmd, 1, 2);
641 silc_server_query_command(cmd->server, SILC_COMMAND_WHOWAS, cmd, NULL);
642 silc_server_command_free(cmd);
645 /* Server side of command IDENTIFY. */
647 SILC_SERVER_CMD_FUNC(identify)
649 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
650 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_IDENTIFY, cmd, 1, 256);
651 silc_server_query_command(cmd->server, SILC_COMMAND_IDENTIFY, cmd, NULL);
652 silc_server_command_free(cmd);
655 /* Server side of command NICK. Sets nickname for user. Setting
656 nickname causes generation of a new client ID for the client. The
657 new client ID is sent to the client after changing the nickname. */
659 SILC_SERVER_CMD_FUNC(nick)
661 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
662 SilcClientEntry client = silc_packet_get_context(cmd->sock);
663 SilcServer server = cmd->server;
664 SilcBuffer nidp, oidp = NULL;
665 SilcClientID *new_id;
667 unsigned char *nick, *nickc = NULL;
668 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
670 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
673 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_NICK, cmd, 1, 1);
676 nick = silc_argument_get_arg_type(cmd->args, 1, &nick_len);
678 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
679 SILC_STATUS_ERR_BAD_NICKNAME, 0);
683 /* Truncate over long nicks */
684 if (nick_len > 128) {
686 nick[nick_len - 1] = '\0';
689 /* Check for valid nickname string. This is cached, original is saved
690 in the client context. */
691 nickc = silc_identifier_check(nick, nick_len, SILC_STRING_UTF8, 128, NULL);
693 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
694 SILC_STATUS_ERR_BAD_NICKNAME, 0);
698 /* Check for same nickname */
699 if (strlen(client->nickname) == nick_len &&
700 !memcmp(client->nickname, nick, nick_len)) {
701 nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
706 /* Create new Client ID */
707 if (!silc_id_create_client_id(cmd->server, cmd->server->id,
709 cmd->server->md5hash,
710 nickc, strlen(nickc), &new_id)) {
711 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
712 SILC_STATUS_ERR_BAD_NICKNAME, 0);
717 /* Send notify about nickname change to our router. We send the new
718 ID and ask to replace it with the old one. If we are router the
719 packet is broadcasted. Send NICK_CHANGE notify. */
720 silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
721 SILC_BROADCAST(server), client->id,
724 /* Check if anyone is watching the old nickname */
725 if (server->server_type == SILC_ROUTER)
726 silc_server_check_watcher_list(server, client, nick,
727 SILC_NOTIFY_TYPE_NICK_CHANGE);
729 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
731 /* Update client entry */
732 silc_idcache_update_by_context(server->local_list->clients, client,
733 new_id, nickc, TRUE);
735 silc_free(client->nickname);
736 client->nickname = strdup(nick);
738 nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
740 /* Send NICK_CHANGE notify to the client's channels */
741 silc_server_send_notify_on_channels(server, NULL, client,
742 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
743 oidp->data, silc_buffer_len(oidp),
744 nidp->data, silc_buffer_len(nidp),
746 strlen(client->nickname));
748 /* Check if anyone is watching the new nickname */
749 if (server->server_type == SILC_ROUTER)
750 silc_server_check_watcher_list(server, client, NULL,
751 SILC_NOTIFY_TYPE_NICK_CHANGE);
754 /* Send the new Client ID as reply command back to client */
755 silc_server_send_command_reply(cmd->server, cmd->sock,
757 SILC_STATUS_OK, 0, ident, 2,
758 2, nidp->data, silc_buffer_len(nidp),
760 silc_buffer_free(nidp);
762 silc_buffer_free(oidp);
765 silc_server_command_free(cmd);
768 /* Sends the LIST command reply */
771 silc_server_command_list_send_reply(SilcServerCommandContext cmd,
772 SilcChannelEntry *lch,
773 SilcUInt32 lch_count,
774 SilcChannelEntry *gch,
775 SilcUInt32 gch_count)
779 SilcChannelEntry entry;
781 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
783 unsigned char usercount[4];
785 int valid_lcount = 0, valid_rcount = 0;
787 for (i = 0; i < lch_count; i++) {
788 if (lch[i]->mode & SILC_CHANNEL_MODE_SECRET)
793 for (i = 0; i < gch_count; i++) {
794 if (gch[i]->mode & SILC_CHANNEL_MODE_SECRET)
800 if (!lch_count && !gch_count) {
801 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LIST,
806 status = SILC_STATUS_OK;
807 if ((lch_count + gch_count) > 1)
808 status = SILC_STATUS_LIST_START;
811 for (i = 0, k = 0; i < lch_count; i++) {
817 status = SILC_STATUS_LIST_ITEM;
818 if (valid_lcount > 1 && k == valid_lcount - 1 && !valid_rcount)
819 status = SILC_STATUS_LIST_END;
821 idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
823 if (entry->mode & SILC_CHANNEL_MODE_PRIVATE) {
825 memset(usercount, 0, sizeof(usercount));
827 topic = entry->topic;
828 users = silc_hash_table_count(entry->user_list);
829 SILC_PUT32_MSB(users, usercount);
833 silc_server_send_command_reply(cmd->server, cmd->sock, SILC_COMMAND_LIST,
835 2, idp->data, silc_buffer_len(idp),
836 3, entry->channel_name,
837 strlen(entry->channel_name),
838 4, topic, topic ? strlen(topic) : 0,
840 silc_buffer_free(idp);
845 for (i = 0, k = 0; i < gch_count; i++) {
851 status = SILC_STATUS_LIST_ITEM;
852 if (valid_rcount > 1 && k == valid_rcount - 1)
853 status = SILC_STATUS_LIST_END;
855 idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
857 if (entry->mode & SILC_CHANNEL_MODE_PRIVATE) {
859 memset(usercount, 0, sizeof(usercount));
861 topic = entry->topic;
862 users = entry->user_count;
863 SILC_PUT32_MSB(users, usercount);
867 silc_server_send_command_reply(cmd->server, cmd->sock, SILC_COMMAND_LIST,
869 2, idp->data, silc_buffer_len(idp),
870 3, entry->channel_name,
871 strlen(entry->channel_name),
872 4, topic, topic ? strlen(topic) : 0,
874 silc_buffer_free(idp);
879 /* Server side of LIST command. This lists the channel of the requested
880 server. Secret channels are not listed. */
882 SILC_SERVER_CMD_FUNC(list)
884 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
885 SilcServer server = cmd->server;
887 SilcChannelID *channel_id = NULL;
888 SilcChannelEntry *lchannels = NULL, *gchannels = NULL;
889 SilcUInt32 lch_count = 0, gch_count = 0;
891 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LIST, cmd, 0, 1);
893 /* If we are normal server, send the command to router, since we
894 want to know all channels in the network. */
895 if (!cmd->pending && server->server_type != SILC_ROUTER &&
896 !server->standalone) {
898 SilcUInt16 old_ident;
901 cmd->server->stat.commands_sent++;
903 old_ident = silc_command_get_ident(cmd->payload);
904 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
905 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
906 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
907 SILC_PACKET_COMMAND, cmd->packet->flags,
908 tmpbuf->data, silc_buffer_len(tmpbuf));
910 /* Reprocess this packet after received reply from router */
911 silc_server_command_pending(server, SILC_COMMAND_LIST,
912 silc_command_get_ident(cmd->payload),
913 silc_server_command_list,
914 silc_server_command_dup(cmd));
916 silc_command_set_ident(cmd->payload, old_ident);
917 silc_buffer_free(tmpbuf);
922 if (silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL))
923 channel_id = SILC_ID_GET_ID(id);
925 /* Get the channels from local list */
926 lchannels = silc_idlist_get_channels(server->local_list, channel_id,
929 /* Get the channels from global list */
930 gchannels = silc_idlist_get_channels(server->global_list, channel_id,
934 silc_server_command_list_send_reply(cmd, lchannels, lch_count,
935 gchannels, gch_count);
937 silc_free(lchannels);
938 silc_free(gchannels);
941 silc_server_command_free(cmd);
944 /* Server side of TOPIC command. Sets topic for channel and/or returns
945 current topic to client. */
947 SILC_SERVER_CMD_FUNC(topic)
949 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
950 SilcServer server = cmd->server;
951 SilcClientEntry client = silc_packet_get_context(cmd->sock);
953 SilcChannelEntry channel;
954 SilcChannelClientEntry chl;
957 SilcUInt32 argc, tmp_len;
958 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
960 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
963 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_TOPIC, cmd, 1, 2);
965 argc = silc_argument_get_arg_num(cmd->args);
968 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
969 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
970 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
974 /* Check whether the channel exists */
975 channel = silc_idlist_find_channel_by_id(server->local_list,
976 SILC_ID_GET_ID(id), NULL);
978 channel = silc_idlist_find_channel_by_id(server->global_list,
979 SILC_ID_GET_ID(id), NULL);
981 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
982 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
983 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
991 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
993 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
994 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1000 tmp[tmp_len - 1] = '\0';
1003 if (!silc_utf8_valid(tmp, tmp_len)) {
1004 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
1005 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1010 /* See whether the client is on channel and has rights to change topic */
1011 if (!silc_server_client_on_channel(client, channel, &chl)) {
1012 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1013 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
1014 SILC_STATUS_ERR_NOT_ON_CHANNEL,
1015 0, 2, tmp, tmp_len);
1019 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
1020 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1021 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1022 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1023 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
1024 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
1025 0, 2, tmp, tmp_len);
1029 if (!channel->topic || strcmp(channel->topic, tmp)) {
1030 /* Set the topic for channel */
1031 silc_free(channel->topic);
1032 channel->topic = strdup(tmp);
1034 /* Send TOPIC_SET notify type to the network */
1035 silc_server_send_notify_topic_set(server, SILC_PRIMARY_ROUTE(server),
1036 SILC_BROADCAST(server), channel,
1037 client->id, SILC_ID_CLIENT,
1040 /* Send notify about topic change to all clients on the channel */
1041 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
1042 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
1043 SILC_NOTIFY_TYPE_TOPIC_SET, 2,
1044 idp->data, silc_buffer_len(idp),
1046 strlen(channel->topic));
1047 silc_buffer_free(idp);
1051 /* Send the topic to client as reply packet */
1052 idp = silc_id_payload_encode(SILC_ID_GET_ID(id), SILC_ID_CHANNEL);
1053 silc_server_send_command_reply(cmd->server, cmd->sock, SILC_COMMAND_TOPIC,
1054 SILC_STATUS_OK, 0, ident, 2,
1055 2, idp->data, silc_buffer_len(idp),
1058 strlen(channel->topic) : 0);
1059 silc_buffer_free(idp);
1062 silc_server_command_free(cmd);
1065 /* Server side of INVITE command. Invites some client to join some channel.
1066 This command is also used to manage the invite list of the channel. */
1068 SILC_SERVER_CMD_FUNC(invite)
1070 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1071 SilcServer server = cmd->server;
1072 SilcPacketStream sock = cmd->sock, dest_sock;
1073 SilcChannelClientEntry chl;
1074 SilcClientEntry sender, dest;
1075 SilcChannelEntry channel;
1077 SilcIDListData idata;
1078 SilcArgumentPayload args;
1079 SilcHashTableList htl;
1080 SilcBuffer list, tmp2;
1081 SilcBufferStruct alist;
1082 unsigned char *tmp, *atype = NULL;
1083 SilcUInt32 len, len2, ttype;
1085 SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
1087 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INVITE, cmd, 1, 4);
1089 /* Get Channel ID */
1090 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
1091 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1092 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
1096 /* Get the channel entry */
1097 channel = silc_idlist_find_channel_by_id(server->local_list,
1098 SILC_ID_GET_ID(id), NULL);
1100 channel = silc_idlist_find_channel_by_id(server->global_list,
1101 SILC_ID_GET_ID(id), NULL);
1103 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1104 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1105 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
1111 /* Check whether the sender of this command is on the channel. */
1112 sender = silc_packet_get_context(sock);
1113 if (!sender || !silc_server_client_on_channel(sender, channel, &chl)) {
1114 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1115 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1116 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
1121 /* Check whether the channel is invite-only channel. If yes then the
1122 sender of this command must be at least channel operator. */
1123 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
1124 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1125 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1126 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1127 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1128 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
1133 /* Get destination client ID */
1134 if (silc_argument_get_decoded(cmd->args, 2, SILC_ARGUMENT_ID, &id2, NULL)) {
1137 /* Get the client entry */
1138 dest = silc_server_query_client(server, SILC_ID_GET_ID(id2),
1141 if (server->server_type != SILC_SERVER || !resolve || cmd->pending) {
1142 tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
1143 silc_server_command_send_status_data(
1144 cmd, SILC_COMMAND_INVITE,
1145 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1150 /* The client info is being resolved. Reprocess this packet after
1151 receiving the reply to the query. */
1152 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
1154 silc_server_command_invite,
1155 silc_server_command_dup(cmd));
1156 cmd->pending = TRUE;
1160 /* Check whether the requested client is already on the channel. */
1161 if (silc_server_client_on_channel(dest, channel, NULL)) {
1162 tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
1163 atype = silc_argument_get_arg_type(cmd->args, 1, &len2);
1164 silc_server_command_send_status_data2(cmd, SILC_COMMAND_INVITE,
1165 SILC_STATUS_ERR_USER_ON_CHANNEL,
1171 /* Get route to the client */
1172 dest_sock = silc_server_get_client_route(server, NULL, 0,
1173 SILC_ID_GET_ID(id2),
1176 tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
1177 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1178 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1183 /* Add the client to the invite list */
1185 /* Allocate hash table for invite list if it doesn't exist yet */
1186 if (!channel->invite_list)
1187 channel->invite_list =
1188 silc_hash_table_alloc(0, silc_hash_ptr,
1190 silc_server_inviteban_destruct, channel, TRUE);
1192 /* Check if the ID is in the list already */
1193 tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
1194 silc_hash_table_list(channel->invite_list, &htl);
1195 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
1196 if (SILC_PTR_TO_32(type) == 3 && !memcmp(tmp2->data, tmp, len)) {
1201 silc_hash_table_list_reset(&htl);
1203 /* Add new Client ID to invite list */
1205 list = silc_buffer_alloc_size(len);
1206 silc_buffer_put(list, tmp, len);
1207 silc_hash_table_add(channel->invite_list, (void *)3, list);
1210 if (!(dest->mode & SILC_UMODE_BLOCK_INVITE)) {
1211 /* Send notify to the client that is invited to the channel */
1212 SilcBuffer idp, idp2;
1213 idp = silc_id_payload_encode(SILC_ID_GET_ID(id), SILC_ID_CHANNEL);
1214 idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
1215 silc_server_send_notify_dest(server, dest_sock, FALSE,
1216 SILC_ID_GET_ID(id2), SILC_ID_CLIENT,
1217 SILC_NOTIFY_TYPE_INVITE, 3,
1218 idp->data, silc_buffer_len(idp),
1219 channel->channel_name,
1220 strlen(channel->channel_name),
1221 idp2->data, silc_buffer_len(idp2));
1222 silc_buffer_free(idp);
1223 silc_buffer_free(idp2);
1227 /* Get the invite information */
1228 tmp = silc_argument_get_arg_type(cmd->args, 4, &len2);
1229 if (tmp && len2 > 2) {
1230 /* Parse the arguments to see they are constructed correctly */
1231 SILC_GET16_MSB(argc, tmp);
1232 args = silc_argument_payload_parse(tmp + 2, len2 - 2, argc);
1234 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1235 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1240 /* Get the type of action */
1241 atype = silc_argument_get_arg_type(cmd->args, 3, &len);
1242 if (atype && len == 1) {
1243 if (atype[0] == 0x00) {
1244 /* Allocate hash table for invite list if it doesn't exist yet */
1245 if (!channel->invite_list)
1246 channel->invite_list =
1247 silc_hash_table_alloc(0, silc_hash_ptr,
1249 silc_server_inviteban_destruct, channel,
1252 /* Check for resource limit */
1253 if (silc_hash_table_count(channel->invite_list) > 64) {
1254 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1255 SILC_STATUS_ERR_RESOURCE_LIMIT,
1261 /* Now add or delete the information. */
1262 if (!silc_server_inviteban_process(server, channel->invite_list,
1263 (SilcUInt8)atype[0], args)) {
1264 silc_server_command_send_status_reply(
1265 cmd, SILC_COMMAND_INVITE,
1266 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1271 silc_argument_payload_free(args);
1274 /* Encode invite list */
1276 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
1277 list = silc_buffer_alloc_size(2);
1278 silc_buffer_format(list,
1279 SILC_STR_UI_SHORT(silc_hash_table_count(
1280 channel->invite_list)),
1282 silc_hash_table_list(channel->invite_list, &htl);
1283 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
1284 list = silc_argument_payload_encode_one(list, tmp2->data,
1285 silc_buffer_len(tmp2),
1286 SILC_PTR_TO_32(type));
1287 silc_hash_table_list_reset(&htl);
1290 /* The notify is sent to local servers (not clients), and to network. */
1291 if (atype && tmp && len2) {
1292 silc_buffer_set(&alist, tmp, len2);
1294 /* Send to local servers if we are router */
1295 if (server->server_type == SILC_ROUTER) {
1296 SilcBuffer idp, idp2;
1297 idp = silc_id_payload_encode(SILC_ID_GET_ID(id), SILC_ID_CHANNEL);
1298 idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
1299 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
1300 SILC_NOTIFY_TYPE_INVITE, 5,
1301 idp->data, silc_buffer_len(idp),
1302 channel->channel_name,
1303 strlen(channel->channel_name),
1304 idp2->data, silc_buffer_len(idp2),
1306 tmp ? alist.data : NULL,
1307 tmp ? silc_buffer_len(&alist) : 0);
1308 silc_buffer_free(idp);
1309 silc_buffer_free(idp2);
1312 /* Send to network */
1313 silc_server_send_notify_invite(server, SILC_PRIMARY_ROUTE(server),
1314 SILC_BROADCAST(server), channel,
1316 tmp ? &alist : NULL);
1319 /* Send invite list back only if the list was modified, or no arguments
1322 argc = silc_argument_get_arg_num(cmd->args);
1325 if (silc_argument_get_arg_type(cmd->args, 3, &len))
1328 /* Send command reply */
1329 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1330 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_INVITE,
1331 SILC_STATUS_OK, 0, ident, 2,
1335 ttype && list ? silc_buffer_len(list) : 0);
1336 silc_buffer_free(list);
1339 silc_server_command_free(cmd);
1343 SilcPacketStream sock;
1347 /* Quits connection to client. This gets called if client won't
1348 close the connection even when it has issued QUIT command. */
1350 SILC_TASK_CALLBACK(silc_server_command_quit_cb)
1352 SilcServer server = app_context;
1353 QuitInternal q = (QuitInternal)context;
1354 SilcClientEntry client = silc_packet_get_context(q->sock);
1357 /* Free all client specific data, such as client entry and entires
1358 on channels this client may be on. */
1359 silc_server_free_sock_user_data(server, q->sock, q->signoff);
1360 silc_server_close_connection(server, q->sock);
1363 silc_packet_stream_unref(q->sock);
1364 silc_free(q->signoff);
1368 /* Quits SILC session. This is the normal way to disconnect client. */
1370 SILC_SERVER_CMD_FUNC(quit)
1372 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1373 SilcServer server = cmd->server;
1374 SilcPacketStream sock = cmd->sock;
1375 SilcClientEntry client = silc_packet_get_context(sock);
1377 unsigned char *tmp = NULL;
1380 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_QUIT, cmd, 0, 1);
1382 if (client->data.conn_type != SILC_CONN_CLIENT)
1386 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1390 q = silc_calloc(1, sizeof(*q));
1394 q->signoff = tmp ? strdup(tmp) : NULL;
1395 silc_packet_stream_ref(q->sock);
1397 /* We quit the connection with little timeout */
1398 silc_schedule_task_add_timeout(server->schedule,
1399 silc_server_command_quit_cb, (void *)q,
1403 silc_server_command_free(cmd);
1406 /* Server side of command KILL. This command is used by router operator
1407 to remove an client from the SILC Network temporarily. */
1409 SILC_SERVER_CMD_FUNC(kill)
1411 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1412 SilcServer server = cmd->server;
1413 SilcClientEntry client = silc_packet_get_context(cmd->sock);
1414 SilcClientEntry remote_client;
1416 unsigned char *tmp, *comment, *auth;
1417 SilcUInt32 tmp_len, tmp_len2, auth_len;
1419 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 3);
1421 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
1424 /* Get authentication payload if present */
1425 auth = silc_argument_get_arg_type(cmd->args, 3, &auth_len);
1428 /* Router operator killing */
1430 /* KILL command works only on router */
1431 if (server->server_type != SILC_ROUTER) {
1432 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1433 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
1437 /* Check whether client has the permissions. */
1438 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1439 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1440 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
1445 /* Get the client ID */
1446 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
1447 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1448 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
1452 /* Get the client entry */
1453 remote_client = silc_idlist_find_client_by_id(server->local_list,
1456 if (!remote_client) {
1457 remote_client = silc_idlist_find_client_by_id(server->global_list,
1460 if (!remote_client) {
1461 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1462 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1463 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1464 0, 2, tmp, tmp_len);
1470 comment = silc_argument_get_arg_type(cmd->args, 2, &tmp_len2);
1471 if (comment && tmp_len2 > 128) {
1473 comment[tmp_len2 - 1] = '\0';
1476 /* If authentication data is provided then verify that killing is
1478 if (auth && auth_len) {
1479 SilcPacketStream sock;
1481 if (!SILC_IS_LOCAL(remote_client) || !remote_client->data.public_key) {
1482 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1483 SILC_STATUS_ERR_OPERATION_ALLOWED,
1488 /* Verify the signature */
1489 if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
1490 remote_client->data.public_key, 0,
1491 server->sha1hash, remote_client->id,
1493 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1494 SILC_STATUS_ERR_AUTH_FAILED, 0);
1498 /* Send reply to the sender */
1499 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1500 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1504 /* Do normal signoff for the destination client */
1505 sock = remote_client->connection;
1508 silc_packet_stream_ref(sock);
1510 silc_server_remove_from_channels(server, NULL, remote_client,
1511 TRUE, (char *)"Killed", TRUE, TRUE);
1512 silc_server_free_sock_user_data(server, sock, comment ? comment :
1513 (unsigned char *)"Killed");
1515 silc_packet_set_context(sock, NULL);
1516 silc_server_close_connection(server, sock);
1517 silc_packet_stream_unref(sock);
1520 /* Router operator killing */
1522 /* Send reply to the sender */
1523 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1524 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1528 /* Check if anyone is watching this nickname */
1529 if (server->server_type == SILC_ROUTER)
1530 silc_server_check_watcher_list(server, client, NULL,
1531 SILC_NOTIFY_TYPE_KILLED);
1533 /* Now do the killing */
1534 silc_server_kill_client(server, remote_client, comment, client->id,
1539 silc_server_command_free(cmd);
1542 /* Server side of command INFO. This sends information about us to
1543 the client. If client requested specific server we will send the
1544 command to that server. */
1546 SILC_SERVER_CMD_FUNC(info)
1548 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1549 SilcServer server = cmd->server;
1553 char *dest_server = NULL, *server_info = NULL, *server_name;
1554 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1555 SilcServerEntry entry = NULL;
1558 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INFO, cmd, 0, 2);
1560 /* Get server name */
1561 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
1563 /* Check server name. */
1564 dest_server = silc_identifier_check(dest_server, strlen(dest_server),
1565 SILC_STRING_UTF8, 256, &tmp_len);
1567 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
1568 SILC_STATUS_ERR_BAD_SERVER, 0);
1574 if (silc_argument_get_decoded(cmd->args, 2, SILC_ARGUMENT_ID, &id, NULL)) {
1575 /* Check whether we have this server cached */
1576 entry = silc_idlist_find_server_by_id(server->local_list,
1577 SILC_ID_GET_ID(id), TRUE, NULL);
1579 entry = silc_idlist_find_server_by_id(server->global_list,
1580 SILC_ID_GET_ID(id), TRUE, NULL);
1581 if (!entry && server->server_type != SILC_SERVER) {
1582 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
1583 silc_server_command_send_status_data(cmd, SILC_COMMAND_INFO,
1584 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
1585 0, 2, tmp, tmp_len);
1591 if ((!dest_server && !entry) || (entry && entry == server->id_entry) ||
1592 (dest_server && !cmd->pending &&
1593 !memcmp(dest_server, server->server_name, strlen(dest_server)))) {
1594 /* Send our reply */
1595 char info_string[256];
1597 memset(info_string, 0, sizeof(info_string));
1598 silc_snprintf(info_string, sizeof(info_string),
1599 "location: %s server: %s admin: %s <%s> version: %s",
1600 server->config->server_info->location,
1601 server->config->server_info->server_type,
1602 server->config->server_info->admin,
1603 server->config->server_info->email,
1606 server_info = info_string;
1607 entry = server->id_entry;
1609 /* Check whether we have this server cached */
1610 if (!entry && dest_server) {
1611 entry = silc_idlist_find_server_by_name(server->global_list,
1612 dest_server, TRUE, NULL);
1614 entry = silc_idlist_find_server_by_name(server->local_list,
1615 dest_server, TRUE, NULL);
1619 if (!cmd->pending &&
1620 server->server_type != SILC_SERVER && entry && !entry->server_info) {
1621 /* Send to the server */
1623 SilcUInt16 old_ident;
1626 cmd->server->stat.commands_sent++;
1628 old_ident = silc_command_get_ident(cmd->payload);
1629 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1630 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1632 silc_server_packet_send(server, entry->connection,
1633 SILC_PACKET_COMMAND, cmd->packet->flags,
1634 tmpbuf->data, silc_buffer_len(tmpbuf));
1636 /* Reprocess this packet after received reply from router */
1637 silc_server_command_pending(server, SILC_COMMAND_INFO,
1638 silc_command_get_ident(cmd->payload),
1639 silc_server_command_info,
1640 silc_server_command_dup(cmd));
1641 cmd->pending = TRUE;
1642 silc_command_set_ident(cmd->payload, old_ident);
1643 silc_buffer_free(tmpbuf);
1647 if (!entry && !cmd->pending && !server->standalone) {
1648 /* Send to the primary router */
1650 SilcUInt16 old_ident;
1653 cmd->server->stat.commands_sent++;
1655 old_ident = silc_command_get_ident(cmd->payload);
1656 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1657 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1659 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
1660 SILC_PACKET_COMMAND, cmd->packet->flags,
1661 tmpbuf->data, silc_buffer_len(tmpbuf));
1663 /* Reprocess this packet after received reply from router */
1664 silc_server_command_pending(server, SILC_COMMAND_INFO,
1665 silc_command_get_ident(cmd->payload),
1666 silc_server_command_info,
1667 silc_server_command_dup(cmd));
1668 cmd->pending = TRUE;
1669 silc_command_set_ident(cmd->payload, old_ident);
1670 silc_buffer_free(tmpbuf);
1677 silc_free(dest_server);
1678 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
1679 silc_server_command_send_status_data(cmd, SILC_COMMAND_INFO,
1680 SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
1682 strlen(dest_server));
1688 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
1690 server_info = entry->server_info;
1691 server_name = entry->server_name;
1693 /* Send the reply */
1694 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_INFO,
1695 SILC_STATUS_OK, 0, ident, 3,
1696 2, idp->data, silc_buffer_len(idp),
1698 strlen(server_name),
1701 strlen(server_info) : 0);
1702 silc_buffer_free(idp);
1705 silc_free(dest_server);
1706 silc_server_command_free(cmd);
1709 /* Server side of command PING. This just replies to the ping. */
1711 SILC_SERVER_CMD_FUNC(ping)
1713 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1714 SilcServer server = cmd->server;
1719 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PING, cmd, 1, 1);
1722 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
1723 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
1724 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1729 if (SILC_ID_SERVER_COMPARE(SILC_ID_GET_ID(id), server->id)) {
1730 /* Send our reply */
1731 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
1734 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1735 silc_server_command_send_status_data(cmd, SILC_COMMAND_PING,
1736 SILC_STATUS_ERR_NO_SUCH_SERVER_ID, 0,
1742 silc_server_command_free(cmd);
1745 /* Server side of command STATS. */
1747 SILC_SERVER_CMD_FUNC(stats)
1749 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1750 SilcServer server = cmd->server;
1754 SilcBuffer packet, stats;
1755 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1758 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_STATS, cmd, 1, 1);
1761 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
1762 silc_server_command_send_status_reply(cmd, SILC_COMMAND_STATS,
1763 SILC_STATUS_ERR_NO_SERVER_ID, 0);
1767 SILC_LOG_DEBUG(("id %s", silc_id_render(SILC_ID_GET_ID(id),
1770 /* The ID must be ours */
1771 if (!SILC_ID_SERVER_COMPARE(server->id, SILC_ID_GET_ID(id))) {
1772 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1773 silc_server_command_send_status_data(cmd, SILC_COMMAND_STATS,
1774 SILC_STATUS_ERR_NO_SUCH_SERVER_ID, 0,
1779 /* If we are router then just send everything we got. If we are normal
1780 server then we'll send this to our router to get all the latest
1781 statistical information. */
1782 if (!cmd->pending && server->server_type != SILC_ROUTER &&
1783 !server->standalone) {
1787 cmd->server->stat.commands_sent++;
1789 /* Send request to our router */
1790 idp = silc_id_payload_encode(server->router->id,
1792 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
1793 ++server->cmd_ident, 1,
1795 silc_buffer_len(idp));
1796 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
1797 SILC_PACKET_COMMAND, 0, packet->data,
1798 silc_buffer_len(packet));
1800 /* Reprocess this packet after received reply from router */
1801 silc_server_command_pending(server, SILC_COMMAND_STATS,
1803 silc_server_command_stats,
1804 silc_server_command_dup(cmd));
1805 cmd->pending = TRUE;
1806 silc_buffer_free(packet);
1807 silc_buffer_free(idp);
1811 /* Send our reply to sender */
1812 uptime = time(NULL) - server->starttime;
1814 stats = silc_buffer_alloc_size(60);
1815 silc_buffer_format(stats,
1816 SILC_STR_UI_INT(server->starttime),
1817 SILC_STR_UI_INT(uptime),
1818 SILC_STR_UI_INT(server->stat.my_clients),
1819 SILC_STR_UI_INT(server->stat.my_channels),
1820 SILC_STR_UI_INT(server->stat.my_server_ops),
1821 SILC_STR_UI_INT(server->stat.my_router_ops),
1822 SILC_STR_UI_INT(server->stat.cell_clients),
1823 SILC_STR_UI_INT(server->stat.cell_channels),
1824 SILC_STR_UI_INT(server->stat.cell_servers),
1825 SILC_STR_UI_INT(server->stat.clients),
1826 SILC_STR_UI_INT(server->stat.channels),
1827 SILC_STR_UI_INT(server->stat.servers),
1828 SILC_STR_UI_INT(server->stat.routers),
1829 SILC_STR_UI_INT(server->stat.server_ops),
1830 SILC_STR_UI_INT(server->stat.router_ops),
1833 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1834 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_STATS,
1835 SILC_STATUS_OK, 0, ident, 2,
1837 3, stats->data, silc_buffer_len(stats));
1838 silc_buffer_free(stats);
1841 silc_server_command_free(cmd);
1844 /* Internal routine to join channel. The channel sent to this function
1845 has been either created or resolved from ID lists. This joins the sent
1846 client to the channel. */
1848 static void silc_server_command_join_channel(SilcServer server,
1849 SilcServerCommandContext cmd,
1850 SilcChannelEntry channel,
1851 SilcClientID *client_id,
1853 SilcBool create_key,
1855 const unsigned char *auth,
1856 SilcUInt32 auth_len,
1857 const unsigned char *cauth,
1858 SilcUInt32 cauth_len)
1860 SilcPacketStream sock = cmd->sock;
1861 SilcIDListData idata = silc_packet_get_context(sock);
1863 SilcUInt32 tmp_len, user_count;
1864 unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4], ulimit[4];
1865 SilcClientEntry client;
1866 SilcChannelClientEntry chl;
1867 SilcBuffer reply, chidp, clidp, keyp = NULL;
1868 SilcBuffer user_list, mode_list, invite_list, ban_list;
1869 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1870 char check[512], check2[512];
1872 SilcBool founder = FALSE;
1874 SilcBuffer fkey = NULL, chpklist = NULL;
1875 const char *cipher, *hostname, *ip;
1877 SILC_LOG_DEBUG(("Joining client to channel"));
1882 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
1883 NULL, &hostname, &ip, NULL);
1885 /* Get the client entry */
1886 if (idata->conn_type == SILC_CONN_CLIENT) {
1887 client = (SilcClientEntry)idata;
1891 client = silc_server_query_client(server, client_id, FALSE,
1894 if (!resolve || cmd->pending) {
1895 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
1896 silc_server_command_send_status_data(
1897 cmd, SILC_COMMAND_JOIN,
1898 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1903 /* The client info is being resolved. Reprocess this packet after
1904 receiving the reply to the query. */
1905 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
1907 silc_server_command_join,
1908 silc_server_command_dup(cmd));
1909 cmd->pending = TRUE;
1913 if (!client->data.public_key &&
1914 (auth || cauth || channel->ban_list ||
1915 (channel->mode & SILC_CHANNEL_MODE_INVITE))) {
1916 if (cmd->pending == 2)
1919 /* We must retrieve the client's public key by sending
1920 GETKEY command. Reprocess this packet after receiving the key */
1921 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1922 silc_server_send_command(server, cmd->sock,
1923 SILC_COMMAND_GETKEY, ++server->cmd_ident,
1924 1, 1, clidp->data, silc_buffer_len(clidp));
1925 silc_buffer_free(clidp);
1926 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
1928 silc_server_command_join,
1929 silc_server_command_dup(cmd));
1934 cmd->pending = FALSE;
1938 * Check founder auth payload if provided. If client can gain founder
1939 * privileges it can override various conditions on joining the channel,
1940 * and can have directly the founder mode set on the channel.
1942 if (auth && auth_len && channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1943 SilcIDListData idata = (SilcIDListData)client;
1944 SilcChannelClientEntry chl2;
1945 SilcHashTableList htl;
1947 if (channel->founder_key && idata->public_key &&
1948 silc_pkcs_public_key_compare(channel->founder_key,
1949 idata->public_key)) {
1950 /* Check whether the client is to become founder */
1951 if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
1952 channel->founder_key, 0, server->sha1hash,
1953 client->id, SILC_ID_CLIENT)) {
1955 /* There cannot be anyone else as founder on the channel now. This
1956 client is definitely the founder due to this authentication */
1957 silc_hash_table_list(channel->user_list, &htl);
1958 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
1959 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
1960 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
1961 silc_server_force_cumode_change(server, NULL, channel, chl2,
1965 silc_hash_table_list_reset(&htl);
1967 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
1974 * Check channel modes
1978 memset(check, 0, sizeof(check));
1979 memset(check2, 0, sizeof(check2));
1980 silc_strncat(check, sizeof(check),
1981 client->nickname, strlen(client->nickname));
1982 silc_strncat(check, sizeof(check), "!", 1);
1983 silc_strncat(check, sizeof(check),
1984 client->username, strlen(client->username));
1985 if (!strchr(client->username, '@')) {
1986 silc_strncat(check, sizeof(check), "@", 1);
1987 silc_strncat(check, sizeof(check),
1988 hostname, strlen(hostname));
1991 silc_strncat(check2, sizeof(check2),
1992 client->nickname, strlen(client->nickname));
1993 if (!strchr(client->nickname, '@')) {
1994 silc_strncat(check2, sizeof(check2), "@", 1);
1995 silc_strncat(check2, sizeof(check2),
1996 SILC_IS_LOCAL(client) ? server->server_name :
1997 client->router->server_name,
1998 SILC_IS_LOCAL(client) ? strlen(server->server_name) :
1999 strlen(client->router->server_name));
2001 silc_strncat(check2, sizeof(check2), "!", 1);
2002 silc_strncat(check2, sizeof(check2),
2003 client->username, strlen(client->username));
2004 if (!strchr(client->username, '@')) {
2005 silc_strncat(check2, sizeof(check2), "@", 1);
2006 silc_strncat(check2, sizeof(check2),
2007 hostname, strlen(hostname));
2010 /* Check invite list if channel is invite-only channel */
2011 if (channel->mode & SILC_CHANNEL_MODE_INVITE) {
2012 if (!channel->invite_list ||
2013 !silc_hash_table_count(channel->invite_list) ||
2014 (!silc_server_inviteban_match(server, channel->invite_list,
2016 !silc_server_inviteban_match(server, channel->invite_list,
2017 2, client->data.public_key) &&
2018 !silc_server_inviteban_match(server, channel->invite_list,
2019 1, client->nickname) &&
2020 !silc_server_inviteban_match(server, channel->invite_list,
2022 !silc_server_inviteban_match(server, channel->invite_list,
2024 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2025 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2026 SILC_STATUS_ERR_NOT_INVITED, 0,
2028 silc_buffer_len(chidp));
2029 silc_buffer_free(chidp);
2034 /* Check ban list if it exists. If the client's nickname, server,
2035 username and/or hostname is in the ban list the access to the
2036 channel is denied. */
2037 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
2038 if (silc_server_inviteban_match(server, channel->ban_list,
2040 silc_server_inviteban_match(server, channel->ban_list,
2041 2, client->data.public_key) ||
2042 silc_server_inviteban_match(server, channel->ban_list,
2043 1, client->nickname) ||
2044 silc_server_inviteban_match(server, channel->ban_list,
2046 silc_server_inviteban_match(server, channel->ban_list,
2048 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2049 silc_server_command_send_status_data(
2050 cmd, SILC_COMMAND_JOIN,
2051 SILC_STATUS_ERR_BANNED_FROM_CHANNEL, 0,
2053 silc_buffer_len(chidp));
2054 silc_buffer_free(chidp);
2059 /* Check user count limit if set. */
2060 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT) {
2061 if (silc_hash_table_count(channel->user_list) + 1 >
2062 channel->user_limit) {
2063 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2064 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2065 SILC_STATUS_ERR_CHANNEL_IS_FULL,
2067 silc_buffer_len(chidp));
2068 silc_buffer_free(chidp);
2074 /* Check the channel passphrase if set. */
2075 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
2076 /* Get passphrase */
2077 tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
2079 passphrase = silc_memdup(tmp, tmp_len);
2081 if (!passphrase || !channel->passphrase ||
2082 strlen(channel->passphrase) != strlen(passphrase) ||
2083 memcmp(passphrase, channel->passphrase, strlen(channel->passphrase))) {
2084 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2085 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2086 SILC_STATUS_ERR_BAD_PASSWORD, 0,
2088 silc_buffer_len(chidp));
2089 silc_buffer_free(chidp);
2094 /* Verify channel authentication with channel public keys if set. */
2095 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
2096 if (!silc_server_verify_channel_auth(server, channel, client->id,
2097 cauth, cauth_len)) {
2098 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2099 SILC_STATUS_ERR_PERM_DENIED, 0);
2105 * Client is allowed to join to the channel. Make it happen.
2108 /* Check whether the client already is on the channel */
2109 if (silc_server_client_on_channel(client, channel, NULL)) {
2110 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
2111 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2112 silc_server_command_send_status_data2(cmd, SILC_COMMAND_JOIN,
2113 SILC_STATUS_ERR_USER_ON_CHANNEL, 0,
2115 silc_buffer_len(clidp),
2117 silc_buffer_len(chidp));
2118 silc_buffer_free(clidp);
2119 silc_buffer_free(chidp);
2123 /* Generate new channel key as protocol dictates */
2125 if (!silc_server_create_channel_key(server, channel, 0))
2128 /* Send the channel key. This is broadcasted to the channel but is not
2129 sent to the client who is joining to the channel. */
2130 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
2131 silc_server_send_channel_key(server, NULL, channel,
2132 server->server_type == SILC_ROUTER ?
2133 FALSE : !server->standalone);
2136 /* Join the client to the channel by adding it to channel's user list.
2137 Add also the channel to client entry's channels list for fast cross-
2139 chl = silc_calloc(1, sizeof(*chl));
2143 chl->client = client;
2144 chl->channel = channel;
2145 silc_hash_table_add(channel->user_list, client, chl);
2146 silc_hash_table_add(client->channels, channel, chl);
2147 channel->user_count++;
2148 channel->disabled = FALSE;
2150 /* Get users on the channel */
2151 silc_server_get_users_on_channel(server, channel, &user_list, &mode_list,
2154 /* Encode Client ID Payload of the original client who wants to join */
2155 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2157 /* Encode command reply packet */
2158 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2159 SILC_PUT32_MSB(channel->mode, mode);
2160 SILC_PUT32_MSB(created, tmp2);
2161 SILC_PUT32_MSB(user_count, tmp3);
2162 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2163 SILC_PUT32_MSB(channel->user_limit, ulimit);
2165 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2166 unsigned char cid[32];
2168 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid), &cid_len);
2169 cipher = silc_cipher_get_name(channel->send_key);
2170 keyp = silc_channel_key_payload_encode(cid_len, cid,
2171 strlen(cipher), cipher,
2172 channel->key_len / 8, channel->key);
2175 if (channel->founder_key)
2176 fkey = silc_public_key_payload_encode(channel->founder_key);
2178 /* Encode invite list */
2180 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
2181 SilcHashTableList htl;
2183 invite_list = silc_buffer_alloc_size(2);
2184 silc_buffer_format(invite_list,
2185 SILC_STR_UI_SHORT(silc_hash_table_count(
2186 channel->invite_list)),
2189 silc_hash_table_list(channel->invite_list, &htl);
2190 while (silc_hash_table_get(&htl, (void *)&plen, (void *)&reply))
2191 invite_list = silc_argument_payload_encode_one(invite_list,
2193 silc_buffer_len(reply),
2194 SILC_PTR_TO_32(plen));
2195 silc_hash_table_list_reset(&htl);
2198 /* Encode ban list */
2200 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
2201 SilcHashTableList htl;
2203 ban_list = silc_buffer_alloc_size(2);
2204 silc_buffer_format(ban_list,
2205 SILC_STR_UI_SHORT(silc_hash_table_count(
2206 channel->ban_list)),
2209 silc_hash_table_list(channel->ban_list, &htl);
2210 while (silc_hash_table_get(&htl, (void *)&plen, (void *)&reply))
2211 ban_list = silc_argument_payload_encode_one(ban_list,
2213 silc_buffer_len(reply),
2214 SILC_PTR_TO_32(plen));
2215 silc_hash_table_list_reset(&htl);
2218 if (channel->channel_pubkeys)
2219 chpklist = silc_server_get_channel_pk_list(server, channel, FALSE, FALSE);
2222 silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
2223 SILC_STATUS_OK, 0, ident, 16,
2224 2, channel->channel_name,
2225 strlen(channel->channel_name),
2227 silc_buffer_len(chidp),
2229 silc_buffer_len(clidp),
2232 7, keyp ? keyp->data : NULL,
2233 keyp ? silc_buffer_len(keyp) : 0,
2234 8, ban_list ? ban_list->data : NULL,
2236 silc_buffer_len(ban_list): 0,
2237 9, invite_list ? invite_list->data :
2240 silc_buffer_len(invite_list) : 0,
2243 strlen(channel->topic) : 0,
2244 11, silc_hmac_get_name(channel->hmac),
2245 strlen(silc_hmac_get_name(channel->
2248 13, user_list->data,
2249 silc_buffer_len(user_list),
2250 14, mode_list->data,
2251 silc_buffer_len(mode_list),
2252 15, fkey ? fkey->data : NULL,
2253 fkey ? silc_buffer_len(fkey) : 0,
2254 16, chpklist ? chpklist->data : NULL,
2255 chpklist ? silc_buffer_len(chpklist) : 0,
2256 17, (channel->mode &
2257 SILC_CHANNEL_MODE_ULIMIT ?
2260 SILC_CHANNEL_MODE_ULIMIT ?
2261 sizeof(ulimit) : 0));
2263 /* Send command reply */
2264 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
2265 reply->data, silc_buffer_len(reply));
2268 cmd->server->stat.commands_sent++;
2270 /* Send JOIN notify to locally connected clients on the channel. If
2271 we are normal server then router will send or have sent JOIN notify
2272 already. However since we've added the client already to our channel
2273 we'll ignore it (in packet_receive.c) so we must send it here. If
2274 we are router then this will send it to local clients and local
2276 SILC_LOG_DEBUG(("Send JOIN notify to channel"));
2277 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2278 SILC_NOTIFY_TYPE_JOIN, 2,
2279 clidp->data, silc_buffer_len(clidp),
2280 chidp->data, silc_buffer_len(chidp));
2282 /* Update statistics */
2283 server->stat.my_chanclients++;
2284 if (server->server_type == SILC_ROUTER) {
2285 server->stat.cell_chanclients++;
2286 server->stat.chanclients++;
2289 if (!cmd->pending) {
2290 /* Send JOIN notify packet to our primary router */
2291 silc_server_send_notify_join(server, SILC_PRIMARY_ROUTE(server),
2292 SILC_BROADCAST(server), channel, client->id);
2295 /* Distribute the channel key to all backup routers. */
2296 silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
2297 keyp->data, silc_buffer_len(keyp), FALSE, TRUE);
2299 /* If client became founder by providing correct founder auth data
2300 notify the mode change to the channel. */
2302 SILC_PUT32_MSB(chl->mode, mode);
2303 SILC_LOG_DEBUG(("Send CUMODE_CHANGE notify to channel"));
2304 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2305 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
2307 silc_buffer_len(clidp),
2308 mode, 4, clidp->data,
2309 silc_buffer_len(clidp),
2310 fkey ? fkey->data : NULL,
2311 fkey ? silc_buffer_len(fkey) : 0);
2315 /* Set CUMODE notify type to network */
2317 silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
2318 SILC_BROADCAST(server), channel,
2319 chl->mode, client->id, SILC_ID_CLIENT,
2320 client->id, channel->founder_key);
2322 silc_buffer_free(reply);
2323 silc_buffer_free(clidp);
2324 silc_buffer_free(chidp);
2325 silc_buffer_free(keyp);
2326 silc_buffer_free(user_list);
2327 silc_buffer_free(mode_list);
2328 silc_buffer_free(fkey);
2329 silc_buffer_free(chpklist);
2330 silc_buffer_free(invite_list);
2331 silc_buffer_free(ban_list);
2335 memset(passphrase, 0, strlen(passphrase));
2336 silc_free(passphrase);
2339 /* Server side of command JOIN. Joins client into requested channel. If
2340 the channel does not exist it will be created. */
2342 void silc_server_command_join_connected(SilcServer server,
2343 SilcServerEntry server_entry,
2346 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2348 if (!server_entry) {
2350 unsigned char *tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
2353 SILC_LOG_DEBUG(("Connecting to router failed"));
2354 silc_parse_userfqdn(tmp, NULL, 0, serv, sizeof(serv));
2357 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2358 SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
2359 2, serv, strlen(serv));
2361 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2362 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
2365 silc_server_command_free(cmd);
2369 /* Reprocess command */
2370 SILC_LOG_DEBUG(("Reprocess JOIN after connecting to router"));
2371 silc_server_command_join(cmd, NULL);
2374 SILC_SERVER_CMD_FUNC(join)
2376 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2377 SilcServer server = cmd->server;
2378 SilcIDListData idata = silc_packet_get_context(cmd->sock);
2379 unsigned char *auth, *cauth;
2380 SilcUInt32 tmp_len, auth_len, cauth_len;
2381 char *tmp, *channel_name, *channel_namec = NULL, *cipher, *hmac;
2382 char parsed[256 + 1], serv[256 + 1];
2383 SilcChannelEntry channel;
2384 SilcUInt32 umode = 0;
2385 SilcBool created = FALSE, create_key = TRUE;
2388 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_JOIN, cmd, 2, 7);
2390 /* Get channel name */
2391 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
2393 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2394 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2399 /* Truncate over long channel names */
2400 if (tmp_len > 256) {
2402 tmp[tmp_len - 1] = '\0';
2405 /* Parse server name from the channel name */
2406 silc_parse_userfqdn(tmp, parsed, sizeof(parsed), serv,
2408 channel_name = parsed;
2410 if (server->config->dynamic_server) {
2411 /* If server name is not specified but local channels is FALSE then the
2412 channel will be global, based on our router name. */
2413 if (!serv[0] && !server->config->local_channels) {
2414 if (!server->standalone) {
2415 silc_snprintf(serv, sizeof(serv), "%s", server->router->server_name);
2417 SilcServerConfigRouter *router;
2418 router = silc_server_config_get_primary_router(server);
2420 /* Create connection to primary router */
2421 SILC_LOG_DEBUG(("Create dynamic connection to primary router %s:%d",
2422 router->host, router->port));
2423 silc_server_create_connection(server, FALSE, TRUE,
2424 router->host, router->port,
2425 silc_server_command_join_connected,
2432 /* If server name is ours, ignore it. */
2433 if (serv[0] && silc_utf8_strcasecmp(serv, server->server_name))
2434 memset(serv, 0, sizeof(serv));
2436 /* Create connection */
2437 if (serv[0] && server->standalone) {
2438 SilcServerConfigRouter *router;
2439 router = silc_server_config_get_primary_router(server);
2441 /* Create connection to primary router */
2442 SILC_LOG_DEBUG(("Create dynamic connection to primary router %s:%d",
2443 router->host, router->port));
2444 silc_server_create_connection(server, FALSE, TRUE,
2445 router->host, router->port,
2446 silc_server_command_join_connected, cmd);
2452 /* Check for valid channel name. This is cached, the original is saved
2453 in the channel context. */
2454 channel_namec = silc_channel_name_check(channel_name, strlen(channel_name),
2455 SILC_STRING_UTF8, 256, NULL);
2456 if (!channel_namec) {
2457 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2458 SILC_STATUS_ERR_BAD_CHANNEL, 0);
2462 /* Get Client ID of the client who is joining to the channel */
2463 if (!silc_argument_get_decoded(cmd->args, 2, SILC_ARGUMENT_ID, &id, NULL)) {
2464 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2465 SILC_STATUS_ERR_NO_CLIENT_ID,
2470 /* Get cipher, hmac name and auth payload */
2471 cipher = silc_argument_get_arg_type(cmd->args, 4, NULL);
2472 hmac = silc_argument_get_arg_type(cmd->args, 5, NULL);
2473 auth = silc_argument_get_arg_type(cmd->args, 6, &auth_len);
2474 cauth = silc_argument_get_arg_type(cmd->args, 7, &cauth_len);
2476 /* See if the channel exists */
2477 channel = silc_idlist_find_channel_by_name(server->local_list,
2478 channel_namec, NULL);
2480 if (idata->conn_type == SILC_CONN_CLIENT) {
2481 SilcClientEntry entry = (SilcClientEntry)idata;
2483 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2484 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2489 #ifndef SILC_DIST_INPLACE
2490 /* Limit how many channels client can join */
2491 if (!cmd->pending && entry->channels &&
2492 silc_hash_table_count(entry->channels) >=
2493 server->config->param.chlimit) {
2494 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2495 SILC_STATUS_ERR_RESOURCE_LIMIT,
2499 #endif /* SILC_DIST_INPLACE */
2502 (channel->disabled && server->server_type != SILC_ROUTER)) {
2503 /* Channel not found or not valid */
2505 /* If we are standalone server we don't have a router, we just create
2506 the channel by ourselves (unless it existed). */
2507 if (server->standalone) {
2509 channel = silc_server_create_new_channel(server, server->id, cipher,
2510 hmac, channel_name, TRUE);
2513 silc_server_command_send_status_data(
2514 cmd, SILC_COMMAND_JOIN,
2515 SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
2516 0, 2, cipher, strlen(cipher));
2518 silc_server_command_send_status_data(
2519 cmd, SILC_COMMAND_JOIN,
2520 SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
2521 0, 2, hmac, strlen(hmac));
2523 silc_server_command_send_status_reply(
2524 cmd, SILC_COMMAND_JOIN,
2525 SILC_STATUS_ERR_RESOURCE_LIMIT,
2531 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2537 /* The channel does not exist on our server. If we are normal server
2538 we will send JOIN command to our router which will handle the
2539 joining procedure (either creates the channel if it doesn't exist
2540 or joins the client to it). */
2541 if (server->server_type != SILC_ROUTER) {
2543 SilcUInt16 old_ident;
2545 /* If this is pending command callback then we've resolved
2546 it and it didn't work, return since we've notified the
2547 client already in the command reply callback. */
2552 cmd->server->stat.commands_sent++;
2554 old_ident = silc_command_get_ident(cmd->payload);
2555 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2556 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2558 /* Send JOIN command to our router */
2559 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2560 SILC_PACKET_COMMAND, cmd->packet->flags,
2561 tmpbuf->data, silc_buffer_len(tmpbuf));
2563 /* Reprocess this packet after received reply from router */
2564 silc_server_command_pending(server, SILC_COMMAND_JOIN,
2565 silc_command_get_ident(cmd->payload),
2566 silc_server_command_join,
2567 silc_server_command_dup(cmd));
2568 cmd->pending = TRUE;
2569 silc_command_set_ident(cmd->payload, old_ident);
2570 silc_buffer_free(tmpbuf);
2574 /* We are router and the channel does not seem exist so we will check
2575 our global list as well for the channel. */
2576 channel = silc_idlist_find_channel_by_name(server->global_list,
2577 channel_namec, NULL);
2579 /* Channel really does not exist, create it */
2580 channel = silc_server_create_new_channel(server, server->id, cipher,
2581 hmac, channel_name, TRUE);
2584 silc_server_command_send_status_data(
2585 cmd, SILC_COMMAND_JOIN,
2586 SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
2587 0, 2, cipher, strlen(cipher));
2589 silc_server_command_send_status_data(
2590 cmd, SILC_COMMAND_JOIN,
2591 SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
2592 0, 2, hmac, strlen(hmac));
2594 silc_server_command_send_status_reply(
2595 cmd, SILC_COMMAND_JOIN,
2596 SILC_STATUS_ERR_RESOURCE_LIMIT,
2602 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2610 /* Channel not found */
2612 /* If the command came from router and we are normal server then
2613 something went wrong with the joining as the channel was not found.
2614 We can't do anything else but ignore this. */
2615 if (idata->conn_type == SILC_CONN_ROUTER ||
2616 server->server_type != SILC_ROUTER)
2619 /* We are router and the channel does not seem exist so we will check
2620 our global list as well for the channel. */
2621 channel = silc_idlist_find_channel_by_name(server->global_list,
2622 channel_namec, NULL);
2624 /* Channel really does not exist, create it */
2625 channel = silc_server_create_new_channel(server, server->id, cipher,
2626 hmac, channel_name, TRUE);
2629 silc_server_command_send_status_data(
2630 cmd, SILC_COMMAND_JOIN,
2631 SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
2632 0, 2, cipher, strlen(cipher));
2634 silc_server_command_send_status_data(
2635 cmd, SILC_COMMAND_JOIN,
2636 SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
2637 0, 2, hmac, strlen(hmac));
2639 silc_server_command_send_status_reply(
2640 cmd, SILC_COMMAND_JOIN,
2641 SILC_STATUS_ERR_RESOURCE_LIMIT,
2647 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2654 /* Check whether the channel was created by our router */
2655 if (cmd->pending && context2) {
2656 SilcServerCommandReplyContext reply = context2;
2658 if (silc_command_get(reply->payload) == SILC_COMMAND_JOIN) {
2659 tmp = silc_argument_get_arg_type(reply->args, 6, NULL);
2660 SILC_GET32_MSB(created, tmp);
2661 if (silc_argument_get_arg_type(reply->args, 7, NULL))
2662 create_key = FALSE; /* Router returned the key already */
2664 if (silc_command_get_status(reply->payload, NULL, NULL) &&
2665 channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
2666 /* Save channel passphrase, if user provided it successfully */
2669 pa = silc_argument_get_arg_type(cmd->args, 3, &pa_len);
2671 silc_free(channel->passphrase);
2672 channel->passphrase = silc_memdup(pa, pa_len);
2677 if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
2678 !channel->disabled && !silc_hash_table_count(channel->user_list))
2682 /* If the channel does not have global users and is also empty the client
2683 will be the channel founder and operator. */
2684 if (!channel->disabled &&
2685 !channel->global_users && !silc_hash_table_count(channel->user_list))
2686 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2688 /* Join to the channel */
2689 silc_server_command_join_channel(server, cmd, channel, SILC_ID_GET_ID(id),
2690 created, create_key, umode,
2691 auth, auth_len, cauth, cauth_len);
2694 silc_free(channel_namec);
2695 silc_server_command_free(cmd);
2698 /* Server side of command MOTD. Sends server's current "message of the
2699 day" to the client. */
2701 SILC_SERVER_CMD_FUNC(motd)
2703 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2704 SilcServer server = cmd->server;
2706 char *motd, *dest_server = NULL;
2707 SilcUInt32 motd_len;
2708 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2710 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_MOTD, cmd, 1, 1);
2712 /* Get server name */
2713 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2715 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
2716 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2721 /* Check server name */
2722 dest_server = silc_identifier_check(dest_server, strlen(dest_server),
2723 SILC_STRING_UTF8, 256, NULL);
2725 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
2726 SILC_STATUS_ERR_BAD_SERVER,
2731 if (!memcmp(dest_server, server->server_name, strlen(dest_server))) {
2734 idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
2736 if (server->config && server->config->server_info &&
2737 server->config->server_info->motd_file) {
2739 motd = silc_file_readfile(server->config->server_info->motd_file,
2743 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_MOTD,
2744 SILC_STATUS_OK, 0, ident, 1,
2745 2, idp->data, silc_buffer_len(idp));
2750 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_MOTD,
2751 SILC_STATUS_OK, 0, ident, 2,
2752 2, idp->data, silc_buffer_len(idp),
2756 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_MOTD,
2757 SILC_STATUS_OK, 0, ident, 1,
2758 2, idp->data, silc_buffer_len(idp));
2760 silc_buffer_free(idp);
2762 SilcServerEntry entry;
2764 /* Check whether we have this server cached */
2765 entry = silc_idlist_find_server_by_name(server->global_list,
2766 dest_server, TRUE, NULL);
2768 entry = silc_idlist_find_server_by_name(server->local_list,
2769 dest_server, TRUE, NULL);
2772 if (server->server_type != SILC_SERVER && !cmd->pending &&
2773 entry && !entry->motd) {
2774 /* Send to the server */
2776 SilcUInt16 old_ident;
2779 cmd->server->stat.commands_sent++;
2781 old_ident = silc_command_get_ident(cmd->payload);
2782 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2783 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2785 silc_server_packet_send(server, entry->connection,
2786 SILC_PACKET_COMMAND, cmd->packet->flags,
2787 tmpbuf->data, silc_buffer_len(tmpbuf));
2789 /* Reprocess this packet after received reply from router */
2790 silc_server_command_pending(server, SILC_COMMAND_MOTD,
2791 silc_command_get_ident(cmd->payload),
2792 silc_server_command_motd,
2793 silc_server_command_dup(cmd));
2794 cmd->pending = TRUE;
2795 silc_command_set_ident(cmd->payload, old_ident);
2796 silc_buffer_free(tmpbuf);
2800 /* Send to primary router only if we don't know the server
2801 * the client requested or if the server is not locally connected */
2802 if ((!entry || !(entry->data.status & SILC_IDLIST_STATUS_LOCAL))
2803 && !cmd->pending && !server->standalone) {
2804 /* Send to the primary router */
2806 SilcUInt16 old_ident;
2809 cmd->server->stat.commands_sent++;
2811 old_ident = silc_command_get_ident(cmd->payload);
2812 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2813 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2815 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2816 SILC_PACKET_COMMAND, cmd->packet->flags,
2817 tmpbuf->data, silc_buffer_len(tmpbuf));
2819 /* Reprocess this packet after received reply from router */
2820 silc_server_command_pending(server, SILC_COMMAND_MOTD,
2821 silc_command_get_ident(cmd->payload),
2822 silc_server_command_motd,
2823 silc_server_command_dup(cmd));
2824 cmd->pending = TRUE;
2825 silc_command_set_ident(cmd->payload, old_ident);
2826 silc_buffer_free(tmpbuf);
2831 silc_free(dest_server);
2832 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2833 silc_server_command_send_status_data(cmd, SILC_COMMAND_MOTD,
2834 SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
2836 strlen(dest_server));
2841 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
2842 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_MOTD,
2843 SILC_STATUS_OK, 0, ident, 2,
2844 2, idp->data, silc_buffer_len(idp),
2847 strlen(entry->motd) : 0);
2848 silc_buffer_free(idp);
2852 silc_free(dest_server);
2853 silc_server_command_free(cmd);
2856 /* Server side of command UMODE. Client can use this command to set/unset
2857 user mode. Client actually cannot set itself to be as server/router
2858 operator so this can be used only to unset the modes. */
2860 SILC_SERVER_CMD_FUNC(umode)
2862 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2863 SilcServer server = cmd->server;
2864 SilcClientEntry client = silc_packet_get_context(cmd->sock);
2865 unsigned char *tmp_mask, m[4];
2866 SilcUInt32 mask = 0, tmp_len;
2867 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2868 SilcBool set_mask = FALSE;
2870 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
2873 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_UMODE, cmd, 1, 2);
2875 /* Get the client's mode mask */
2876 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
2877 if (tmp_mask && tmp_len == 4) {
2878 SILC_GET32_MSB(mask, tmp_mask);
2883 /* Check that mode changing is allowed. */
2884 if (!silc_server_check_umode_rights(server, client, mask)) {
2885 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
2886 SILC_STATUS_ERR_PERM_DENIED, 0);
2890 /* Anonymous mode cannot be set by client */
2891 if (mask & SILC_UMODE_ANONYMOUS &&
2892 !(client->mode & SILC_UMODE_ANONYMOUS)) {
2893 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
2894 SILC_STATUS_ERR_PERM_DENIED, 0);
2898 /* Update statistics */
2899 if (mask & SILC_UMODE_GONE) {
2900 if (!(client->mode & SILC_UMODE_GONE))
2901 server->stat.my_aways++;
2903 if (client->mode & SILC_UMODE_GONE)
2904 server->stat.my_aways--;
2907 /* If the client has anonymous mode set, preserve it. */
2908 if (client->mode & SILC_UMODE_ANONYMOUS)
2909 mask |= SILC_UMODE_ANONYMOUS;
2911 /* Change the mode */
2912 client->mode = mask;
2914 /* Send UMODE change to primary router */
2915 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
2916 SILC_BROADCAST(server), client->id,
2919 /* Check if anyone is watching this nickname */
2920 if (server->server_type == SILC_ROUTER)
2921 silc_server_check_watcher_list(server, client, NULL,
2922 SILC_NOTIFY_TYPE_UMODE_CHANGE);
2925 /* Send command reply to sender */
2926 SILC_PUT32_MSB(client->mode, m);
2927 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_UMODE,
2928 SILC_STATUS_OK, 0, ident, 1,
2932 silc_server_command_free(cmd);
2935 /* Server side command of CMODE. Changes channel mode */
2937 SILC_SERVER_CMD_FUNC(cmode)
2939 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2940 SilcServer server = cmd->server;
2941 SilcClientEntry client = silc_packet_get_context(cmd->sock);
2942 SilcIDListData idata = (SilcIDListData)client;
2944 SilcChannelEntry channel;
2945 SilcChannelClientEntry chl;
2947 unsigned char *tmp, *tmp_id, *tmp_mask, *chpkdata = NULL;
2948 char *cipher = NULL, *hmac = NULL, *passphrase = NULL, ulimit[4];
2949 SilcUInt32 mode_mask = 0, old_mask = 0, tmp_len, tmp_len2, chpklen;
2950 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2951 SilcBool set_mask = FALSE, set_chpk = FALSE;
2952 SilcPublicKey founder_key = NULL;
2953 SilcBuffer fkey = NULL, chpklist = NULL;
2954 SilcBufferStruct chpk;
2957 silc_server_command_free(cmd);
2961 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 9);
2963 /* Get Channel ID */
2964 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
2965 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2966 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2967 silc_server_command_free(cmd);
2971 /* Get channel entry */
2972 channel = silc_idlist_find_channel_by_id(server->local_list,
2973 SILC_ID_GET_ID(id), NULL);
2975 channel = silc_idlist_find_channel_by_id(server->global_list,
2976 SILC_ID_GET_ID(id), NULL);
2978 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
2979 silc_server_command_send_status_data(cmd, SILC_COMMAND_CMODE,
2980 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
2981 0, 2, tmp_id, tmp_len2);
2982 silc_server_command_free(cmd);
2986 old_mask = channel->mode;
2988 /* Get the channel mode mask */
2989 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
2990 if (tmp_mask && tmp_len == 4) {
2991 SILC_GET32_MSB(mode_mask, tmp_mask);
2995 /* Check whether this client is on the channel */
2996 if (!silc_server_client_on_channel(client, channel, &chl)) {
2997 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
2998 silc_server_command_send_status_data(cmd, SILC_COMMAND_CMODE,
2999 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
3000 2, tmp_id, tmp_len2);
3004 /* Check that client has rights to change any requested channel modes */
3005 if (set_mask && !silc_server_check_cmode_rights(server, channel, chl,
3007 SILC_LOG_DEBUG(("Client does not have rights to change mode"));
3008 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
3009 silc_server_command_send_status_data(
3010 cmd, SILC_COMMAND_CMODE,
3011 (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) ?
3012 SILC_STATUS_ERR_NO_CHANNEL_PRIV :
3013 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV), 0,
3014 2, tmp_id, tmp_len2);
3018 /* If mode mask was not sent as argument then merely return the current
3019 mode mask, founder key and channel public key list to the sender. */
3022 SILC_PUT32_MSB(channel->mode, m);
3023 if (channel->founder_key)
3024 fkey = silc_public_key_payload_encode(channel->founder_key);
3025 if (channel->channel_pubkeys)
3026 chpklist = silc_server_get_channel_pk_list(server, channel,
3028 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
3029 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_CMODE,
3030 SILC_STATUS_OK, 0, ident, 4,
3031 2, tmp_id, tmp_len2,
3033 4, fkey ? fkey->data : NULL,
3034 fkey ? silc_buffer_len(fkey) : 0,
3035 5, chpklist ? chpklist->data : NULL,
3036 chpklist ? silc_buffer_len(chpklist) : 0);
3041 * Check the modes. Modes that requires nothing special operation are
3045 if (mode_mask & SILC_CHANNEL_MODE_PRIVKEY) {
3046 /* Channel uses private keys to protect traffic. Client(s) has set the
3047 key locally they want to use, server does not know that key. */
3048 /* Nothing interesting to do here */
3050 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
3051 /* The mode is removed and we need to generate and distribute
3052 new channel key. Clients are not using private channel keys
3053 anymore after this. */
3055 /* if we don't remove the flag from the mode
3056 * silc_server_create_channel_key won't create a new key */
3057 channel->mode &= ~SILC_CHANNEL_MODE_PRIVKEY;
3059 /* Re-generate channel key */
3060 if (!silc_server_create_channel_key(server, channel, 0))
3063 /* Send the channel key. This sends it to our local clients and if
3064 we are normal server to our router as well. */
3065 silc_server_send_channel_key(server, NULL, channel,
3066 server->server_type == SILC_ROUTER ?
3067 FALSE : !server->standalone);
3069 cipher = (char *)silc_cipher_get_name(channel->send_key);
3070 hmac = (char *)silc_hmac_get_name(channel->hmac);
3074 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT) {
3075 /* User limit is set on channel */
3076 SilcUInt32 user_limit;
3078 /* Get user limit */
3079 tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
3081 if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT)) {
3082 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3083 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3087 SILC_GET32_MSB(user_limit, tmp);
3088 channel->user_limit = user_limit;
3091 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
3092 /* User limit mode is unset. Remove user limit */
3093 channel->user_limit = 0;
3096 if (mode_mask & SILC_CHANNEL_MODE_PASSPHRASE) {
3097 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
3098 /* Passphrase has been set to channel */
3100 /* Get the passphrase */
3101 tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
3103 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3104 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3108 /* Save the passphrase */
3109 passphrase = channel->passphrase = silc_memdup(tmp, strlen(tmp));
3112 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
3113 /* Passphrase mode is unset. remove the passphrase */
3114 silc_free(channel->passphrase);
3115 channel->passphrase = NULL;
3119 if (mode_mask & SILC_CHANNEL_MODE_CIPHER) {
3120 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
3121 /* Cipher to use protect the traffic */
3122 SilcCipher send_key, receive_key, olds, oldr;
3125 cipher = silc_argument_get_arg_type(cmd->args, 5, NULL);
3127 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3128 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3132 /* Delete old cipher and allocate the new one */
3133 if (!silc_cipher_alloc(cipher, &send_key)) {
3134 silc_server_command_send_status_data(
3135 cmd, SILC_COMMAND_CMODE,
3136 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3137 2, cipher, strlen(cipher));
3140 if (!silc_cipher_alloc(cipher, &receive_key)) {
3141 silc_server_command_send_status_data(
3142 cmd, SILC_COMMAND_CMODE,
3143 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3144 2, cipher, strlen(cipher));
3148 olds = channel->send_key;
3149 oldr = channel->receive_key;
3150 channel->send_key = send_key;
3151 channel->receive_key = receive_key;
3153 /* Re-generate channel key */
3154 if (!silc_server_create_channel_key(server, channel, 0)) {
3155 /* We don't have new key, revert to old one */
3156 channel->send_key = olds;
3157 channel->receive_key = oldr;
3161 /* Remove old channel key for good */
3162 silc_cipher_free(olds);
3163 silc_cipher_free(oldr);
3165 /* Send the channel key. This sends it to our local clients and if
3166 we are normal server to our router as well. */
3167 silc_server_send_channel_key(server, NULL, channel,
3168 server->server_type == SILC_ROUTER ?
3169 FALSE : !server->standalone);
3172 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
3173 /* Cipher mode is unset. Remove the cipher and revert back to
3175 SilcCipher send_key, receive_key, olds, oldr;
3176 cipher = channel->cipher;
3178 /* Delete old cipher and allocate default one */
3179 if (!silc_cipher_alloc(cipher ? cipher : SILC_DEFAULT_CIPHER,
3181 silc_server_command_send_status_data(
3182 cmd, SILC_COMMAND_CMODE,
3183 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3184 2, cipher, strlen(cipher));
3187 if (!silc_cipher_alloc(cipher ? cipher : SILC_DEFAULT_CIPHER,
3189 silc_server_command_send_status_data(
3190 cmd, SILC_COMMAND_CMODE,
3191 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3192 2, cipher, strlen(cipher));
3196 olds = channel->send_key;
3197 oldr = channel->receive_key;
3198 channel->send_key = send_key;
3199 channel->receive_key = receive_key;
3201 /* Re-generate channel key */
3202 if (!silc_server_create_channel_key(server, channel, 0)) {
3203 /* We don't have new key, revert to old one */
3204 channel->send_key = olds;
3205 channel->receive_key = oldr;
3209 /* Remove old channel key for good */
3210 silc_cipher_free(olds);
3211 silc_cipher_free(oldr);
3213 /* Send the channel key. This sends it to our local clients and if
3214 we are normal server to our router as well. */
3215 silc_server_send_channel_key(server, NULL, channel,
3216 server->server_type == SILC_ROUTER ?
3217 FALSE : !server->standalone);
3221 if (mode_mask & SILC_CHANNEL_MODE_HMAC) {
3222 if (!(channel->mode & SILC_CHANNEL_MODE_HMAC)) {
3223 /* HMAC to use protect the traffic */
3224 unsigned char hash[SILC_HASH_MAXLEN];
3228 hmac = silc_argument_get_arg_type(cmd->args, 6, NULL);
3230 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3231 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3235 /* Delete old hmac and allocate the new one */
3236 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3237 silc_server_command_send_status_data(
3238 cmd, SILC_COMMAND_CMODE,
3239 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3240 2, hmac, strlen(hmac));
3244 silc_hmac_free(channel->hmac);
3245 channel->hmac = newhmac;
3247 /* Set the HMAC key out of current channel key. The client must do
3249 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
3250 channel->key_len / 8, hash);
3251 silc_hmac_set_key(channel->hmac, hash,
3252 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3253 memset(hash, 0, sizeof(hash));
3256 if (channel->mode & SILC_CHANNEL_MODE_HMAC) {
3257 /* Hmac mode is unset. Remove the hmac and revert back to
3260 unsigned char hash[SILC_HASH_MAXLEN];
3261 hmac = channel->hmac_name;
3263 /* Delete old hmac and allocate default one */
3264 if (!silc_hmac_alloc(hmac ? hmac : SILC_DEFAULT_HMAC, NULL, &newhmac)) {
3265 silc_server_command_send_status_data(
3266 cmd, SILC_COMMAND_CMODE,
3267 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3268 2, hmac ? hmac : SILC_DEFAULT_HMAC,
3269 strlen(hmac ? hmac : SILC_DEFAULT_HMAC));
3273 silc_hmac_free(channel->hmac);
3274 channel->hmac = newhmac;
3276 /* Set the HMAC key out of current channel key. The client must do
3278 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
3279 channel->key_len / 8,
3281 silc_hmac_set_key(channel->hmac, hash,
3282 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3283 memset(hash, 0, sizeof(hash));
3287 if (mode_mask & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3288 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3289 /* Check if the founder public key was received */
3290 founder_key = idata->public_key;
3291 tmp = silc_argument_get_arg_type(cmd->args, 8, &tmp_len);
3293 if (!silc_public_key_payload_decode(tmp, tmp_len, &founder_key)) {
3294 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3295 SILC_STATUS_ERR_AUTH_FAILED,
3300 /* If key was not sent and the channel mode has already founder
3301 then the key was not to be changed. */
3302 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
3306 /* Set the founder authentication */
3307 tmp = silc_argument_get_arg_type(cmd->args, 7, &tmp_len);
3309 silc_server_command_send_status_reply(
3310 cmd, SILC_COMMAND_CMODE,
3311 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3315 /* Verify the payload before setting the mode */
3316 if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY,
3317 founder_key, 0, server->sha1hash,
3318 client->id, SILC_ID_CLIENT)) {
3319 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3320 SILC_STATUS_ERR_AUTH_FAILED,
3325 /* Save the public key */
3326 if (channel->founder_key)
3327 silc_pkcs_public_key_free(channel->founder_key);
3328 if (silc_argument_get_arg_type(cmd->args, 8, NULL))
3329 channel->founder_key = founder_key;
3331 channel->founder_key = silc_pkcs_public_key_copy(founder_key);
3332 if (!channel->founder_key) {
3333 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3334 SILC_STATUS_ERR_AUTH_FAILED,
3339 fkey = silc_public_key_payload_encode(channel->founder_key);
3341 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3342 SILC_STATUS_ERR_AUTH_FAILED,
3344 silc_pkcs_public_key_free(channel->founder_key);
3345 channel->founder_key = NULL;
3350 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3351 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3352 if (channel->founder_key)
3353 silc_pkcs_public_key_free(channel->founder_key);
3354 channel->founder_key = NULL;
3360 if (mode_mask & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
3361 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3364 chpkdata = silc_argument_get_arg_type(cmd->args, 9, &chpklen);
3366 if (!chpkdata && channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
3371 /* Process the channel public key(s) */
3372 st = silc_server_set_channel_pk_list(server, NULL, channel,
3374 if (st != SILC_STATUS_OK) {
3375 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, st, 0);
3380 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3381 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
3382 if (channel->channel_pubkeys)
3383 silc_hash_table_free(channel->channel_pubkeys);
3384 channel->channel_pubkeys = NULL;
3391 /* Finally, set the mode */
3392 old_mask = channel->mode = mode_mask;
3394 /* Send CMODE_CHANGE notify. */
3395 cidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3396 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT)
3397 SILC_PUT32_MSB(channel->user_limit, ulimit);
3398 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3399 SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
3400 cidp->data, silc_buffer_len(cidp),
3402 cipher, cipher ? strlen(cipher) : 0,
3403 hmac, hmac ? strlen(hmac) : 0,
3404 passphrase, passphrase ?
3405 strlen(passphrase) : 0,
3406 fkey ? fkey->data : NULL,
3407 fkey ? silc_buffer_len(fkey) : 0,
3408 chpkdata ? chpkdata : NULL,
3409 chpkdata ? chpklen : 0,
3410 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
3412 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
3413 sizeof(ulimit) : 0);
3415 /* Set CMODE notify type to network */
3416 if (chpkdata && chpklen)
3417 silc_buffer_set(&chpk, chpkdata, chpklen);
3418 silc_server_send_notify_cmode(server, SILC_PRIMARY_ROUTE(server),
3419 SILC_BROADCAST(server), channel,
3420 mode_mask, client->id, SILC_ID_CLIENT,
3421 cipher, hmac, passphrase, founder_key,
3422 chpkdata ? &chpk : NULL);
3425 chpklist = silc_server_get_channel_pk_list(server, channel, FALSE, FALSE);
3427 /* Send command reply to sender */
3428 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
3429 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_CMODE,
3430 SILC_STATUS_OK, 0, ident, 5,
3431 2, tmp_id, tmp_len2,
3433 4, fkey ? fkey->data : NULL,
3434 fkey ? silc_buffer_len(fkey) : 0,
3435 5, chpklist ? chpklist->data :
3436 NULL, chpklist ? silc_buffer_len(chpklist)
3439 SILC_CHANNEL_MODE_ULIMIT ?
3442 SILC_CHANNEL_MODE_ULIMIT ?
3443 sizeof(ulimit) : 0));
3444 silc_buffer_free(cidp);
3447 channel->mode = old_mask;
3448 silc_buffer_free(chpklist);
3449 silc_buffer_free(fkey);
3450 silc_server_command_free(cmd);
3453 /* Server side of CUMODE command. Changes client's mode on a channel. */
3455 SILC_SERVER_CMD_FUNC(cumode)
3457 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3458 SilcServer server = cmd->server;
3459 SilcClientEntry client = silc_packet_get_context(cmd->sock);
3461 SilcChannelEntry channel;
3462 SilcClientEntry target_client;
3463 SilcChannelClientEntry chl;
3465 unsigned char *tmp_id, *tmp_ch_id, *tmp_mask;
3466 SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
3468 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3469 SilcPublicKey founder_key = NULL;
3470 SilcBuffer fkey = NULL;
3475 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4);
3477 /* Get Channel ID */
3478 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
3479 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3480 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3484 /* Get channel entry */
3485 channel = silc_idlist_find_channel_by_id(server->local_list,
3486 SILC_ID_GET_ID(id), NULL);
3488 channel = silc_idlist_find_channel_by_id(server->global_list,
3489 SILC_ID_GET_ID(id), NULL);
3491 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3492 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3493 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
3494 0, 2, tmp_ch_id, tmp_ch_len);
3499 /* Check whether sender is on the channel */
3500 if (!silc_server_client_on_channel(client, channel, &chl)) {
3501 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3502 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3503 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
3504 2, tmp_ch_id, tmp_ch_len);
3507 sender_mask = chl->mode;
3509 /* Get the target client's channel mode mask */
3510 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
3512 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3513 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3517 SILC_GET32_MSB(target_mask, tmp_mask);
3519 /* Get target Client ID */
3520 if (!silc_argument_get_decoded(cmd->args, 3, SILC_ARGUMENT_ID, &id2, NULL)) {
3521 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3522 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3526 /* Get target client's entry */
3527 target_client = silc_idlist_find_client_by_id(server->local_list,
3528 SILC_ID_GET_ID(id2),
3531 target_client = silc_idlist_find_client_by_id(server->global_list,
3532 SILC_ID_GET_ID(id2),
3535 if (target_client != client &&
3536 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO) &&
3537 !(sender_mask & SILC_CHANNEL_UMODE_CHANOP)) {
3538 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3539 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3540 SILC_STATUS_ERR_NOT_YOU, 0,
3541 2, tmp_ch_id, tmp_ch_len);
3545 /* Check whether target client is on the channel */
3546 if (target_client != client) {
3547 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
3548 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3549 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3550 silc_server_command_send_status_data2(
3551 cmd, SILC_COMMAND_CUMODE,
3552 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL, 0,
3554 3, tmp_ch_id, tmp_ch_len);
3563 /* If the target client is founder, no one else can change their mode
3565 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && client != target_client) {
3566 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3567 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3568 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3569 0, 2, tmp_ch_id, tmp_ch_len);
3573 if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
3574 if (target_client != client) {
3575 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3576 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3581 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
3582 /* The client tries to claim the founder rights. */
3583 unsigned char *tmp_auth;
3584 SilcUInt32 tmp_auth_len;
3585 SilcChannelClientEntry chl2;
3586 SilcHashTableList htl;
3588 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
3589 !channel->founder_key) {
3590 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3591 SILC_STATUS_ERR_AUTH_FAILED, 0);
3595 tmp_auth = silc_argument_get_arg_type(cmd->args, 4, &tmp_auth_len);
3597 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3598 SILC_STATUS_ERR_AUTH_FAILED, 0);
3602 /* Verify the authentication payload */
3603 if (!silc_auth_verify_data(tmp_auth, tmp_auth_len, SILC_AUTH_PUBLIC_KEY,
3604 channel->founder_key, 0, server->sha1hash,
3605 client->id, SILC_ID_CLIENT)) {
3606 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3607 SILC_STATUS_ERR_AUTH_FAILED, 0);
3612 founder_key = channel->founder_key;
3613 fkey = silc_public_key_payload_encode(founder_key);
3615 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3616 SILC_STATUS_ERR_AUTH_FAILED, 0);
3620 /* There cannot be anyone else as founder on the channel now. This
3621 client is definitely the founder due to this authentication. This
3622 is done only on router, not on server, since server cannot know
3623 whether router will accept this mode change or not. XXX This
3624 probably shouldn't be done anymore at all, may cause problems in
3625 router-router connections too (maybe just AUTH_FAILED error should
3626 be returned). -Pekka */
3627 if (server->server_type == SILC_ROUTER) {
3628 silc_hash_table_list(channel->user_list, &htl);
3629 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
3630 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
3631 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3632 silc_server_force_cumode_change(server, NULL, channel, chl2,
3636 silc_hash_table_list_reset(&htl);
3639 sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
3642 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3643 if (target_client == client) {
3644 /* Remove channel founder rights from itself */
3645 chl->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3648 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3649 SILC_STATUS_ERR_NOT_YOU, 0);
3655 if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
3656 /* Promote to operator */
3657 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
3658 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
3659 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
3660 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3661 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3662 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3663 0, 2, tmp_ch_id, tmp_ch_len);
3667 chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
3671 if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
3672 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
3673 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
3674 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3675 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3676 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3677 0, 2, tmp_ch_id, tmp_ch_len);
3681 /* Demote to normal user */
3682 chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
3687 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
3688 if (target_client != client) {
3689 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3690 SILC_STATUS_ERR_NOT_YOU, 0);
3694 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)) {
3695 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
3699 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
3700 if (target_client != client) {
3701 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3702 SILC_STATUS_ERR_NOT_YOU, 0);
3706 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
3711 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
3712 if (target_client != client) {
3713 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3714 SILC_STATUS_ERR_NOT_YOU, 0);
3718 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)) {
3719 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
3723 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
3724 if (target_client != client) {
3725 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3726 SILC_STATUS_ERR_NOT_YOU, 0);
3730 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
3735 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
3736 if (target_client != client) {
3737 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3738 SILC_STATUS_ERR_NOT_YOU, 0);
3742 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)) {
3743 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
3747 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
3748 if (target_client != client) {
3749 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3750 SILC_STATUS_ERR_NOT_YOU, 0);
3754 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
3759 if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
3760 if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
3761 if (client == target_client) {
3762 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3763 SILC_STATUS_ERR_PERM_DENIED, 0);
3766 chl->mode |= SILC_CHANNEL_UMODE_QUIET;
3770 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
3771 if (client == target_client) {
3772 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3773 SILC_STATUS_ERR_PERM_DENIED, 0);
3776 chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
3781 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3782 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3783 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3785 /* Send notify to channel, notify only if mode was actually changed. */
3787 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3788 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
3789 idp->data, silc_buffer_len(idp),
3792 fkey ? fkey->data : NULL,
3793 fkey ? silc_buffer_len(fkey) : 0);
3795 /* Set CUMODE notify type to network */
3796 silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
3797 SILC_BROADCAST(server), channel,
3798 target_mask, client->id, SILC_ID_CLIENT,
3799 target_client->id, founder_key);
3802 /* Send command reply to sender */
3803 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_CUMODE,
3804 SILC_STATUS_OK, 0, ident, 3,
3806 3, tmp_ch_id, tmp_ch_len,
3807 4, tmp_id, tmp_len);
3808 silc_buffer_free(idp);
3811 silc_buffer_free(fkey);
3812 silc_server_command_free(cmd);
3815 /* Server side of KICK command. Kicks client out of channel. */
3817 SILC_SERVER_CMD_FUNC(kick)
3819 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3820 SilcServer server = cmd->server;
3821 SilcClientEntry client = silc_packet_get_context(cmd->sock);
3822 SilcClientEntry target_client;
3824 SilcChannelEntry channel;
3825 SilcChannelClientEntry chl;
3827 SilcUInt32 tmp_len, target_idp_len, clen;
3828 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3829 unsigned char *tmp, *comment, *target_idp;
3834 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 3);
3836 /* Get Channel ID */
3837 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
3838 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
3839 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3843 /* Get channel entry */
3844 channel = silc_idlist_find_channel_by_id(server->local_list,
3845 SILC_ID_GET_ID(id), NULL);
3847 channel = silc_idlist_find_channel_by_id(server->local_list,
3848 SILC_ID_GET_ID(id), NULL);
3850 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3851 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3852 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
3853 0, 2, tmp, tmp_len);
3858 /* Check whether sender is on the channel */
3859 if (!silc_server_client_on_channel(client, channel, &chl)) {
3860 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3861 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3862 SILC_STATUS_ERR_NOT_ON_CHANNEL,
3863 0, 2, tmp, tmp_len);
3867 /* Check that the kicker is channel operator or channel founder */
3868 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
3869 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
3870 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3871 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3872 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3873 0, 2, tmp, tmp_len);
3877 /* Get target Client ID */
3878 if (!silc_argument_get_decoded(cmd->args, 2, SILC_ARGUMENT_ID, &id2, NULL)) {
3879 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
3880 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3884 /* Get target client's entry */
3885 target_client = silc_idlist_find_client_by_id(server->local_list,
3886 SILC_ID_GET_ID(id2),
3889 target_client = silc_idlist_find_client_by_id(server->global_list,
3890 SILC_ID_GET_ID(id2),
3893 /* Check whether target client is on the channel */
3894 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
3895 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3896 target_idp = silc_argument_get_arg_type(cmd->args, 2, &target_idp_len);
3897 silc_server_command_send_status_data2(cmd, SILC_COMMAND_KICK,
3898 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL,
3899 0, 2, target_idp, target_idp_len,
3904 /* Check that the target client is not channel founder. Channel founder
3905 cannot be kicked from the channel. */
3906 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3907 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3908 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3909 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3910 0, 2, tmp, tmp_len);
3915 comment = silc_argument_get_arg_type(cmd->args, 3, &clen);
3919 /* Send the reply back to the client */
3920 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3921 target_idp = silc_argument_get_arg_type(cmd->args, 2, &target_idp_len);
3922 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_KICK,
3923 SILC_STATUS_OK, 0, ident, 2,
3925 3, target_idp, target_idp_len);
3927 /* Send KICKED notify to local clients on the channel */
3928 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3929 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3930 SILC_NOTIFY_TYPE_KICKED, 3,
3931 target_idp, target_idp_len,
3932 comment, comment ? strlen(comment) : 0,
3933 idp->data, silc_buffer_len(idp));
3934 silc_buffer_free(idp);
3936 /* Send KICKED notify to primary route */
3937 silc_server_send_notify_kicked(server, SILC_PRIMARY_ROUTE(server),
3938 SILC_BROADCAST(server), channel,
3939 target_client->id, client->id, comment);
3941 /* Remove the client from channel's invite list */
3942 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
3944 silc_argument_payload_encode_one(NULL, target_idp, target_idp_len, 3);
3945 SilcArgumentPayload args =
3946 silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
3948 silc_server_inviteban_process(server, channel->invite_list, 1, args);
3949 silc_buffer_free(ab);
3950 silc_argument_payload_free(args);
3953 /* Remove the client from the channel. If the channel does not exist
3954 after removing the client then the client kicked itself off the channel
3955 and we don't have to send anything after that. */
3956 if (!silc_server_remove_from_one_channel(server, NULL, channel,
3957 target_client, FALSE))
3960 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3961 /* Re-generate channel key */
3962 if (!silc_server_create_channel_key(server, channel, 0))
3965 /* Send the channel key to the channel. The key of course is not sent
3966 to the client who was kicked off the channel. */
3967 silc_server_send_channel_key(server, target_client->connection, channel,
3968 server->server_type == SILC_ROUTER ?
3969 FALSE : !server->standalone);
3973 silc_server_command_free(cmd);
3976 /* Server side of OPER command. Client uses this comand to obtain server
3977 operator privileges to this server/router. */
3979 SILC_SERVER_CMD_FUNC(oper)
3981 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3982 SilcServer server = cmd->server;
3983 SilcClientEntry client = silc_packet_get_context(cmd->sock);
3984 unsigned char *username = NULL, *auth;
3986 SilcServerConfigAdmin *admin;
3987 SilcIDListData idata = (SilcIDListData)client;
3988 SilcBool result = FALSE;
3989 SilcPublicKey cached_key;
3990 const char *hostname, *ip;
3992 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
3995 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2);
3997 silc_socket_stream_get_info(silc_packet_stream_get_stream(cmd->sock),
3998 NULL, &hostname, &ip, NULL);
4000 /* Get the username */
4001 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4003 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4004 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4009 /* Check username */
4010 username = silc_identifier_check(username, strlen(username),
4011 SILC_STRING_UTF8, 128, &tmp_len);
4013 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4014 SILC_STATUS_ERR_BAD_USERNAME,
4019 /* Get the admin configuration */
4020 admin = silc_server_config_find_admin(server, (char *)ip,
4021 username, client->nickname);
4023 admin = silc_server_config_find_admin(server, (char *)hostname,
4024 username, client->nickname);
4026 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4027 SILC_STATUS_ERR_AUTH_FAILED,
4029 SILC_LOG_INFO(("OPER authentication failed for username '%s' by "
4030 "nickname '%s' from %s", username,
4031 client->nickname, hostname));
4036 /* Get the authentication payload */
4037 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
4039 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4040 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4045 /* Verify the authentication data. If both passphrase and public key
4046 is set then try both of them. */
4047 if (admin->passphrase)
4048 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
4049 admin->passphrase, admin->passphrase_len,
4050 idata->hash, client->id, SILC_ID_CLIENT);
4051 if (!result && admin->publickeys) {
4053 silc_server_get_public_key(server,
4054 SILC_SKR_USAGE_SERVICE_AUTHORIZATION, admin);
4057 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
4058 cached_key, 0, idata->hash,
4059 client->id, SILC_ID_CLIENT);
4062 /* Authentication failed */
4063 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4064 SILC_STATUS_ERR_AUTH_FAILED,
4069 /* Client is now server operator */
4070 client->mode |= SILC_UMODE_SERVER_OPERATOR;
4072 /* Update statistics */
4073 if (SILC_IS_LOCAL(client))
4074 server->stat.my_server_ops++;
4075 if (server->server_type == SILC_ROUTER)
4076 server->stat.server_ops++;
4078 /* Send UMODE change to primary router */
4079 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4080 SILC_BROADCAST(server), client->id,
4083 /* Check if anyone is watching this nickname */
4084 if (server->server_type == SILC_ROUTER)
4085 silc_server_check_watcher_list(server, client, NULL,
4086 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4088 /* Send reply to the sender */
4089 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4093 silc_free(username);
4094 silc_server_command_free(cmd);
4097 SILC_TASK_CALLBACK(silc_server_command_detach_cb)
4099 SilcServer server = app_context;
4100 QuitInternal q = (QuitInternal)context;
4101 SilcPacketStream sock = q->sock;
4102 SilcClientEntry client = silc_packet_get_context(sock);
4103 SilcIDListData idata;
4106 silc_packet_stream_unref(sock);
4111 SILC_LOG_DEBUG(("Detaching client %s",
4112 silc_id_render(client->id, SILC_ID_CLIENT)));
4114 /* Stop rekey for the client. */
4115 silc_server_stop_rekey(server, client);
4117 /* Abort any active protocol */
4118 idata = silc_packet_get_context(sock);
4119 if (idata && idata->sconn && idata->sconn->op) {
4120 SILC_LOG_DEBUG(("Abort active protocol"));
4121 silc_async_abort(idata->sconn->op, NULL, NULL);
4122 idata->sconn->op = NULL;
4125 silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_heartbeat,
4128 /* Close the connection on our side */
4129 client->router = NULL;
4130 client->connection = NULL;
4131 silc_server_close_connection(server, sock);
4133 /* Mark the client as locally detached. */
4134 client->local_detached = TRUE;
4136 /* Decrement the user count; we'll increment it if the user resumes on our
4138 SILC_VERIFY(&server->stat.my_clients > 0);
4139 server->stat.my_clients--;
4141 silc_packet_stream_unref(sock);
4145 SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
4147 SilcServer server = app_context;
4148 QuitInternal q = (QuitInternal)context;
4149 SilcClientID *client_id = (SilcClientID *)q->sock;
4150 SilcClientEntry client;
4152 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4154 if (client && client->mode & SILC_UMODE_DETACHED) {
4155 SILC_LOG_DEBUG(("Detach timeout"));
4156 silc_server_free_client_data(server, NULL, client, TRUE,
4160 silc_free(client_id);
4164 /* Server side of DETACH command. Detached the client from the network
4165 by closing the connection but preserving the session. */
4167 SILC_SERVER_CMD_FUNC(detach)
4169 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4170 SilcServer server = cmd->server;
4171 SilcClientEntry client = silc_packet_get_context(cmd->sock);
4174 if (server->config->detach_disabled) {
4175 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4176 SILC_STATUS_ERR_OPERATION_ALLOWED,
4181 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
4184 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_DETACH, cmd, 0, 0);
4186 /* Remove operator privileges, since the client may resume in some
4187 other server which to it does not have operator privileges. */
4188 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
4189 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
4191 /* Send the user mode notify to notify that client is detached */
4192 client->mode |= SILC_UMODE_DETACHED;
4193 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
4194 client->data.status &= ~SILC_IDLIST_STATUS_NOATTR;
4195 client->last_command = 0;
4196 client->fast_command = 0;
4197 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4198 SILC_BROADCAST(server), client->id,
4200 server->stat.my_detached++;
4202 /* Check if anyone is watching this nickname */
4203 if (server->server_type == SILC_ROUTER)
4204 silc_server_check_watcher_list(server, client, NULL,
4205 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4207 q = silc_calloc(1, sizeof(*q));
4210 q->sock = cmd->sock;
4211 silc_packet_stream_ref(q->sock);
4212 silc_schedule_task_add_timeout(server->schedule,
4213 silc_server_command_detach_cb,
4216 if (server->config->detach_timeout) {
4217 q = silc_calloc(1, sizeof(*q));
4220 q->sock = (void *)silc_id_dup(client->id, SILC_ID_CLIENT);
4221 silc_schedule_task_add_timeout(server->schedule,
4222 silc_server_command_detach_timeout,
4223 q, server->config->detach_timeout * 60, 0);
4226 /* Send reply to the sender */
4227 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4231 silc_server_command_free(cmd);
4234 /* Server side of WATCH command. */
4236 SILC_SERVER_CMD_FUNC(watch)
4238 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4239 SilcServer server = cmd->server;
4240 char *add_nick, *del_nick;
4241 SilcUInt32 add_nick_len, del_nick_len, tmp_len, pk_len;
4242 unsigned char hash[SILC_HASH_MAXLEN], *tmp, *pk, *nick;
4243 SilcClientEntry client;
4245 SilcUInt16 old_ident;
4247 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WATCH, cmd, 1, 3);
4249 if (server->server_type != SILC_ROUTER && !server->standalone) {
4250 if (!cmd->pending) {
4251 /* Send the command to router */
4254 /* If backup receives this from primary, handle it locally */
4255 if (server->server_type == SILC_BACKUP_ROUTER &&
4256 cmd->sock == SILC_PRIMARY_ROUTE(server))
4259 SILC_LOG_DEBUG(("Forwarding WATCH to router"));
4262 cmd->server->stat.commands_sent++;
4264 old_ident = silc_command_get_ident(cmd->payload);
4265 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4266 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4268 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4269 SILC_PACKET_COMMAND, cmd->packet->flags,
4270 tmpbuf->data, silc_buffer_len(tmpbuf));
4272 /* Reprocess this packet after received reply from router */
4273 silc_server_command_pending(server, SILC_COMMAND_WATCH,
4274 silc_command_get_ident(cmd->payload),
4275 silc_server_command_watch,
4276 silc_server_command_dup(cmd));
4277 cmd->pending = TRUE;
4278 silc_command_set_ident(cmd->payload, old_ident);
4279 silc_buffer_free(tmpbuf);
4282 SilcServerCommandReplyContext reply = context2;
4288 silc_command_get_status(reply->payload, &status, NULL);
4290 /* Backup router handles the WATCH command also. */
4291 if (server->server_type != SILC_BACKUP_ROUTER ||
4292 SILC_STATUS_IS_ERROR(status)) {
4293 /* Received reply from router, just send same data to the client. */
4294 SILC_LOG_DEBUG(("Received reply to WATCH from router"));
4295 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH, status,
4302 /* We are router and keep the watch list for local cell */
4305 /* Get the client ID */
4306 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
4307 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4308 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4313 /* Get the client entry which must be in local list */
4314 client = silc_idlist_find_client_by_id(server->local_list,
4315 SILC_ID_GET_ID(id), TRUE, NULL);
4317 /* Backup checks global list also */
4318 if (server->server_type == SILC_BACKUP_ROUTER)
4319 client = silc_idlist_find_client_by_id(server->global_list,
4320 SILC_ID_GET_ID(id), TRUE, NULL);
4322 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4323 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4324 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4325 0, 2, tmp, tmp_len);
4330 /* Take public key for watching by public key */
4331 pk = silc_argument_get_arg_type(cmd->args, 4, &pk_len);
4334 add_nick = silc_argument_get_arg_type(cmd->args, 2, &add_nick_len);
4335 del_nick = silc_argument_get_arg_type(cmd->args, 3, &del_nick_len);
4336 if (!add_nick && !del_nick && !pk) {
4337 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4338 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4343 if (add_nick && add_nick_len > 128) {
4345 add_nick[add_nick_len - 1] = '\0';
4347 if (del_nick && del_nick_len > 128) {
4349 del_nick[del_nick_len - 1] = '\0';
4352 /* Add new nickname to be watched in our cell */
4354 nick = silc_identifier_check(add_nick, add_nick_len, SILC_STRING_UTF8, 128,
4357 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4358 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4362 /* Hash the nick, we have the hash saved, not nicks because we can
4363 do one to one mapping to the nick from Client ID hash this way. */
4364 silc_hash_make(server->md5hash, nick, add_nick_len, hash);
4366 /* Check whether this client is already watching this nickname */
4367 if (silc_hash_table_find_by_context(server->watcher_list, hash,
4369 /* Nickname is alredy being watched for this client */
4370 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4371 SILC_STATUS_ERR_NICKNAME_IN_USE,
4377 /* Get the nickname from the watcher list and use the same key in
4378 new entries as well. If key doesn't exist then create it. */
4379 if (!silc_hash_table_find(server->watcher_list, hash, (void *)&tmp, NULL))
4380 tmp = silc_memdup(hash, CLIENTID_HASH_LEN);
4382 /* Add the client to the watcher list with the specified nickname hash. */
4383 silc_hash_table_add(server->watcher_list, tmp, client);
4387 /* Delete nickname from watch list */
4389 nick = silc_identifier_check(del_nick, del_nick_len, SILC_STRING_UTF8, 128,
4392 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4393 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4397 /* Hash the nick, we have the hash saved, not nicks because we can
4398 do one to one mapping to the nick from Client ID hash this way. */
4399 silc_hash_make(server->md5hash, nick, del_nick_len, hash);
4401 /* Check that this client is watching for this nickname */
4402 if (!silc_hash_table_find_by_context(server->watcher_list, hash,
4403 client, (void *)&tmp)) {
4404 /* Nickname is alredy being watched for this client */
4405 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4406 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
4407 2, nick, del_nick_len);
4412 /* Delete the nickname from the watcher list. */
4413 silc_hash_table_del_by_context(server->watcher_list, hash, client);
4415 /* Now check whether there still exists entries with this key, if not
4416 then free the key to not leak memory. */
4417 if (!silc_hash_table_find(server->watcher_list, hash, NULL, NULL))
4422 /* Add/del public key */
4425 SilcArgumentPayload pkargs;
4427 SilcPublicKey public_key, pkkey;
4430 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4431 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4436 /* Get the argument from the Argument List Payload */
4437 SILC_GET16_MSB(pkargc, pk);
4438 pkargs = silc_argument_payload_parse(pk + 2, pk_len - 2, pkargc);
4440 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4441 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4446 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4448 if (!silc_public_key_payload_decode(pk, pk_len, &public_key)) {
4449 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4456 /* Add public key to watch list */
4458 /* Check whether this client is already watching this public key */
4459 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4460 public_key, client, NULL)) {
4461 silc_pkcs_public_key_free(public_key);
4462 silc_server_command_send_status_reply(
4463 cmd, SILC_COMMAND_WATCH,
4464 SILC_STATUS_ERR_NICKNAME_IN_USE, 0);
4468 /* Get the public key from the watcher list and use the same key in
4469 new entries as well. If key doesn't exist then create it. */
4471 if (!silc_hash_table_find(server->watcher_list_pk, public_key,
4472 (void *)&pkkey, NULL))
4475 silc_pkcs_public_key_free(public_key);
4477 /* Add the client to the watcher list with the specified public
4479 silc_hash_table_add(server->watcher_list_pk, pkkey, client);
4481 } else if (type == 0x01) {
4482 /* Delete public key from watch list */
4484 /* Check that this client is watching this public key */
4485 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4488 silc_pkcs_public_key_free(public_key);
4489 silc_server_command_send_status_reply(
4490 cmd, SILC_COMMAND_WATCH,
4491 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4495 /* Delete the public key from the watcher list. */
4496 silc_hash_table_del_by_context(server->watcher_list_pk,
4497 public_key, client);
4499 /* Now check whether there still exists entries with this key, if
4500 not then free the key to not leak memory. */
4501 if (!silc_hash_table_find(server->watcher_list_pk, hash, NULL, NULL))
4502 silc_pkcs_public_key_free(pkkey);
4503 silc_pkcs_public_key_free(public_key);
4506 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4511 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4514 /* Distribute the watch list to backup routers too */
4515 if (server->backup) {
4519 cmd->server->stat.commands_sent++;
4521 old_ident = silc_command_get_ident(cmd->payload);
4522 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4523 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4524 silc_server_backup_send(server, silc_packet_get_context(cmd->sock),
4525 SILC_PACKET_COMMAND,
4526 cmd->packet->flags, tmpbuf->data,
4527 silc_buffer_len(tmpbuf),
4529 silc_command_set_ident(cmd->payload, old_ident);
4530 silc_buffer_free(tmpbuf);
4534 silc_server_command_free(cmd);
4537 /* Server side of SILCOPER command. Client uses this comand to obtain router
4538 operator privileges to this router. */
4540 SILC_SERVER_CMD_FUNC(silcoper)
4542 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4543 SilcServer server = cmd->server;
4544 SilcClientEntry client = silc_packet_get_context(cmd->sock);
4545 unsigned char *username = NULL, *auth;
4547 SilcServerConfigAdmin *admin;
4548 SilcIDListData idata = (SilcIDListData)client;
4549 SilcBool result = FALSE;
4550 SilcPublicKey cached_key;
4551 const char *hostname, *ip;
4553 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
4556 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
4558 silc_socket_stream_get_info(silc_packet_stream_get_stream(cmd->sock),
4559 NULL, &hostname, &ip, NULL);
4561 if (server->server_type != SILC_ROUTER) {
4562 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4563 SILC_STATUS_ERR_AUTH_FAILED, 0);
4567 /* Get the username */
4568 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4570 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4571 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4576 /* Check username */
4577 username = silc_identifier_check(username, tmp_len, SILC_STRING_UTF8, 128,
4580 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4581 SILC_STATUS_ERR_BAD_USERNAME,
4586 /* Get the admin configuration */
4587 admin = silc_server_config_find_admin(server, (char *)ip,
4588 username, client->nickname);
4590 admin = silc_server_config_find_admin(server, (char *)hostname,
4591 username, client->nickname);
4593 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4594 SILC_STATUS_ERR_AUTH_FAILED, 0);
4595 SILC_LOG_INFO(("SILCOPER authentication failed for username '%s' by "
4596 "nickname '%s' from %s", username,
4597 client->nickname, hostname));
4602 /* Get the authentication payload */
4603 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
4605 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4606 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4611 /* Verify the authentication data. If both passphrase and public key
4612 is set then try both of them. */
4613 if (admin->passphrase)
4614 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
4615 admin->passphrase, admin->passphrase_len,
4616 idata->hash, client->id, SILC_ID_CLIENT);
4617 if (!result && admin->publickeys) {
4619 silc_server_get_public_key(server,
4620 SILC_SKR_USAGE_SERVICE_AUTHORIZATION, admin);
4623 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
4624 cached_key, 0, idata->hash,
4625 client->id, SILC_ID_CLIENT);
4628 /* Authentication failed */
4629 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4630 SILC_STATUS_ERR_AUTH_FAILED, 0);
4634 /* Client is now router operator */
4635 client->mode |= SILC_UMODE_ROUTER_OPERATOR;
4637 /* Update statistics */
4638 if (SILC_IS_LOCAL(client))
4639 server->stat.my_router_ops++;
4640 if (server->server_type == SILC_ROUTER)
4641 server->stat.router_ops++;
4643 /* Send UMODE change to primary router */
4644 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4645 SILC_BROADCAST(server), client->id,
4648 /* Check if anyone is watching this nickname */
4649 if (server->server_type == SILC_ROUTER)
4650 silc_server_check_watcher_list(server, client, NULL,
4651 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4653 /* Send reply to the sender */
4654 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4658 silc_free(username);
4659 silc_server_command_free(cmd);
4662 /* Server side of command BAN. This is used to manage the ban list of the
4663 channel. To add clients and remove clients from the ban list. */
4665 SILC_SERVER_CMD_FUNC(ban)
4667 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4668 SilcServer server = cmd->server;
4669 SilcClientEntry client = silc_packet_get_context(cmd->sock);
4670 SilcBuffer list, tmp2;
4671 SilcChannelEntry channel;
4672 SilcChannelClientEntry chl;
4674 unsigned char *tmp_id, *tmp, *atype = NULL;
4675 SilcUInt32 id_len, len, len2;
4676 SilcArgumentPayload args;
4677 SilcHashTableList htl;
4679 SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
4680 SilcBufferStruct blist;
4682 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
4685 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_BAN, cmd, 0, 3);
4687 /* Get Channel ID */
4688 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
4689 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4690 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4694 /* Get channel entry. The server must know about the channel since the
4695 client is expected to be on the channel. */
4696 channel = silc_idlist_find_channel_by_id(server->local_list,
4697 SILC_ID_GET_ID(id), NULL);
4699 channel = silc_idlist_find_channel_by_id(server->global_list,
4700 SILC_ID_GET_ID(id), NULL);
4702 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
4703 silc_server_command_send_status_data(
4704 cmd, SILC_COMMAND_BAN,
4705 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4706 0, 2, tmp_id, id_len);
4711 /* Check whether this client is on the channel */
4712 if (!silc_server_client_on_channel(client, channel, &chl)) {
4713 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
4714 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4715 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4720 /* The client must be at least channel operator. */
4721 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
4722 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
4723 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4724 SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0,
4729 /* Get the ban information */
4730 tmp = silc_argument_get_arg_type(cmd->args, 3, &len2);
4731 if (tmp && len2 > 2) {
4732 /* Parse the arguments to see they are constructed correctly */
4733 SILC_GET16_MSB(argc, tmp);
4734 args = silc_argument_payload_parse(tmp + 2, len2 - 2, argc);
4736 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4737 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4742 /* Get the type of action */
4743 atype = silc_argument_get_arg_type(cmd->args, 2, &len);
4744 if (atype && len == 1) {
4745 if (atype[0] == 0x00) {
4746 /* Allocate hash table for ban list if it doesn't exist yet */
4747 if (!channel->ban_list)
4749 silc_hash_table_alloc(0, silc_hash_ptr,
4751 silc_server_inviteban_destruct, channel,
4754 /* Check for resource limit */
4755 if (silc_hash_table_count(channel->ban_list) > 64) {
4756 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4757 SILC_STATUS_ERR_RESOURCE_LIMIT,
4763 /* Now add or delete the information. */
4764 if (!silc_server_inviteban_process(server, channel->ban_list,
4765 (SilcUInt8)atype[0], args)) {
4766 silc_server_command_send_status_reply(
4767 cmd, SILC_COMMAND_BAN,
4768 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4773 silc_argument_payload_free(args);
4776 /* Encode ban list */
4778 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4779 list = silc_buffer_alloc_size(2);
4780 silc_buffer_format(list,
4781 SILC_STR_UI_SHORT(silc_hash_table_count(
4782 channel->ban_list)),
4784 silc_hash_table_list(channel->ban_list, &htl);
4785 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4786 list = silc_argument_payload_encode_one(list, tmp2->data,
4787 silc_buffer_len(tmp2),
4788 SILC_PTR_TO_32(type));
4789 silc_hash_table_list_reset(&htl);
4792 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
4794 /* Send BAN notify type to local servers (but not clients) and to
4796 if (atype && tmp && len2) {
4797 silc_buffer_set(&blist, tmp, len2);
4799 /* Send to local servers if we are router */
4800 if (server->server_type == SILC_ROUTER)
4801 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
4802 SILC_NOTIFY_TYPE_BAN, 3,
4805 tmp ? blist.data : NULL,
4806 tmp ? silc_buffer_len(&blist) : 0);
4808 /* Send to network. */
4809 silc_server_send_notify_ban(server, SILC_PRIMARY_ROUTE(server),
4810 SILC_BROADCAST(server), channel, atype,
4814 /* Send the reply back to the client */
4815 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_BAN,
4816 SILC_STATUS_OK, 0, ident, 2,
4818 3, list ? list->data : NULL,
4819 list ? silc_buffer_len(list) : 0);
4820 silc_buffer_free(list);
4823 silc_server_command_free(cmd);
4826 /* Server side command of LEAVE. Removes client from a channel. */
4828 SILC_SERVER_CMD_FUNC(leave)
4830 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4831 SilcServer server = cmd->server;
4832 SilcPacketStream sock = cmd->sock;
4833 SilcClientEntry id_entry = silc_packet_get_context(cmd->sock);
4835 SilcChannelEntry channel;
4839 if (id_entry->data.conn_type != SILC_CONN_CLIENT || !id_entry)
4842 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 2);
4844 /* Get Channel ID */
4845 if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
4846 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4847 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4851 /* Get channel entry */
4852 channel = silc_idlist_find_channel_by_id(server->local_list,
4853 SILC_ID_GET_ID(id), NULL);
4855 channel = silc_idlist_find_channel_by_id(server->global_list,
4856 SILC_ID_GET_ID(id), NULL);
4858 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
4859 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4860 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4866 /* Check whether this client is on the channel */
4867 if (!silc_server_client_on_channel(id_entry, channel, NULL)) {
4868 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
4869 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4870 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4875 /* Notify routers that they should remove this client from their list
4876 of clients on the channel. Send LEAVE notify type. */
4877 silc_server_send_notify_leave(server, SILC_PRIMARY_ROUTE(server),
4878 SILC_BROADCAST(server), channel, id_entry->id);
4880 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
4881 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4882 SILC_STATUS_OK, 0, 2, tmp, len);
4884 /* Remove client from channel */
4885 if (!silc_server_remove_from_one_channel(server, sock, channel, id_entry,
4887 /* If the channel does not exist anymore we won't send anything */
4890 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
4891 /* Re-generate channel key */
4892 if (!silc_server_create_channel_key(server, channel, 0))
4895 /* Send the channel key */
4896 silc_server_send_channel_key(server, NULL, channel,
4897 server->server_type == SILC_ROUTER ?
4898 FALSE : !server->standalone);
4902 silc_server_command_free(cmd);
4905 /* Server side of command USERS. Resolves clients and their USERS currently
4906 joined on the requested channel. The list of Client ID's and their modes
4907 on the channel is sent back. */
4909 SILC_SERVER_CMD_FUNC(users)
4911 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4912 SilcServer server = cmd->server;
4913 SilcIDListData idata = silc_packet_get_context(cmd->sock);
4914 SilcChannelEntry channel;
4917 unsigned char *channel_id;
4918 SilcUInt32 channel_id_len;
4919 SilcBuffer client_id_list;
4920 SilcBuffer client_mode_list;
4921 unsigned char lc[4];
4922 SilcUInt32 list_count = 0;
4923 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4924 char *channel_name, *channel_namec = NULL;
4926 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2);
4928 /* Get Channel ID */
4929 channel_id = silc_argument_get_arg_type(cmd->args, 1, &channel_id_len);
4931 /* Get channel name */
4932 channel_name = silc_argument_get_arg_type(cmd->args, 2, NULL);
4934 if (!channel_id && !channel_name) {
4935 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4936 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4940 /* Check channel name */
4942 channel_namec = silc_channel_name_check(channel_name, strlen(channel_name),
4943 SILC_STRING_UTF8, 256, NULL);
4944 if (!channel_namec) {
4945 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4946 SILC_STATUS_ERR_BAD_CHANNEL, 0);
4951 /* Check Channel ID */
4953 if (!silc_id_payload_parse_id(channel_id, channel_id_len, &id)) {
4954 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4955 SILC_STATUS_ERR_BAD_CHANNEL_ID, 0,
4956 2, channel_id, channel_id_len);
4961 /* If we are server and we don't know about this channel we will send
4962 the command to our router. If we know about the channel then we also
4963 have the list of users already. */
4965 channel = silc_idlist_find_channel_by_id(server->local_list,
4966 SILC_ID_GET_ID(id), NULL);
4968 channel = silc_idlist_find_channel_by_name(server->local_list,
4969 channel_namec, NULL);
4971 if (!channel || (!server->standalone && (channel->disabled ||
4972 !channel->users_resolved))) {
4973 if (server->server_type != SILC_ROUTER && !server->standalone &&
4978 cmd->server->stat.commands_sent++;
4980 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4981 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4983 /* Send USERS command */
4984 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4985 SILC_PACKET_COMMAND, cmd->packet->flags,
4986 tmpbuf->data, silc_buffer_len(tmpbuf));
4988 /* Reprocess this packet after received reply */
4989 silc_server_command_pending(server, SILC_COMMAND_USERS,
4990 silc_command_get_ident(cmd->payload),
4991 silc_server_command_users,
4992 silc_server_command_dup(cmd));
4993 cmd->pending = TRUE;
4994 silc_command_set_ident(cmd->payload, ident);
4995 silc_buffer_free(tmpbuf);
4999 /* Check the global list as well. */
5001 channel = silc_idlist_find_channel_by_id(server->global_list,
5002 SILC_ID_GET_ID(id), NULL);
5004 channel = silc_idlist_find_channel_by_name(server->global_list,
5005 channel_namec, NULL);
5007 /* Channel really does not exist */
5009 silc_server_command_send_status_data(
5010 cmd, SILC_COMMAND_USERS,
5011 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID, 0,
5012 2, channel_id, channel_id_len);
5014 silc_server_command_send_status_data(
5015 cmd, SILC_COMMAND_USERS,
5016 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
5017 2, channel_name, strlen(channel_name));
5022 /* If the channel is private or secret do not send anything, unless the
5023 user requesting this command is on the channel or is server */
5024 if (idata->conn_type == SILC_CONN_CLIENT) {
5025 if (channel->mode & (SILC_CHANNEL_MODE_PRIVATE | SILC_CHANNEL_MODE_SECRET)
5026 && !silc_server_client_on_channel((SilcClientEntry)idata, channel,
5028 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
5029 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
5030 2, channel->channel_name,
5031 strlen(channel->channel_name));
5036 /* Get the users list */
5037 if (!silc_server_get_users_on_channel(server, channel, &client_id_list,
5038 &client_mode_list, &list_count)) {
5040 client_id_list = NULL;
5041 client_mode_list = NULL;
5045 SILC_PUT32_MSB(list_count, lc);
5048 idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
5049 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_USERS,
5050 SILC_STATUS_OK, 0, ident, 4,
5051 2, idp->data, silc_buffer_len(idp),
5054 client_id_list->data : NULL,
5056 silc_buffer_len(client_id_list) : 0,
5057 5, client_mode_list ?
5058 client_mode_list->data : NULL,
5060 silc_buffer_len(client_mode_list) : 0);
5061 silc_buffer_free(idp);
5063 silc_buffer_free(client_id_list);
5064 if (client_mode_list)
5065 silc_buffer_free(client_mode_list);
5068 silc_free(channel_namec);
5069 silc_server_command_free(cmd);
5072 /* Server side of command GETKEY. This fetches the client's public key
5073 from the server where to the client is connected. */
5075 SILC_SERVER_CMD_FUNC(getkey)
5077 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5078 SilcServer server = cmd->server;
5079 SilcClientEntry client;
5080 SilcServerEntry server_entry;
5081 SilcClientID client_id;
5082 SilcServerID server_id;
5083 SilcIDPayload idp = NULL;
5084 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
5087 SilcBuffer pk = NULL;
5089 SilcPublicKey public_key;
5091 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5093 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
5094 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5098 idp = silc_id_payload_parse(tmp, tmp_len);
5100 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
5101 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5106 id_type = silc_id_payload_get_type(idp);
5107 if (id_type == SILC_ID_CLIENT) {
5108 silc_id_payload_get_id(idp, &client_id, sizeof(client_id));
5110 /* If the client is not found from local list there is no chance it
5111 would be locally connected client so send the command further. */
5112 client = silc_idlist_find_client_by_id(server->local_list,
5113 &client_id, TRUE, NULL);
5115 client = silc_idlist_find_client_by_id(server->global_list,
5116 &client_id, TRUE, NULL);
5118 if ((!client && !cmd->pending && !server->standalone) ||
5119 (client && !client->connection && !cmd->pending &&
5120 !(client->mode & SILC_UMODE_DETACHED)) ||
5121 (client && !client->data.public_key && !cmd->pending)) {
5123 SilcUInt16 old_ident;
5124 SilcPacketStream dest_sock;
5126 dest_sock = silc_server_get_client_route(server, NULL, 0,
5127 &client_id, NULL, NULL);
5132 cmd->server->stat.commands_sent++;
5134 old_ident = silc_command_get_ident(cmd->payload);
5135 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5136 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5138 silc_server_packet_send(server, dest_sock,
5139 SILC_PACKET_COMMAND, cmd->packet->flags,
5140 tmpbuf->data, silc_buffer_len(tmpbuf));
5142 /* Reprocess this packet after received reply from router */
5143 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
5144 silc_command_get_ident(cmd->payload),
5145 silc_server_command_getkey,
5146 silc_server_command_dup(cmd));
5147 cmd->pending = TRUE;
5148 silc_command_set_ident(cmd->payload, old_ident);
5149 silc_buffer_free(tmpbuf);
5154 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
5155 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
5156 0, 2, tmp, tmp_len);
5160 /* The client is locally connected, just get the public key and
5161 send it back. If they key does not exist then do not send it,
5162 send just OK reply */
5163 public_key = client->data.public_key;
5165 pk = silc_public_key_payload_encode(public_key);
5166 } else if (id_type == SILC_ID_SERVER) {
5167 silc_id_payload_get_id(idp, &server_id, sizeof(server_id));
5169 /* If the server is not found from local list there is no chance it
5170 would be locally connected server so send the command further. */
5171 server_entry = silc_idlist_find_server_by_id(server->local_list,
5172 &server_id, TRUE, NULL);
5174 server_entry = silc_idlist_find_server_by_id(server->global_list,
5175 &server_id, TRUE, NULL);
5177 if (server_entry != server->id_entry &&
5178 ((!server_entry && !cmd->pending && !server->standalone) ||
5179 (server_entry && !server_entry->connection && !cmd->pending &&
5180 !server->standalone) ||
5181 (server_entry && !server_entry->data.public_key && !cmd->pending &&
5182 !server->standalone))) {
5184 SilcUInt16 old_ident;
5187 cmd->server->stat.commands_sent++;
5189 old_ident = silc_command_get_ident(cmd->payload);
5190 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5191 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5193 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5194 SILC_PACKET_COMMAND, cmd->packet->flags,
5195 tmpbuf->data, silc_buffer_len(tmpbuf));
5197 /* Reprocess this packet after received reply from router */
5198 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
5199 silc_command_get_ident(cmd->payload),
5200 silc_server_command_getkey,
5201 silc_server_command_dup(cmd));
5202 cmd->pending = TRUE;
5203 silc_command_set_ident(cmd->payload, old_ident);
5204 silc_buffer_free(tmpbuf);
5208 if (!server_entry) {
5209 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
5210 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
5211 0, 2, tmp, tmp_len);
5215 /* If they key does not exist then do not send it, send just OK reply */
5216 public_key = (!server_entry->data.public_key ?
5217 (server_entry == server->id_entry ? server->public_key :
5218 NULL) : server_entry->data.public_key);
5220 pk = silc_public_key_payload_encode(public_key);
5225 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5226 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_GETKEY,
5227 SILC_STATUS_OK, 0, ident, 2,
5229 3, pk ? pk->data : NULL,
5230 pk ? silc_buffer_len(pk) : 0);
5234 silc_id_payload_free(idp);
5235 silc_buffer_free(pk);
5236 silc_server_command_free(cmd);
5239 /* Server side of command SERVICE. */
5240 /* XXX currently this just sends empty reply back */
5242 SILC_SERVER_CMD_FUNC(service)
5244 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5245 SilcServer server = cmd->server;
5246 SilcUInt32 tmp_len, auth_len;
5247 unsigned char *service_name, *auth;
5248 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
5250 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SERVICE, cmd, 0, 256);
5252 /* Get requested service */
5253 service_name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5254 if (service_name && tmp_len) {
5255 /* Verify service name */
5256 if (!silc_identifier_verify(service_name, tmp_len,
5257 SILC_STRING_UTF8, 256)) {
5258 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SERVICE,
5259 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5265 /* Get authentication payload if present */
5266 auth = silc_argument_get_arg_type(cmd->args, 2, &auth_len);
5272 /* Send our service list back */
5273 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_SERVICE,
5274 SILC_STATUS_OK, 0, ident, 0);
5277 silc_server_command_free(cmd);
5281 /* Private range commands, specific to this implementation */
5283 /* Server side command of CONNECT. Connects us to the specified remote
5284 server or router. */
5286 SILC_SERVER_CMD_FUNC(connect)
5288 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5289 SilcServer server = cmd->server;
5290 SilcClientEntry client = silc_packet_get_context(cmd->sock);
5291 unsigned char *tmp, *host;
5293 SilcUInt32 port = SILC_PORT;
5295 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
5298 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CONNECT, cmd, 1, 2);
5300 /* Check whether client has the permissions. */
5301 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5302 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5303 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5304 SILC_STATUS_ERR_NO_SERVER_PRIV, 0);
5308 if (server->server_type == SILC_ROUTER && !server->backup_router &&
5309 client->mode & SILC_UMODE_SERVER_OPERATOR) {
5310 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5311 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
5315 /* Get the remote server */
5316 host = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5318 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5319 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5325 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5327 SILC_GET32_MSB(port, tmp);
5329 /* Create the connection. It is done with timeout and is async. */
5330 silc_server_create_connection(server, FALSE, FALSE, host, port, NULL, NULL);
5332 /* Send reply to the sender */
5333 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5337 silc_server_command_free(cmd);
5340 /* Server side command of CLOSE. Closes connection to a specified server. */
5342 SILC_SERVER_CMD_FUNC(close)
5344 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5345 SilcServer server = cmd->server;
5346 SilcClientEntry client = silc_packet_get_context(cmd->sock);
5347 SilcServerEntry server_entry;
5348 SilcPacketStream sock;
5351 unsigned char *name;
5352 SilcUInt32 port = SILC_PORT;
5354 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
5357 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CLOSE, cmd, 1, 2);
5359 /* Check whether client has the permissions. */
5360 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5361 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5362 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5363 SILC_STATUS_ERR_NO_SERVER_PRIV,
5368 /* Get the remote server */
5369 name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5371 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5372 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5378 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5380 SILC_GET32_MSB(port, tmp);
5382 server_entry = silc_idlist_find_server_by_conn(server->local_list,
5383 name, port, TRUE, NULL);
5385 server_entry = silc_idlist_find_server_by_conn(server->global_list,
5386 name, port, TRUE, NULL);
5387 if (!server_entry) {
5388 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5389 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5393 if (server_entry == server->id_entry) {
5394 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5395 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5399 /* Send reply to the sender */
5400 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5403 /* Close the connection to the server */
5404 sock = server_entry->connection;
5406 if (server_entry->server_type == SILC_BACKUP_ROUTER) {
5407 server->backup_closed = TRUE;
5408 silc_server_backup_del(server, server_entry);
5411 server->backup_noswitch = TRUE;
5412 if (server->router == server_entry) {
5413 server->id_entry->router = NULL;
5414 server->router = NULL;
5415 server->standalone = TRUE;
5417 silc_server_disconnect_remote(server, sock,
5418 SILC_STATUS_ERR_BANNED_FROM_SERVER,
5419 "Closed by administrator");
5420 silc_server_free_sock_user_data(server, sock, NULL);
5421 server->backup_noswitch = FALSE;
5424 silc_server_command_free(cmd);
5427 /* Server side command of SHUTDOWN. Shutdowns the server and closes all
5428 active connections. */
5430 SILC_SERVER_CMD_FUNC(shutdown)
5432 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5433 SilcServer server = cmd->server;
5434 SilcClientEntry client = silc_packet_get_context(cmd->sock);
5436 if (client->data.conn_type != SILC_CONN_CLIENT || !client)
5439 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_SHUTDOWN, cmd, 0, 0);
5441 /* Check whether client has the permission. */
5442 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5443 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5444 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5445 SILC_STATUS_ERR_NO_SERVER_PRIV,
5450 /* Send reply to the sender */
5451 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5454 /* Then, gracefully, or not, bring the server down. */
5455 silc_server_stop(server);
5459 silc_server_command_free(cmd);