5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2005 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.
21 #include "serverincludes.h"
22 #include "server_internal.h"
24 static int silc_server_is_registered(SilcServer server,
25 SilcSocketConnection sock,
26 SilcServerCommandContext cmd,
29 silc_server_command_send_status_reply(SilcServerCommandContext cmd,
34 silc_server_command_send_status_data(SilcServerCommandContext cmd,
39 const unsigned char *arg,
42 silc_server_command_pending_error_check(SilcServerCommandContext cmd,
43 SilcServerCommandReplyContext cmdr,
45 SILC_TASK_CALLBACK(silc_server_command_process_timeout);
47 /* Server command list. */
48 SilcServerCommand silc_command_list[] =
50 SILC_SERVER_CMD(whois, WHOIS, SILC_CF_LAG | SILC_CF_REG),
51 SILC_SERVER_CMD(whowas, WHOWAS, SILC_CF_LAG | SILC_CF_REG),
52 SILC_SERVER_CMD(identify, IDENTIFY, SILC_CF_LAG | SILC_CF_REG),
53 SILC_SERVER_CMD(nick, NICK, SILC_CF_LAG_STRICT | SILC_CF_REG),
54 SILC_SERVER_CMD(list, LIST, SILC_CF_LAG_STRICT | SILC_CF_REG),
55 SILC_SERVER_CMD(topic, TOPIC, SILC_CF_LAG | SILC_CF_REG),
56 SILC_SERVER_CMD(invite, INVITE, SILC_CF_LAG | SILC_CF_REG),
57 SILC_SERVER_CMD(quit, QUIT, SILC_CF_LAG | SILC_CF_REG),
58 SILC_SERVER_CMD(kill, KILL, SILC_CF_LAG_STRICT | SILC_CF_REG | SILC_CF_OPER),
59 SILC_SERVER_CMD(info, INFO, SILC_CF_LAG | SILC_CF_REG),
60 SILC_SERVER_CMD(stats, STATS, SILC_CF_LAG | SILC_CF_REG),
61 SILC_SERVER_CMD(ping, PING, SILC_CF_LAG | SILC_CF_REG),
62 SILC_SERVER_CMD(oper, OPER, SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
63 SILC_SERVER_CMD(join, JOIN, SILC_CF_LAG_STRICT | SILC_CF_REG),
64 SILC_SERVER_CMD(motd, MOTD, SILC_CF_LAG | SILC_CF_REG),
65 SILC_SERVER_CMD(umode, UMODE, SILC_CF_LAG | SILC_CF_REG),
66 SILC_SERVER_CMD(cmode, CMODE, SILC_CF_LAG_STRICT | SILC_CF_REG),
67 SILC_SERVER_CMD(cumode, CUMODE, SILC_CF_LAG | SILC_CF_REG),
68 SILC_SERVER_CMD(kick, KICK, SILC_CF_LAG_STRICT | SILC_CF_REG),
69 SILC_SERVER_CMD(ban, BAN, SILC_CF_LAG_STRICT | SILC_CF_REG),
70 SILC_SERVER_CMD(detach, DETACH, SILC_CF_LAG_STRICT | SILC_CF_REG),
71 SILC_SERVER_CMD(watch, WATCH, SILC_CF_LAG | SILC_CF_REG),
72 SILC_SERVER_CMD(silcoper, SILCOPER,
73 SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER),
74 SILC_SERVER_CMD(leave, LEAVE, SILC_CF_LAG_STRICT | SILC_CF_REG),
75 SILC_SERVER_CMD(users, USERS, SILC_CF_LAG | SILC_CF_REG),
76 SILC_SERVER_CMD(getkey, GETKEY, SILC_CF_LAG | SILC_CF_REG),
77 SILC_SERVER_CMD(service, SERVICE, SILC_CF_LAG_STRICT | SILC_CF_REG),
79 SILC_SERVER_CMD(connect, PRIV_CONNECT,
80 SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
81 SILC_SERVER_CMD(close, PRIV_CLOSE,
82 SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
83 SILC_SERVER_CMD(shutdown, PRIV_SHUTDOWN, SILC_CF_LAG | SILC_CF_REG |
89 /* Performs several checks to the command. It first checks whether this
90 command was called as pending command callback. If it was then it checks
91 whether error occurred in the command reply where the pending command
94 It also checks that the requested command includes correct amount
96 #define SILC_SERVER_COMMAND_CHECK(command, context, min, max) \
100 if (silc_server_command_pending_error_check(cmd, context2, command)) { \
101 SILC_LOG_DEBUG(("Error occurred in command reply, command not called")); \
102 silc_server_command_free(cmd); \
106 _argc = silc_argument_get_arg_num(cmd->args); \
108 SILC_LOG_DEBUG(("Not enough parameters in command")); \
109 silc_server_command_send_status_reply(cmd, command, \
110 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, \
112 silc_server_command_free(cmd); \
116 SILC_LOG_DEBUG(("Too many parameters in command")); \
117 silc_server_command_send_status_reply(cmd, command, \
118 SILC_STATUS_ERR_TOO_MANY_PARAMS, \
120 silc_server_command_free(cmd); \
125 /* Returns TRUE if the connection is registered. Unregistered connections
126 usually cannot send commands hence the check. */
128 static int silc_server_is_registered(SilcServer server,
129 SilcSocketConnection sock,
130 SilcServerCommandContext cmd,
133 SilcIDListData idata = (SilcIDListData)sock->user_data;
138 if (idata->status & SILC_IDLIST_STATUS_REGISTERED)
141 silc_server_command_send_status_reply(cmd, command,
142 SILC_STATUS_ERR_NOT_REGISTERED, 0);
146 /* Internal context to hold data when executed command with timeout. */
148 SilcServerCommandContext ctx;
149 SilcServerCommand *cmd;
150 } *SilcServerCommandTimeout;
152 /* Timeout callback to process commands with timeout for client. Client's
153 commands are always executed with timeout. */
155 SILC_TASK_CALLBACK(silc_server_command_process_timeout)
157 SilcServerCommandTimeout timeout = (SilcServerCommandTimeout)context;
158 SilcClientEntry client = (SilcClientEntry)timeout->ctx->sock->user_data;
161 SILC_LOG_DEBUG(("Client entry is invalid"));
162 silc_server_command_free(timeout->ctx);
167 /* Update access time */
168 client->last_command = time(NULL);
170 if (!(timeout->cmd->flags & SILC_CF_REG)) {
171 SILC_LOG_DEBUG(("Calling %s command",
172 silc_get_command_name(timeout->cmd->cmd)));
173 timeout->cmd->cb(timeout->ctx, NULL);
174 } else if (silc_server_is_registered(timeout->ctx->server,
177 timeout->cmd->cmd)) {
178 SILC_LOG_DEBUG(("Calling %s command",
179 silc_get_command_name(timeout->cmd->cmd)));
180 timeout->cmd->cb(timeout->ctx, NULL);
182 SILC_LOG_DEBUG(("Client is not registered"));
183 silc_server_command_free(timeout->ctx);
189 /* Processes received command packet. */
191 void silc_server_command_process(SilcServer server,
192 SilcSocketConnection sock,
193 SilcPacketContext *packet)
195 SilcServerCommandContext ctx;
196 SilcServerCommand *cmd;
199 /* Allocate command context. This must be free'd by the
200 command routine receiving it. */
201 ctx = silc_server_command_alloc();
202 ctx->server = server;
203 ctx->sock = silc_socket_dup(sock);
204 ctx->packet = silc_packet_context_dup(packet); /* Save original packet */
206 /* Parse the command payload in the packet */
207 ctx->payload = silc_command_payload_parse(packet->buffer->data,
208 packet->buffer->len);
210 SILC_LOG_ERROR(("Bad command payload, dropped (%s:%d [%s])",
211 sock->hostname, sock->port,
212 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
213 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
214 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
216 silc_packet_context_free(packet);
217 silc_socket_free(ctx->sock);
221 ctx->args = silc_command_get_args(ctx->payload);
223 /* Get the command */
224 command = silc_command_get(ctx->payload);
225 for (cmd = silc_command_list; cmd->cb; cmd++)
226 if (cmd->cmd == command)
229 if (!cmd || !cmd->cb) {
230 SILC_LOG_DEBUG(("Unknown command %d", command));
231 silc_server_command_send_status_reply(ctx, command,
232 SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
233 silc_server_command_free(ctx);
237 /* Execute client's commands always with timeout. Normally they are
238 executed with zero (0) timeout but if client is sending command more
239 frequently than once in 2 seconds, then the timeout may be 0 to 2
241 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
242 SilcClientEntry client = (SilcClientEntry)sock->user_data;
243 SilcServerCommandTimeout timeout;
247 SILC_LOG_DEBUG(("Client entry is invalid"));
248 silc_server_command_free(ctx);
252 timeout = silc_calloc(1, sizeof(*timeout));
256 if (client->last_command && (time(NULL) - client->last_command) < 2) {
257 client->fast_command++;
260 if (client->fast_command - 2 <= 0)
261 client->fast_command = 0;
263 client->fast_command -= 2;
267 if (!fast && ((cmd->flags & SILC_CF_LAG_STRICT) ||
268 (client->fast_command > 5 && cmd->flags & SILC_CF_LAG)))
269 silc_schedule_task_add(server->schedule, sock->sock,
270 silc_server_command_process_timeout, timeout,
271 (client->fast_command < 3 ? 0 :
272 2 - (time(NULL) - client->last_command)),
273 (client->fast_command < 3 ? 200000 : 0),
274 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
276 silc_schedule_task_add(server->schedule, sock->sock,
277 silc_server_command_process_timeout, timeout,
278 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
282 /* Execute for server */
284 if (!(cmd->flags & SILC_CF_REG)) {
285 SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
287 } else if (silc_server_is_registered(server, sock, ctx, cmd->cmd)) {
288 SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
291 SILC_LOG_DEBUG(("Server is not registered"));
292 silc_server_command_free(ctx);
296 /* Allocate Command Context */
298 SilcServerCommandContext silc_server_command_alloc()
300 SilcServerCommandContext ctx = silc_calloc(1, sizeof(*ctx));
305 /* Free's the command context allocated before executing the command */
307 void silc_server_command_free(SilcServerCommandContext ctx)
310 SILC_LOG_DEBUG(("Command context %p refcnt %d->%d", ctx, ctx->users + 1,
312 if (ctx->users < 1) {
314 silc_command_payload_free(ctx->payload);
316 silc_packet_context_free(ctx->packet);
318 silc_socket_free(ctx->sock); /* Decrease reference counter */
323 /* Duplicate Command Context by adding reference counter. The context won't
324 be free'd untill it hits zero. */
326 SilcServerCommandContext
327 silc_server_command_dup(SilcServerCommandContext ctx)
330 SILC_LOG_DEBUG(("Command context %p refcnt %d->%d", ctx, ctx->users - 1,
335 /* Timeout for pending command. If reply to pending command never arrives
336 this is called to free resources. */
338 SILC_TASK_CALLBACK(silc_server_command_pending_timeout)
340 SilcServer server = app_context;
341 SilcServerCommandPending *reply = context;
342 SilcServerCommandReplyContext cmdr;
346 SILC_LOG_DEBUG(("Timeout pending command"));
348 /* Allocate temporary and bogus command reply context */
349 cmdr = silc_calloc(1, sizeof(*cmdr));
350 cmdr->server = server;
351 cmdr->ident = reply->ident;
353 /* Check for pending commands and mark to be exeucted */
355 silc_server_command_pending_check(server, reply->reply_cmd,
356 reply->ident, &cmdr->callbacks_count);
358 /* Create bogus command reply with an error inside */
360 silc_command_reply_payload_encode_va(reply->reply_cmd ? reply->reply_cmd :
361 SILC_COMMAND_RESERVED,
362 SILC_STATUS_ERR_TIMEDOUT, 0,
364 cmdr->payload = silc_command_payload_parse(tmpreply->data, tmpreply->len);
365 silc_buffer_free(tmpreply);
367 /* Call all callbacks. Same as SILC_SERVER_PENDING_EXEC macro. */
368 for (i = 0; i < cmdr->callbacks_count; i++)
369 if (cmdr->callbacks[i].callback)
370 (*cmdr->callbacks[i].callback)(cmdr->callbacks[i].context, cmdr);
372 silc_server_command_pending_del(server, reply->reply_cmd, reply->ident);
373 silc_server_command_reply_free(cmdr);
376 /* Add new pending command to be executed when reply to a command has been
377 received. The `reply_cmd' is the command that will call the `callback'
378 with `context' when reply has been received. It can be SILC_COMMAND_NONE
379 to match any command with the `ident'. If `ident' is non-zero
380 the `callback' will be executed when received reply with command
381 identifier `ident'. If there already exists pending command for the
382 specified command, ident, callback and context this function has no
385 bool silc_server_command_pending(SilcServer server,
386 SilcCommand reply_cmd,
388 SilcCommandCb callback,
391 return silc_server_command_pending_timed(server, reply_cmd, ident, callback,
395 /* Same as silc_server_command_pending with specific timeout for pending
396 commands. If the `timeout' is zero default timeout is used. */
398 bool silc_server_command_pending_timed(SilcServer server,
399 SilcCommand reply_cmd,
401 SilcCommandCb callback,
405 SilcServerCommandPending *reply;
407 /* Check whether identical pending already exists for same command,
408 ident, callback and callback context. If it does then it would be
409 error to register it again. */
410 silc_dlist_start(server->pending_commands);
411 while ((reply = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
412 if (reply->reply_cmd == reply_cmd && reply->ident == ident &&
413 reply->callback == callback && reply->context == context)
417 reply = silc_calloc(1, sizeof(*reply));
418 reply->reply_cmd = reply_cmd;
419 reply->ident = ident;
420 reply->context = context;
421 reply->callback = callback;
423 silc_schedule_task_add(server->schedule, 0,
424 silc_server_command_pending_timeout, reply,
425 timeout ? timeout : 12, 0,
426 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
427 silc_dlist_add(server->pending_commands, reply);
432 /* Deletes pending command by reply command type. */
434 void silc_server_command_pending_del(SilcServer server,
435 SilcCommand reply_cmd,
438 SilcServerCommandPending *r;
440 silc_dlist_start(server->pending_commands);
441 while ((r = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
442 if ((r->reply_cmd == reply_cmd || (r->reply_cmd == SILC_COMMAND_NONE &&
444 && r->ident == ident) {
445 silc_dlist_del(server->pending_commands, r);
447 silc_schedule_task_del(server->schedule, r->timeout);
453 /* Checks for pending commands and marks callbacks to be called from
454 the command reply function. Returns TRUE if there were pending command. */
456 SilcServerCommandPendingCallbacks
457 silc_server_command_pending_check(SilcServer server,
460 SilcUInt32 *callbacks_count)
462 SilcServerCommandPending *r;
463 SilcServerCommandPendingCallbacks callbacks = NULL;
466 silc_dlist_start(server->pending_commands);
467 while ((r = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
468 if ((r->reply_cmd == command || r->reply_cmd == SILC_COMMAND_NONE)
469 && r->ident == ident) {
470 callbacks = silc_realloc(callbacks, sizeof(*callbacks) * (i + 1));
471 callbacks[i].context = r->context;
472 callbacks[i].callback = r->callback;
473 r->reply_check = TRUE;
478 *callbacks_count = i;
482 /* Sends simple status message as command reply packet */
485 silc_server_command_send_status_reply(SilcServerCommandContext cmd,
493 cmd->server->stat.commands_sent++;
495 SILC_LOG_DEBUG(("Sending command status %d", status));
498 silc_command_reply_payload_encode_va(command, status, error,
499 silc_command_get_ident(cmd->payload),
501 silc_server_packet_send(cmd->server, cmd->sock,
502 SILC_PACKET_COMMAND_REPLY, 0,
503 buffer->data, buffer->len, FALSE);
504 silc_buffer_free(buffer);
507 /* Sends command status reply with one extra argument. The argument
508 type must be sent as argument. */
511 silc_server_command_send_status_data(SilcServerCommandContext cmd,
516 const unsigned char *arg,
522 cmd->server->stat.commands_sent++;
524 SILC_LOG_DEBUG(("Sending command status %d", status));
527 silc_command_reply_payload_encode_va(command, status, 0,
528 silc_command_get_ident(cmd->payload),
529 1, arg_type, arg, arg_len);
530 silc_server_packet_send(cmd->server, cmd->sock,
531 SILC_PACKET_COMMAND_REPLY, 0,
532 buffer->data, buffer->len, FALSE);
533 silc_buffer_free(buffer);
537 silc_server_command_send_status_data2(SilcServerCommandContext cmd,
541 SilcUInt32 arg_type1,
542 const unsigned char *arg1,
544 SilcUInt32 arg_type2,
545 const unsigned char *arg2,
551 cmd->server->stat.commands_sent++;
553 SILC_LOG_DEBUG(("Sending command status %d", status));
556 silc_command_reply_payload_encode_va(command, status, 0,
557 silc_command_get_ident(cmd->payload),
558 2, arg_type1, arg1, arg_len1,
559 arg_type2, arg2, arg_len2);
560 silc_server_packet_send(cmd->server, cmd->sock,
561 SILC_PACKET_COMMAND_REPLY, 0,
562 buffer->data, buffer->len, FALSE);
563 silc_buffer_free(buffer);
566 /* This function can be called to check whether in the command reply
567 an error occurred. This function has no effect if this is called
568 when the command function was not called as pending command callback.
569 This returns TRUE if error had occurred. */
572 silc_server_command_pending_error_check(SilcServerCommandContext cmd,
573 SilcServerCommandReplyContext cmdr,
576 if (!cmd->pending || !cmdr)
579 if (!silc_command_get_status(cmdr->payload, NULL, NULL)) {
583 cmd->server->stat.commands_sent++;
585 /* Send the same command reply payload */
586 silc_command_set_command(cmdr->payload, silc_command_get(cmd->payload));
587 silc_command_set_ident(cmdr->payload,
588 silc_command_get_ident(cmd->payload));
589 buffer = silc_command_payload_encode_payload(cmdr->payload);
590 silc_server_packet_send(cmd->server, cmd->sock,
591 SILC_PACKET_COMMAND_REPLY, 0,
592 buffer->data, buffer->len, FALSE);
593 silc_buffer_free(buffer);
600 /* Server side of command WHOIS. */
602 SILC_SERVER_CMD_FUNC(whois)
604 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
605 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WHOIS, cmd, 1, 256);
606 silc_server_query_command(cmd->server, SILC_COMMAND_WHOIS, cmd);
607 silc_server_command_free(cmd);
610 /* Server side of command WHOWAS. */
612 SILC_SERVER_CMD_FUNC(whowas)
614 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
615 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WHOWAS, cmd, 1, 2);
616 silc_server_query_command(cmd->server, SILC_COMMAND_WHOWAS, cmd);
617 silc_server_command_free(cmd);
620 /* Server side of command IDENTIFY. */
622 SILC_SERVER_CMD_FUNC(identify)
624 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
625 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_IDENTIFY, cmd, 1, 256);
626 silc_server_query_command(cmd->server, SILC_COMMAND_IDENTIFY, cmd);
627 silc_server_command_free(cmd);
630 /* Server side of command NICK. Sets nickname for user. Setting
631 nickname causes generation of a new client ID for the client. The
632 new client ID is sent to the client after changing the nickname. */
634 SILC_SERVER_CMD_FUNC(nick)
636 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
637 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
638 SilcServer server = cmd->server;
639 SilcBuffer nidp, oidp = NULL;
640 SilcClientID *new_id;
642 unsigned char *nick, *nickc = NULL;
643 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
645 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
648 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_NICK, cmd, 1, 1);
651 nick = silc_argument_get_arg_type(cmd->args, 1, &nick_len);
653 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
654 SILC_STATUS_ERR_BAD_NICKNAME, 0);
658 /* Truncate over long nicks */
659 if (nick_len > 128) {
664 /* Check for valid nickname string. This is cached, original is saved
665 in the client context. */
666 nickc = silc_identifier_check(nick, nick_len, SILC_STRING_UTF8, 128, NULL);
668 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
669 SILC_STATUS_ERR_BAD_NICKNAME, 0);
673 /* Check for same nickname */
674 if (strlen(client->nickname) == nick_len &&
675 !memcmp(client->nickname, nick, nick_len)) {
676 nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
681 /* Create new Client ID */
682 if (!silc_id_create_client_id(cmd->server, cmd->server->id,
684 cmd->server->md5hash,
685 nickc, strlen(nickc), &new_id)) {
686 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
687 SILC_STATUS_ERR_BAD_NICKNAME, 0);
692 /* Send notify about nickname change to our router. We send the new
693 ID and ask to replace it with the old one. If we are router the
694 packet is broadcasted. Send NICK_CHANGE notify. */
695 silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
696 SILC_BROADCAST(server), client->id,
699 /* Check if anyone is watching the old nickname */
700 if (server->server_type == SILC_ROUTER)
701 silc_server_check_watcher_list(server, client, nick,
702 SILC_NOTIFY_TYPE_NICK_CHANGE);
704 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
706 /* Remove old cache entry */
707 silc_idcache_del_by_context(server->local_list->clients, client);
709 silc_free(client->id);
712 silc_free(client->nickname);
713 client->nickname = strdup(nick);
715 /* Update client cache */
716 silc_idcache_add(server->local_list->clients, nickc,
717 client->id, (void *)client, 0, NULL);
719 nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
721 /* Send NICK_CHANGE notify to the client's channels */
722 silc_server_send_notify_on_channels(server, NULL, client,
723 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
724 oidp->data, oidp->len,
725 nidp->data, nidp->len,
727 strlen(client->nickname));
729 /* Check if anyone is watching the new nickname */
730 if (server->server_type == SILC_ROUTER)
731 silc_server_check_watcher_list(server, client, NULL,
732 SILC_NOTIFY_TYPE_NICK_CHANGE);
735 /* Send the new Client ID as reply command back to client */
736 silc_server_send_command_reply(cmd->server, cmd->sock,
738 SILC_STATUS_OK, 0, ident, 2,
739 2, nidp->data, nidp->len,
741 silc_buffer_free(nidp);
743 silc_buffer_free(oidp);
746 silc_server_command_free(cmd);
749 /* Sends the LIST command reply */
752 silc_server_command_list_send_reply(SilcServerCommandContext cmd,
753 SilcChannelEntry *lch,
754 SilcUInt32 lch_count,
755 SilcChannelEntry *gch,
756 SilcUInt32 gch_count)
760 SilcChannelEntry entry;
762 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
764 unsigned char usercount[4];
766 int valid_lcount = 0, valid_rcount = 0;
768 for (i = 0; i < lch_count; i++) {
769 if (lch[i]->mode & SILC_CHANNEL_MODE_SECRET)
774 for (i = 0; i < gch_count; i++) {
775 if (gch[i]->mode & SILC_CHANNEL_MODE_SECRET)
781 if (!lch_count && !gch_count) {
782 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LIST,
787 status = SILC_STATUS_OK;
788 if ((lch_count + gch_count) > 1)
789 status = SILC_STATUS_LIST_START;
792 for (i = 0, k = 0; i < lch_count; i++) {
798 status = SILC_STATUS_LIST_ITEM;
799 if (valid_lcount > 1 && k == valid_lcount - 1 && !valid_rcount)
800 status = SILC_STATUS_LIST_END;
802 idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
804 if (entry->mode & SILC_CHANNEL_MODE_PRIVATE) {
806 memset(usercount, 0, sizeof(usercount));
808 topic = entry->topic;
809 users = silc_hash_table_count(entry->user_list);
810 SILC_PUT32_MSB(users, usercount);
814 silc_server_send_command_reply(cmd->server, cmd->sock, SILC_COMMAND_LIST,
816 2, idp->data, idp->len,
817 3, entry->channel_name,
818 strlen(entry->channel_name),
819 4, topic, topic ? strlen(topic) : 0,
821 silc_buffer_free(idp);
826 for (i = 0, k = 0; i < gch_count; i++) {
832 status = SILC_STATUS_LIST_ITEM;
833 if (valid_rcount > 1 && k == valid_rcount - 1)
834 status = SILC_STATUS_LIST_END;
836 idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
838 if (entry->mode & SILC_CHANNEL_MODE_PRIVATE) {
840 memset(usercount, 0, sizeof(usercount));
842 topic = entry->topic;
843 users = entry->user_count;
844 SILC_PUT32_MSB(users, usercount);
848 silc_server_send_command_reply(cmd->server, cmd->sock, SILC_COMMAND_LIST,
850 2, idp->data, idp->len,
851 3, entry->channel_name,
852 strlen(entry->channel_name),
853 4, topic, topic ? strlen(topic) : 0,
855 silc_buffer_free(idp);
860 /* Server side of LIST command. This lists the channel of the requested
861 server. Secret channels are not listed. */
863 SILC_SERVER_CMD_FUNC(list)
865 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
866 SilcServer server = cmd->server;
867 SilcChannelID *channel_id = NULL;
870 SilcChannelEntry *lchannels = NULL, *gchannels = NULL;
871 SilcUInt32 lch_count = 0, gch_count = 0;
873 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LIST, cmd, 0, 1);
875 /* If we are normal server, send the command to router, since we
876 want to know all channels in the network. */
877 if (!cmd->pending && server->server_type != SILC_ROUTER &&
878 !server->standalone) {
880 SilcUInt16 old_ident;
883 cmd->server->stat.commands_sent++;
885 old_ident = silc_command_get_ident(cmd->payload);
886 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
887 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
888 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
889 SILC_PACKET_COMMAND, cmd->packet->flags,
890 tmpbuf->data, tmpbuf->len, TRUE);
892 /* Reprocess this packet after received reply from router */
893 silc_server_command_pending(server, SILC_COMMAND_LIST,
894 silc_command_get_ident(cmd->payload),
895 silc_server_command_list,
896 silc_server_command_dup(cmd));
898 silc_command_set_ident(cmd->payload, old_ident);
899 silc_buffer_free(tmpbuf);
904 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
906 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
908 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LIST,
909 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
914 /* Get the channels from local list */
915 lchannels = silc_idlist_get_channels(server->local_list, channel_id,
918 /* Get the channels from global list */
919 gchannels = silc_idlist_get_channels(server->global_list, channel_id,
923 silc_server_command_list_send_reply(cmd, lchannels, lch_count,
924 gchannels, gch_count);
926 silc_free(lchannels);
927 silc_free(gchannels);
930 silc_server_command_free(cmd);
933 /* Server side of TOPIC command. Sets topic for channel and/or returns
934 current topic to client. */
936 SILC_SERVER_CMD_FUNC(topic)
938 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
939 SilcServer server = cmd->server;
940 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
941 SilcChannelID *channel_id;
942 SilcChannelEntry channel;
943 SilcChannelClientEntry chl;
946 SilcUInt32 argc, tmp_len;
947 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
949 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
952 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_TOPIC, cmd, 1, 2);
954 argc = silc_argument_get_arg_num(cmd->args);
957 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
959 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
960 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
963 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
965 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
966 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
970 /* Check whether the channel exists */
971 channel = silc_idlist_find_channel_by_id(server->local_list,
974 channel = silc_idlist_find_channel_by_id(server->global_list,
977 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
978 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
986 tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
988 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
989 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
994 if (strlen(tmp) > 256) {
995 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
996 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1001 if (!silc_utf8_valid(tmp, strlen(tmp))) {
1002 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
1003 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1008 /* See whether the client is on channel and has rights to change topic */
1009 if (!silc_server_client_on_channel(client, channel, &chl)) {
1010 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1011 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
1012 SILC_STATUS_ERR_NOT_ON_CHANNEL,
1013 0, 2, tmp, tmp_len);
1017 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
1018 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1019 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1020 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1021 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
1022 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
1023 0, 2, tmp, tmp_len);
1027 if (!channel->topic || strcmp(channel->topic, tmp)) {
1028 /* Set the topic for channel */
1029 silc_free(channel->topic);
1030 channel->topic = strdup(tmp);
1032 /* Send TOPIC_SET notify type to the network */
1033 silc_server_send_notify_topic_set(server, SILC_PRIMARY_ROUTE(server),
1034 SILC_BROADCAST(server), channel,
1035 client->id, SILC_ID_CLIENT,
1038 /* Send notify about topic change to all clients on the channel */
1039 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
1040 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
1041 SILC_NOTIFY_TYPE_TOPIC_SET, 2,
1042 idp->data, idp->len,
1044 strlen(channel->topic));
1045 silc_buffer_free(idp);
1049 /* Send the topic to client as reply packet */
1050 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
1051 silc_server_send_command_reply(cmd->server, cmd->sock, SILC_COMMAND_TOPIC,
1052 SILC_STATUS_OK, 0, ident, 2,
1053 2, idp->data, idp->len,
1056 strlen(channel->topic) : 0);
1057 silc_buffer_free(idp);
1058 silc_free(channel_id);
1061 silc_server_command_free(cmd);
1064 /* Server side of INVITE command. Invites some client to join some channel.
1065 This command is also used to manage the invite list of the channel. */
1067 SILC_SERVER_CMD_FUNC(invite)
1069 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1070 SilcServer server = cmd->server;
1071 SilcSocketConnection sock = cmd->sock, dest_sock;
1072 SilcChannelClientEntry chl;
1073 SilcClientEntry sender, dest;
1074 SilcClientID *dest_id = NULL;
1075 SilcChannelEntry channel;
1076 SilcChannelID *channel_id = NULL;
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, type, len2;
1084 SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
1086 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INVITE, cmd, 1, 4);
1088 /* Get Channel ID */
1089 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1091 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1092 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
1095 channel_id = silc_id_payload_parse_id(tmp, len, NULL);
1097 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1098 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
1102 /* Get the channel entry */
1103 channel = silc_idlist_find_channel_by_id(server->local_list,
1106 channel = silc_idlist_find_channel_by_id(server->global_list,
1109 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1110 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
1116 /* Check whether the sender of this command is on the channel. */
1117 sender = (SilcClientEntry)sock->user_data;
1118 if (!sender || !silc_server_client_on_channel(sender, channel, &chl)) {
1119 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1120 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
1125 /* Check whether the channel is invite-only channel. If yes then the
1126 sender of this command must be at least channel operator. */
1127 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
1128 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1129 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1130 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1131 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
1136 /* Get destination client ID */
1137 tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
1141 dest_id = silc_id_payload_parse_id(tmp, len, NULL);
1143 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1144 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
1148 /* Get the client entry */
1149 dest = silc_server_query_client(server, dest_id, FALSE, &resolve);
1151 if (server->server_type != SILC_SERVER || !resolve || cmd->pending) {
1152 silc_server_command_send_status_data(
1153 cmd, SILC_COMMAND_INVITE,
1154 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1159 /* The client info is being resolved. Reprocess this packet after
1160 receiving the reply to the query. */
1161 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
1163 silc_server_command_invite,
1164 silc_server_command_dup(cmd));
1165 cmd->pending = TRUE;
1169 /* Check whether the requested client is already on the channel. */
1170 if (silc_server_client_on_channel(dest, channel, NULL)) {
1171 atype = silc_argument_get_arg_type(cmd->args, 1, &len2);
1172 silc_server_command_send_status_data2(cmd, SILC_COMMAND_INVITE,
1173 SILC_STATUS_ERR_USER_ON_CHANNEL,
1179 /* Get route to the client */
1180 dest_sock = silc_server_get_client_route(server, NULL, 0, dest_id,
1183 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1184 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1189 /* Add the client to the invite list */
1191 /* Allocate hash table for invite list if it doesn't exist yet */
1192 if (!channel->invite_list)
1193 channel->invite_list =
1194 silc_hash_table_alloc(0, silc_hash_ptr,
1196 silc_server_inviteban_destruct, channel, TRUE);
1198 /* Check if the ID is in the list already */
1199 silc_hash_table_list(channel->invite_list, &htl);
1200 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
1201 if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
1206 silc_hash_table_list_reset(&htl);
1208 /* Add new Client ID to invite list */
1210 list = silc_buffer_alloc_size(len);
1211 silc_buffer_put(list, tmp, len);
1212 silc_hash_table_add(channel->invite_list, (void *)3, list);
1215 if (!(dest->mode & SILC_UMODE_BLOCK_INVITE)) {
1216 /* Send notify to the client that is invited to the channel */
1217 SilcBuffer idp, idp2;
1218 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
1219 idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
1220 silc_server_send_notify_dest(server, dest_sock, FALSE, dest_id,
1222 SILC_NOTIFY_TYPE_INVITE, 3,
1223 idp->data, idp->len,
1224 channel->channel_name,
1225 strlen(channel->channel_name),
1226 idp2->data, idp2->len);
1227 silc_buffer_free(idp);
1228 silc_buffer_free(idp2);
1232 /* Get the invite information */
1233 tmp = silc_argument_get_arg_type(cmd->args, 4, &len2);
1234 if (tmp && len2 > 2) {
1235 /* Parse the arguments to see they are constructed correctly */
1236 SILC_GET16_MSB(argc, tmp);
1237 args = silc_argument_payload_parse(tmp + 2, len2 - 2, argc);
1239 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1240 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1245 /* Get the type of action */
1246 atype = silc_argument_get_arg_type(cmd->args, 3, &len);
1247 if (atype && len == 1) {
1248 if (atype[0] == 0x00) {
1249 /* Allocate hash table for invite list if it doesn't exist yet */
1250 if (!channel->invite_list)
1251 channel->invite_list =
1252 silc_hash_table_alloc(0, silc_hash_ptr,
1254 silc_server_inviteban_destruct, channel,
1257 /* Check for resource limit */
1258 if (silc_hash_table_count(channel->invite_list) > 64) {
1259 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1260 SILC_STATUS_ERR_RESOURCE_LIMIT,
1266 /* Now add or delete the information. */
1267 if (!silc_server_inviteban_process(server, channel->invite_list,
1268 (SilcUInt8)atype[0], args)) {
1269 silc_server_command_send_status_reply(
1270 cmd, SILC_COMMAND_INVITE,
1271 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1276 silc_argument_payload_free(args);
1279 /* Encode invite list */
1281 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
1282 list = silc_buffer_alloc_size(2);
1283 silc_buffer_format(list,
1284 SILC_STR_UI_SHORT(silc_hash_table_count(
1285 channel->invite_list)),
1287 silc_hash_table_list(channel->invite_list, &htl);
1288 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
1289 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
1291 silc_hash_table_list_reset(&htl);
1294 /* The notify is sent to local servers (not clients), and to network. */
1295 if (atype && tmp && len2) {
1296 silc_buffer_set(&alist, tmp, len2);
1298 /* Send to local servers if we are router */
1299 if (server->server_type == SILC_ROUTER) {
1300 SilcBuffer idp, idp2;
1301 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
1302 idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
1303 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
1304 SILC_NOTIFY_TYPE_INVITE, 5,
1305 idp->data, idp->len,
1306 channel->channel_name,
1307 strlen(channel->channel_name),
1308 idp2->data, idp2->len,
1310 tmp ? alist.data : NULL,
1311 tmp ? alist.len : 0);
1312 silc_buffer_free(idp);
1313 silc_buffer_free(idp2);
1316 /* Send to network */
1317 silc_server_send_notify_invite(server, SILC_PRIMARY_ROUTE(server),
1318 SILC_BROADCAST(server), channel,
1320 tmp ? &alist : NULL);
1323 /* Send invite list back only if the list was modified, or no arguments
1326 argc = silc_argument_get_arg_num(cmd->args);
1329 if (silc_argument_get_arg_type(cmd->args, 3, &len))
1332 /* Send command reply */
1333 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1334 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_INVITE,
1335 SILC_STATUS_OK, 0, ident, 2,
1339 type && list ? list->len : 0);
1340 silc_buffer_free(list);
1344 silc_free(channel_id);
1345 silc_server_command_free(cmd);
1349 SilcSocketConnection sock;
1353 /* Quits connection to client. This gets called if client won't
1354 close the connection even when it has issued QUIT command. */
1356 SILC_TASK_CALLBACK(silc_server_command_quit_cb)
1358 SilcServer server = app_context;
1359 QuitInternal q = (QuitInternal)context;
1361 if (q->sock->user_data) {
1362 /* Free all client specific data, such as client entry and entires
1363 on channels this client may be on. */
1364 silc_server_free_client_data(server, q->sock, q->sock->user_data,
1366 q->sock->user_data = NULL;
1369 if (!SILC_IS_DISCONNECTED(q->sock))
1370 /* Close the connection on our side */
1371 silc_server_close_connection(server, q->sock);
1373 silc_socket_free(q->sock);
1374 silc_free(q->signoff);
1378 /* Quits SILC session. This is the normal way to disconnect client. */
1380 SILC_SERVER_CMD_FUNC(quit)
1382 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1383 SilcServer server = cmd->server;
1384 SilcSocketConnection sock = cmd->sock;
1386 unsigned char *tmp = NULL;
1389 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_QUIT, cmd, 0, 1);
1391 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
1395 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1399 q = silc_calloc(1, sizeof(*q));
1400 q->sock = silc_socket_dup(sock);
1401 q->signoff = tmp ? strdup(tmp) : NULL;
1403 /* We quit the connection with little timeout */
1404 silc_schedule_task_add(server->schedule, sock->sock,
1405 silc_server_command_quit_cb, (void *)q,
1406 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
1409 silc_server_command_free(cmd);
1412 /* Server side of command KILL. This command is used by router operator
1413 to remove an client from the SILC Network temporarily. */
1415 SILC_SERVER_CMD_FUNC(kill)
1417 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1418 SilcServer server = cmd->server;
1419 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
1420 SilcClientEntry remote_client;
1421 SilcClientID *client_id = NULL;
1422 unsigned char *tmp, *comment, *auth;
1423 SilcUInt32 tmp_len, tmp_len2, auth_len;
1425 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 3);
1427 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
1430 /* Get authentication payload if present */
1431 auth = silc_argument_get_arg_type(cmd->args, 3, &auth_len);
1434 /* Router operator killing */
1436 /* KILL command works only on router */
1437 if (server->server_type != SILC_ROUTER) {
1438 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1439 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
1443 /* Check whether client has the permissions. */
1444 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1445 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1446 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
1451 /* Get the client ID */
1452 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1454 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1455 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1459 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1461 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1462 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1463 0, 2, tmp, tmp_len);
1467 /* Get the client entry */
1468 remote_client = silc_idlist_find_client_by_id(server->local_list,
1469 client_id, TRUE, NULL);
1470 if (!remote_client) {
1471 remote_client = silc_idlist_find_client_by_id(server->global_list,
1472 client_id, TRUE, NULL);
1473 if (!remote_client) {
1474 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1475 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1476 0, 2, tmp, tmp_len);
1482 comment = silc_argument_get_arg_type(cmd->args, 2, &tmp_len2);
1483 if (comment && tmp_len2 > 128) {
1485 comment[127] = '\0';
1488 /* If authentication data is provided then verify that killing is
1490 if (auth && auth_len) {
1491 SilcSocketConnection sock;
1493 if (!SILC_IS_LOCAL(remote_client) || !remote_client->data.public_key) {
1494 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1495 SILC_STATUS_ERR_OPERATION_ALLOWED,
1500 /* Verify the signature */
1501 if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
1502 remote_client->data.public_key, 0,
1503 server->sha1hash, remote_client->id,
1505 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1506 SILC_STATUS_ERR_AUTH_FAILED, 0);
1510 /* Send reply to the sender */
1511 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1515 /* Do normal signoff for the destination client */
1516 sock = remote_client->connection;
1517 silc_server_remove_from_channels(server, NULL, remote_client,
1518 TRUE, (char *)"Killed", TRUE, TRUE);
1519 silc_server_free_client_data(server, NULL, remote_client, TRUE,
1521 (unsigned char *)"Killed");
1523 silc_server_close_connection(server, sock);
1525 /* Router operator killing */
1527 /* Send reply to the sender */
1528 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1532 /* Check if anyone is watching this nickname */
1533 if (server->server_type == SILC_ROUTER)
1534 silc_server_check_watcher_list(server, client, NULL,
1535 SILC_NOTIFY_TYPE_KILLED);
1537 /* Now do the killing */
1538 silc_server_kill_client(server, remote_client, comment, client->id,
1543 silc_free(client_id);
1544 silc_server_command_free(cmd);
1547 /* Server side of command INFO. This sends information about us to
1548 the client. If client requested specific server we will send the
1549 command to that server. */
1551 SILC_SERVER_CMD_FUNC(info)
1553 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1554 SilcServer server = cmd->server;
1558 char *dest_server = NULL, *server_info = NULL, *server_name;
1559 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1560 SilcServerEntry entry = NULL;
1561 SilcServerID *server_id = NULL;
1563 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INFO, cmd, 0, 2);
1565 /* Get server name */
1566 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
1568 /* Check server name. */
1569 dest_server = silc_identifier_check(dest_server, strlen(dest_server),
1570 SILC_STRING_UTF8, 256, &tmp_len);
1572 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
1573 SILC_STATUS_ERR_BAD_SERVER, 0);
1579 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
1581 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1583 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
1584 SILC_STATUS_ERR_NO_SERVER_ID, 0);
1590 /* Check whether we have this server cached */
1591 entry = silc_idlist_find_server_by_id(server->local_list,
1592 server_id, TRUE, NULL);
1594 entry = silc_idlist_find_server_by_id(server->global_list,
1595 server_id, TRUE, NULL);
1596 if (!entry && server->server_type != SILC_SERVER) {
1597 silc_server_command_send_status_data(cmd, SILC_COMMAND_INFO,
1598 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
1599 0, 2, tmp, tmp_len);
1605 /* Some buggy servers has sent request to router about themselves. */
1606 if (server->server_type != SILC_SERVER && cmd->sock->user_data == entry)
1609 if ((!dest_server && !server_id && !entry) || (entry &&
1610 entry == server->id_entry) ||
1611 (dest_server && !cmd->pending &&
1612 !memcmp(dest_server, server->server_name, strlen(dest_server)))) {
1613 /* Send our reply */
1614 char info_string[256];
1616 memset(info_string, 0, sizeof(info_string));
1617 snprintf(info_string, sizeof(info_string),
1618 "location: %s server: %s admin: %s <%s>",
1619 server->config->server_info->location,
1620 server->config->server_info->server_type,
1621 server->config->server_info->admin,
1622 server->config->server_info->email);
1624 server_info = info_string;
1625 entry = server->id_entry;
1627 /* Check whether we have this server cached */
1628 if (!entry && dest_server) {
1629 entry = silc_idlist_find_server_by_name(server->global_list,
1630 dest_server, TRUE, NULL);
1632 entry = silc_idlist_find_server_by_name(server->local_list,
1633 dest_server, TRUE, NULL);
1637 if (!cmd->pending &&
1638 server->server_type != SILC_SERVER && entry && !entry->server_info) {
1639 /* Send to the server */
1641 SilcUInt16 old_ident;
1644 cmd->server->stat.commands_sent++;
1646 old_ident = silc_command_get_ident(cmd->payload);
1647 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1648 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1650 silc_server_packet_send(server, entry->connection,
1651 SILC_PACKET_COMMAND, cmd->packet->flags,
1652 tmpbuf->data, tmpbuf->len, TRUE);
1654 /* Reprocess this packet after received reply from router */
1655 silc_server_command_pending(server, SILC_COMMAND_INFO,
1656 silc_command_get_ident(cmd->payload),
1657 silc_server_command_info,
1658 silc_server_command_dup(cmd));
1659 cmd->pending = TRUE;
1660 silc_command_set_ident(cmd->payload, old_ident);
1661 silc_buffer_free(tmpbuf);
1665 if (!entry && !cmd->pending && !server->standalone) {
1666 /* Send to the primary router */
1668 SilcUInt16 old_ident;
1671 cmd->server->stat.commands_sent++;
1673 old_ident = silc_command_get_ident(cmd->payload);
1674 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1675 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1677 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
1678 SILC_PACKET_COMMAND, cmd->packet->flags,
1679 tmpbuf->data, tmpbuf->len, TRUE);
1681 /* Reprocess this packet after received reply from router */
1682 silc_server_command_pending(server, SILC_COMMAND_INFO,
1683 silc_command_get_ident(cmd->payload),
1684 silc_server_command_info,
1685 silc_server_command_dup(cmd));
1686 cmd->pending = TRUE;
1687 silc_command_set_ident(cmd->payload, old_ident);
1688 silc_buffer_free(tmpbuf);
1693 silc_free(server_id);
1697 silc_free(dest_server);
1698 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
1699 silc_server_command_send_status_data(cmd, SILC_COMMAND_INFO,
1700 SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
1702 strlen(dest_server));
1708 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
1710 server_info = entry->server_info;
1711 server_name = entry->server_name;
1713 /* Send the reply */
1714 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_INFO,
1715 SILC_STATUS_OK, 0, ident, 3,
1716 2, idp->data, idp->len,
1718 strlen(server_name),
1721 strlen(server_info) : 0);
1722 silc_buffer_free(idp);
1725 silc_free(dest_server);
1726 silc_server_command_free(cmd);
1729 /* Server side of command PING. This just replies to the ping. */
1731 SILC_SERVER_CMD_FUNC(ping)
1733 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1734 SilcServer server = cmd->server;
1737 SilcServerID *server_id = NULL;
1739 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PING, cmd, 1, 1);
1742 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1744 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
1745 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1749 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1753 if (SILC_ID_SERVER_COMPARE(server_id, server->id)) {
1754 /* Send our reply */
1755 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
1758 silc_server_command_send_status_data(cmd, SILC_COMMAND_PING,
1759 SILC_STATUS_ERR_NO_SUCH_SERVER_ID, 0,
1765 silc_free(server_id);
1766 silc_server_command_free(cmd);
1769 /* Server side of command STATS. */
1771 SILC_SERVER_CMD_FUNC(stats)
1773 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1774 SilcServer server = cmd->server;
1775 SilcServerID *server_id;
1778 SilcBuffer packet, stats;
1779 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1782 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_STATS, cmd, 1, 1);
1785 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1787 silc_server_command_send_status_reply(cmd, SILC_COMMAND_STATS,
1788 SILC_STATUS_ERR_NO_SERVER_ID, 0);
1791 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1795 /* The ID must be ours */
1796 if (!SILC_ID_SERVER_COMPARE(server->id, server_id)) {
1797 silc_server_command_send_status_data(cmd, SILC_COMMAND_STATS,
1798 SILC_STATUS_ERR_NO_SUCH_SERVER_ID, 0,
1800 silc_free(server_id);
1803 silc_free(server_id);
1805 /* If we are router then just send everything we got. If we are normal
1806 server then we'll send this to our router to get all the latest
1807 statistical information. */
1808 if (!cmd->pending && server->server_type != SILC_ROUTER &&
1809 !server->standalone) {
1813 cmd->server->stat.commands_sent++;
1815 /* Send request to our router */
1816 idp = silc_id_payload_encode(server->router->id,
1818 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
1819 ++server->cmd_ident, 1,
1820 1, idp->data, idp->len);
1821 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
1822 SILC_PACKET_COMMAND, 0, packet->data,
1823 packet->len, FALSE);
1825 /* Reprocess this packet after received reply from router */
1826 silc_server_command_pending(server, SILC_COMMAND_STATS,
1828 silc_server_command_stats,
1829 silc_server_command_dup(cmd));
1830 cmd->pending = TRUE;
1831 silc_buffer_free(packet);
1832 silc_buffer_free(idp);
1836 /* Send our reply to sender */
1837 uptime = time(NULL) - server->starttime;
1839 stats = silc_buffer_alloc_size(60);
1840 silc_buffer_format(stats,
1841 SILC_STR_UI_INT(server->starttime),
1842 SILC_STR_UI_INT(uptime),
1843 SILC_STR_UI_INT(server->stat.my_clients),
1844 SILC_STR_UI_INT(server->stat.my_channels),
1845 SILC_STR_UI_INT(server->stat.my_server_ops),
1846 SILC_STR_UI_INT(server->stat.my_router_ops),
1847 SILC_STR_UI_INT(server->stat.cell_clients),
1848 SILC_STR_UI_INT(server->stat.cell_channels),
1849 SILC_STR_UI_INT(server->stat.cell_servers),
1850 SILC_STR_UI_INT(server->stat.clients),
1851 SILC_STR_UI_INT(server->stat.channels),
1852 SILC_STR_UI_INT(server->stat.servers),
1853 SILC_STR_UI_INT(server->stat.routers),
1854 SILC_STR_UI_INT(server->stat.server_ops),
1855 SILC_STR_UI_INT(server->stat.router_ops),
1858 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_STATS,
1859 SILC_STATUS_OK, 0, ident, 2,
1861 3, stats->data, stats->len);
1862 silc_buffer_free(stats);
1865 silc_server_command_free(cmd);
1868 /* Internal routine to join channel. The channel sent to this function
1869 has been either created or resolved from ID lists. This joins the sent
1870 client to the channel. */
1872 static void silc_server_command_join_channel(SilcServer server,
1873 SilcServerCommandContext cmd,
1874 SilcChannelEntry channel,
1875 SilcClientID *client_id,
1879 const unsigned char *auth,
1880 SilcUInt32 auth_len,
1881 const unsigned char *cauth,
1882 SilcUInt32 cauth_len)
1884 SilcSocketConnection sock = cmd->sock;
1886 SilcUInt32 tmp_len, user_count;
1887 unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4], ulimit[4];
1888 SilcClientEntry client;
1889 SilcChannelClientEntry chl;
1890 SilcBuffer reply, chidp, clidp, keyp = NULL;
1891 SilcBuffer user_list, mode_list, invite_list, ban_list;
1892 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1893 char check[512], check2[512];
1894 bool founder = FALSE;
1896 SilcBuffer fkey = NULL, chpklist = NULL;
1899 SILC_LOG_DEBUG(("Joining client to channel"));
1904 /* Get the client entry */
1905 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
1906 client = (SilcClientEntry)sock->user_data;
1910 client = silc_server_query_client(server, client_id, FALSE,
1913 if (!resolve || cmd->pending) {
1914 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
1915 silc_server_command_send_status_data(
1916 cmd, SILC_COMMAND_JOIN,
1917 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1922 /* The client info is being resolved. Reprocess this packet after
1923 receiving the reply to the query. */
1924 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
1926 silc_server_command_join,
1927 silc_server_command_dup(cmd));
1928 cmd->pending = TRUE;
1932 if (!client->data.public_key &&
1933 (auth || cauth || channel->ban_list ||
1934 (channel->mode & SILC_CHANNEL_MODE_INVITE))) {
1935 if (cmd->pending == 2)
1938 /* We must retrieve the client's public key by sending
1939 GETKEY command. Reprocess this packet after receiving the key */
1940 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1941 silc_server_send_command(server, cmd->sock,
1942 SILC_COMMAND_GETKEY, ++server->cmd_ident,
1943 1, 1, clidp->data, clidp->len);
1944 silc_buffer_free(clidp);
1945 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
1947 silc_server_command_join,
1948 silc_server_command_dup(cmd));
1953 cmd->pending = FALSE;
1957 * Check founder auth payload if provided. If client can gain founder
1958 * privileges it can override various conditions on joining the channel,
1959 * and can have directly the founder mode set on the channel.
1961 if (auth && auth_len && channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1962 SilcIDListData idata = (SilcIDListData)client;
1963 SilcChannelClientEntry chl2;
1964 SilcHashTableList htl;
1966 if (channel->founder_key && idata->public_key &&
1967 silc_pkcs_public_key_compare(channel->founder_key,
1968 idata->public_key)) {
1969 /* Check whether the client is to become founder */
1970 if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
1971 channel->founder_key, 0, server->sha1hash,
1972 client->id, SILC_ID_CLIENT)) {
1974 /* There cannot be anyone else as founder on the channel now. This
1975 client is definitely the founder due to this authentication */
1976 silc_hash_table_list(channel->user_list, &htl);
1977 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
1978 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
1979 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
1980 silc_server_force_cumode_change(server, NULL, channel, chl2,
1984 silc_hash_table_list_reset(&htl);
1986 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
1993 * Check channel modes
1997 memset(check, 0, sizeof(check));
1998 memset(check2, 0, sizeof(check2));
1999 silc_strncat(check, sizeof(check),
2000 client->nickname, strlen(client->nickname));
2001 silc_strncat(check, sizeof(check), "!", 1);
2002 silc_strncat(check, sizeof(check),
2003 client->username, strlen(client->username));
2004 if (!strchr(client->username, '@')) {
2005 silc_strncat(check, sizeof(check), "@", 1);
2006 silc_strncat(check, sizeof(check),
2007 cmd->sock->hostname, strlen(cmd->sock->hostname));
2010 silc_strncat(check2, sizeof(check2),
2011 client->nickname, strlen(client->nickname));
2012 if (!strchr(client->nickname, '@')) {
2013 silc_strncat(check2, sizeof(check2), "@", 1);
2014 silc_strncat(check2, sizeof(check2),
2015 SILC_IS_LOCAL(client) ? server->server_name :
2016 client->router->server_name,
2017 SILC_IS_LOCAL(client) ? strlen(server->server_name) :
2018 strlen(client->router->server_name));
2020 silc_strncat(check2, sizeof(check2), "!", 1);
2021 silc_strncat(check2, sizeof(check2),
2022 client->username, strlen(client->username));
2023 if (!strchr(client->username, '@')) {
2024 silc_strncat(check2, sizeof(check2), "@", 1);
2025 silc_strncat(check2, sizeof(check2),
2026 cmd->sock->hostname, strlen(cmd->sock->hostname));
2029 /* Check invite list if channel is invite-only channel */
2030 if (channel->mode & SILC_CHANNEL_MODE_INVITE) {
2031 if (!channel->invite_list ||
2032 !silc_hash_table_count(channel->invite_list) ||
2033 (!silc_server_inviteban_match(server, channel->invite_list,
2035 !silc_server_inviteban_match(server, channel->invite_list,
2036 2, client->data.public_key) &&
2037 !silc_server_inviteban_match(server, channel->invite_list,
2038 1, client->nickname) &&
2039 !silc_server_inviteban_match(server, channel->invite_list,
2041 !silc_server_inviteban_match(server, channel->invite_list,
2043 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2044 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2045 SILC_STATUS_ERR_NOT_INVITED, 0,
2046 2, chidp->data, chidp->len);
2047 silc_buffer_free(chidp);
2052 /* Check ban list if it exists. If the client's nickname, server,
2053 username and/or hostname is in the ban list the access to the
2054 channel is denied. */
2055 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
2056 if (silc_server_inviteban_match(server, channel->ban_list,
2058 silc_server_inviteban_match(server, channel->ban_list,
2059 2, client->data.public_key) ||
2060 silc_server_inviteban_match(server, channel->ban_list,
2061 1, client->nickname) ||
2062 silc_server_inviteban_match(server, channel->ban_list,
2064 silc_server_inviteban_match(server, channel->ban_list,
2066 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2067 silc_server_command_send_status_data(
2068 cmd, SILC_COMMAND_JOIN,
2069 SILC_STATUS_ERR_BANNED_FROM_CHANNEL, 0,
2070 2, chidp->data, chidp->len);
2071 silc_buffer_free(chidp);
2076 /* Check user count limit if set. */
2077 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT) {
2078 if (silc_hash_table_count(channel->user_list) + 1 >
2079 channel->user_limit) {
2080 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2081 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2082 SILC_STATUS_ERR_CHANNEL_IS_FULL,
2083 0, 2, chidp->data, chidp->len);
2084 silc_buffer_free(chidp);
2090 /* Check the channel passphrase if set. */
2091 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
2092 /* Get passphrase */
2093 tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
2095 passphrase = silc_memdup(tmp, tmp_len);
2097 if (!passphrase || !channel->passphrase ||
2098 strlen(channel->passphrase) != strlen(passphrase) ||
2099 memcmp(passphrase, channel->passphrase, strlen(channel->passphrase))) {
2100 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2101 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2102 SILC_STATUS_ERR_BAD_PASSWORD, 0,
2103 2, chidp->data, chidp->len);
2104 silc_buffer_free(chidp);
2109 /* Verify channel authentication with channel public keys if set. */
2110 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
2111 if (!silc_server_verify_channel_auth(server, channel, client->id,
2112 cauth, cauth_len)) {
2113 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2114 SILC_STATUS_ERR_PERM_DENIED, 0);
2120 * Client is allowed to join to the channel. Make it happen.
2123 /* Check whether the client already is on the channel */
2124 if (silc_server_client_on_channel(client, channel, NULL)) {
2125 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
2126 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2127 silc_server_command_send_status_data2(cmd, SILC_COMMAND_JOIN,
2128 SILC_STATUS_ERR_USER_ON_CHANNEL, 0,
2129 2, clidp->data, clidp->len,
2130 3, chidp->data, chidp->len);
2131 silc_buffer_free(clidp);
2132 silc_buffer_free(chidp);
2136 /* Generate new channel key as protocol dictates */
2138 if (!silc_server_create_channel_key(server, channel, 0))
2141 /* Send the channel key. This is broadcasted to the channel but is not
2142 sent to the client who is joining to the channel. */
2143 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
2144 silc_server_send_channel_key(server, NULL, channel,
2145 server->server_type == SILC_ROUTER ?
2146 FALSE : !server->standalone);
2149 /* Join the client to the channel by adding it to channel's user list.
2150 Add also the channel to client entry's channels list for fast cross-
2152 chl = silc_calloc(1, sizeof(*chl));
2154 chl->client = client;
2155 chl->channel = channel;
2156 silc_hash_table_add(channel->user_list, client, chl);
2157 silc_hash_table_add(client->channels, channel, chl);
2158 channel->user_count++;
2159 channel->disabled = FALSE;
2161 /* Get users on the channel */
2162 silc_server_get_users_on_channel(server, channel, &user_list, &mode_list,
2165 /* Encode Client ID Payload of the original client who wants to join */
2166 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2168 /* Encode command reply packet */
2169 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2170 SILC_PUT32_MSB(channel->mode, mode);
2171 SILC_PUT32_MSB(created, tmp2);
2172 SILC_PUT32_MSB(user_count, tmp3);
2173 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2174 SILC_PUT32_MSB(channel->user_limit, ulimit);
2176 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2177 tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2178 cipher = silc_cipher_get_name(channel->channel_key);
2179 keyp = silc_channel_key_payload_encode(silc_id_get_len(channel->id,
2182 strlen(cipher), cipher,
2183 channel->key_len / 8, channel->key);
2187 if (channel->founder_key)
2188 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
2190 /* Encode invite list */
2192 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
2193 SilcHashTableList htl;
2195 invite_list = silc_buffer_alloc_size(2);
2196 silc_buffer_format(invite_list,
2197 SILC_STR_UI_SHORT(silc_hash_table_count(
2198 channel->invite_list)),
2201 silc_hash_table_list(channel->invite_list, &htl);
2202 while (silc_hash_table_get(&htl, (void *)&tmp_len, (void *)&reply))
2203 invite_list = silc_argument_payload_encode_one(invite_list,
2205 reply->len, tmp_len);
2206 silc_hash_table_list_reset(&htl);
2209 /* Encode ban list */
2211 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
2212 SilcHashTableList htl;
2214 ban_list = silc_buffer_alloc_size(2);
2215 silc_buffer_format(ban_list,
2216 SILC_STR_UI_SHORT(silc_hash_table_count(
2217 channel->ban_list)),
2220 silc_hash_table_list(channel->ban_list, &htl);
2221 while (silc_hash_table_get(&htl, (void *)&tmp_len, (void *)&reply))
2222 ban_list = silc_argument_payload_encode_one(ban_list,
2224 reply->len, tmp_len);
2225 silc_hash_table_list_reset(&htl);
2228 if (channel->channel_pubkeys)
2229 chpklist = silc_server_get_channel_pk_list(server, channel, FALSE, FALSE);
2232 silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
2233 SILC_STATUS_OK, 0, ident, 16,
2234 2, channel->channel_name,
2235 strlen(channel->channel_name),
2236 3, chidp->data, chidp->len,
2237 4, clidp->data, clidp->len,
2240 7, keyp ? keyp->data : NULL,
2241 keyp ? keyp->len : 0,
2242 8, ban_list ? ban_list->data : NULL,
2243 ban_list ? ban_list->len : 0,
2244 9, invite_list ? invite_list->data :
2246 invite_list ? invite_list->len : 0,
2249 strlen(channel->topic) : 0,
2250 11, silc_hmac_get_name(channel->hmac),
2251 strlen(silc_hmac_get_name(channel->
2254 13, user_list->data, user_list->len,
2255 14, mode_list->data,
2257 15, fkey ? fkey->data : NULL,
2258 fkey ? fkey->len : 0,
2259 16, chpklist ? chpklist->data : NULL,
2260 chpklist ? chpklist->len : 0,
2261 17, (channel->mode &
2262 SILC_CHANNEL_MODE_ULIMIT ?
2265 SILC_CHANNEL_MODE_ULIMIT ?
2266 sizeof(ulimit) : 0));
2268 /* Send command reply */
2269 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
2270 reply->data, reply->len, FALSE);
2273 cmd->server->stat.commands_sent++;
2275 /* Send JOIN notify to locally connected clients on the channel. If
2276 we are normal server then router will send or have sent JOIN notify
2277 already. However since we've added the client already to our channel
2278 we'll ignore it (in packet_receive.c) so we must send it here. If
2279 we are router then this will send it to local clients and local
2281 SILC_LOG_DEBUG(("Send JOIN notify to channel"));
2282 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2283 SILC_NOTIFY_TYPE_JOIN, 2,
2284 clidp->data, clidp->len,
2285 chidp->data, chidp->len);
2287 /* Update statistics */
2288 server->stat.my_chanclients++;
2289 if (server->server_type == SILC_ROUTER) {
2290 server->stat.cell_chanclients++;
2291 server->stat.chanclients++;
2294 if (!cmd->pending) {
2295 /* Send JOIN notify packet to our primary router */
2296 silc_server_send_notify_join(server, SILC_PRIMARY_ROUTE(server),
2297 SILC_BROADCAST(server), channel, client->id);
2300 /* Distribute the channel key to all backup routers. */
2301 silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
2302 keyp->data, keyp->len, FALSE, TRUE);
2304 /* If client became founder by providing correct founder auth data
2305 notify the mode change to the channel. */
2307 SILC_PUT32_MSB(chl->mode, mode);
2308 SILC_LOG_DEBUG(("Send CUMODE_CHANGE notify to channel"));
2309 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2310 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
2311 clidp->data, clidp->len,
2312 mode, 4, clidp->data, clidp->len,
2313 fkey ? fkey->data : NULL,
2314 fkey ? fkey->len : 0);
2318 /* Set CUMODE notify type to network */
2320 silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
2321 SILC_BROADCAST(server), channel,
2322 chl->mode, client->id, SILC_ID_CLIENT,
2323 client->id, channel->founder_key);
2325 silc_buffer_free(reply);
2326 silc_buffer_free(clidp);
2327 silc_buffer_free(chidp);
2328 silc_buffer_free(keyp);
2329 silc_buffer_free(user_list);
2330 silc_buffer_free(mode_list);
2331 silc_buffer_free(fkey);
2332 silc_buffer_free(chpklist);
2333 silc_buffer_free(invite_list);
2334 silc_buffer_free(ban_list);
2338 memset(passphrase, 0, strlen(passphrase));
2339 silc_free(passphrase);
2342 /* Server side of command JOIN. Joins client into requested channel. If
2343 the channel does not exist it will be created. */
2345 SILC_SERVER_CMD_FUNC(join)
2347 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2348 SilcServer server = cmd->server;
2349 unsigned char *auth, *cauth;
2350 SilcUInt32 tmp_len, auth_len, cauth_len;
2351 char *tmp, *channel_name, *channel_namec = NULL, *cipher, *hmac;
2352 SilcChannelEntry channel;
2353 SilcUInt32 umode = 0;
2354 bool created = FALSE, create_key = TRUE;
2355 SilcClientID *client_id;
2357 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_JOIN, cmd, 2, 7);
2359 /* Get channel name */
2360 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
2362 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2363 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2368 /* Truncate over long channel names */
2369 if (tmp_len > 256) {
2375 /* Check for valid channel name. This is cached, the original is saved
2376 in the channel context. */
2377 channel_namec = silc_channel_name_check(tmp, tmp_len, SILC_STRING_UTF8, 256,
2379 if (!channel_namec) {
2380 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2381 SILC_STATUS_ERR_BAD_CHANNEL, 0);
2385 /* Get Client ID of the client who is joining to the channel */
2386 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
2388 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2389 SILC_STATUS_ERR_NO_CLIENT_ID,
2393 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
2395 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2396 SILC_STATUS_ERR_BAD_CLIENT_ID, 0,
2401 /* Get cipher, hmac name and auth payload */
2402 cipher = silc_argument_get_arg_type(cmd->args, 4, NULL);
2403 hmac = silc_argument_get_arg_type(cmd->args, 5, NULL);
2404 auth = silc_argument_get_arg_type(cmd->args, 6, &auth_len);
2405 cauth = silc_argument_get_arg_type(cmd->args, 7, &cauth_len);
2407 /* See if the channel exists */
2408 channel = silc_idlist_find_channel_by_name(server->local_list,
2409 channel_namec, NULL);
2411 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
2412 SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
2414 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2415 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2420 #ifndef SILC_DIST_INPLACE
2421 /* Limit how many channels client can join */
2422 if (entry->channels && silc_hash_table_count(entry->channels) >=
2423 server->config->param.chlimit) {
2424 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2425 SILC_STATUS_ERR_RESOURCE_LIMIT,
2429 #endif /* SILC_DIST_INPLACE */
2431 silc_free(client_id);
2432 client_id = silc_id_dup(entry->id, SILC_ID_CLIENT);
2435 (channel->disabled && server->server_type != SILC_ROUTER)) {
2436 /* Channel not found or not valid */
2438 /* If we are standalone server we don't have a router, we just create
2439 the channel by ourselves (unless it existed). */
2440 if (server->standalone) {
2442 channel = silc_server_create_new_channel(server, server->id, cipher,
2443 hmac, channel_name, TRUE);
2445 silc_server_command_send_status_data(
2446 cmd, SILC_COMMAND_JOIN,
2447 SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
2448 0, 2, cipher, strlen(cipher));
2449 silc_free(client_id);
2453 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2459 /* The channel does not exist on our server. If we are normal server
2460 we will send JOIN command to our router which will handle the
2461 joining procedure (either creates the channel if it doesn't exist
2462 or joins the client to it). */
2463 if (server->server_type != SILC_ROUTER) {
2465 SilcUInt16 old_ident;
2467 /* If this is pending command callback then we've resolved
2468 it and it didn't work, return since we've notified the
2469 client already in the command reply callback. */
2471 silc_free(client_id);
2476 cmd->server->stat.commands_sent++;
2478 old_ident = silc_command_get_ident(cmd->payload);
2479 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2480 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2482 /* Send JOIN command to our router */
2483 silc_server_packet_send(server, (SilcSocketConnection)
2484 SILC_PRIMARY_ROUTE(server),
2485 SILC_PACKET_COMMAND, cmd->packet->flags,
2486 tmpbuf->data, tmpbuf->len, TRUE);
2488 /* Reprocess this packet after received reply from router */
2489 silc_server_command_pending(server, SILC_COMMAND_JOIN,
2490 silc_command_get_ident(cmd->payload),
2491 silc_server_command_join,
2492 silc_server_command_dup(cmd));
2493 cmd->pending = TRUE;
2494 silc_command_set_ident(cmd->payload, old_ident);
2495 silc_buffer_free(tmpbuf);
2496 silc_free(client_id);
2500 /* We are router and the channel does not seem exist so we will check
2501 our global list as well for the channel. */
2502 channel = silc_idlist_find_channel_by_name(server->global_list,
2503 channel_namec, NULL);
2505 /* Channel really does not exist, create it */
2506 channel = silc_server_create_new_channel(server, server->id, cipher,
2507 hmac, channel_name, TRUE);
2509 silc_server_command_send_status_data(
2510 cmd, SILC_COMMAND_JOIN,
2511 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
2512 2, cipher, strlen(cipher));
2513 silc_free(client_id);
2517 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2525 /* Channel not found */
2527 /* If the command came from router and we are normal server then
2528 something went wrong with the joining as the channel was not found.
2529 We can't do anything else but ignore this. */
2530 if (cmd->sock->type == SILC_SOCKET_TYPE_ROUTER ||
2531 server->server_type != SILC_ROUTER) {
2532 silc_free(client_id);
2536 /* We are router and the channel does not seem exist so we will check
2537 our global list as well for the channel. */
2538 channel = silc_idlist_find_channel_by_name(server->global_list,
2539 channel_namec, NULL);
2541 /* Channel really does not exist, create it */
2542 channel = silc_server_create_new_channel(server, server->id, cipher,
2543 hmac, channel_name, TRUE);
2545 silc_server_command_send_status_data(
2546 cmd, SILC_COMMAND_JOIN,
2547 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
2548 2, cipher, strlen(cipher));
2549 silc_free(client_id);
2553 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2560 /* Check whether the channel was created by our router */
2561 if (cmd->pending && context2) {
2562 SilcServerCommandReplyContext reply = context2;
2564 if (silc_command_get(reply->payload) == SILC_COMMAND_JOIN) {
2565 tmp = silc_argument_get_arg_type(reply->args, 6, NULL);
2566 SILC_GET32_MSB(created, tmp);
2567 if (silc_argument_get_arg_type(reply->args, 7, NULL))
2568 create_key = FALSE; /* Router returned the key already */
2570 if (silc_command_get_status(reply->payload, NULL, NULL) &&
2571 channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
2572 /* Save channel passphrase, if user provided it successfully */
2575 pa = silc_argument_get_arg_type(cmd->args, 3, &pa_len);
2577 silc_free(channel->passphrase);
2578 channel->passphrase = silc_memdup(pa, pa_len);
2583 if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
2584 !channel->disabled && !silc_hash_table_count(channel->user_list))
2588 /* If the channel does not have global users and is also empty the client
2589 will be the channel founder and operator. */
2590 if (!channel->disabled &&
2591 !channel->global_users && !silc_hash_table_count(channel->user_list))
2592 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2594 /* Join to the channel */
2595 silc_server_command_join_channel(server, cmd, channel, client_id,
2596 created, create_key, umode,
2597 auth, auth_len, cauth, cauth_len);
2599 silc_free(client_id);
2602 silc_free(channel_namec);
2603 silc_server_command_free(cmd);
2606 /* Server side of command MOTD. Sends server's current "message of the
2607 day" to the client. */
2609 SILC_SERVER_CMD_FUNC(motd)
2611 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2612 SilcServer server = cmd->server;
2614 char *motd, *dest_server = NULL;
2615 SilcUInt32 motd_len;
2616 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2618 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_MOTD, cmd, 1, 1);
2620 /* Get server name */
2621 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2623 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
2624 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2629 /* Check server name */
2630 dest_server = silc_identifier_check(dest_server, strlen(dest_server),
2631 SILC_STRING_UTF8, 256, NULL);
2633 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
2634 SILC_STATUS_ERR_BAD_SERVER,
2639 if (!memcmp(dest_server, server->server_name, strlen(dest_server))) {
2642 idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
2644 if (server->config && server->config->server_info &&
2645 server->config->server_info->motd_file) {
2647 motd = silc_file_readfile(server->config->server_info->motd_file,
2651 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_MOTD,
2652 SILC_STATUS_OK, 0, ident, 1,
2653 2, idp->data, idp->len);
2658 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_MOTD,
2659 SILC_STATUS_OK, 0, ident, 2,
2660 2, idp->data, idp->len,
2664 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_MOTD,
2665 SILC_STATUS_OK, 0, ident, 1,
2666 2, idp->data, idp->len);
2668 silc_buffer_free(idp);
2670 SilcServerEntry entry;
2672 /* Check whether we have this server cached */
2673 entry = silc_idlist_find_server_by_name(server->global_list,
2674 dest_server, TRUE, NULL);
2676 entry = silc_idlist_find_server_by_name(server->local_list,
2677 dest_server, TRUE, NULL);
2680 if (server->server_type != SILC_SERVER && !cmd->pending &&
2681 entry && !entry->motd) {
2682 /* Send to the server */
2684 SilcUInt16 old_ident;
2687 cmd->server->stat.commands_sent++;
2689 old_ident = silc_command_get_ident(cmd->payload);
2690 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2691 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2693 silc_server_packet_send(server, entry->connection,
2694 SILC_PACKET_COMMAND, cmd->packet->flags,
2695 tmpbuf->data, tmpbuf->len, TRUE);
2697 /* Reprocess this packet after received reply from router */
2698 silc_server_command_pending(server, SILC_COMMAND_MOTD,
2699 silc_command_get_ident(cmd->payload),
2700 silc_server_command_motd,
2701 silc_server_command_dup(cmd));
2702 cmd->pending = TRUE;
2703 silc_command_set_ident(cmd->payload, old_ident);
2704 silc_buffer_free(tmpbuf);
2708 /* Send to primary router only if we don't know the server
2709 * the client requested or if the server is not locally connected */
2710 if ((!entry || !(entry->data.status & SILC_IDLIST_STATUS_LOCAL))
2711 && !cmd->pending && !server->standalone) {
2712 /* Send to the primary router */
2714 SilcUInt16 old_ident;
2717 cmd->server->stat.commands_sent++;
2719 old_ident = silc_command_get_ident(cmd->payload);
2720 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2721 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2723 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2724 SILC_PACKET_COMMAND, cmd->packet->flags,
2725 tmpbuf->data, tmpbuf->len, TRUE);
2727 /* Reprocess this packet after received reply from router */
2728 silc_server_command_pending(server, SILC_COMMAND_MOTD,
2729 silc_command_get_ident(cmd->payload),
2730 silc_server_command_motd,
2731 silc_server_command_dup(cmd));
2732 cmd->pending = TRUE;
2733 silc_command_set_ident(cmd->payload, old_ident);
2734 silc_buffer_free(tmpbuf);
2739 silc_free(dest_server);
2740 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2741 silc_server_command_send_status_data(cmd, SILC_COMMAND_MOTD,
2742 SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
2744 strlen(dest_server));
2749 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
2750 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_MOTD,
2751 SILC_STATUS_OK, 0, ident, 2,
2752 2, idp->data, idp->len,
2755 strlen(entry->motd) : 0);
2756 silc_buffer_free(idp);
2760 silc_free(dest_server);
2761 silc_server_command_free(cmd);
2764 /* Server side of command UMODE. Client can use this command to set/unset
2765 user mode. Client actually cannot set itself to be as server/router
2766 operator so this can be used only to unset the modes. */
2768 SILC_SERVER_CMD_FUNC(umode)
2770 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2771 SilcServer server = cmd->server;
2772 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2773 unsigned char *tmp_mask, m[4];
2774 SilcUInt32 mask = 0;
2775 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2776 bool set_mask = FALSE;
2778 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
2781 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_UMODE, cmd, 1, 2);
2783 /* Get the client's mode mask */
2784 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
2786 SILC_GET32_MSB(mask, tmp_mask);
2791 /* Check that mode changing is allowed. */
2792 if (!silc_server_check_umode_rights(server, client, mask)) {
2793 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
2794 SILC_STATUS_ERR_PERM_DENIED, 0);
2798 /* Anonymous mode cannot be set by client */
2799 if (mask & SILC_UMODE_ANONYMOUS &&
2800 !(client->mode & SILC_UMODE_ANONYMOUS)) {
2801 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
2802 SILC_STATUS_ERR_PERM_DENIED, 0);
2806 /* Update statistics */
2807 if (mask & SILC_UMODE_GONE) {
2808 if (!(client->mode & SILC_UMODE_GONE))
2809 server->stat.my_aways++;
2811 if (client->mode & SILC_UMODE_GONE)
2812 server->stat.my_aways--;
2815 /* If the client has anonymous mode set, preserve it. */
2816 if (client->mode & SILC_UMODE_ANONYMOUS)
2817 mask |= SILC_UMODE_ANONYMOUS;
2819 /* Change the mode */
2820 client->mode = mask;
2822 /* Send UMODE change to primary router */
2823 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
2824 SILC_BROADCAST(server), client->id,
2827 /* Check if anyone is watching this nickname */
2828 if (server->server_type == SILC_ROUTER)
2829 silc_server_check_watcher_list(server, client, NULL,
2830 SILC_NOTIFY_TYPE_UMODE_CHANGE);
2833 /* Send command reply to sender */
2834 SILC_PUT32_MSB(client->mode, m);
2835 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_UMODE,
2836 SILC_STATUS_OK, 0, ident, 1,
2840 silc_server_command_free(cmd);
2843 /* Server side command of CMODE. Changes channel mode */
2845 SILC_SERVER_CMD_FUNC(cmode)
2847 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2848 SilcServer server = cmd->server;
2849 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2850 SilcIDListData idata = (SilcIDListData)client;
2851 SilcChannelID *channel_id = NULL;
2852 SilcChannelEntry channel;
2853 SilcChannelClientEntry chl;
2855 unsigned char *tmp, *tmp_id, *tmp_mask, *chpkdata = NULL;
2856 char *cipher = NULL, *hmac = NULL, *passphrase = NULL, ulimit[4];
2857 SilcUInt32 mode_mask = 0, old_mask = 0, tmp_len, tmp_len2, chpklen;
2858 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2859 bool set_mask = FALSE, set_chpk = FALSE;
2860 SilcPublicKey founder_key = NULL;
2861 SilcBuffer fkey = NULL, chpklist = NULL;
2862 SilcBufferStruct chpk;
2865 silc_server_command_free(cmd);
2869 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 9);
2871 /* Get Channel ID */
2872 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
2874 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2875 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2876 silc_server_command_free(cmd);
2879 channel_id = silc_id_payload_parse_id(tmp_id, tmp_len2, NULL);
2881 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2882 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2883 silc_server_command_free(cmd);
2887 /* Get channel entry */
2888 channel = silc_idlist_find_channel_by_id(server->local_list,
2891 channel = silc_idlist_find_channel_by_id(server->global_list,
2894 silc_server_command_send_status_data(cmd, SILC_COMMAND_CMODE,
2895 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
2896 0, 2, tmp_id, tmp_len2);
2897 silc_free(channel_id);
2898 silc_server_command_free(cmd);
2902 old_mask = channel->mode;
2904 /* Get the channel mode mask */
2905 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
2907 SILC_GET32_MSB(mode_mask, tmp_mask);
2911 /* Check whether this client is on the channel */
2912 if (!silc_server_client_on_channel(client, channel, &chl)) {
2913 silc_server_command_send_status_data(cmd, SILC_COMMAND_CMODE,
2914 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
2915 2, tmp_id, tmp_len2);
2919 /* Check that client has rights to change any requested channel modes */
2920 if (set_mask && !silc_server_check_cmode_rights(server, channel, chl,
2922 SILC_LOG_DEBUG(("Client does not have rights to change mode"));
2923 silc_server_command_send_status_data(
2924 cmd, SILC_COMMAND_CMODE,
2925 (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) ?
2926 SILC_STATUS_ERR_NO_CHANNEL_PRIV :
2927 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV), 0,
2928 2, tmp_id, tmp_len2);
2932 /* If mode mask was not sent as argument then merely return the current
2933 mode mask, founder key and channel public key list to the sender. */
2936 SILC_PUT32_MSB(channel->mode, m);
2937 if (channel->founder_key)
2938 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
2939 if (channel->channel_pubkeys)
2940 chpklist = silc_server_get_channel_pk_list(server, channel,
2942 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_CMODE,
2943 SILC_STATUS_OK, 0, ident, 4,
2944 2, tmp_id, tmp_len2,
2946 4, fkey ? fkey->data : NULL,
2947 fkey ? fkey->len : 0,
2948 5, chpklist ? chpklist->data : NULL,
2949 chpklist ? chpklist->len : 0);
2954 * Check the modes. Modes that requires nothing special operation are
2958 if (mode_mask & SILC_CHANNEL_MODE_PRIVKEY) {
2959 /* Channel uses private keys to protect traffic. Client(s) has set the
2960 key locally they want to use, server does not know that key. */
2961 /* Nothing interesting to do here */
2963 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
2964 /* The mode is removed and we need to generate and distribute
2965 new channel key. Clients are not using private channel keys
2966 anymore after this. */
2968 /* Re-generate channel key */
2969 if (!silc_server_create_channel_key(server, channel, 0))
2972 /* Send the channel key. This sends it to our local clients and if
2973 we are normal server to our router as well. */
2974 silc_server_send_channel_key(server, NULL, channel,
2975 server->server_type == SILC_ROUTER ?
2976 FALSE : !server->standalone);
2978 cipher = (char *)silc_cipher_get_name(channel->channel_key);
2979 hmac = (char *)silc_hmac_get_name(channel->hmac);
2983 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT) {
2984 /* User limit is set on channel */
2985 SilcUInt32 user_limit;
2987 /* Get user limit */
2988 tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
2990 if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT)) {
2991 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2992 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
2996 SILC_GET32_MSB(user_limit, tmp);
2997 channel->user_limit = user_limit;
3000 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
3001 /* User limit mode is unset. Remove user limit */
3002 channel->user_limit = 0;
3005 if (mode_mask & SILC_CHANNEL_MODE_PASSPHRASE) {
3006 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
3007 /* Passphrase has been set to channel */
3009 /* Get the passphrase */
3010 tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
3012 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3013 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3017 /* Save the passphrase */
3018 passphrase = channel->passphrase = silc_memdup(tmp, strlen(tmp));
3021 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
3022 /* Passphrase mode is unset. remove the passphrase */
3023 silc_free(channel->passphrase);
3024 channel->passphrase = NULL;
3028 if (mode_mask & SILC_CHANNEL_MODE_CIPHER) {
3029 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
3030 /* Cipher to use protect the traffic */
3031 SilcCipher newkey, oldkey;
3034 cipher = silc_argument_get_arg_type(cmd->args, 5, NULL);
3036 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3037 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3041 /* Delete old cipher and allocate the new one */
3042 if (!silc_cipher_alloc(cipher, &newkey)) {
3043 silc_server_command_send_status_data(
3044 cmd, SILC_COMMAND_CMODE,
3045 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3046 2, cipher, strlen(cipher));
3050 oldkey = channel->channel_key;
3051 channel->channel_key = newkey;
3053 /* Re-generate channel key */
3054 if (!silc_server_create_channel_key(server, channel, 0)) {
3055 /* We don't have new key, revert to old one */
3056 channel->channel_key = oldkey;
3060 /* Remove old channel key for good */
3061 silc_cipher_free(oldkey);
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);
3070 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
3071 /* Cipher mode is unset. Remove the cipher and revert back to
3073 SilcCipher newkey, oldkey;
3074 cipher = channel->cipher;
3076 /* Delete old cipher and allocate default one */
3077 if (!silc_cipher_alloc(cipher ? cipher : SILC_DEFAULT_CIPHER, &newkey)) {
3078 silc_server_command_send_status_data(
3079 cmd, SILC_COMMAND_CMODE,
3080 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3081 2, cipher, strlen(cipher));
3085 oldkey = channel->channel_key;
3086 channel->channel_key = newkey;
3088 /* Re-generate channel key */
3089 if (!silc_server_create_channel_key(server, channel, 0)) {
3090 /* We don't have new key, revert to old one */
3091 channel->channel_key = oldkey;
3095 /* Remove old channel key for good */
3096 silc_cipher_free(oldkey);
3098 /* Send the channel key. This sends it to our local clients and if
3099 we are normal server to our router as well. */
3100 silc_server_send_channel_key(server, NULL, channel,
3101 server->server_type == SILC_ROUTER ?
3102 FALSE : !server->standalone);
3106 if (mode_mask & SILC_CHANNEL_MODE_HMAC) {
3107 if (!(channel->mode & SILC_CHANNEL_MODE_HMAC)) {
3108 /* HMAC to use protect the traffic */
3109 unsigned char hash[32];
3113 hmac = silc_argument_get_arg_type(cmd->args, 6, NULL);
3115 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3116 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3120 /* Delete old hmac and allocate the new one */
3121 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3122 silc_server_command_send_status_data(
3123 cmd, SILC_COMMAND_CMODE,
3124 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3125 2, hmac, strlen(hmac));
3129 silc_hmac_free(channel->hmac);
3130 channel->hmac = newhmac;
3132 /* Set the HMAC key out of current channel key. The client must do
3134 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
3135 channel->key_len / 8, hash);
3136 silc_hmac_set_key(channel->hmac, hash,
3137 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3138 memset(hash, 0, sizeof(hash));
3141 if (channel->mode & SILC_CHANNEL_MODE_HMAC) {
3142 /* Hmac mode is unset. Remove the hmac and revert back to
3145 unsigned char hash[32];
3146 hmac = channel->hmac_name;
3148 /* Delete old hmac and allocate default one */
3149 if (!silc_hmac_alloc(hmac ? hmac : SILC_DEFAULT_HMAC, NULL, &newhmac)) {
3150 silc_server_command_send_status_data(
3151 cmd, SILC_COMMAND_CMODE,
3152 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3153 2, hmac, strlen(hmac));
3157 silc_hmac_free(channel->hmac);
3158 channel->hmac = newhmac;
3160 /* Set the HMAC key out of current channel key. The client must do
3162 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
3163 channel->key_len / 8,
3165 silc_hmac_set_key(channel->hmac, hash,
3166 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3167 memset(hash, 0, sizeof(hash));
3171 if (mode_mask & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3172 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3173 /* Check if the founder public key was received */
3174 founder_key = idata->public_key;
3175 tmp = silc_argument_get_arg_type(cmd->args, 8, &tmp_len);
3177 if (!silc_pkcs_public_key_payload_decode(tmp, tmp_len, &founder_key)) {
3178 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3179 SILC_STATUS_ERR_AUTH_FAILED,
3184 /* If key was not sent and the channel mode has already founder
3185 then the key was not to be changed. */
3186 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
3190 /* Set the founder authentication */
3191 tmp = silc_argument_get_arg_type(cmd->args, 7, &tmp_len);
3193 silc_server_command_send_status_reply(
3194 cmd, SILC_COMMAND_CMODE,
3195 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3199 /* Verify the payload before setting the mode */
3200 if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY,
3201 founder_key, 0, server->sha1hash,
3202 client->id, SILC_ID_CLIENT)) {
3203 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3204 SILC_STATUS_ERR_AUTH_FAILED,
3209 /* Save the public key */
3210 if (channel->founder_key)
3211 silc_pkcs_public_key_free(channel->founder_key);
3212 if (silc_argument_get_arg_type(cmd->args, 8, NULL))
3213 channel->founder_key = founder_key;
3215 channel->founder_key = silc_pkcs_public_key_copy(founder_key);
3216 if (!channel->founder_key) {
3217 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3218 SILC_STATUS_ERR_AUTH_FAILED,
3223 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
3225 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3226 SILC_STATUS_ERR_AUTH_FAILED,
3228 silc_pkcs_public_key_free(channel->founder_key);
3229 channel->founder_key = NULL;
3234 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3235 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3236 if (channel->founder_key)
3237 silc_pkcs_public_key_free(channel->founder_key);
3238 channel->founder_key = NULL;
3244 if (mode_mask & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
3245 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3248 chpkdata = silc_argument_get_arg_type(cmd->args, 9, &chpklen);
3250 if (!chpkdata && channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
3255 /* Process the channel public key(s) */
3256 st = silc_server_set_channel_pk_list(server, NULL, channel,
3258 if (st != SILC_STATUS_OK) {
3259 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, st, 0);
3264 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3265 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
3266 if (channel->channel_pubkeys)
3267 silc_hash_table_free(channel->channel_pubkeys);
3268 channel->channel_pubkeys = NULL;
3275 /* Finally, set the mode */
3276 old_mask = channel->mode = mode_mask;
3278 /* Send CMODE_CHANGE notify. */
3279 cidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3280 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT)
3281 SILC_PUT32_MSB(channel->user_limit, ulimit);
3282 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3283 SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
3284 cidp->data, cidp->len,
3286 cipher, cipher ? strlen(cipher) : 0,
3287 hmac, hmac ? strlen(hmac) : 0,
3288 passphrase, passphrase ?
3289 strlen(passphrase) : 0,
3290 fkey ? fkey->data : NULL,
3291 fkey ? fkey->len : 0,
3292 chpkdata ? chpkdata : NULL,
3293 chpkdata ? chpklen : 0,
3294 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
3296 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
3297 sizeof(ulimit) : 0);
3299 /* Set CMODE notify type to network */
3300 if (chpkdata && chpklen)
3301 silc_buffer_set(&chpk, chpkdata, chpklen);
3302 silc_server_send_notify_cmode(server, SILC_PRIMARY_ROUTE(server),
3303 SILC_BROADCAST(server), channel,
3304 mode_mask, client->id, SILC_ID_CLIENT,
3305 cipher, hmac, passphrase, founder_key,
3306 chpkdata ? &chpk : NULL);
3309 chpklist = silc_server_get_channel_pk_list(server, channel, FALSE, FALSE);
3311 /* Send command reply to sender */
3312 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_CMODE,
3313 SILC_STATUS_OK, 0, ident, 5,
3314 2, tmp_id, tmp_len2,
3316 4, fkey ? fkey->data : NULL,
3317 fkey ? fkey->len : 0,
3318 5, chpklist ? chpklist->data :
3319 NULL, chpklist ? chpklist->len
3322 SILC_CHANNEL_MODE_ULIMIT ?
3325 SILC_CHANNEL_MODE_ULIMIT ?
3326 sizeof(ulimit) : 0));
3327 silc_buffer_free(cidp);
3330 channel->mode = old_mask;
3331 silc_buffer_free(chpklist);
3332 silc_buffer_free(fkey);
3333 silc_free(channel_id);
3334 silc_server_command_free(cmd);
3337 /* Server side of CUMODE command. Changes client's mode on a channel. */
3339 SILC_SERVER_CMD_FUNC(cumode)
3341 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3342 SilcServer server = cmd->server;
3343 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3344 SilcChannelID *channel_id = NULL;
3345 SilcClientID *client_id = NULL;
3346 SilcChannelEntry channel;
3347 SilcClientEntry target_client;
3348 SilcChannelClientEntry chl;
3350 unsigned char *tmp_id, *tmp_ch_id, *tmp_mask;
3351 SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
3353 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3354 SilcPublicKey founder_key = NULL;
3355 SilcBuffer fkey = NULL;
3360 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4);
3362 /* Get Channel ID */
3363 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3365 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3366 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3369 channel_id = silc_id_payload_parse_id(tmp_ch_id, tmp_ch_len, NULL);
3371 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3372 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3376 /* Get channel entry */
3377 channel = silc_idlist_find_channel_by_id(server->local_list,
3380 channel = silc_idlist_find_channel_by_id(server->global_list,
3383 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3384 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
3385 0, 2, tmp_ch_id, tmp_ch_len);
3390 /* Check whether sender is on the channel */
3391 if (!silc_server_client_on_channel(client, channel, &chl)) {
3392 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3393 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
3394 2, tmp_ch_id, tmp_ch_len);
3397 sender_mask = chl->mode;
3399 /* Get the target client's channel mode mask */
3400 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
3402 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3403 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3407 SILC_GET32_MSB(target_mask, tmp_mask);
3409 /* Get target Client ID */
3410 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3412 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3413 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3416 client_id = silc_id_payload_parse_id(tmp_id, tmp_len, NULL);
3418 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3419 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3423 /* Get target client's entry */
3424 target_client = silc_idlist_find_client_by_id(server->local_list,
3425 client_id, TRUE, NULL);
3427 target_client = silc_idlist_find_client_by_id(server->global_list,
3428 client_id, TRUE, NULL);
3430 if (target_client != client &&
3431 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO) &&
3432 !(sender_mask & SILC_CHANNEL_UMODE_CHANOP)) {
3433 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3434 SILC_STATUS_ERR_NOT_YOU, 0,
3435 2, tmp_ch_id, tmp_ch_len);
3439 /* Check whether target client is on the channel */
3440 if (target_client != client) {
3441 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
3442 silc_server_command_send_status_data2(
3443 cmd, SILC_COMMAND_CUMODE,
3444 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL, 0,
3446 3, tmp_ch_id, tmp_ch_len);
3455 /* If the target client is founder, no one else can change their mode
3457 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && client != target_client) {
3458 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3459 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3460 0, 2, tmp_ch_id, tmp_ch_len);
3464 if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
3465 if (target_client != client) {
3466 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3467 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3472 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
3473 /* The client tries to claim the founder rights. */
3474 unsigned char *tmp_auth;
3475 SilcUInt32 tmp_auth_len;
3476 SilcChannelClientEntry chl2;
3477 SilcHashTableList htl;
3479 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
3480 !channel->founder_key) {
3481 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3482 SILC_STATUS_ERR_AUTH_FAILED, 0);
3486 tmp_auth = silc_argument_get_arg_type(cmd->args, 4, &tmp_auth_len);
3488 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3489 SILC_STATUS_ERR_AUTH_FAILED, 0);
3493 /* Verify the authentication payload */
3494 if (!silc_auth_verify_data(tmp_auth, tmp_auth_len, SILC_AUTH_PUBLIC_KEY,
3495 channel->founder_key, 0, server->sha1hash,
3496 client->id, SILC_ID_CLIENT)) {
3497 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3498 SILC_STATUS_ERR_AUTH_FAILED, 0);
3503 founder_key = channel->founder_key;
3504 fkey = silc_pkcs_public_key_payload_encode(founder_key);
3506 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3507 SILC_STATUS_ERR_AUTH_FAILED, 0);
3511 /* There cannot be anyone else as founder on the channel now. This
3512 client is definitely the founder due to this authentication. This
3513 is done only on router, not on server, since server cannot know
3514 whether router will accept this mode change or not. XXX This
3515 probably shouldn't be done anymore at all, may cause problems in
3516 router-router connections too (maybe just AUTH_FAILED error should
3517 be returned). -Pekka */
3518 if (server->server_type == SILC_ROUTER) {
3519 silc_hash_table_list(channel->user_list, &htl);
3520 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
3521 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
3522 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3523 silc_server_force_cumode_change(server, NULL, channel, chl2,
3527 silc_hash_table_list_reset(&htl);
3530 sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
3533 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3534 if (target_client == client) {
3535 /* Remove channel founder rights from itself */
3536 chl->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3539 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3540 SILC_STATUS_ERR_NOT_YOU, 0);
3546 if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
3547 /* Promote to operator */
3548 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
3549 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
3550 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
3551 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3552 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3553 0, 2, tmp_ch_id, tmp_ch_len);
3557 chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
3561 if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
3562 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
3563 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
3564 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3565 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3566 0, 2, tmp_ch_id, tmp_ch_len);
3570 /* Demote to normal user */
3571 chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
3576 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
3577 if (target_client != client) {
3578 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3579 SILC_STATUS_ERR_NOT_YOU, 0);
3583 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)) {
3584 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
3588 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
3589 if (target_client != client) {
3590 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3591 SILC_STATUS_ERR_NOT_YOU, 0);
3595 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
3600 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
3601 if (target_client != client) {
3602 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3603 SILC_STATUS_ERR_NOT_YOU, 0);
3607 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)) {
3608 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
3612 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
3613 if (target_client != client) {
3614 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3615 SILC_STATUS_ERR_NOT_YOU, 0);
3619 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
3624 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
3625 if (target_client != client) {
3626 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3627 SILC_STATUS_ERR_NOT_YOU, 0);
3631 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)) {
3632 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
3636 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
3637 if (target_client != client) {
3638 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3639 SILC_STATUS_ERR_NOT_YOU, 0);
3643 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
3648 if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
3649 if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
3650 if (client == target_client) {
3651 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3652 SILC_STATUS_ERR_PERM_DENIED, 0);
3655 chl->mode |= SILC_CHANNEL_UMODE_QUIET;
3659 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
3660 if (client == target_client) {
3661 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3662 SILC_STATUS_ERR_PERM_DENIED, 0);
3665 chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
3670 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3671 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3673 /* Send notify to channel, notify only if mode was actually changed. */
3675 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3676 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
3677 idp->data, idp->len,
3680 fkey ? fkey->data : NULL,
3681 fkey ? fkey->len : 0);
3683 /* Set CUMODE notify type to network */
3684 silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
3685 SILC_BROADCAST(server), channel,
3686 target_mask, client->id, SILC_ID_CLIENT,
3687 target_client->id, founder_key);
3690 /* Send command reply to sender */
3691 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_CUMODE,
3692 SILC_STATUS_OK, 0, ident, 3,
3694 3, tmp_ch_id, tmp_ch_len,
3695 4, tmp_id, tmp_len);
3696 silc_buffer_free(idp);
3699 silc_free(channel_id);
3700 silc_free(client_id);
3701 silc_buffer_free(fkey);
3702 silc_server_command_free(cmd);
3705 /* Server side of KICK command. Kicks client out of channel. */
3707 SILC_SERVER_CMD_FUNC(kick)
3709 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3710 SilcServer server = cmd->server;
3711 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3712 SilcClientEntry target_client;
3713 SilcChannelID *channel_id;
3714 SilcClientID *client_id;
3715 SilcChannelEntry channel;
3716 SilcChannelClientEntry chl;
3718 SilcUInt32 tmp_len, target_idp_len, clen;
3719 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3720 unsigned char *tmp, *comment, *target_idp;
3725 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 3);
3727 /* Get Channel ID */
3728 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3730 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
3731 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3734 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
3736 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3737 SILC_STATUS_ERR_BAD_CHANNEL_ID, 0,
3742 /* Get channel entry */
3743 channel = silc_idlist_find_channel_by_id(server->local_list,
3746 channel = silc_idlist_find_channel_by_id(server->local_list,
3749 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3750 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
3751 0, 2, tmp, tmp_len);
3756 /* Check whether sender is on the channel */
3757 if (!silc_server_client_on_channel(client, channel, &chl)) {
3758 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3759 SILC_STATUS_ERR_NOT_ON_CHANNEL,
3760 0, 2, tmp, tmp_len);
3764 /* Check that the kicker is channel operator or channel founder */
3765 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
3766 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
3767 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3768 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3769 0, 2, tmp, tmp_len);
3773 /* Get target Client ID */
3774 target_idp = silc_argument_get_arg_type(cmd->args, 2, &target_idp_len);
3776 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
3777 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3780 client_id = silc_id_payload_parse_id(target_idp, target_idp_len, NULL);
3782 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3783 SILC_STATUS_ERR_BAD_CLIENT_ID,
3784 0, 2, target_idp, target_idp_len);
3788 /* Get target client's entry */
3789 target_client = silc_idlist_find_client_by_id(server->local_list,
3790 client_id, TRUE, NULL);
3791 if (!target_client) {
3792 target_client = silc_idlist_find_client_by_id(server->global_list,
3793 client_id, TRUE, NULL);
3796 /* Check whether target client is on the channel */
3797 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
3798 silc_server_command_send_status_data2(cmd, SILC_COMMAND_KICK,
3799 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL,
3800 0, 2, target_idp, target_idp_len,
3805 /* Check that the target client is not channel founder. Channel founder
3806 cannot be kicked from the channel. */
3807 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3808 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3809 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3810 0, 2, tmp, tmp_len);
3815 comment = silc_argument_get_arg_type(cmd->args, 3, &clen);
3820 /* Send the reply back to the client */
3821 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_KICK,
3822 SILC_STATUS_OK, 0, ident, 2,
3824 3, target_idp, target_idp_len);
3826 /* Send KICKED notify to local clients on the channel */
3827 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3828 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3829 SILC_NOTIFY_TYPE_KICKED, 3,
3830 target_idp, target_idp_len,
3831 comment, comment ? strlen(comment) : 0,
3832 idp->data, idp->len);
3833 silc_buffer_free(idp);
3835 /* Send KICKED notify to primary route */
3836 silc_server_send_notify_kicked(server, SILC_PRIMARY_ROUTE(server),
3837 SILC_BROADCAST(server), channel,
3838 target_client->id, client->id, comment);
3840 /* Remove the client from channel's invite list */
3841 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
3843 silc_argument_payload_encode_one(NULL, target_idp, target_idp_len, 3);
3844 SilcArgumentPayload args =
3845 silc_argument_payload_parse(ab->data, ab->len, 1);
3847 silc_server_inviteban_process(server, channel->invite_list, 1, args);
3848 silc_buffer_free(ab);
3849 silc_argument_payload_free(args);
3852 /* Remove the client from the channel. If the channel does not exist
3853 after removing the client then the client kicked itself off the channel
3854 and we don't have to send anything after that. */
3855 if (!silc_server_remove_from_one_channel(server, NULL, channel,
3856 target_client, FALSE))
3859 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3860 /* Re-generate channel key */
3861 if (!silc_server_create_channel_key(server, channel, 0))
3864 /* Send the channel key to the channel. The key of course is not sent
3865 to the client who was kicked off the channel. */
3866 silc_server_send_channel_key(server, target_client->connection, channel,
3867 server->server_type == SILC_ROUTER ?
3868 FALSE : !server->standalone);
3872 silc_server_command_free(cmd);
3875 /* Server side of OPER command. Client uses this comand to obtain server
3876 operator privileges to this server/router. */
3878 SILC_SERVER_CMD_FUNC(oper)
3880 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3881 SilcServer server = cmd->server;
3882 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3883 unsigned char *username = NULL, *auth;
3885 SilcServerConfigAdmin *admin;
3886 SilcIDListData idata = (SilcIDListData)client;
3887 bool result = FALSE;
3888 SilcPublicKey cached_key;
3890 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
3893 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2);
3895 /* Get the username */
3896 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3898 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3899 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3904 /* Check username */
3905 username = silc_identifier_check(username, strlen(username),
3906 SILC_STRING_UTF8, 128, &tmp_len);
3908 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3909 SILC_STATUS_ERR_BAD_USERNAME,
3914 /* Get the admin configuration */
3915 admin = silc_server_config_find_admin(server, cmd->sock->ip,
3916 username, client->nickname);
3918 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
3919 username, client->nickname);
3921 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3922 SILC_STATUS_ERR_AUTH_FAILED,
3924 SILC_LOG_INFO(("OPER authentication failed for username '%s' by "
3925 "nickname '%s' from %s", username,
3926 client->nickname, cmd->sock->hostname));
3931 /* Get the authentication payload */
3932 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
3934 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3935 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3940 /* Verify the authentication data. If both passphrase and public key
3941 is set then try both of them. */
3942 if (admin->passphrase)
3943 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
3944 admin->passphrase, admin->passphrase_len,
3945 idata->hash, client->id, SILC_ID_CLIENT);
3946 if (!result && admin->publickeys) {
3947 cached_key = silc_server_get_public_key(server, admin->publickeys);
3950 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
3951 cached_key, 0, idata->hash,
3952 client->id, SILC_ID_CLIENT);
3955 /* Authentication failed */
3956 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3957 SILC_STATUS_ERR_AUTH_FAILED,
3962 /* Client is now server operator */
3963 client->mode |= SILC_UMODE_SERVER_OPERATOR;
3965 /* Update statistics */
3966 if (SILC_IS_LOCAL(client))
3967 server->stat.my_server_ops++;
3968 if (server->server_type == SILC_ROUTER)
3969 server->stat.server_ops++;
3971 /* Send UMODE change to primary router */
3972 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
3973 SILC_BROADCAST(server), client->id,
3976 /* Check if anyone is watching this nickname */
3977 if (server->server_type == SILC_ROUTER)
3978 silc_server_check_watcher_list(server, client, NULL,
3979 SILC_NOTIFY_TYPE_UMODE_CHANGE);
3981 /* Send reply to the sender */
3982 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3986 silc_free(username);
3987 silc_server_command_free(cmd);
3990 SILC_TASK_CALLBACK(silc_server_command_detach_cb)
3992 SilcServer server = app_context;
3993 QuitInternal q = (QuitInternal)context;
3994 SilcClientID *client_id = (SilcClientID *)q->sock;
3995 SilcClientEntry client;
3996 SilcSocketConnection sock;
3998 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4000 if (client && client->connection) {
4001 sock = client->connection;
4003 /* If there is pending outgoing data for the client then purge it
4004 to the network before closing connection. */
4005 silc_server_packet_queue_purge(server, sock);
4007 /* Close the connection on our side */
4008 client->router = NULL;
4009 client->connection = NULL;
4010 sock->user_data = NULL;
4011 silc_server_close_connection(server, sock);
4014 silc_free(client_id);
4018 SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
4020 SilcServer server = app_context;
4021 QuitInternal q = (QuitInternal)context;
4022 SilcClientID *client_id = (SilcClientID *)q->sock;
4023 SilcClientEntry client;
4025 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4027 if (client && client->mode & SILC_UMODE_DETACHED) {
4028 SILC_LOG_DEBUG(("Detach timeout"));
4029 silc_server_free_client_data(server, NULL, client, TRUE,
4033 silc_free(client_id);
4037 /* Server side of DETACH command. Detached the client from the network
4038 by closing the connection but preserving the session. */
4040 SILC_SERVER_CMD_FUNC(detach)
4042 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4043 SilcServer server = cmd->server;
4044 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4047 if (server->config->detach_disabled) {
4048 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4049 SILC_STATUS_ERR_OPERATION_ALLOWED,
4054 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4057 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_DETACH, cmd, 0, 0);
4059 /* Remove operator privileges, since the client may resume in some
4060 other server which to it does not have operator privileges. */
4061 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
4062 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
4064 /* Send the user mode notify to notify that client is detached */
4065 client->mode |= SILC_UMODE_DETACHED;
4066 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
4067 client->data.status &= ~SILC_IDLIST_STATUS_NOATTR;
4068 client->last_command = 0;
4069 client->fast_command = 0;
4070 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4071 SILC_BROADCAST(server), client->id,
4073 server->stat.my_detached++;
4075 /* Check if anyone is watching this nickname */
4076 if (server->server_type == SILC_ROUTER)
4077 silc_server_check_watcher_list(server, client, NULL,
4078 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4080 q = silc_calloc(1, sizeof(*q));
4081 q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
4082 silc_schedule_task_add(server->schedule, 0, silc_server_command_detach_cb,
4083 q, 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
4085 if (server->config->detach_timeout) {
4086 q = silc_calloc(1, sizeof(*q));
4087 q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
4088 silc_schedule_task_add(server->schedule, 0,
4089 silc_server_command_detach_timeout,
4090 q, server->config->detach_timeout * 60,
4091 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
4094 /* Send reply to the sender */
4095 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4099 silc_server_command_free(cmd);
4102 /* Server side of WATCH command. */
4104 SILC_SERVER_CMD_FUNC(watch)
4106 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4107 SilcServer server = cmd->server;
4108 char *add_nick, *del_nick;
4109 SilcUInt32 add_nick_len, del_nick_len, tmp_len, pk_len;
4110 unsigned char hash[16], *tmp, *pk, *nick;
4111 SilcClientEntry client;
4112 SilcClientID *client_id = NULL;
4113 SilcUInt16 old_ident;
4115 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WATCH, cmd, 1, 3);
4117 if (server->server_type != SILC_ROUTER && !server->standalone) {
4118 if (!cmd->pending) {
4119 /* Send the command to router */
4122 /* If backup receives this from primary, handle it locally */
4123 if (server->server_type == SILC_BACKUP_ROUTER &&
4124 cmd->sock == SILC_PRIMARY_ROUTE(server))
4127 SILC_LOG_DEBUG(("Forwarding WATCH to router"));
4130 cmd->server->stat.commands_sent++;
4132 old_ident = silc_command_get_ident(cmd->payload);
4133 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4134 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4136 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4137 SILC_PACKET_COMMAND, cmd->packet->flags,
4138 tmpbuf->data, tmpbuf->len, TRUE);
4140 /* Reprocess this packet after received reply from router */
4141 silc_server_command_pending(server, SILC_COMMAND_WATCH,
4142 silc_command_get_ident(cmd->payload),
4143 silc_server_command_watch,
4144 silc_server_command_dup(cmd));
4145 cmd->pending = TRUE;
4146 silc_command_set_ident(cmd->payload, old_ident);
4147 silc_buffer_free(tmpbuf);
4150 SilcServerCommandReplyContext reply = context2;
4156 silc_command_get_status(reply->payload, &status, NULL);
4158 /* Backup router handles the WATCH command also. */
4159 if (server->server_type != SILC_BACKUP_ROUTER ||
4160 SILC_STATUS_IS_ERROR(status)) {
4161 /* Received reply from router, just send same data to the client. */
4162 SILC_LOG_DEBUG(("Received reply to WATCH from router"));
4163 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH, status,
4170 /* We are router and keep the watch list for local cell */
4173 /* Get the client ID */
4174 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4176 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4177 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4181 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
4183 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4184 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4185 0, 2, tmp, tmp_len);
4189 /* Get the client entry which must be in local list */
4190 client = silc_idlist_find_client_by_id(server->local_list,
4191 client_id, TRUE, NULL);
4193 /* Backup checks global list also */
4194 if (server->server_type == SILC_BACKUP_ROUTER)
4195 client = silc_idlist_find_client_by_id(server->global_list,
4196 client_id, TRUE, NULL);
4198 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4199 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4200 0, 2, tmp, tmp_len);
4205 /* Take public key for watching by public key */
4206 pk = silc_argument_get_arg_type(cmd->args, 4, &pk_len);
4209 add_nick = silc_argument_get_arg_type(cmd->args, 2, &add_nick_len);
4210 del_nick = silc_argument_get_arg_type(cmd->args, 3, &del_nick_len);
4211 if (!add_nick && !del_nick && !pk) {
4212 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4213 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4218 if (add_nick && add_nick_len > 128) {
4219 add_nick[128] = '\0';
4222 if (del_nick && del_nick_len > 128) {
4223 del_nick[128] = '\0';
4227 /* Add new nickname to be watched in our cell */
4229 nick = silc_identifier_check(add_nick, add_nick_len, SILC_STRING_UTF8, 128,
4232 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4233 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4237 /* Hash the nick, we have the hash saved, not nicks because we can
4238 do one to one mapping to the nick from Client ID hash this way. */
4239 silc_hash_make(server->md5hash, nick, add_nick_len, hash);
4241 /* Check whether this client is already watching this nickname */
4242 if (silc_hash_table_find_by_context(server->watcher_list, hash,
4244 /* Nickname is alredy being watched for this client */
4245 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4246 SILC_STATUS_ERR_NICKNAME_IN_USE,
4252 /* Get the nickname from the watcher list and use the same key in
4253 new entries as well. If key doesn't exist then create it. */
4254 if (!silc_hash_table_find(server->watcher_list, hash, (void *)&tmp, NULL))
4255 tmp = silc_memdup(hash, CLIENTID_HASH_LEN);
4257 /* Add the client to the watcher list with the specified nickname hash. */
4258 silc_hash_table_add(server->watcher_list, tmp, client);
4262 /* Delete nickname from watch list */
4264 nick = silc_identifier_check(del_nick, del_nick_len, SILC_STRING_UTF8, 128,
4267 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4268 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4272 /* Hash the nick, we have the hash saved, not nicks because we can
4273 do one to one mapping to the nick from Client ID hash this way. */
4274 silc_hash_make(server->md5hash, nick, del_nick_len, hash);
4276 /* Check that this client is watching for this nickname */
4277 if (!silc_hash_table_find_by_context(server->watcher_list, hash,
4278 client, (void *)&tmp)) {
4279 /* Nickname is alredy being watched for this client */
4280 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4281 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
4282 2, nick, del_nick_len);
4287 /* Delete the nickname from the watcher list. */
4288 silc_hash_table_del_by_context(server->watcher_list, hash, client);
4290 /* Now check whether there still exists entries with this key, if not
4291 then free the key to not leak memory. */
4292 if (!silc_hash_table_find(server->watcher_list, hash, NULL, NULL))
4297 /* Add/del public key */
4300 SilcArgumentPayload pkargs;
4302 SilcPublicKey public_key, pkkey;
4305 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4306 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4311 /* Get the argument from the Argument List Payload */
4312 SILC_GET16_MSB(pkargc, pk);
4313 pkargs = silc_argument_payload_parse(pk + 2, pk_len - 2, pkargc);
4315 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4316 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4321 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4323 if (!silc_pkcs_public_key_payload_decode(pk, pk_len, &public_key))
4329 /* Add public key to watch list */
4331 /* Check whether this client is already watching this public key */
4332 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4333 public_key, client, NULL)) {
4334 silc_pkcs_public_key_free(public_key);
4335 silc_server_command_send_status_reply(
4336 cmd, SILC_COMMAND_WATCH,
4337 SILC_STATUS_ERR_NICKNAME_IN_USE, 0);
4341 /* Get the public key from the watcher list and use the same key in
4342 new entries as well. If key doesn't exist then create it. */
4344 if (!silc_hash_table_find(server->watcher_list_pk, public_key,
4345 (void *)&pkkey, NULL))
4348 silc_pkcs_public_key_free(public_key);
4350 /* Add the client to the watcher list with the specified public
4352 silc_hash_table_add(server->watcher_list_pk, pkkey, client);
4354 } else if (type == 0x01) {
4355 /* Delete public key from watch list */
4357 /* Check that this client is watching this public key */
4358 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4361 silc_pkcs_public_key_free(public_key);
4362 silc_server_command_send_status_reply(
4363 cmd, SILC_COMMAND_WATCH,
4364 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4368 /* Delete the public key from the watcher list. */
4369 silc_hash_table_del_by_context(server->watcher_list_pk,
4370 public_key, client);
4372 /* Now check whether there still exists entries with this key, if
4373 not then free the key to not leak memory. */
4374 if (!silc_hash_table_find(server->watcher_list_pk, hash, NULL, NULL))
4375 silc_pkcs_public_key_free(pkkey);
4376 silc_pkcs_public_key_free(public_key);
4379 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4384 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4387 /* Distribute the watch list to backup routers too */
4388 if (server->backup) {
4392 cmd->server->stat.commands_sent++;
4394 old_ident = silc_command_get_ident(cmd->payload);
4395 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4396 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4397 silc_server_backup_send(server, cmd->sock->user_data, SILC_PACKET_COMMAND,
4398 cmd->packet->flags, tmpbuf->data, tmpbuf->len,
4400 silc_command_set_ident(cmd->payload, old_ident);
4401 silc_buffer_free(tmpbuf);
4405 silc_free(client_id);
4406 silc_server_command_free(cmd);
4409 /* Server side of SILCOPER command. Client uses this comand to obtain router
4410 operator privileges to this router. */
4412 SILC_SERVER_CMD_FUNC(silcoper)
4414 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4415 SilcServer server = cmd->server;
4416 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4417 unsigned char *username = NULL, *auth;
4419 SilcServerConfigAdmin *admin;
4420 SilcIDListData idata = (SilcIDListData)client;
4421 bool result = FALSE;
4422 SilcPublicKey cached_key;
4424 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4427 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
4429 if (server->server_type != SILC_ROUTER) {
4430 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4431 SILC_STATUS_ERR_AUTH_FAILED, 0);
4435 /* Get the username */
4436 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4438 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4439 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4444 /* Check username */
4445 username = silc_identifier_check(username, tmp_len, SILC_STRING_UTF8, 128,
4448 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4449 SILC_STATUS_ERR_BAD_USERNAME,
4454 /* Get the admin configuration */
4455 admin = silc_server_config_find_admin(server, cmd->sock->ip,
4456 username, client->nickname);
4458 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
4459 username, client->nickname);
4461 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4462 SILC_STATUS_ERR_AUTH_FAILED, 0);
4463 SILC_LOG_INFO(("SILCOPER authentication failed for username '%s' by "
4464 "nickname '%s' from %s", username,
4465 client->nickname, cmd->sock->hostname));
4470 /* Get the authentication payload */
4471 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
4473 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4474 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4479 /* Verify the authentication data. If both passphrase and public key
4480 is set then try both of them. */
4481 if (admin->passphrase)
4482 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
4483 admin->passphrase, admin->passphrase_len,
4484 idata->hash, client->id, SILC_ID_CLIENT);
4485 if (!result && admin->publickeys) {
4486 cached_key = silc_server_get_public_key(server, admin->publickeys);
4489 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
4490 cached_key, 0, idata->hash,
4491 client->id, SILC_ID_CLIENT);
4494 /* Authentication failed */
4495 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4496 SILC_STATUS_ERR_AUTH_FAILED, 0);
4500 /* Client is now router operator */
4501 client->mode |= SILC_UMODE_ROUTER_OPERATOR;
4503 /* Update statistics */
4504 if (SILC_IS_LOCAL(client))
4505 server->stat.my_router_ops++;
4506 if (server->server_type == SILC_ROUTER)
4507 server->stat.router_ops++;
4509 /* Send UMODE change to primary router */
4510 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4511 SILC_BROADCAST(server), client->id,
4514 /* Check if anyone is watching this nickname */
4515 if (server->server_type == SILC_ROUTER)
4516 silc_server_check_watcher_list(server, client, NULL,
4517 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4519 /* Send reply to the sender */
4520 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4524 silc_free(username);
4525 silc_server_command_free(cmd);
4528 /* Server side of command BAN. This is used to manage the ban list of the
4529 channel. To add clients and remove clients from the ban list. */
4531 SILC_SERVER_CMD_FUNC(ban)
4533 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4534 SilcServer server = cmd->server;
4535 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4536 SilcBuffer list, tmp2;
4537 SilcChannelEntry channel;
4538 SilcChannelClientEntry chl;
4539 SilcChannelID *channel_id = NULL;
4540 unsigned char *id, *tmp, *atype = NULL;
4541 SilcUInt32 id_len, len, len2;
4542 SilcArgumentPayload args;
4543 SilcHashTableList htl;
4545 SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
4546 SilcBufferStruct blist;
4548 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4551 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_BAN, cmd, 0, 3);
4553 /* Get Channel ID */
4554 id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
4556 channel_id = silc_id_payload_parse_id(id, id_len, NULL);
4558 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4559 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4564 /* Get channel entry. The server must know about the channel since the
4565 client is expected to be on the channel. */
4566 channel = silc_idlist_find_channel_by_id(server->local_list,
4569 channel = silc_idlist_find_channel_by_id(server->global_list,
4572 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4573 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4579 /* Check whether this client is on the channel */
4580 if (!silc_server_client_on_channel(client, channel, &chl)) {
4581 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4582 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4587 /* The client must be at least channel operator. */
4588 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
4589 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4590 SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0,
4595 /* Get the ban information */
4596 tmp = silc_argument_get_arg_type(cmd->args, 3, &len2);
4597 if (tmp && len2 > 2) {
4598 /* Parse the arguments to see they are constructed correctly */
4599 SILC_GET16_MSB(argc, tmp);
4600 args = silc_argument_payload_parse(tmp + 2, len2 - 2, argc);
4602 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4603 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4608 /* Get the type of action */
4609 atype = silc_argument_get_arg_type(cmd->args, 2, &len);
4610 if (atype && len == 1) {
4611 if (atype[0] == 0x00) {
4612 /* Allocate hash table for ban list if it doesn't exist yet */
4613 if (!channel->ban_list)
4615 silc_hash_table_alloc(0, silc_hash_ptr,
4617 silc_server_inviteban_destruct, channel,
4620 /* Check for resource limit */
4621 if (silc_hash_table_count(channel->ban_list) > 64) {
4622 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4623 SILC_STATUS_ERR_RESOURCE_LIMIT,
4629 /* Now add or delete the information. */
4630 if (!silc_server_inviteban_process(server, channel->ban_list,
4631 (SilcUInt8)atype[0], args)) {
4632 silc_server_command_send_status_reply(
4633 cmd, SILC_COMMAND_BAN,
4634 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4639 silc_argument_payload_free(args);
4642 /* Encode ban list */
4644 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4645 list = silc_buffer_alloc_size(2);
4646 silc_buffer_format(list,
4647 SILC_STR_UI_SHORT(silc_hash_table_count(
4648 channel->ban_list)),
4650 silc_hash_table_list(channel->ban_list, &htl);
4651 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4652 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4654 silc_hash_table_list_reset(&htl);
4657 /* Send BAN notify type to local servers (but not clients) and to
4659 if (atype && tmp && len2) {
4660 silc_buffer_set(&blist, tmp, len2);
4662 /* Send to local servers if we are router */
4663 if (server->server_type == SILC_ROUTER)
4664 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
4665 SILC_NOTIFY_TYPE_BAN, 3,
4668 tmp ? blist.data : NULL,
4669 tmp ? blist.len : 0);
4671 /* Send to network. */
4672 silc_server_send_notify_ban(server, SILC_PRIMARY_ROUTE(server),
4673 SILC_BROADCAST(server), channel, atype,
4677 /* Send the reply back to the client */
4678 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_BAN,
4679 SILC_STATUS_OK, 0, ident, 2,
4681 3, list ? list->data : NULL,
4682 list ? list->len : 0);
4683 silc_buffer_free(list);
4686 silc_free(channel_id);
4687 silc_server_command_free(cmd);
4690 /* Server side command of LEAVE. Removes client from a channel. */
4692 SILC_SERVER_CMD_FUNC(leave)
4694 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4695 SilcServer server = cmd->server;
4696 SilcSocketConnection sock = cmd->sock;
4697 SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
4698 SilcChannelID *id = NULL;
4699 SilcChannelEntry channel;
4703 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !id_entry)
4706 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 2);
4708 /* Get Channel ID */
4709 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
4711 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4712 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4715 id = silc_id_payload_parse_id(tmp, len, NULL);
4717 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4718 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4722 /* Get channel entry */
4723 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4725 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4727 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4728 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4734 /* Check whether this client is on the channel */
4735 if (!silc_server_client_on_channel(id_entry, channel, NULL)) {
4736 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4737 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4742 /* Notify routers that they should remove this client from their list
4743 of clients on the channel. Send LEAVE notify type. */
4744 silc_server_send_notify_leave(server, SILC_PRIMARY_ROUTE(server),
4745 SILC_BROADCAST(server), channel, id_entry->id);
4747 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4748 SILC_STATUS_OK, 0, 2, tmp, len);
4750 /* Remove client from channel */
4751 if (!silc_server_remove_from_one_channel(server, sock, channel, id_entry,
4753 /* If the channel does not exist anymore we won't send anything */
4756 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
4757 /* Re-generate channel key */
4758 if (!silc_server_create_channel_key(server, channel, 0))
4761 /* Send the channel key */
4762 silc_server_send_channel_key(server, NULL, channel,
4763 server->server_type == SILC_ROUTER ?
4764 FALSE : !server->standalone);
4769 silc_server_command_free(cmd);
4772 /* Server side of command USERS. Resolves clients and their USERS currently
4773 joined on the requested channel. The list of Client ID's and their modes
4774 on the channel is sent back. */
4776 SILC_SERVER_CMD_FUNC(users)
4778 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4779 SilcServer server = cmd->server;
4780 SilcChannelEntry channel;
4781 SilcChannelID *id = NULL;
4783 unsigned char *channel_id;
4784 SilcUInt32 channel_id_len;
4785 SilcBuffer client_id_list;
4786 SilcBuffer client_mode_list;
4787 unsigned char lc[4];
4788 SilcUInt32 list_count = 0;
4789 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4790 char *channel_name, *channel_namec = NULL;
4792 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2);
4794 /* Get Channel ID */
4795 channel_id = silc_argument_get_arg_type(cmd->args, 1, &channel_id_len);
4797 /* Get channel name */
4798 channel_name = silc_argument_get_arg_type(cmd->args, 2, NULL);
4800 if (!channel_id && !channel_name) {
4801 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4802 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4806 /* Check channel name */
4808 channel_namec = silc_channel_name_check(channel_name, strlen(channel_name),
4809 SILC_STRING_UTF8, 256, NULL);
4810 if (!channel_namec) {
4811 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4812 SILC_STATUS_ERR_BAD_CHANNEL, 0);
4817 /* Check Channel ID */
4819 id = silc_id_payload_parse_id(channel_id, channel_id_len, NULL);
4821 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4822 SILC_STATUS_ERR_BAD_CHANNEL_ID, 0,
4823 2, channel_id, channel_id_len);
4828 /* If we are server and we don't know about this channel we will send
4829 the command to our router. If we know about the channel then we also
4830 have the list of users already. */
4832 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4834 channel = silc_idlist_find_channel_by_name(server->local_list,
4835 channel_namec, NULL);
4837 if (!channel || (!server->standalone && (channel->disabled ||
4838 !channel->users_resolved))) {
4839 if (server->server_type != SILC_ROUTER && !server->standalone &&
4844 cmd->server->stat.commands_sent++;
4846 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4847 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4849 /* Send USERS command */
4850 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4851 SILC_PACKET_COMMAND, cmd->packet->flags,
4852 tmpbuf->data, tmpbuf->len, TRUE);
4854 /* Reprocess this packet after received reply */
4855 silc_server_command_pending(server, SILC_COMMAND_USERS,
4856 silc_command_get_ident(cmd->payload),
4857 silc_server_command_users,
4858 silc_server_command_dup(cmd));
4859 cmd->pending = TRUE;
4860 silc_command_set_ident(cmd->payload, ident);
4861 silc_buffer_free(tmpbuf);
4866 /* Check the global list as well. */
4868 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4870 channel = silc_idlist_find_channel_by_name(server->global_list,
4871 channel_namec, NULL);
4873 /* Channel really does not exist */
4875 silc_server_command_send_status_data(
4876 cmd, SILC_COMMAND_USERS,
4877 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID, 0,
4878 2, channel_id, channel_id_len);
4880 silc_server_command_send_status_data(
4881 cmd, SILC_COMMAND_USERS,
4882 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
4883 2, channel_name, strlen(channel_name));
4888 /* If the channel is private or secret do not send anything, unless the
4889 user requesting this command is on the channel or is server */
4890 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
4891 if (channel->mode & (SILC_CHANNEL_MODE_PRIVATE | SILC_CHANNEL_MODE_SECRET)
4892 && !silc_server_client_on_channel(cmd->sock->user_data, channel,
4894 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4895 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
4896 2, channel->channel_name,
4897 strlen(channel->channel_name));
4902 /* Get the users list */
4903 if (!silc_server_get_users_on_channel(server, channel, &client_id_list,
4904 &client_mode_list, &list_count)) {
4906 client_id_list = NULL;
4907 client_mode_list = NULL;
4911 SILC_PUT32_MSB(list_count, lc);
4914 idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4915 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_USERS,
4916 SILC_STATUS_OK, 0, ident, 4,
4917 2, idp->data, idp->len,
4920 client_id_list->data : NULL,
4922 client_id_list->len : 0,
4923 5, client_mode_list ?
4924 client_mode_list->data : NULL,
4926 client_mode_list->len : 0);
4927 silc_buffer_free(idp);
4929 silc_buffer_free(client_id_list);
4930 if (client_mode_list)
4931 silc_buffer_free(client_mode_list);
4935 silc_free(channel_namec);
4936 silc_server_command_free(cmd);
4939 /* Server side of command GETKEY. This fetches the client's public key
4940 from the server where to the client is connected. */
4942 SILC_SERVER_CMD_FUNC(getkey)
4944 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4945 SilcServer server = cmd->server;
4946 SilcClientEntry client;
4947 SilcServerEntry server_entry;
4948 SilcClientID *client_id = NULL;
4949 SilcServerID *server_id = NULL;
4950 SilcIDPayload idp = NULL;
4951 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4954 SilcBuffer pk = NULL;
4956 SilcPublicKey public_key;
4958 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4960 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
4961 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4965 idp = silc_id_payload_parse(tmp, tmp_len);
4967 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
4968 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4973 id_type = silc_id_payload_get_type(idp);
4974 if (id_type == SILC_ID_CLIENT) {
4975 client_id = silc_id_payload_get_id(idp);
4977 /* If the client is not found from local list there is no chance it
4978 would be locally connected client so send the command further. */
4979 client = silc_idlist_find_client_by_id(server->local_list,
4980 client_id, TRUE, NULL);
4982 client = silc_idlist_find_client_by_id(server->global_list,
4983 client_id, TRUE, NULL);
4985 if ((!client && !cmd->pending && !server->standalone) ||
4986 (client && !client->connection && !cmd->pending &&
4987 !(client->mode & SILC_UMODE_DETACHED)) ||
4988 (client && !client->data.public_key && !cmd->pending)) {
4990 SilcUInt16 old_ident;
4991 SilcSocketConnection dest_sock;
4993 dest_sock = silc_server_get_client_route(server, NULL, 0,
4994 client_id, NULL, NULL);
4999 cmd->server->stat.commands_sent++;
5001 old_ident = silc_command_get_ident(cmd->payload);
5002 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5003 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5005 silc_server_packet_send(server, dest_sock,
5006 SILC_PACKET_COMMAND, cmd->packet->flags,
5007 tmpbuf->data, tmpbuf->len, TRUE);
5009 /* Reprocess this packet after received reply from router */
5010 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
5011 silc_command_get_ident(cmd->payload),
5012 silc_server_command_getkey,
5013 silc_server_command_dup(cmd));
5014 cmd->pending = TRUE;
5015 silc_command_set_ident(cmd->payload, old_ident);
5016 silc_buffer_free(tmpbuf);
5021 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
5022 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
5023 0, 2, tmp, tmp_len);
5027 /* The client is locally connected, just get the public key and
5028 send it back. If they key does not exist then do not send it,
5029 send just OK reply */
5030 public_key = client->data.public_key;
5032 pk = silc_pkcs_public_key_payload_encode(public_key);
5033 } else if (id_type == SILC_ID_SERVER) {
5034 server_id = silc_id_payload_get_id(idp);
5036 /* If the server is not found from local list there is no chance it
5037 would be locally connected server so send the command further. */
5038 server_entry = silc_idlist_find_server_by_id(server->local_list,
5039 server_id, TRUE, NULL);
5041 server_entry = silc_idlist_find_server_by_id(server->global_list,
5042 server_id, TRUE, NULL);
5044 if (server_entry != server->id_entry &&
5045 ((!server_entry && !cmd->pending && !server->standalone) ||
5046 (server_entry && !server_entry->connection && !cmd->pending &&
5047 !server->standalone) ||
5048 (server_entry && !server_entry->data.public_key && !cmd->pending &&
5049 !server->standalone))) {
5051 SilcUInt16 old_ident;
5054 cmd->server->stat.commands_sent++;
5056 old_ident = silc_command_get_ident(cmd->payload);
5057 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5058 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5060 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5061 SILC_PACKET_COMMAND, cmd->packet->flags,
5062 tmpbuf->data, tmpbuf->len, TRUE);
5064 /* Reprocess this packet after received reply from router */
5065 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
5066 silc_command_get_ident(cmd->payload),
5067 silc_server_command_getkey,
5068 silc_server_command_dup(cmd));
5069 cmd->pending = TRUE;
5070 silc_command_set_ident(cmd->payload, old_ident);
5071 silc_buffer_free(tmpbuf);
5075 if (!server_entry) {
5076 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
5077 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
5078 0, 2, tmp, tmp_len);
5082 /* If they key does not exist then do not send it, send just OK reply */
5083 public_key = (!server_entry->data.public_key ?
5084 (server_entry == server->id_entry ? server->public_key :
5085 NULL) : server_entry->data.public_key);
5087 pk = silc_pkcs_public_key_payload_encode(public_key);
5092 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5093 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_GETKEY,
5094 SILC_STATUS_OK, 0, ident, 2,
5096 3, pk ? pk->data : NULL,
5101 silc_id_payload_free(idp);
5102 silc_buffer_free(pk);
5103 silc_free(client_id);
5104 silc_free(server_id);
5105 silc_server_command_free(cmd);
5108 /* Server side of command SERVICE. */
5109 /* XXX currently this just sends empty reply back */
5111 SILC_SERVER_CMD_FUNC(service)
5113 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5114 SilcServer server = cmd->server;
5115 SilcUInt32 tmp_len, auth_len;
5116 unsigned char *service_name, *auth;
5117 bool send_list = FALSE;
5118 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
5120 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SERVICE, cmd, 0, 256);
5122 /* Get requested service */
5123 service_name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5124 if (service_name && tmp_len) {
5125 /* Verify service name */
5126 if (!silc_identifier_verify(service_name, tmp_len,
5127 SILC_STRING_UTF8, 256)) {
5128 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SERVICE,
5129 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5135 /* Get authentication payload if present */
5136 auth = silc_argument_get_arg_type(cmd->args, 2, &auth_len);
5144 /* Send our service list back */
5145 silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_SERVICE,
5146 SILC_STATUS_OK, 0, ident, 0);
5149 silc_server_command_free(cmd);
5153 /* Private range commands, specific to this implementation */
5155 /* Server side command of CONNECT. Connects us to the specified remote
5156 server or router. */
5158 SILC_SERVER_CMD_FUNC(connect)
5160 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5161 SilcServer server = cmd->server;
5162 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5163 unsigned char *tmp, *host;
5165 SilcUInt32 port = SILC_PORT;
5167 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5170 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CONNECT, cmd, 1, 2);
5172 /* Check whether client has the permissions. */
5173 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5174 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5175 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5176 SILC_STATUS_ERR_NO_SERVER_PRIV, 0);
5180 if (server->server_type == SILC_ROUTER && !server->backup_router &&
5181 client->mode & SILC_UMODE_SERVER_OPERATOR) {
5182 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5183 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
5187 /* Get the remote server */
5188 host = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5190 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5191 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5197 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5199 SILC_GET32_MSB(port, tmp);
5201 /* Create the connection. It is done with timeout and is async. */
5202 silc_server_create_connection(server, host, port);
5204 /* Send reply to the sender */
5205 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5209 silc_server_command_free(cmd);
5212 /* Server side command of CLOSE. Closes connection to a specified server. */
5214 SILC_SERVER_CMD_FUNC(close)
5216 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5217 SilcServer server = cmd->server;
5218 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5219 SilcServerEntry server_entry;
5220 SilcSocketConnection sock;
5223 unsigned char *name;
5224 SilcUInt32 port = SILC_PORT;
5226 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5229 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CLOSE, cmd, 1, 2);
5231 /* Check whether client has the permissions. */
5232 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5233 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5234 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5235 SILC_STATUS_ERR_NO_SERVER_PRIV,
5240 /* Get the remote server */
5241 name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5243 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5244 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5250 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5252 SILC_GET32_MSB(port, tmp);
5254 server_entry = silc_idlist_find_server_by_conn(server->local_list,
5255 name, port, TRUE, NULL);
5257 server_entry = silc_idlist_find_server_by_conn(server->global_list,
5258 name, port, TRUE, NULL);
5259 if (!server_entry) {
5260 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5261 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5265 if (server_entry == server->id_entry) {
5266 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5267 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5271 /* Send reply to the sender */
5272 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5275 /* Close the connection to the server */
5276 sock = (SilcSocketConnection)server_entry->connection;
5278 if (server_entry->server_type == SILC_BACKUP_ROUTER) {
5279 server->backup_closed = TRUE;
5280 silc_server_backup_del(server, server_entry);
5283 server->backup_noswitch = TRUE;
5284 if (server->router == server_entry) {
5285 server->id_entry->router = NULL;
5286 server->router = NULL;
5287 server->standalone = TRUE;
5289 silc_server_disconnect_remote(server, sock,
5290 SILC_STATUS_ERR_BANNED_FROM_SERVER,
5291 "Closed by administrator");
5292 if (sock->user_data)
5293 silc_server_free_sock_user_data(server, sock, NULL);
5294 server->backup_noswitch = FALSE;
5297 silc_server_command_free(cmd);
5300 /* Server side command of SHUTDOWN. Shutdowns the server and closes all
5301 active connections. */
5303 SILC_SERVER_CMD_FUNC(shutdown)
5305 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5306 SilcServer server = cmd->server;
5307 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5309 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5312 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_SHUTDOWN, cmd, 0, 0);
5314 /* Check whether client has the permission. */
5315 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5316 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5317 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5318 SILC_STATUS_ERR_NO_SERVER_PRIV,
5323 /* Send reply to the sender */
5324 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5327 /* Then, gracefully, or not, bring the server down. */
5328 silc_server_stop(server);
5332 silc_server_command_free(cmd);