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),
78 SILC_SERVER_CMD(connect, PRIV_CONNECT,
79 SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
80 SILC_SERVER_CMD(close, PRIV_CLOSE,
81 SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
82 SILC_SERVER_CMD(shutdown, PRIV_SHUTDOWN, SILC_CF_LAG | SILC_CF_REG |
88 /* Performs several checks to the command. It first checks whether this
89 command was called as pending command callback. If it was then it checks
90 whether error occurred in the command reply where the pending command
93 It also checks that the requested command includes correct amount
95 #define SILC_SERVER_COMMAND_CHECK(command, context, min, max) \
99 if (silc_server_command_pending_error_check(cmd, context2, command)) { \
100 SILC_LOG_DEBUG(("Error occurred in command reply, command not called")); \
101 silc_server_command_free(cmd); \
105 _argc = silc_argument_get_arg_num(cmd->args); \
107 SILC_LOG_DEBUG(("Not enough parameters in command")); \
108 silc_server_command_send_status_reply(cmd, command, \
109 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, \
111 silc_server_command_free(cmd); \
115 SILC_LOG_DEBUG(("Too many parameters in command")); \
116 silc_server_command_send_status_reply(cmd, command, \
117 SILC_STATUS_ERR_TOO_MANY_PARAMS, \
119 silc_server_command_free(cmd); \
124 /* Returns TRUE if the connection is registered. Unregistered connections
125 usually cannot send commands hence the check. */
127 static int silc_server_is_registered(SilcServer server,
128 SilcSocketConnection sock,
129 SilcServerCommandContext cmd,
132 SilcIDListData idata = (SilcIDListData)sock->user_data;
137 if (idata->status & SILC_IDLIST_STATUS_REGISTERED)
140 silc_server_command_send_status_reply(cmd, command,
141 SILC_STATUS_ERR_NOT_REGISTERED, 0);
145 /* Internal context to hold data when executed command with timeout. */
147 SilcServerCommandContext ctx;
148 SilcServerCommand *cmd;
149 } *SilcServerCommandTimeout;
151 /* Timeout callback to process commands with timeout for client. Client's
152 commands are always executed with timeout. */
154 SILC_TASK_CALLBACK(silc_server_command_process_timeout)
156 SilcServerCommandTimeout timeout = (SilcServerCommandTimeout)context;
157 SilcClientEntry client = (SilcClientEntry)timeout->ctx->sock->user_data;
160 SILC_LOG_DEBUG(("Client entry is invalid"));
161 silc_server_command_free(timeout->ctx);
166 /* Update access time */
167 client->last_command = time(NULL);
169 if (!(timeout->cmd->flags & SILC_CF_REG)) {
170 SILC_LOG_DEBUG(("Calling %s command",
171 silc_get_command_name(timeout->cmd->cmd)));
172 timeout->cmd->cb(timeout->ctx, NULL);
173 } else if (silc_server_is_registered(timeout->ctx->server,
176 timeout->cmd->cmd)) {
177 SILC_LOG_DEBUG(("Calling %s command",
178 silc_get_command_name(timeout->cmd->cmd)));
179 timeout->cmd->cb(timeout->ctx, NULL);
181 SILC_LOG_DEBUG(("Client is not registered"));
182 silc_server_command_free(timeout->ctx);
188 /* Processes received command packet. */
190 void silc_server_command_process(SilcServer server,
191 SilcSocketConnection sock,
192 SilcPacketContext *packet)
194 SilcServerCommandContext ctx;
195 SilcServerCommand *cmd;
198 /* Allocate command context. This must be free'd by the
199 command routine receiving it. */
200 ctx = silc_server_command_alloc();
201 ctx->server = server;
202 ctx->sock = silc_socket_dup(sock);
203 ctx->packet = silc_packet_context_dup(packet); /* Save original packet */
205 /* Parse the command payload in the packet */
206 ctx->payload = silc_command_payload_parse(packet->buffer->data,
207 packet->buffer->len);
209 SILC_LOG_ERROR(("Bad command payload, dropped (%s:%d [%s])",
210 sock->hostname, sock->port,
211 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
212 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
213 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
215 silc_packet_context_free(packet);
216 silc_socket_free(ctx->sock);
220 ctx->args = silc_command_get_args(ctx->payload);
222 /* Get the command */
223 command = silc_command_get(ctx->payload);
224 for (cmd = silc_command_list; cmd->cb; cmd++)
225 if (cmd->cmd == command)
228 if (!cmd || !cmd->cb) {
229 SILC_LOG_DEBUG(("Unknown command %d", command));
230 silc_server_command_send_status_reply(ctx, command,
231 SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
232 silc_server_command_free(ctx);
236 /* Execute client's commands always with timeout. Normally they are
237 executed with zero (0) timeout but if client is sending command more
238 frequently than once in 2 seconds, then the timeout may be 0 to 2
240 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
241 SilcClientEntry client = (SilcClientEntry)sock->user_data;
242 SilcServerCommandTimeout timeout;
246 SILC_LOG_DEBUG(("Client entry is invalid"));
247 silc_server_command_free(ctx);
251 timeout = silc_calloc(1, sizeof(*timeout));
255 if (client->last_command && (time(NULL) - client->last_command) < 2) {
256 client->fast_command++;
259 if (client->fast_command - 2 <= 0)
260 client->fast_command = 0;
262 client->fast_command -= 2;
266 if (!fast && ((cmd->flags & SILC_CF_LAG_STRICT) ||
267 (client->fast_command > 5 && cmd->flags & SILC_CF_LAG)))
268 silc_schedule_task_add(server->schedule, sock->sock,
269 silc_server_command_process_timeout, timeout,
270 (client->fast_command < 3 ? 0 :
271 2 - (time(NULL) - client->last_command)),
272 (client->fast_command < 3 ? 200000 : 0),
273 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
275 silc_schedule_task_add(server->schedule, sock->sock,
276 silc_server_command_process_timeout, timeout,
277 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
281 /* Execute for server */
283 if (!(cmd->flags & SILC_CF_REG)) {
284 SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
286 } else if (silc_server_is_registered(server, sock, ctx, cmd->cmd)) {
287 SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
290 SILC_LOG_DEBUG(("Server is not registered"));
291 silc_server_command_free(ctx);
295 /* Allocate Command Context */
297 SilcServerCommandContext silc_server_command_alloc()
299 SilcServerCommandContext ctx = silc_calloc(1, sizeof(*ctx));
304 /* Free's the command context allocated before executing the command */
306 void silc_server_command_free(SilcServerCommandContext ctx)
309 SILC_LOG_DEBUG(("Command context %p refcnt %d->%d", ctx, ctx->users + 1,
311 if (ctx->users < 1) {
313 silc_command_payload_free(ctx->payload);
315 silc_packet_context_free(ctx->packet);
317 silc_socket_free(ctx->sock); /* Decrease reference counter */
322 /* Duplicate Command Context by adding reference counter. The context won't
323 be free'd untill it hits zero. */
325 SilcServerCommandContext
326 silc_server_command_dup(SilcServerCommandContext ctx)
329 SILC_LOG_DEBUG(("Command context %p refcnt %d->%d", ctx, ctx->users - 1,
334 /* Timeout for pending command. If reply to pending command never arrives
335 this is called to free resources. */
337 SILC_TASK_CALLBACK(silc_server_command_pending_timeout)
339 SilcServer server = app_context;
340 SilcServerCommandPending *reply = context;
341 SilcServerCommandReplyContext cmdr;
345 SILC_LOG_DEBUG(("Timeout pending command"));
347 /* Allocate temporary and bogus command reply context */
348 cmdr = silc_calloc(1, sizeof(*cmdr));
349 cmdr->server = server;
350 cmdr->ident = reply->ident;
352 /* Check for pending commands and mark to be exeucted */
354 silc_server_command_pending_check(server, reply->reply_cmd,
355 reply->ident, &cmdr->callbacks_count);
357 /* Create bogus command reply with an error inside */
359 silc_command_reply_payload_encode_va(reply->reply_cmd ? reply->reply_cmd :
360 SILC_COMMAND_RESERVED,
361 SILC_STATUS_ERR_TIMEDOUT, 0,
363 cmdr->payload = silc_command_payload_parse(tmpreply->data, tmpreply->len);
364 silc_buffer_free(tmpreply);
366 /* Call all callbacks. Same as SILC_SERVER_PENDING_EXEC macro. */
367 for (i = 0; i < cmdr->callbacks_count; i++)
368 if (cmdr->callbacks[i].callback)
369 (*cmdr->callbacks[i].callback)(cmdr->callbacks[i].context, cmdr);
371 silc_server_command_pending_del(server, reply->reply_cmd, reply->ident);
372 silc_server_command_reply_free(cmdr);
375 /* Add new pending command to be executed when reply to a command has been
376 received. The `reply_cmd' is the command that will call the `callback'
377 with `context' when reply has been received. It can be SILC_COMMAND_NONE
378 to match any command with the `ident'. If `ident' is non-zero
379 the `callback' will be executed when received reply with command
380 identifier `ident'. If there already exists pending command for the
381 specified command, ident, callback and context this function has no
384 bool silc_server_command_pending(SilcServer server,
385 SilcCommand reply_cmd,
387 SilcCommandCb callback,
390 return silc_server_command_pending_timed(server, reply_cmd, ident, callback,
394 /* Same as silc_server_command_pending with specific timeout for pending
395 commands. If the `timeout' is zero default timeout is used. */
397 bool silc_server_command_pending_timed(SilcServer server,
398 SilcCommand reply_cmd,
400 SilcCommandCb callback,
404 SilcServerCommandPending *reply;
406 /* Check whether identical pending already exists for same command,
407 ident, callback and callback context. If it does then it would be
408 error to register it again. */
409 silc_dlist_start(server->pending_commands);
410 while ((reply = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
411 if (reply->reply_cmd == reply_cmd && reply->ident == ident &&
412 reply->callback == callback && reply->context == context)
416 reply = silc_calloc(1, sizeof(*reply));
417 reply->reply_cmd = reply_cmd;
418 reply->ident = ident;
419 reply->context = context;
420 reply->callback = callback;
422 silc_schedule_task_add(server->schedule, 0,
423 silc_server_command_pending_timeout, reply,
424 timeout ? timeout : 10, 0,
425 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
426 silc_dlist_add(server->pending_commands, reply);
431 /* Deletes pending command by reply command type. */
433 void silc_server_command_pending_del(SilcServer server,
434 SilcCommand reply_cmd,
437 SilcServerCommandPending *r;
439 silc_dlist_start(server->pending_commands);
440 while ((r = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
441 if ((r->reply_cmd == reply_cmd || (r->reply_cmd == SILC_COMMAND_NONE &&
443 && r->ident == ident) {
444 silc_dlist_del(server->pending_commands, r);
446 silc_schedule_task_del(server->schedule, r->timeout);
452 /* Checks for pending commands and marks callbacks to be called from
453 the command reply function. Returns TRUE if there were pending command. */
455 SilcServerCommandPendingCallbacks
456 silc_server_command_pending_check(SilcServer server,
459 SilcUInt32 *callbacks_count)
461 SilcServerCommandPending *r;
462 SilcServerCommandPendingCallbacks callbacks = NULL;
465 silc_dlist_start(server->pending_commands);
466 while ((r = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
467 if ((r->reply_cmd == command || r->reply_cmd == SILC_COMMAND_NONE)
468 && r->ident == ident) {
469 callbacks = silc_realloc(callbacks, sizeof(*callbacks) * (i + 1));
470 callbacks[i].context = r->context;
471 callbacks[i].callback = r->callback;
472 r->reply_check = TRUE;
477 *callbacks_count = i;
481 /* Sends simple status message as command reply packet */
484 silc_server_command_send_status_reply(SilcServerCommandContext cmd,
491 SILC_LOG_DEBUG(("Sending command status %d", status));
494 silc_command_reply_payload_encode_va(command, status, error,
495 silc_command_get_ident(cmd->payload),
497 silc_server_packet_send(cmd->server, cmd->sock,
498 SILC_PACKET_COMMAND_REPLY, 0,
499 buffer->data, buffer->len, FALSE);
500 silc_buffer_free(buffer);
503 /* Sends command status reply with one extra argument. The argument
504 type must be sent as argument. */
507 silc_server_command_send_status_data(SilcServerCommandContext cmd,
512 const unsigned char *arg,
517 SILC_LOG_DEBUG(("Sending command status %d", status));
520 silc_command_reply_payload_encode_va(command, status, 0,
521 silc_command_get_ident(cmd->payload),
522 1, arg_type, arg, arg_len);
523 silc_server_packet_send(cmd->server, cmd->sock,
524 SILC_PACKET_COMMAND_REPLY, 0,
525 buffer->data, buffer->len, FALSE);
526 silc_buffer_free(buffer);
530 silc_server_command_send_status_data2(SilcServerCommandContext cmd,
534 SilcUInt32 arg_type1,
535 const unsigned char *arg1,
537 SilcUInt32 arg_type2,
538 const unsigned char *arg2,
543 SILC_LOG_DEBUG(("Sending command status %d", status));
546 silc_command_reply_payload_encode_va(command, status, 0,
547 silc_command_get_ident(cmd->payload),
548 2, arg_type1, arg1, arg_len1,
549 arg_type2, arg2, arg_len2);
550 silc_server_packet_send(cmd->server, cmd->sock,
551 SILC_PACKET_COMMAND_REPLY, 0,
552 buffer->data, buffer->len, FALSE);
553 silc_buffer_free(buffer);
556 /* This function can be called to check whether in the command reply
557 an error occurred. This function has no effect if this is called
558 when the command function was not called as pending command callback.
559 This returns TRUE if error had occurred. */
562 silc_server_command_pending_error_check(SilcServerCommandContext cmd,
563 SilcServerCommandReplyContext cmdr,
566 if (!cmd->pending || !cmdr)
569 if (!silc_command_get_status(cmdr->payload, NULL, NULL)) {
572 /* Send the same command reply payload */
573 silc_command_set_command(cmdr->payload, silc_command_get(cmd->payload));
574 silc_command_set_ident(cmdr->payload,
575 silc_command_get_ident(cmd->payload));
576 buffer = silc_command_payload_encode_payload(cmdr->payload);
577 silc_server_packet_send(cmd->server, cmd->sock,
578 SILC_PACKET_COMMAND_REPLY, 0,
579 buffer->data, buffer->len, FALSE);
580 silc_buffer_free(buffer);
587 /* Server side of command WHOIS. */
589 SILC_SERVER_CMD_FUNC(whois)
591 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
592 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WHOIS, cmd, 1, 256);
593 silc_server_query_command(cmd->server, SILC_COMMAND_WHOIS, cmd);
594 silc_server_command_free(cmd);
597 /* Server side of command WHOWAS. */
599 SILC_SERVER_CMD_FUNC(whowas)
601 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
602 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WHOWAS, cmd, 1, 2);
603 silc_server_query_command(cmd->server, SILC_COMMAND_WHOWAS, cmd);
604 silc_server_command_free(cmd);
607 /* Server side of command IDENTIFY. */
609 SILC_SERVER_CMD_FUNC(identify)
611 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
612 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_IDENTIFY, cmd, 1, 256);
613 silc_server_query_command(cmd->server, SILC_COMMAND_IDENTIFY, cmd);
614 silc_server_command_free(cmd);
617 /* Server side of command NICK. Sets nickname for user. Setting
618 nickname causes generation of a new client ID for the client. The
619 new client ID is sent to the client after changing the nickname. */
621 SILC_SERVER_CMD_FUNC(nick)
623 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
624 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
625 SilcServer server = cmd->server;
626 SilcBuffer packet, nidp, oidp = NULL;
627 SilcClientID *new_id;
629 unsigned char *nick, *nickc = NULL;
630 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
632 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
635 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_NICK, cmd, 1, 1);
638 nick = silc_argument_get_arg_type(cmd->args, 1, &nick_len);
640 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
641 SILC_STATUS_ERR_BAD_NICKNAME, 0);
645 /* Truncate over long nicks */
646 if (nick_len > 128) {
651 /* Check for valid nickname string. This is cached, original is saved
652 in the client context. */
653 nickc = silc_identifier_check(nick, nick_len, SILC_STRING_UTF8, 128, NULL);
655 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
656 SILC_STATUS_ERR_BAD_NICKNAME, 0);
660 /* Check for same nickname */
661 if (!memcmp(client->nickname, nick, nick_len)) {
662 nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
667 /* Create new Client ID */
668 if (!silc_id_create_client_id(cmd->server, cmd->server->id,
670 cmd->server->md5hash,
671 nickc, strlen(nickc), &new_id)) {
672 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
673 SILC_STATUS_ERR_BAD_NICKNAME, 0);
678 /* Send notify about nickname change to our router. We send the new
679 ID and ask to replace it with the old one. If we are router the
680 packet is broadcasted. Send NICK_CHANGE notify. */
681 silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
682 SILC_BROADCAST(server), client->id,
685 /* Check if anyone is watching the old nickname */
686 if (server->server_type == SILC_ROUTER)
687 silc_server_check_watcher_list(server, client, nick,
688 SILC_NOTIFY_TYPE_NICK_CHANGE);
690 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
692 /* Remove old cache entry */
693 silc_idcache_del_by_context(server->local_list->clients, client);
695 silc_free(client->id);
698 silc_free(client->nickname);
699 client->nickname = nick;
701 /* Update client cache */
702 silc_idcache_add(server->local_list->clients, nickc,
703 client->id, (void *)client, 0, NULL);
705 nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
707 /* Send NICK_CHANGE notify to the client's channels */
708 silc_server_send_notify_on_channels(server, NULL, client,
709 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
710 oidp->data, oidp->len,
711 nidp->data, nidp->len,
713 strlen(client->nickname));
715 /* Check if anyone is watching the new nickname */
716 if (server->server_type == SILC_ROUTER)
717 silc_server_check_watcher_list(server, client, NULL,
718 SILC_NOTIFY_TYPE_NICK_CHANGE);
721 /* Send the new Client ID as reply command back to client */
722 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_NICK,
723 SILC_STATUS_OK, 0, ident, 2,
724 2, nidp->data, nidp->len,
726 silc_server_packet_send(cmd->server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
727 0, packet->data, packet->len, FALSE);
729 silc_buffer_free(packet);
730 silc_buffer_free(nidp);
732 silc_buffer_free(oidp);
735 silc_server_command_free(cmd);
738 /* Sends the LIST command reply */
741 silc_server_command_list_send_reply(SilcServerCommandContext cmd,
742 SilcChannelEntry *lch,
743 SilcUInt32 lch_count,
744 SilcChannelEntry *gch,
745 SilcUInt32 gch_count)
748 SilcBuffer packet, idp;
749 SilcChannelEntry entry;
751 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
753 unsigned char usercount[4];
755 int valid_lcount = 0, valid_rcount = 0;
757 for (i = 0; i < lch_count; i++) {
758 if (lch[i]->mode & SILC_CHANNEL_MODE_SECRET)
763 for (i = 0; i < gch_count; i++) {
764 if (gch[i]->mode & SILC_CHANNEL_MODE_SECRET)
770 if (!lch_count && !gch_count) {
771 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LIST,
776 status = SILC_STATUS_OK;
777 if ((lch_count + gch_count) > 1)
778 status = SILC_STATUS_LIST_START;
781 for (i = 0, k = 0; i < lch_count; i++) {
787 status = SILC_STATUS_LIST_ITEM;
788 if (valid_lcount > 1 && k == valid_lcount - 1 && !valid_rcount)
789 status = SILC_STATUS_LIST_END;
791 idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
793 if (entry->mode & SILC_CHANNEL_MODE_PRIVATE) {
795 memset(usercount, 0, sizeof(usercount));
797 topic = entry->topic;
798 users = silc_hash_table_count(entry->user_list);
799 SILC_PUT32_MSB(users, usercount);
804 silc_command_reply_payload_encode_va(SILC_COMMAND_LIST,
806 2, idp->data, idp->len,
807 3, entry->channel_name,
808 strlen(entry->channel_name),
809 4, topic, topic ? strlen(topic) : 0,
811 silc_server_packet_send(cmd->server, cmd->sock,
812 SILC_PACKET_COMMAND_REPLY, 0, packet->data,
814 silc_buffer_free(packet);
815 silc_buffer_free(idp);
820 for (i = 0, k = 0; i < gch_count; i++) {
826 status = SILC_STATUS_LIST_ITEM;
827 if (valid_rcount > 1 && k == valid_rcount - 1)
828 status = SILC_STATUS_LIST_END;
830 idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
832 if (entry->mode & SILC_CHANNEL_MODE_PRIVATE) {
834 memset(usercount, 0, sizeof(usercount));
836 topic = entry->topic;
837 users = entry->user_count;
838 SILC_PUT32_MSB(users, usercount);
843 silc_command_reply_payload_encode_va(SILC_COMMAND_LIST,
845 2, idp->data, idp->len,
846 3, entry->channel_name,
847 strlen(entry->channel_name),
848 4, topic, topic ? strlen(topic) : 0,
850 silc_server_packet_send(cmd->server, cmd->sock,
851 SILC_PACKET_COMMAND_REPLY, 0, packet->data,
853 silc_buffer_free(packet);
854 silc_buffer_free(idp);
859 /* Server side of LIST command. This lists the channel of the requested
860 server. Secret channels are not listed. */
862 SILC_SERVER_CMD_FUNC(list)
864 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
865 SilcServer server = cmd->server;
866 SilcChannelID *channel_id = NULL;
869 SilcChannelEntry *lchannels = NULL, *gchannels = NULL;
870 SilcUInt32 lch_count = 0, gch_count = 0;
872 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LIST, cmd, 0, 1);
874 /* If we are normal server, send the command to router, since we
875 want to know all channels in the network. */
876 if (!cmd->pending && server->server_type != SILC_ROUTER &&
877 !server->standalone) {
879 SilcUInt16 old_ident;
881 old_ident = silc_command_get_ident(cmd->payload);
882 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
883 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
884 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
885 SILC_PACKET_COMMAND, cmd->packet->flags,
886 tmpbuf->data, tmpbuf->len, TRUE);
888 /* Reprocess this packet after received reply from router */
889 silc_server_command_pending(server, SILC_COMMAND_LIST,
890 silc_command_get_ident(cmd->payload),
891 silc_server_command_list,
892 silc_server_command_dup(cmd));
894 silc_command_set_ident(cmd->payload, old_ident);
895 silc_buffer_free(tmpbuf);
900 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
902 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
904 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LIST,
905 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
910 /* Get the channels from local list */
911 lchannels = silc_idlist_get_channels(server->local_list, channel_id,
914 /* Get the channels from global list */
915 gchannels = silc_idlist_get_channels(server->global_list, channel_id,
919 silc_server_command_list_send_reply(cmd, lchannels, lch_count,
920 gchannels, gch_count);
922 silc_free(lchannels);
923 silc_free(gchannels);
926 silc_server_command_free(cmd);
929 /* Server side of TOPIC command. Sets topic for channel and/or returns
930 current topic to client. */
932 SILC_SERVER_CMD_FUNC(topic)
934 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
935 SilcServer server = cmd->server;
936 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
937 SilcChannelID *channel_id;
938 SilcChannelEntry channel;
939 SilcChannelClientEntry chl;
940 SilcBuffer packet, idp;
942 SilcUInt32 argc, tmp_len;
943 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
945 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
948 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_TOPIC, cmd, 1, 2);
950 argc = silc_argument_get_arg_num(cmd->args);
953 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
955 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
956 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
959 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
961 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
962 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
966 /* Check whether the channel exists */
967 channel = silc_idlist_find_channel_by_id(server->local_list,
970 channel = silc_idlist_find_channel_by_id(server->global_list,
973 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
974 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
982 tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
984 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
985 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
990 if (strlen(tmp) > 256) {
991 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
992 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
997 /* See whether the client is on channel and has rights to change topic */
998 if (!silc_server_client_on_channel(client, channel, &chl)) {
999 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1000 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
1001 SILC_STATUS_ERR_NOT_ON_CHANNEL,
1002 0, 2, tmp, tmp_len);
1006 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
1007 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1008 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1009 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1010 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
1011 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
1012 0, 2, tmp, tmp_len);
1016 if (!channel->topic || strcmp(channel->topic, tmp)) {
1017 /* Set the topic for channel */
1018 silc_free(channel->topic);
1019 channel->topic = strdup(tmp);
1021 /* Send TOPIC_SET notify type to the network */
1022 silc_server_send_notify_topic_set(server, SILC_PRIMARY_ROUTE(server),
1023 SILC_BROADCAST(server), channel,
1024 client->id, SILC_ID_CLIENT,
1027 /* Send notify about topic change to all clients on the channel */
1028 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
1029 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
1030 SILC_NOTIFY_TYPE_TOPIC_SET, 2,
1031 idp->data, idp->len,
1033 strlen(channel->topic));
1034 silc_buffer_free(idp);
1038 /* Send the topic to client as reply packet */
1039 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
1040 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_TOPIC,
1041 SILC_STATUS_OK, 0, ident, 2,
1042 2, idp->data, idp->len,
1045 strlen(channel->topic) : 0);
1046 silc_server_packet_send(cmd->server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
1047 0, packet->data, packet->len, FALSE);
1049 silc_buffer_free(packet);
1050 silc_buffer_free(idp);
1051 silc_free(channel_id);
1054 silc_server_command_free(cmd);
1057 /* Server side of INVITE command. Invites some client to join some channel.
1058 This command is also used to manage the invite list of the channel. */
1060 SILC_SERVER_CMD_FUNC(invite)
1062 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1063 SilcServer server = cmd->server;
1064 SilcSocketConnection sock = cmd->sock, dest_sock;
1065 SilcChannelClientEntry chl;
1066 SilcClientEntry sender, dest;
1067 SilcClientID *dest_id = NULL;
1068 SilcChannelEntry channel;
1069 SilcChannelID *channel_id = NULL;
1070 SilcIDListData idata;
1071 SilcArgumentPayload args;
1072 SilcHashTableList htl;
1073 SilcBuffer packet, list, tmp2;
1074 SilcBufferStruct alist;
1075 unsigned char *tmp, *atype = NULL;
1076 SilcUInt32 len, type, len2;
1077 SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
1079 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INVITE, cmd, 1, 4);
1081 /* Get Channel ID */
1082 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1084 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1085 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
1088 channel_id = silc_id_payload_parse_id(tmp, len, NULL);
1090 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1091 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
1095 /* Get the channel entry */
1096 channel = silc_idlist_find_channel_by_id(server->local_list,
1099 channel = silc_idlist_find_channel_by_id(server->global_list,
1102 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1103 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
1109 /* Check whether the sender of this command is on the channel. */
1110 sender = (SilcClientEntry)sock->user_data;
1111 if (!sender || !silc_server_client_on_channel(sender, channel, &chl)) {
1112 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1113 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
1118 /* Check whether the channel is invite-only channel. If yes then the
1119 sender of this command must be at least channel operator. */
1120 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
1121 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1122 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1123 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1124 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
1129 /* Get destination client ID */
1130 tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
1134 dest_id = silc_id_payload_parse_id(tmp, len, NULL);
1136 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1137 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
1141 /* Get the client entry */
1142 dest = silc_server_query_client(server, dest_id, FALSE, &resolve);
1144 if (server->server_type != SILC_SERVER || !resolve || cmd->pending) {
1145 silc_server_command_send_status_data(
1146 cmd, SILC_COMMAND_INVITE,
1147 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1152 /* The client info is being resolved. Reprocess this packet after
1153 receiving the reply to the query. */
1154 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
1156 silc_server_command_invite,
1157 silc_server_command_dup(cmd));
1158 cmd->pending = TRUE;
1162 /* Check whether the requested client is already on the channel. */
1163 if (silc_server_client_on_channel(dest, channel, NULL)) {
1164 atype = silc_argument_get_arg_type(cmd->args, 1, &len2);
1165 silc_server_command_send_status_data2(cmd, SILC_COMMAND_INVITE,
1166 SILC_STATUS_ERR_USER_ON_CHANNEL,
1172 /* Get route to the client */
1173 dest_sock = silc_server_get_client_route(server, NULL, 0, dest_id,
1176 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1177 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1182 /* Add the client to the invite list */
1184 /* Allocate hash table for invite list if it doesn't exist yet */
1185 if (!channel->invite_list)
1186 channel->invite_list =
1187 silc_hash_table_alloc(0, silc_hash_ptr,
1189 silc_server_inviteban_destruct, channel, TRUE);
1191 /* Check if the ID is in the list already */
1192 silc_hash_table_list(channel->invite_list, &htl);
1193 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
1194 if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
1199 silc_hash_table_list_reset(&htl);
1201 /* Add new Client ID to invite list */
1203 list = silc_buffer_alloc_size(len);
1204 silc_buffer_put(list, tmp, len);
1205 silc_hash_table_add(channel->invite_list, (void *)3, list);
1208 if (!(dest->mode & SILC_UMODE_BLOCK_INVITE)) {
1209 /* Send notify to the client that is invited to the channel */
1210 SilcBuffer idp, idp2;
1211 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
1212 idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
1213 silc_server_send_notify_dest(server, dest_sock, FALSE, dest_id,
1215 SILC_NOTIFY_TYPE_INVITE, 3,
1216 idp->data, idp->len,
1217 channel->channel_name,
1218 strlen(channel->channel_name),
1219 idp2->data, idp2->len);
1220 silc_buffer_free(idp);
1221 silc_buffer_free(idp2);
1225 /* Get the invite information */
1226 tmp = silc_argument_get_arg_type(cmd->args, 4, &len2);
1227 if (tmp && len2 > 2) {
1228 /* Parse the arguments to see they are constructed correctly */
1229 SILC_GET16_MSB(argc, tmp);
1230 args = silc_argument_payload_parse(tmp + 2, len2 - 2, argc);
1232 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1233 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1238 /* Get the type of action */
1239 atype = silc_argument_get_arg_type(cmd->args, 3, &len);
1240 if (atype && len == 1) {
1241 if (atype[0] == 0x00) {
1242 /* Allocate hash table for invite list if it doesn't exist yet */
1243 if (!channel->invite_list)
1244 channel->invite_list =
1245 silc_hash_table_alloc(0, silc_hash_ptr,
1247 silc_server_inviteban_destruct, channel,
1250 /* Check for resource limit */
1251 if (silc_hash_table_count(channel->invite_list) > 64) {
1252 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1253 SILC_STATUS_ERR_RESOURCE_LIMIT,
1259 /* Now add or delete the information. */
1260 silc_server_inviteban_process(server, channel->invite_list,
1261 (SilcUInt8)atype[0], args);
1263 silc_argument_payload_free(args);
1266 /* Encode invite list */
1268 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
1269 list = silc_buffer_alloc_size(2);
1270 silc_buffer_format(list,
1271 SILC_STR_UI_SHORT(silc_hash_table_count(
1272 channel->invite_list)),
1274 silc_hash_table_list(channel->invite_list, &htl);
1275 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
1276 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
1278 silc_hash_table_list_reset(&htl);
1281 /* The notify is sent to local servers (not clients), and to network. */
1282 if (atype && tmp && len2) {
1283 silc_buffer_set(&alist, tmp, len2);
1285 /* Send to local servers if we are router */
1286 if (server->server_type == SILC_ROUTER) {
1287 SilcBuffer idp, idp2;
1288 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
1289 idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
1290 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
1291 SILC_NOTIFY_TYPE_INVITE, 5,
1292 idp->data, idp->len,
1293 channel->channel_name,
1294 strlen(channel->channel_name),
1295 idp2->data, idp2->len,
1297 tmp ? alist.data : NULL,
1298 tmp ? alist.len : 0);
1299 silc_buffer_free(idp);
1300 silc_buffer_free(idp2);
1303 /* Send to network */
1304 silc_server_send_notify_invite(server, SILC_PRIMARY_ROUTE(server),
1305 SILC_BROADCAST(server), channel,
1307 tmp ? &alist : NULL);
1310 /* Send invite list back only if the list was modified, or no arguments
1313 argc = silc_argument_get_arg_num(cmd->args);
1316 if (silc_argument_get_arg_type(cmd->args, 3, &len))
1319 /* Send command reply */
1320 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1321 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
1322 SILC_STATUS_OK, 0, ident, 2,
1326 type && list ? list->len : 0);
1327 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
1328 packet->data, packet->len, FALSE);
1329 silc_buffer_free(packet);
1330 silc_buffer_free(list);
1334 silc_free(channel_id);
1335 silc_server_command_free(cmd);
1339 SilcSocketConnection sock;
1343 /* Quits connection to client. This gets called if client won't
1344 close the connection even when it has issued QUIT command. */
1346 SILC_TASK_CALLBACK(silc_server_command_quit_cb)
1348 SilcServer server = app_context;
1349 QuitInternal q = (QuitInternal)context;
1351 if (q->sock->user_data) {
1352 /* Free all client specific data, such as client entry and entires
1353 on channels this client may be on. */
1354 silc_server_free_client_data(server, q->sock, q->sock->user_data,
1356 q->sock->user_data = NULL;
1359 if (!SILC_IS_DISCONNECTED(q->sock))
1360 /* Close the connection on our side */
1361 silc_server_close_connection(server, q->sock);
1363 silc_socket_free(q->sock);
1364 silc_free(q->signoff);
1368 /* Quits SILC session. This is the normal way to disconnect client. */
1370 SILC_SERVER_CMD_FUNC(quit)
1372 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1373 SilcServer server = cmd->server;
1374 SilcSocketConnection sock = cmd->sock;
1376 unsigned char *tmp = NULL;
1379 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_QUIT, cmd, 0, 1);
1381 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
1385 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1389 q = silc_calloc(1, sizeof(*q));
1390 q->sock = silc_socket_dup(sock);
1391 q->signoff = tmp ? strdup(tmp) : NULL;
1393 /* We quit the connection with little timeout */
1394 silc_schedule_task_add(server->schedule, sock->sock,
1395 silc_server_command_quit_cb, (void *)q,
1396 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
1399 silc_server_command_free(cmd);
1402 /* Server side of command KILL. This command is used by router operator
1403 to remove an client from the SILC Network temporarily. */
1405 SILC_SERVER_CMD_FUNC(kill)
1407 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1408 SilcServer server = cmd->server;
1409 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
1410 SilcClientEntry remote_client;
1411 SilcClientID *client_id = NULL;
1412 unsigned char *tmp, *comment, *auth;
1413 SilcUInt32 tmp_len, tmp_len2, auth_len;
1415 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 3);
1417 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
1420 /* Get authentication payload if present */
1421 auth = silc_argument_get_arg_type(cmd->args, 3, &auth_len);
1424 /* Router operator killing */
1426 /* KILL command works only on router */
1427 if (server->server_type != SILC_ROUTER) {
1428 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1429 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
1433 /* Check whether client has the permissions. */
1434 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1435 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1436 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
1441 /* Get the client ID */
1442 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1444 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1445 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1449 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1451 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1452 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1453 0, 2, tmp, tmp_len);
1457 /* Get the client entry */
1458 remote_client = silc_idlist_find_client_by_id(server->local_list,
1459 client_id, TRUE, NULL);
1460 if (!remote_client) {
1461 remote_client = silc_idlist_find_client_by_id(server->global_list,
1462 client_id, TRUE, NULL);
1463 if (!remote_client) {
1464 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1465 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1466 0, 2, tmp, tmp_len);
1472 comment = silc_argument_get_arg_type(cmd->args, 2, &tmp_len2);
1473 if (comment && tmp_len2 > 128) {
1475 comment[127] = '\0';
1478 /* If authentication data is provided then verify that killing is
1480 if (auth && auth_len) {
1481 SilcSocketConnection sock;
1483 if (!SILC_IS_LOCAL(remote_client) || !remote_client->data.public_key) {
1484 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1485 SILC_STATUS_ERR_OPERATION_ALLOWED,
1490 /* Verify the signature */
1491 if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
1492 remote_client->data.public_key, 0,
1493 server->sha1hash, remote_client->id,
1495 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1496 SILC_STATUS_ERR_AUTH_FAILED, 0);
1500 /* Send reply to the sender */
1501 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1505 /* Do normal signoff for the destination client */
1506 sock = remote_client->connection;
1507 silc_server_remove_from_channels(server, NULL, remote_client,
1508 TRUE, (char *)"Killed", TRUE, TRUE);
1509 silc_server_free_client_data(server, NULL, remote_client, TRUE,
1511 (unsigned char *)"Killed");
1513 silc_server_close_connection(server, sock);
1515 /* Router operator killing */
1517 /* Send reply to the sender */
1518 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1522 /* Check if anyone is watching this nickname */
1523 if (server->server_type == SILC_ROUTER)
1524 silc_server_check_watcher_list(server, client, NULL,
1525 SILC_NOTIFY_TYPE_KILLED);
1527 /* Now do the killing */
1528 silc_server_kill_client(server, remote_client, comment, client->id,
1533 silc_free(client_id);
1534 silc_server_command_free(cmd);
1537 /* Server side of command INFO. This sends information about us to
1538 the client. If client requested specific server we will send the
1539 command to that server. */
1541 SILC_SERVER_CMD_FUNC(info)
1543 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1544 SilcServer server = cmd->server;
1545 SilcBuffer packet, idp;
1548 char *dest_server = NULL, *server_info = NULL, *server_name;
1549 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1550 SilcServerEntry entry = NULL;
1551 SilcServerID *server_id = NULL;
1553 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INFO, cmd, 0, 2);
1555 /* Get server name */
1556 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
1558 /* Check server name. */
1559 dest_server = silc_identifier_check(dest_server, strlen(dest_server),
1560 SILC_STRING_UTF8, 256, &tmp_len);
1562 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
1563 SILC_STATUS_ERR_BAD_SERVER, 0);
1569 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
1571 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1573 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
1574 SILC_STATUS_ERR_NO_SERVER_ID, 0);
1580 /* Check whether we have this server cached */
1581 entry = silc_idlist_find_server_by_id(server->local_list,
1582 server_id, TRUE, NULL);
1584 entry = silc_idlist_find_server_by_id(server->global_list,
1585 server_id, TRUE, NULL);
1586 if (!entry && server->server_type != SILC_SERVER) {
1587 silc_server_command_send_status_data(cmd, SILC_COMMAND_INFO,
1588 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
1589 0, 2, tmp, tmp_len);
1595 /* Some buggy servers has sent request to router about themselves. */
1596 if (server->server_type != SILC_SERVER && cmd->sock->user_data == entry)
1599 if ((!dest_server && !server_id && !entry) || (entry &&
1600 entry == server->id_entry) ||
1601 (dest_server && !cmd->pending &&
1602 !memcmp(dest_server, server->server_name, strlen(dest_server)))) {
1603 /* Send our reply */
1604 char info_string[256];
1606 memset(info_string, 0, sizeof(info_string));
1607 snprintf(info_string, sizeof(info_string),
1608 "location: %s server: %s admin: %s <%s>",
1609 server->config->server_info->location,
1610 server->config->server_info->server_type,
1611 server->config->server_info->admin,
1612 server->config->server_info->email);
1614 server_info = info_string;
1615 entry = server->id_entry;
1617 /* Check whether we have this server cached */
1618 if (!entry && dest_server) {
1619 entry = silc_idlist_find_server_by_name(server->global_list,
1620 dest_server, TRUE, NULL);
1622 entry = silc_idlist_find_server_by_name(server->local_list,
1623 dest_server, TRUE, NULL);
1627 if (!cmd->pending &&
1628 server->server_type != SILC_SERVER && entry && !entry->server_info) {
1629 /* Send to the server */
1631 SilcUInt16 old_ident;
1633 old_ident = silc_command_get_ident(cmd->payload);
1634 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1635 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1637 silc_server_packet_send(server, entry->connection,
1638 SILC_PACKET_COMMAND, cmd->packet->flags,
1639 tmpbuf->data, tmpbuf->len, TRUE);
1641 /* Reprocess this packet after received reply from router */
1642 silc_server_command_pending(server, SILC_COMMAND_INFO,
1643 silc_command_get_ident(cmd->payload),
1644 silc_server_command_info,
1645 silc_server_command_dup(cmd));
1646 cmd->pending = TRUE;
1647 silc_command_set_ident(cmd->payload, old_ident);
1648 silc_buffer_free(tmpbuf);
1652 if (!entry && !cmd->pending && !server->standalone) {
1653 /* Send to the primary router */
1655 SilcUInt16 old_ident;
1657 old_ident = silc_command_get_ident(cmd->payload);
1658 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1659 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1661 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
1662 SILC_PACKET_COMMAND, cmd->packet->flags,
1663 tmpbuf->data, tmpbuf->len, TRUE);
1665 /* Reprocess this packet after received reply from router */
1666 silc_server_command_pending(server, SILC_COMMAND_INFO,
1667 silc_command_get_ident(cmd->payload),
1668 silc_server_command_info,
1669 silc_server_command_dup(cmd));
1670 cmd->pending = TRUE;
1671 silc_command_set_ident(cmd->payload, old_ident);
1672 silc_buffer_free(tmpbuf);
1677 silc_free(server_id);
1681 silc_free(dest_server);
1682 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
1683 silc_server_command_send_status_data(cmd, SILC_COMMAND_INFO,
1684 SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
1686 strlen(dest_server));
1692 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
1694 server_info = entry->server_info;
1695 server_name = entry->server_name;
1697 /* Send the reply */
1698 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO,
1699 SILC_STATUS_OK, 0, ident, 3,
1700 2, idp->data, idp->len,
1702 strlen(server_name),
1705 strlen(server_info) : 0);
1706 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
1707 packet->data, packet->len, FALSE);
1709 silc_buffer_free(packet);
1710 silc_buffer_free(idp);
1713 silc_free(dest_server);
1714 silc_server_command_free(cmd);
1717 /* Server side of command PING. This just replies to the ping. */
1719 SILC_SERVER_CMD_FUNC(ping)
1721 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1722 SilcServer server = cmd->server;
1725 SilcServerID *server_id = NULL;
1727 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PING, cmd, 1, 1);
1730 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1732 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
1733 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1737 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1741 if (SILC_ID_SERVER_COMPARE(server_id, server->id)) {
1742 /* Send our reply */
1743 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
1746 silc_server_command_send_status_data(cmd, SILC_COMMAND_PING,
1747 SILC_STATUS_ERR_NO_SUCH_SERVER_ID, 0,
1753 silc_free(server_id);
1754 silc_server_command_free(cmd);
1757 /* Server side of command STATS. */
1759 SILC_SERVER_CMD_FUNC(stats)
1761 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1762 SilcServer server = cmd->server;
1763 SilcServerID *server_id;
1766 SilcBuffer packet, stats;
1767 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1770 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_STATS, cmd, 1, 1);
1773 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1775 silc_server_command_send_status_reply(cmd, SILC_COMMAND_STATS,
1776 SILC_STATUS_ERR_NO_SERVER_ID, 0);
1779 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1783 /* The ID must be ours */
1784 if (!SILC_ID_SERVER_COMPARE(server->id, server_id)) {
1785 silc_server_command_send_status_data(cmd, SILC_COMMAND_STATS,
1786 SILC_STATUS_ERR_NO_SUCH_SERVER_ID, 0,
1788 silc_free(server_id);
1791 silc_free(server_id);
1793 /* If we are router then just send everything we got. If we are normal
1794 server then we'll send this to our router to get all the latest
1795 statistical information. */
1796 if (!cmd->pending && server->server_type != SILC_ROUTER &&
1797 !server->standalone) {
1798 /* Send request to our router */
1799 SilcBuffer idp = silc_id_payload_encode(server->router->id,
1801 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
1802 ++server->cmd_ident, 1,
1803 1, idp->data, idp->len);
1804 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
1805 SILC_PACKET_COMMAND, 0, packet->data,
1806 packet->len, FALSE);
1808 /* Reprocess this packet after received reply from router */
1809 silc_server_command_pending(server, SILC_COMMAND_STATS,
1811 silc_server_command_stats,
1812 silc_server_command_dup(cmd));
1813 cmd->pending = TRUE;
1814 silc_buffer_free(packet);
1815 silc_buffer_free(idp);
1819 /* Send our reply to sender */
1820 uptime = time(NULL) - server->starttime;
1822 stats = silc_buffer_alloc_size(60);
1823 silc_buffer_format(stats,
1824 SILC_STR_UI_INT(server->starttime),
1825 SILC_STR_UI_INT(uptime),
1826 SILC_STR_UI_INT(server->stat.my_clients),
1827 SILC_STR_UI_INT(server->stat.my_channels),
1828 SILC_STR_UI_INT(server->stat.my_server_ops),
1829 SILC_STR_UI_INT(server->stat.my_router_ops),
1830 SILC_STR_UI_INT(server->stat.cell_clients),
1831 SILC_STR_UI_INT(server->stat.cell_channels),
1832 SILC_STR_UI_INT(server->stat.cell_servers),
1833 SILC_STR_UI_INT(server->stat.clients),
1834 SILC_STR_UI_INT(server->stat.channels),
1835 SILC_STR_UI_INT(server->stat.servers),
1836 SILC_STR_UI_INT(server->stat.routers),
1837 SILC_STR_UI_INT(server->stat.server_ops),
1838 SILC_STR_UI_INT(server->stat.router_ops),
1841 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_STATS,
1842 SILC_STATUS_OK, 0, ident, 2,
1844 3, stats->data, stats->len);
1845 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
1846 0, packet->data, packet->len, FALSE);
1847 silc_buffer_free(packet);
1848 silc_buffer_free(stats);
1851 silc_server_command_free(cmd);
1854 /* Internal routine to join channel. The channel sent to this function
1855 has been either created or resolved from ID lists. This joins the sent
1856 client to the channel. */
1858 static void silc_server_command_join_channel(SilcServer server,
1859 SilcServerCommandContext cmd,
1860 SilcChannelEntry channel,
1861 SilcClientID *client_id,
1865 const unsigned char *auth,
1866 SilcUInt32 auth_len,
1867 const unsigned char *cauth,
1868 SilcUInt32 cauth_len)
1870 SilcSocketConnection sock = cmd->sock;
1872 SilcUInt32 tmp_len, user_count;
1873 unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4], ulimit[4];
1874 SilcClientEntry client;
1875 SilcChannelClientEntry chl;
1876 SilcBuffer reply, chidp, clidp, keyp = NULL;
1877 SilcBuffer user_list, mode_list, invite_list, ban_list;
1878 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1879 char check[512], check2[512];
1880 bool founder = FALSE;
1882 SilcBuffer fkey = NULL, chpklist = NULL;
1885 SILC_LOG_DEBUG(("Joining client to channel"));
1890 /* Get the client entry */
1891 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
1892 client = (SilcClientEntry)sock->user_data;
1896 client = silc_server_query_client(server, client_id, FALSE,
1899 if (!resolve || cmd->pending) {
1900 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
1901 silc_server_command_send_status_data(
1902 cmd, SILC_COMMAND_JOIN,
1903 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1908 /* The client info is being resolved. Reprocess this packet after
1909 receiving the reply to the query. */
1910 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
1912 silc_server_command_join,
1913 silc_server_command_dup(cmd));
1914 cmd->pending = TRUE;
1918 if (!client->data.public_key &&
1919 (auth || cauth || channel->ban_list ||
1920 (channel->mode & SILC_CHANNEL_MODE_INVITE))) {
1921 if (cmd->pending == 2)
1924 /* We must retrieve the client's public key by sending
1925 GETKEY command. Reprocess this packet after receiving the key */
1926 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1927 silc_server_send_command(server, cmd->sock,
1928 SILC_COMMAND_GETKEY, ++server->cmd_ident,
1929 1, 1, clidp->data, clidp->len);
1930 silc_buffer_free(clidp);
1931 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
1933 silc_server_command_join,
1934 silc_server_command_dup(cmd));
1939 cmd->pending = FALSE;
1943 * Check founder auth payload if provided. If client can gain founder
1944 * privileges it can override various conditions on joining the channel,
1945 * and can have directly the founder mode set on the channel.
1947 if (auth && auth_len && channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1948 SilcIDListData idata = (SilcIDListData)client;
1949 SilcChannelClientEntry chl2;
1950 SilcHashTableList htl;
1952 if (channel->founder_key && idata->public_key &&
1953 silc_pkcs_public_key_compare(channel->founder_key,
1954 idata->public_key)) {
1955 /* Check whether the client is to become founder */
1956 if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
1957 channel->founder_key, 0, server->sha1hash,
1958 client->id, SILC_ID_CLIENT)) {
1960 /* There cannot be anyone else as founder on the channel now. This
1961 client is definitely the founder due to this authentication */
1962 silc_hash_table_list(channel->user_list, &htl);
1963 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
1964 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
1965 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
1966 silc_server_force_cumode_change(server, NULL, channel, chl2,
1970 silc_hash_table_list_reset(&htl);
1972 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
1979 * Check channel modes
1983 memset(check, 0, sizeof(check));
1984 memset(check2, 0, sizeof(check2));
1985 silc_strncat(check, sizeof(check),
1986 client->nickname, strlen(client->nickname));
1987 silc_strncat(check, sizeof(check), "!", 1);
1988 silc_strncat(check, sizeof(check),
1989 client->username, strlen(client->username));
1990 if (!strchr(client->username, '@')) {
1991 silc_strncat(check, sizeof(check), "@", 1);
1992 silc_strncat(check, sizeof(check),
1993 cmd->sock->hostname, strlen(cmd->sock->hostname));
1996 silc_strncat(check2, sizeof(check2),
1997 client->nickname, strlen(client->nickname));
1998 if (!strchr(client->nickname, '@')) {
1999 silc_strncat(check2, sizeof(check2), "@", 1);
2000 silc_strncat(check2, sizeof(check2),
2001 SILC_IS_LOCAL(client) ? server->server_name :
2002 client->router->server_name,
2003 SILC_IS_LOCAL(client) ? strlen(server->server_name) :
2004 strlen(client->router->server_name));
2006 silc_strncat(check2, sizeof(check2), "!", 1);
2007 silc_strncat(check2, sizeof(check2),
2008 client->username, strlen(client->username));
2009 if (!strchr(client->username, '@')) {
2010 silc_strncat(check2, sizeof(check2), "@", 1);
2011 silc_strncat(check2, sizeof(check2),
2012 cmd->sock->hostname, strlen(cmd->sock->hostname));
2015 /* Check invite list if channel is invite-only channel */
2016 if (channel->mode & SILC_CHANNEL_MODE_INVITE) {
2017 if (!channel->invite_list ||
2018 !silc_hash_table_count(channel->invite_list) ||
2019 (!silc_server_inviteban_match(server, channel->invite_list,
2021 !silc_server_inviteban_match(server, channel->invite_list,
2022 2, client->data.public_key) &&
2023 !silc_server_inviteban_match(server, channel->invite_list,
2024 1, client->nickname) &&
2025 !silc_server_inviteban_match(server, channel->invite_list,
2027 !silc_server_inviteban_match(server, channel->invite_list,
2029 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2030 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2031 SILC_STATUS_ERR_NOT_INVITED, 0,
2032 2, chidp->data, chidp->len);
2033 silc_buffer_free(chidp);
2038 /* Check ban list if it exists. If the client's nickname, server,
2039 username and/or hostname is in the ban list the access to the
2040 channel is denied. */
2041 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
2042 if (silc_server_inviteban_match(server, channel->ban_list,
2044 silc_server_inviteban_match(server, channel->ban_list,
2045 2, client->data.public_key) ||
2046 silc_server_inviteban_match(server, channel->ban_list,
2047 1, client->nickname) ||
2048 silc_server_inviteban_match(server, channel->ban_list,
2050 silc_server_inviteban_match(server, channel->ban_list,
2052 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2053 silc_server_command_send_status_data(
2054 cmd, SILC_COMMAND_JOIN,
2055 SILC_STATUS_ERR_BANNED_FROM_CHANNEL, 0,
2056 2, chidp->data, chidp->len);
2057 silc_buffer_free(chidp);
2062 /* Check user count limit if set. */
2063 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT) {
2064 if (silc_hash_table_count(channel->user_list) + 1 >
2065 channel->user_limit) {
2066 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2067 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2068 SILC_STATUS_ERR_CHANNEL_IS_FULL,
2069 0, 2, chidp->data, chidp->len);
2070 silc_buffer_free(chidp);
2076 /* Check the channel passphrase if set. */
2077 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
2078 /* Get passphrase */
2079 tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
2081 passphrase = silc_memdup(tmp, tmp_len);
2083 if (!passphrase || !channel->passphrase ||
2084 memcmp(passphrase, channel->passphrase, strlen(channel->passphrase))) {
2085 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2086 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2087 SILC_STATUS_ERR_BAD_PASSWORD, 0,
2088 2, chidp->data, chidp->len);
2089 silc_buffer_free(chidp);
2094 /* Verify channel authentication with channel public keys if set. */
2095 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
2096 if (!silc_server_verify_channel_auth(server, channel, client->id,
2097 cauth, cauth_len)) {
2098 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2099 SILC_STATUS_ERR_PERM_DENIED, 0);
2105 * Client is allowed to join to the channel. Make it happen.
2108 /* Check whether the client already is on the channel */
2109 if (silc_server_client_on_channel(client, channel, NULL)) {
2110 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
2111 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2112 silc_server_command_send_status_data2(cmd, SILC_COMMAND_JOIN,
2113 SILC_STATUS_ERR_USER_ON_CHANNEL, 0,
2114 2, clidp->data, clidp->len,
2115 3, chidp->data, chidp->len);
2116 silc_buffer_free(clidp);
2117 silc_buffer_free(chidp);
2121 /* Generate new channel key as protocol dictates */
2123 if (!silc_server_create_channel_key(server, channel, 0))
2126 /* Send the channel key. This is broadcasted to the channel but is not
2127 sent to the client who is joining to the channel. */
2128 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
2129 silc_server_send_channel_key(server, NULL, channel,
2130 server->server_type == SILC_ROUTER ?
2131 FALSE : !server->standalone);
2134 /* Join the client to the channel by adding it to channel's user list.
2135 Add also the channel to client entry's channels list for fast cross-
2137 chl = silc_calloc(1, sizeof(*chl));
2139 chl->client = client;
2140 chl->channel = channel;
2141 silc_hash_table_add(channel->user_list, client, chl);
2142 silc_hash_table_add(client->channels, channel, chl);
2143 channel->user_count++;
2144 channel->disabled = FALSE;
2146 /* Get users on the channel */
2147 silc_server_get_users_on_channel(server, channel, &user_list, &mode_list,
2150 /* Encode Client ID Payload of the original client who wants to join */
2151 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2153 /* Encode command reply packet */
2154 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2155 SILC_PUT32_MSB(channel->mode, mode);
2156 SILC_PUT32_MSB(created, tmp2);
2157 SILC_PUT32_MSB(user_count, tmp3);
2158 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2159 SILC_PUT32_MSB(channel->user_limit, ulimit);
2161 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2162 tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2163 cipher = silc_cipher_get_name(channel->channel_key);
2164 keyp = silc_channel_key_payload_encode(silc_id_get_len(channel->id,
2167 strlen(cipher), cipher,
2168 channel->key_len / 8, channel->key);
2172 if (channel->founder_key)
2173 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
2175 /* Encode invite list */
2177 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
2178 SilcHashTableList htl;
2180 invite_list = silc_buffer_alloc_size(2);
2181 silc_buffer_format(invite_list,
2182 SILC_STR_UI_SHORT(silc_hash_table_count(
2183 channel->invite_list)),
2186 silc_hash_table_list(channel->invite_list, &htl);
2187 while (silc_hash_table_get(&htl, (void *)&tmp_len, (void *)&reply))
2188 invite_list = silc_argument_payload_encode_one(invite_list,
2190 reply->len, tmp_len);
2191 silc_hash_table_list_reset(&htl);
2194 /* Encode ban list */
2196 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
2197 SilcHashTableList htl;
2199 ban_list = silc_buffer_alloc_size(2);
2200 silc_buffer_format(ban_list,
2201 SILC_STR_UI_SHORT(silc_hash_table_count(
2202 channel->ban_list)),
2205 silc_hash_table_list(channel->ban_list, &htl);
2206 while (silc_hash_table_get(&htl, (void *)&tmp_len, (void *)&reply))
2207 ban_list = silc_argument_payload_encode_one(ban_list,
2209 reply->len, tmp_len);
2210 silc_hash_table_list_reset(&htl);
2213 if (channel->channel_pubkeys)
2214 chpklist = silc_server_get_channel_pk_list(server, channel, FALSE, FALSE);
2217 silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
2218 SILC_STATUS_OK, 0, ident, 16,
2219 2, channel->channel_name,
2220 strlen(channel->channel_name),
2221 3, chidp->data, chidp->len,
2222 4, clidp->data, clidp->len,
2225 7, keyp ? keyp->data : NULL,
2226 keyp ? keyp->len : 0,
2227 8, ban_list ? ban_list->data : NULL,
2228 ban_list ? ban_list->len : 0,
2229 9, invite_list ? invite_list->data :
2231 invite_list ? invite_list->len : 0,
2234 strlen(channel->topic) : 0,
2235 11, silc_hmac_get_name(channel->hmac),
2236 strlen(silc_hmac_get_name(channel->
2239 13, user_list->data, user_list->len,
2240 14, mode_list->data,
2242 15, fkey ? fkey->data : NULL,
2243 fkey ? fkey->len : 0,
2244 16, chpklist ? chpklist->data : NULL,
2245 chpklist ? chpklist->len : 0,
2246 17, (channel->mode &
2247 SILC_CHANNEL_MODE_ULIMIT ?
2250 SILC_CHANNEL_MODE_ULIMIT ?
2251 sizeof(ulimit) : 0));
2253 /* Send command reply */
2254 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
2255 reply->data, reply->len, FALSE);
2257 /* Send JOIN notify to locally connected clients on the channel. If
2258 we are normal server then router will send or have sent JOIN notify
2259 already. However since we've added the client already to our channel
2260 we'll ignore it (in packet_receive.c) so we must send it here. If
2261 we are router then this will send it to local clients and local
2263 SILC_LOG_DEBUG(("Send JOIN notify to channel"));
2264 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2265 SILC_NOTIFY_TYPE_JOIN, 2,
2266 clidp->data, clidp->len,
2267 chidp->data, chidp->len);
2269 /* Update statistics */
2270 server->stat.my_chanclients++;
2271 if (server->server_type == SILC_ROUTER) {
2272 server->stat.cell_chanclients++;
2273 server->stat.chanclients++;
2276 if (!cmd->pending) {
2277 /* Send JOIN notify packet to our primary router */
2278 silc_server_send_notify_join(server, SILC_PRIMARY_ROUTE(server),
2279 SILC_BROADCAST(server), channel, client->id);
2282 /* Distribute the channel key to all backup routers. */
2283 silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
2284 keyp->data, keyp->len, FALSE, TRUE);
2286 /* If client became founder by providing correct founder auth data
2287 notify the mode change to the channel. */
2289 SILC_PUT32_MSB(chl->mode, mode);
2290 SILC_LOG_DEBUG(("Send CUMODE_CHANGE notify to channel"));
2291 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2292 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
2293 clidp->data, clidp->len,
2294 mode, 4, clidp->data, clidp->len,
2295 fkey ? fkey->data : NULL,
2296 fkey ? fkey->len : 0);
2300 /* Set CUMODE notify type to network */
2302 silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
2303 SILC_BROADCAST(server), channel,
2304 chl->mode, client->id, SILC_ID_CLIENT,
2305 client->id, channel->founder_key);
2307 silc_buffer_free(reply);
2308 silc_buffer_free(clidp);
2309 silc_buffer_free(chidp);
2310 silc_buffer_free(keyp);
2311 silc_buffer_free(user_list);
2312 silc_buffer_free(mode_list);
2313 silc_buffer_free(fkey);
2314 silc_buffer_free(chpklist);
2315 silc_buffer_free(invite_list);
2316 silc_buffer_free(ban_list);
2320 memset(passphrase, 0, strlen(passphrase));
2321 silc_free(passphrase);
2324 /* Server side of command JOIN. Joins client into requested channel. If
2325 the channel does not exist it will be created. */
2327 SILC_SERVER_CMD_FUNC(join)
2329 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2330 SilcServer server = cmd->server;
2331 unsigned char *auth, *cauth;
2332 SilcUInt32 tmp_len, auth_len, cauth_len;
2333 char *tmp, *channel_name, *channel_namec = NULL, *cipher, *hmac;
2334 SilcChannelEntry channel;
2335 SilcUInt32 umode = 0;
2336 bool created = FALSE, create_key = TRUE;
2337 SilcClientID *client_id;
2339 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_JOIN, cmd, 2, 7);
2341 /* Get channel name */
2342 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
2344 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2345 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2350 /* Truncate over long channel names */
2351 if (tmp_len > 256) {
2357 /* Check for valid channel name. This is cached, the original is saved
2358 in the channel context. */
2359 channel_namec = silc_identifier_check(tmp, tmp_len, SILC_STRING_UTF8, 256,
2361 if (!channel_namec) {
2362 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2363 SILC_STATUS_ERR_BAD_CHANNEL, 0);
2367 /* Get Client ID of the client who is joining to the channel */
2368 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
2370 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2371 SILC_STATUS_ERR_NO_CLIENT_ID,
2375 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
2377 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2378 SILC_STATUS_ERR_BAD_CLIENT_ID, 0,
2383 /* Get cipher, hmac name and auth payload */
2384 cipher = silc_argument_get_arg_type(cmd->args, 4, NULL);
2385 hmac = silc_argument_get_arg_type(cmd->args, 5, NULL);
2386 auth = silc_argument_get_arg_type(cmd->args, 6, &auth_len);
2387 cauth = silc_argument_get_arg_type(cmd->args, 7, &cauth_len);
2389 /* See if the channel exists */
2390 channel = silc_idlist_find_channel_by_name(server->local_list,
2391 channel_namec, NULL);
2393 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
2394 SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
2396 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2397 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2402 silc_free(client_id);
2403 client_id = silc_id_dup(entry->id, SILC_ID_CLIENT);
2406 (channel->disabled && server->server_type != SILC_ROUTER)) {
2407 /* Channel not found or not valid */
2409 /* If we are standalone server we don't have a router, we just create
2410 the channel by ourselves (unless it existed). */
2411 if (server->standalone) {
2413 channel = silc_server_create_new_channel(server, server->id, cipher,
2414 hmac, channel_name, TRUE);
2416 silc_server_command_send_status_data(
2417 cmd, SILC_COMMAND_JOIN,
2418 SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
2419 0, 2, cipher, strlen(cipher));
2420 silc_free(client_id);
2424 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2430 /* The channel does not exist on our server. If we are normal server
2431 we will send JOIN command to our router which will handle the
2432 joining procedure (either creates the channel if it doesn't exist
2433 or joins the client to it). */
2434 if (server->server_type != SILC_ROUTER) {
2436 SilcUInt16 old_ident;
2438 /* If this is pending command callback then we've resolved
2439 it and it didn't work, return since we've notified the
2440 client already in the command reply callback. */
2442 silc_free(client_id);
2446 old_ident = silc_command_get_ident(cmd->payload);
2447 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2448 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2450 /* Send JOIN command to our router */
2451 silc_server_packet_send(server, (SilcSocketConnection)
2452 SILC_PRIMARY_ROUTE(server),
2453 SILC_PACKET_COMMAND, cmd->packet->flags,
2454 tmpbuf->data, tmpbuf->len, TRUE);
2456 /* Reprocess this packet after received reply from router */
2457 silc_server_command_pending(server, SILC_COMMAND_JOIN,
2458 silc_command_get_ident(cmd->payload),
2459 silc_server_command_join,
2460 silc_server_command_dup(cmd));
2461 cmd->pending = TRUE;
2462 silc_command_set_ident(cmd->payload, old_ident);
2463 silc_buffer_free(tmpbuf);
2464 silc_free(client_id);
2468 /* We are router and the channel does not seem exist so we will check
2469 our global list as well for the channel. */
2470 channel = silc_idlist_find_channel_by_name(server->global_list,
2471 channel_namec, NULL);
2473 /* Channel really does not exist, create it */
2474 channel = silc_server_create_new_channel(server, server->id, cipher,
2475 hmac, channel_name, TRUE);
2477 silc_server_command_send_status_data(
2478 cmd, SILC_COMMAND_JOIN,
2479 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
2480 2, cipher, strlen(cipher));
2481 silc_free(client_id);
2485 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2493 /* Channel not found */
2495 /* If the command came from router and we are normal server then
2496 something went wrong with the joining as the channel was not found.
2497 We can't do anything else but ignore this. */
2498 if (cmd->sock->type == SILC_SOCKET_TYPE_ROUTER ||
2499 server->server_type != SILC_ROUTER) {
2500 silc_free(client_id);
2504 /* We are router and the channel does not seem exist so we will check
2505 our global list as well for the channel. */
2506 channel = silc_idlist_find_channel_by_name(server->global_list,
2507 channel_namec, NULL);
2509 /* Channel really does not exist, create it */
2510 channel = silc_server_create_new_channel(server, server->id, cipher,
2511 hmac, channel_name, TRUE);
2513 silc_server_command_send_status_data(
2514 cmd, SILC_COMMAND_JOIN,
2515 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
2516 2, cipher, strlen(cipher));
2517 silc_free(client_id);
2521 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2528 /* Check whether the channel was created by our router */
2529 if (cmd->pending && context2) {
2530 SilcServerCommandReplyContext reply = context2;
2532 if (silc_command_get(reply->payload) == SILC_COMMAND_JOIN) {
2533 tmp = silc_argument_get_arg_type(reply->args, 6, NULL);
2534 SILC_GET32_MSB(created, tmp);
2535 if (silc_argument_get_arg_type(reply->args, 7, NULL))
2536 create_key = FALSE; /* Router returned the key already */
2538 if (silc_command_get_status(reply->payload, NULL, NULL) &&
2539 channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
2540 /* Save channel passphrase, if user provided it successfully */
2543 pa = silc_argument_get_arg_type(cmd->args, 3, &pa_len);
2545 silc_free(channel->passphrase);
2546 channel->passphrase = silc_memdup(pa, pa_len);
2551 if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
2552 !channel->disabled && !silc_hash_table_count(channel->user_list))
2556 /* If the channel does not have global users and is also empty the client
2557 will be the channel founder and operator. */
2558 if (!channel->disabled &&
2559 !channel->global_users && !silc_hash_table_count(channel->user_list))
2560 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2562 /* Join to the channel */
2563 silc_server_command_join_channel(server, cmd, channel, client_id,
2564 created, create_key, umode,
2565 auth, auth_len, cauth, cauth_len);
2567 silc_free(client_id);
2570 silc_server_command_free(cmd);
2573 /* Server side of command MOTD. Sends server's current "message of the
2574 day" to the client. */
2576 SILC_SERVER_CMD_FUNC(motd)
2578 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2579 SilcServer server = cmd->server;
2580 SilcBuffer packet, idp;
2581 char *motd, *dest_server = NULL;
2582 SilcUInt32 motd_len;
2583 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2585 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_MOTD, cmd, 1, 1);
2587 /* Get server name */
2588 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2590 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
2591 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2596 /* Check server name */
2597 dest_server = silc_identifier_check(dest_server, strlen(dest_server),
2598 SILC_STRING_UTF8, 256, NULL);
2600 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
2601 SILC_STATUS_ERR_BAD_SERVER,
2606 if (!memcmp(dest_server, server->server_name, strlen(dest_server))) {
2609 idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
2611 if (server->config && server->config->server_info &&
2612 server->config->server_info->motd_file) {
2614 motd = silc_file_readfile(server->config->server_info->motd_file,
2620 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
2623 2, idp->data, idp->len,
2627 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
2630 2, idp->data, idp->len);
2633 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2634 packet->data, packet->len, FALSE);
2635 silc_buffer_free(packet);
2636 silc_buffer_free(idp);
2638 SilcServerEntry entry;
2640 /* Check whether we have this server cached */
2641 entry = silc_idlist_find_server_by_name(server->global_list,
2642 dest_server, TRUE, NULL);
2644 entry = silc_idlist_find_server_by_name(server->local_list,
2645 dest_server, TRUE, NULL);
2648 if (server->server_type != SILC_SERVER && !cmd->pending &&
2649 entry && !entry->motd) {
2650 /* Send to the server */
2652 SilcUInt16 old_ident;
2654 old_ident = silc_command_get_ident(cmd->payload);
2655 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2656 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2658 silc_server_packet_send(server, entry->connection,
2659 SILC_PACKET_COMMAND, cmd->packet->flags,
2660 tmpbuf->data, tmpbuf->len, TRUE);
2662 /* Reprocess this packet after received reply from router */
2663 silc_server_command_pending(server, SILC_COMMAND_MOTD,
2664 silc_command_get_ident(cmd->payload),
2665 silc_server_command_motd,
2666 silc_server_command_dup(cmd));
2667 cmd->pending = TRUE;
2668 silc_command_set_ident(cmd->payload, old_ident);
2669 silc_buffer_free(tmpbuf);
2673 /* Send to primary router only if we don't know the server
2674 * the client requested or if the server is not locally connected */
2675 if ((!entry || !(entry->data.status & SILC_IDLIST_STATUS_LOCAL))
2676 && !cmd->pending && !server->standalone) {
2677 /* Send to the primary router */
2679 SilcUInt16 old_ident;
2681 old_ident = silc_command_get_ident(cmd->payload);
2682 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2683 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2685 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2686 SILC_PACKET_COMMAND, cmd->packet->flags,
2687 tmpbuf->data, tmpbuf->len, TRUE);
2689 /* Reprocess this packet after received reply from router */
2690 silc_server_command_pending(server, SILC_COMMAND_MOTD,
2691 silc_command_get_ident(cmd->payload),
2692 silc_server_command_motd,
2693 silc_server_command_dup(cmd));
2694 cmd->pending = TRUE;
2695 silc_command_set_ident(cmd->payload, old_ident);
2696 silc_buffer_free(tmpbuf);
2701 silc_free(dest_server);
2702 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2703 silc_server_command_send_status_data(cmd, SILC_COMMAND_MOTD,
2704 SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
2706 strlen(dest_server));
2711 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
2712 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
2713 SILC_STATUS_OK, 0, ident, 2,
2714 2, idp->data, idp->len,
2717 strlen(entry->motd) : 0);
2718 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2719 packet->data, packet->len, FALSE);
2720 silc_buffer_free(packet);
2721 silc_buffer_free(idp);
2725 silc_free(dest_server);
2726 silc_server_command_free(cmd);
2729 /* Server side of command UMODE. Client can use this command to set/unset
2730 user mode. Client actually cannot set itself to be as server/router
2731 operator so this can be used only to unset the modes. */
2733 SILC_SERVER_CMD_FUNC(umode)
2735 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2736 SilcServer server = cmd->server;
2737 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2739 unsigned char *tmp_mask, m[4];
2740 SilcUInt32 mask = 0;
2741 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2742 bool set_mask = FALSE;
2744 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
2747 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_UMODE, cmd, 1, 2);
2749 /* Get the client's mode mask */
2750 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
2752 SILC_GET32_MSB(mask, tmp_mask);
2757 /* Check that mode changing is allowed. */
2758 if (!silc_server_check_umode_rights(server, client, mask)) {
2759 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
2760 SILC_STATUS_ERR_PERM_DENIED, 0);
2764 /* Anonymous mode cannot be set by client */
2765 if (mask & SILC_UMODE_ANONYMOUS &&
2766 !(client->mode & SILC_UMODE_ANONYMOUS)) {
2767 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
2768 SILC_STATUS_ERR_PERM_DENIED, 0);
2772 /* Update statistics */
2773 if (mask & SILC_UMODE_GONE) {
2774 if (!(client->mode & SILC_UMODE_GONE))
2775 server->stat.my_aways++;
2777 if (client->mode & SILC_UMODE_GONE)
2778 server->stat.my_aways--;
2781 /* If the client has anonymous mode set, preserve it. */
2782 if (client->mode & SILC_UMODE_ANONYMOUS)
2783 mask |= SILC_UMODE_ANONYMOUS;
2785 /* Change the mode */
2786 client->mode = mask;
2788 /* Send UMODE change to primary router */
2789 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
2790 SILC_BROADCAST(server), client->id,
2793 /* Check if anyone is watching this nickname */
2794 if (server->server_type == SILC_ROUTER)
2795 silc_server_check_watcher_list(server, client, NULL,
2796 SILC_NOTIFY_TYPE_UMODE_CHANGE);
2799 /* Send command reply to sender */
2800 SILC_PUT32_MSB(client->mode, m);
2801 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_UMODE,
2802 SILC_STATUS_OK, 0, ident, 1,
2804 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2805 packet->data, packet->len, FALSE);
2806 silc_buffer_free(packet);
2809 silc_server_command_free(cmd);
2812 /* Server side command of CMODE. Changes channel mode */
2814 SILC_SERVER_CMD_FUNC(cmode)
2816 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2817 SilcServer server = cmd->server;
2818 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2819 SilcIDListData idata = (SilcIDListData)client;
2820 SilcChannelID *channel_id = NULL;
2821 SilcChannelEntry channel;
2822 SilcChannelClientEntry chl;
2823 SilcBuffer packet, cidp;
2824 unsigned char *tmp, *tmp_id, *tmp_mask, *chpkdata = NULL;
2825 char *cipher = NULL, *hmac = NULL, *passphrase = NULL, ulimit[4];
2826 SilcUInt32 mode_mask = 0, old_mask = 0, tmp_len, tmp_len2, chpklen;
2827 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2828 bool set_mask = FALSE, set_chpk = FALSE;
2829 SilcPublicKey founder_key = NULL;
2830 SilcBuffer fkey = NULL, chpklist = NULL;
2831 SilcBufferStruct chpk;
2834 silc_server_command_free(cmd);
2838 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 9);
2840 /* Get Channel ID */
2841 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
2843 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2844 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2845 silc_server_command_free(cmd);
2848 channel_id = silc_id_payload_parse_id(tmp_id, tmp_len2, NULL);
2850 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2851 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2852 silc_server_command_free(cmd);
2856 /* Get channel entry */
2857 channel = silc_idlist_find_channel_by_id(server->local_list,
2860 channel = silc_idlist_find_channel_by_id(server->global_list,
2863 silc_server_command_send_status_data(cmd, SILC_COMMAND_CMODE,
2864 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
2865 0, 2, tmp_id, tmp_len2);
2866 silc_free(channel_id);
2867 silc_server_command_free(cmd);
2871 old_mask = channel->mode;
2873 /* Get the channel mode mask */
2874 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
2876 SILC_GET32_MSB(mode_mask, tmp_mask);
2880 /* Check whether this client is on the channel */
2881 if (!silc_server_client_on_channel(client, channel, &chl)) {
2882 silc_server_command_send_status_data(cmd, SILC_COMMAND_CMODE,
2883 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
2884 2, tmp_id, tmp_len2);
2888 /* Check that client has rights to change any requested channel modes */
2889 if (set_mask && !silc_server_check_cmode_rights(server, channel, chl,
2891 SILC_LOG_DEBUG(("Client does not have rights to change mode"));
2892 silc_server_command_send_status_data(
2893 cmd, SILC_COMMAND_CMODE,
2894 (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) ?
2895 SILC_STATUS_ERR_NO_CHANNEL_PRIV :
2896 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV), 0,
2897 2, tmp_id, tmp_len2);
2901 /* If mode mask was not sent as argument then merely return the current
2902 mode mask, founder key and channel public key list to the sender. */
2905 SILC_PUT32_MSB(channel->mode, m);
2906 if (channel->founder_key)
2907 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
2908 if (channel->channel_pubkeys)
2909 chpklist = silc_server_get_channel_pk_list(server, channel,
2912 silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
2913 SILC_STATUS_OK, 0, ident, 4,
2914 2, tmp_id, tmp_len2,
2916 4, fkey ? fkey->data : NULL,
2917 fkey ? fkey->len : 0,
2918 5, chpklist ? chpklist->data : NULL,
2919 chpklist ? chpklist->len : 0);
2920 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2921 packet->data, packet->len, FALSE);
2922 silc_buffer_free(packet);
2927 * Check the modes. Modes that requires nothing special operation are
2931 if (mode_mask & SILC_CHANNEL_MODE_PRIVKEY) {
2932 /* Channel uses private keys to protect traffic. Client(s) has set the
2933 key locally they want to use, server does not know that key. */
2934 /* Nothing interesting to do here */
2936 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
2937 /* The mode is removed and we need to generate and distribute
2938 new channel key. Clients are not using private channel keys
2939 anymore after this. */
2941 /* Re-generate channel key */
2942 if (!silc_server_create_channel_key(server, channel, 0))
2945 /* Send the channel key. This sends it to our local clients and if
2946 we are normal server to our router as well. */
2947 silc_server_send_channel_key(server, NULL, channel,
2948 server->server_type == SILC_ROUTER ?
2949 FALSE : !server->standalone);
2951 cipher = (char *)silc_cipher_get_name(channel->channel_key);
2952 hmac = (char *)silc_hmac_get_name(channel->hmac);
2956 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT) {
2957 /* User limit is set on channel */
2958 SilcUInt32 user_limit;
2960 /* Get user limit */
2961 tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
2963 if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT)) {
2964 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2965 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
2969 SILC_GET32_MSB(user_limit, tmp);
2970 channel->user_limit = user_limit;
2973 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2974 /* User limit mode is unset. Remove user limit */
2975 channel->user_limit = 0;
2978 if (mode_mask & SILC_CHANNEL_MODE_PASSPHRASE) {
2979 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
2980 /* Passphrase has been set to channel */
2982 /* Get the passphrase */
2983 tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
2985 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2986 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
2990 /* Save the passphrase */
2991 passphrase = channel->passphrase = silc_memdup(tmp, strlen(tmp));
2994 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
2995 /* Passphrase mode is unset. remove the passphrase */
2996 silc_free(channel->passphrase);
2997 channel->passphrase = NULL;
3001 if (mode_mask & SILC_CHANNEL_MODE_CIPHER) {
3002 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
3003 /* Cipher to use protect the traffic */
3004 SilcCipher newkey, oldkey;
3007 cipher = silc_argument_get_arg_type(cmd->args, 5, NULL);
3009 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3010 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3014 /* Delete old cipher and allocate the new one */
3015 if (!silc_cipher_alloc(cipher, &newkey)) {
3016 silc_server_command_send_status_data(
3017 cmd, SILC_COMMAND_CMODE,
3018 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3019 2, cipher, strlen(cipher));
3023 oldkey = channel->channel_key;
3024 channel->channel_key = newkey;
3026 /* Re-generate channel key */
3027 if (!silc_server_create_channel_key(server, channel, 0)) {
3028 /* We don't have new key, revert to old one */
3029 channel->channel_key = oldkey;
3033 /* Remove old channel key for good */
3034 silc_cipher_free(oldkey);
3036 /* Send the channel key. This sends it to our local clients and if
3037 we are normal server to our router as well. */
3038 silc_server_send_channel_key(server, NULL, channel,
3039 server->server_type == SILC_ROUTER ?
3040 FALSE : !server->standalone);
3043 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
3044 /* Cipher mode is unset. Remove the cipher and revert back to
3046 SilcCipher newkey, oldkey;
3047 cipher = channel->cipher;
3049 /* Delete old cipher and allocate default one */
3050 if (!silc_cipher_alloc(cipher ? cipher : SILC_DEFAULT_CIPHER, &newkey)) {
3051 silc_server_command_send_status_data(
3052 cmd, SILC_COMMAND_CMODE,
3053 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3054 2, cipher, strlen(cipher));
3058 oldkey = channel->channel_key;
3059 channel->channel_key = newkey;
3061 /* Re-generate channel key */
3062 if (!silc_server_create_channel_key(server, channel, 0)) {
3063 /* We don't have new key, revert to old one */
3064 channel->channel_key = oldkey;
3068 /* Remove old channel key for good */
3069 silc_cipher_free(oldkey);
3071 /* Send the channel key. This sends it to our local clients and if
3072 we are normal server to our router as well. */
3073 silc_server_send_channel_key(server, NULL, channel,
3074 server->server_type == SILC_ROUTER ?
3075 FALSE : !server->standalone);
3079 if (mode_mask & SILC_CHANNEL_MODE_HMAC) {
3080 if (!(channel->mode & SILC_CHANNEL_MODE_HMAC)) {
3081 /* HMAC to use protect the traffic */
3082 unsigned char hash[32];
3086 hmac = silc_argument_get_arg_type(cmd->args, 6, NULL);
3088 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3089 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3093 /* Delete old hmac and allocate the new one */
3094 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3095 silc_server_command_send_status_data(
3096 cmd, SILC_COMMAND_CMODE,
3097 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3098 2, hmac, strlen(hmac));
3102 silc_hmac_free(channel->hmac);
3103 channel->hmac = newhmac;
3105 /* Set the HMAC key out of current channel key. The client must do
3107 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
3108 channel->key_len / 8, hash);
3109 silc_hmac_set_key(channel->hmac, hash,
3110 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3111 memset(hash, 0, sizeof(hash));
3114 if (channel->mode & SILC_CHANNEL_MODE_HMAC) {
3115 /* Hmac mode is unset. Remove the hmac and revert back to
3118 unsigned char hash[32];
3119 hmac = channel->hmac_name;
3121 /* Delete old hmac and allocate default one */
3122 if (!silc_hmac_alloc(hmac ? hmac : SILC_DEFAULT_HMAC, NULL, &newhmac)) {
3123 silc_server_command_send_status_data(
3124 cmd, SILC_COMMAND_CMODE,
3125 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3126 2, hmac, strlen(hmac));
3130 silc_hmac_free(channel->hmac);
3131 channel->hmac = newhmac;
3133 /* Set the HMAC key out of current channel key. The client must do
3135 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
3136 channel->key_len / 8,
3138 silc_hmac_set_key(channel->hmac, hash,
3139 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3140 memset(hash, 0, sizeof(hash));
3144 if (mode_mask & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3145 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3146 /* Check if the founder public key was received */
3147 founder_key = idata->public_key;
3148 tmp = silc_argument_get_arg_type(cmd->args, 8, &tmp_len);
3150 if (!silc_pkcs_public_key_payload_decode(tmp, tmp_len, &founder_key)) {
3151 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3152 SILC_STATUS_ERR_AUTH_FAILED,
3157 /* If key was not sent and the channel mode has already founder
3158 then the key was not to be changed. */
3159 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
3163 /* Set the founder authentication */
3164 tmp = silc_argument_get_arg_type(cmd->args, 7, &tmp_len);
3166 silc_server_command_send_status_reply(
3167 cmd, SILC_COMMAND_CMODE,
3168 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3172 /* Verify the payload before setting the mode */
3173 if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY,
3174 founder_key, 0, server->sha1hash,
3175 client->id, SILC_ID_CLIENT)) {
3176 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3177 SILC_STATUS_ERR_AUTH_FAILED,
3182 /* Save the public key */
3183 if (channel->founder_key)
3184 silc_pkcs_public_key_free(channel->founder_key);
3185 if (silc_argument_get_arg_type(cmd->args, 8, NULL))
3186 channel->founder_key = founder_key;
3188 channel->founder_key = silc_pkcs_public_key_copy(founder_key);
3189 if (!channel->founder_key) {
3190 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3191 SILC_STATUS_ERR_AUTH_FAILED,
3196 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
3198 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3199 SILC_STATUS_ERR_AUTH_FAILED,
3201 silc_pkcs_public_key_free(channel->founder_key);
3202 channel->founder_key = NULL;
3207 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3208 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3209 if (channel->founder_key)
3210 silc_pkcs_public_key_free(channel->founder_key);
3211 channel->founder_key = NULL;
3217 if (mode_mask & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
3218 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3221 chpkdata = silc_argument_get_arg_type(cmd->args, 9, &chpklen);
3223 if (!chpkdata && channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
3228 /* Process the channel public key(s) */
3229 st = silc_server_set_channel_pk_list(server, NULL, channel,
3231 if (st != SILC_STATUS_OK) {
3232 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, st, 0);
3237 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3238 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
3239 if (channel->channel_pubkeys)
3240 silc_hash_table_free(channel->channel_pubkeys);
3241 channel->channel_pubkeys = NULL;
3248 /* Finally, set the mode */
3249 old_mask = channel->mode = mode_mask;
3251 /* Send CMODE_CHANGE notify. */
3252 cidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3253 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT)
3254 SILC_PUT32_MSB(channel->user_limit, ulimit);
3255 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3256 SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
3257 cidp->data, cidp->len,
3259 cipher, cipher ? strlen(cipher) : 0,
3260 hmac, hmac ? strlen(hmac) : 0,
3261 passphrase, passphrase ?
3262 strlen(passphrase) : 0,
3263 fkey ? fkey->data : NULL,
3264 fkey ? fkey->len : 0,
3265 chpkdata ? chpkdata : NULL,
3266 chpkdata ? chpklen : 0,
3267 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
3269 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
3270 sizeof(ulimit) : 0);
3272 /* Set CMODE notify type to network */
3273 if (chpkdata && chpklen)
3274 silc_buffer_set(&chpk, chpkdata, chpklen);
3275 silc_server_send_notify_cmode(server, SILC_PRIMARY_ROUTE(server),
3276 SILC_BROADCAST(server), channel,
3277 mode_mask, client->id, SILC_ID_CLIENT,
3278 cipher, hmac, passphrase, founder_key,
3279 chpkdata ? &chpk : NULL);
3282 chpklist = silc_server_get_channel_pk_list(server, channel, FALSE, FALSE);
3284 /* Send command reply to sender */
3285 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
3286 SILC_STATUS_OK, 0, ident, 5,
3287 2, tmp_id, tmp_len2,
3289 4, fkey ? fkey->data : NULL,
3290 fkey ? fkey->len : 0,
3291 5, chpklist ? chpklist->data :
3292 NULL, chpklist ? chpklist->len
3295 SILC_CHANNEL_MODE_ULIMIT ?
3298 SILC_CHANNEL_MODE_ULIMIT ?
3299 sizeof(ulimit) : 0));
3301 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3302 packet->data, packet->len, FALSE);
3304 silc_buffer_free(packet);
3305 silc_buffer_free(cidp);
3308 channel->mode = old_mask;
3309 silc_buffer_free(chpklist);
3310 silc_buffer_free(fkey);
3311 silc_free(channel_id);
3312 silc_server_command_free(cmd);
3315 /* Server side of CUMODE command. Changes client's mode on a channel. */
3317 SILC_SERVER_CMD_FUNC(cumode)
3319 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3320 SilcServer server = cmd->server;
3321 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3322 SilcChannelID *channel_id = NULL;
3323 SilcClientID *client_id = NULL;
3324 SilcChannelEntry channel;
3325 SilcClientEntry target_client;
3326 SilcChannelClientEntry chl;
3327 SilcBuffer packet, idp;
3328 unsigned char *tmp_id, *tmp_ch_id, *tmp_mask;
3329 SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
3331 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3332 SilcPublicKey founder_key = NULL;
3333 SilcBuffer fkey = NULL;
3338 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4);
3340 /* Get Channel ID */
3341 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3343 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3344 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3347 channel_id = silc_id_payload_parse_id(tmp_ch_id, tmp_ch_len, NULL);
3349 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3350 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3354 /* Get channel entry */
3355 channel = silc_idlist_find_channel_by_id(server->local_list,
3358 channel = silc_idlist_find_channel_by_id(server->global_list,
3361 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3362 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
3363 0, 2, tmp_ch_id, tmp_ch_len);
3368 /* Check whether sender is on the channel */
3369 if (!silc_server_client_on_channel(client, channel, &chl)) {
3370 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3371 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
3372 2, tmp_ch_id, tmp_ch_len);
3375 sender_mask = chl->mode;
3377 /* Get the target client's channel mode mask */
3378 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
3380 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3381 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3385 SILC_GET32_MSB(target_mask, tmp_mask);
3387 /* Get target Client ID */
3388 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3390 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3391 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3394 client_id = silc_id_payload_parse_id(tmp_id, tmp_len, NULL);
3396 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3397 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3401 /* Get target client's entry */
3402 target_client = silc_idlist_find_client_by_id(server->local_list,
3403 client_id, TRUE, NULL);
3405 target_client = silc_idlist_find_client_by_id(server->global_list,
3406 client_id, TRUE, NULL);
3408 if (target_client != client &&
3409 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO) &&
3410 !(sender_mask & SILC_CHANNEL_UMODE_CHANOP)) {
3411 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3412 SILC_STATUS_ERR_NOT_YOU, 0,
3413 2, tmp_ch_id, tmp_ch_len);
3417 /* Check whether target client is on the channel */
3418 if (target_client != client) {
3419 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
3420 silc_server_command_send_status_data2(
3421 cmd, SILC_COMMAND_CUMODE,
3422 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL, 0,
3424 3, tmp_ch_id, tmp_ch_len);
3433 /* If the target client is founder, no one else can change their mode
3435 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && client != target_client) {
3436 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3437 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3438 0, 2, tmp_ch_id, tmp_ch_len);
3442 if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
3443 if (target_client != client) {
3444 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3445 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3450 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
3451 /* The client tries to claim the founder rights. */
3452 unsigned char *tmp_auth;
3453 SilcUInt32 tmp_auth_len;
3454 SilcChannelClientEntry chl2;
3455 SilcHashTableList htl;
3457 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
3458 !channel->founder_key) {
3459 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3460 SILC_STATUS_ERR_AUTH_FAILED, 0);
3464 tmp_auth = silc_argument_get_arg_type(cmd->args, 4, &tmp_auth_len);
3466 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3467 SILC_STATUS_ERR_AUTH_FAILED, 0);
3471 /* Verify the authentication payload */
3472 if (!silc_auth_verify_data(tmp_auth, tmp_auth_len, SILC_AUTH_PUBLIC_KEY,
3473 channel->founder_key, 0, server->sha1hash,
3474 client->id, SILC_ID_CLIENT)) {
3475 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3476 SILC_STATUS_ERR_AUTH_FAILED, 0);
3481 founder_key = channel->founder_key;
3482 fkey = silc_pkcs_public_key_payload_encode(founder_key);
3484 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3485 SILC_STATUS_ERR_AUTH_FAILED, 0);
3489 /* There cannot be anyone else as founder on the channel now. This
3490 client is definitely the founder due to this authentication. This
3491 is done only on router, not on server, since server cannot know
3492 whether router will accept this mode change or not. XXX This
3493 probably shouldn't be done anymore at all, may cause problems in
3494 router-router connections too (maybe just AUTH_FAILED error should
3495 be returned). -Pekka */
3496 if (server->server_type == SILC_ROUTER) {
3497 silc_hash_table_list(channel->user_list, &htl);
3498 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
3499 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
3500 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3501 silc_server_force_cumode_change(server, NULL, channel, chl2,
3505 silc_hash_table_list_reset(&htl);
3508 sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
3511 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3512 if (target_client == client) {
3513 /* Remove channel founder rights from itself */
3514 chl->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3517 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3518 SILC_STATUS_ERR_NOT_YOU, 0);
3524 if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
3525 /* Promote to operator */
3526 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
3527 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
3528 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
3529 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3530 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3531 0, 2, tmp_ch_id, tmp_ch_len);
3535 chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
3539 if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
3540 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
3541 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
3542 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3543 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3544 0, 2, tmp_ch_id, tmp_ch_len);
3548 /* Demote to normal user */
3549 chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
3554 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
3555 if (target_client != client) {
3556 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3557 SILC_STATUS_ERR_NOT_YOU, 0);
3561 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)) {
3562 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
3566 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
3567 if (target_client != client) {
3568 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3569 SILC_STATUS_ERR_NOT_YOU, 0);
3573 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
3578 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
3579 if (target_client != client) {
3580 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3581 SILC_STATUS_ERR_NOT_YOU, 0);
3585 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)) {
3586 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
3590 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
3591 if (target_client != client) {
3592 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3593 SILC_STATUS_ERR_NOT_YOU, 0);
3597 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
3602 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
3603 if (target_client != client) {
3604 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3605 SILC_STATUS_ERR_NOT_YOU, 0);
3609 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)) {
3610 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
3614 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
3615 if (target_client != client) {
3616 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3617 SILC_STATUS_ERR_NOT_YOU, 0);
3621 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
3626 if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
3627 if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
3628 if (client == target_client) {
3629 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3630 SILC_STATUS_ERR_PERM_DENIED, 0);
3633 chl->mode |= SILC_CHANNEL_UMODE_QUIET;
3637 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
3638 if (client == target_client) {
3639 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3640 SILC_STATUS_ERR_PERM_DENIED, 0);
3643 chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
3648 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3649 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3651 /* Send notify to channel, notify only if mode was actually changed. */
3653 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3654 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
3655 idp->data, idp->len,
3658 fkey ? fkey->data : NULL,
3659 fkey ? fkey->len : 0);
3661 /* Set CUMODE notify type to network */
3662 silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
3663 SILC_BROADCAST(server), channel,
3664 target_mask, client->id, SILC_ID_CLIENT,
3665 target_client->id, founder_key);
3668 /* Send command reply to sender */
3669 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CUMODE,
3670 SILC_STATUS_OK, 0, ident, 3,
3672 3, tmp_ch_id, tmp_ch_len,
3673 4, tmp_id, tmp_len);
3674 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3675 packet->data, packet->len, FALSE);
3677 silc_buffer_free(packet);
3678 silc_buffer_free(idp);
3681 silc_free(channel_id);
3682 silc_free(client_id);
3683 silc_buffer_free(fkey);
3684 silc_server_command_free(cmd);
3687 /* Server side of KICK command. Kicks client out of channel. */
3689 SILC_SERVER_CMD_FUNC(kick)
3691 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3692 SilcServer server = cmd->server;
3693 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3694 SilcClientEntry target_client;
3695 SilcChannelID *channel_id;
3696 SilcClientID *client_id;
3697 SilcChannelEntry channel;
3698 SilcChannelClientEntry chl;
3699 SilcBuffer idp, packet;
3700 SilcUInt32 tmp_len, target_idp_len, clen;
3701 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3702 unsigned char *tmp, *comment, *target_idp;
3707 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 3);
3709 /* Get Channel ID */
3710 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3712 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
3713 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3716 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
3718 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3719 SILC_STATUS_ERR_BAD_CHANNEL_ID, 0,
3724 /* Get channel entry */
3725 channel = silc_idlist_find_channel_by_id(server->local_list,
3728 channel = silc_idlist_find_channel_by_id(server->local_list,
3731 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3732 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
3733 0, 2, tmp, tmp_len);
3738 /* Check whether sender is on the channel */
3739 if (!silc_server_client_on_channel(client, channel, &chl)) {
3740 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3741 SILC_STATUS_ERR_NOT_ON_CHANNEL,
3742 0, 2, tmp, tmp_len);
3746 /* Check that the kicker is channel operator or channel founder */
3747 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
3748 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
3749 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3750 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3751 0, 2, tmp, tmp_len);
3755 /* Get target Client ID */
3756 target_idp = silc_argument_get_arg_type(cmd->args, 2, &target_idp_len);
3758 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
3759 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3762 client_id = silc_id_payload_parse_id(target_idp, target_idp_len, NULL);
3764 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3765 SILC_STATUS_ERR_BAD_CLIENT_ID,
3766 0, 2, target_idp, target_idp_len);
3770 /* Get target client's entry */
3771 target_client = silc_idlist_find_client_by_id(server->local_list,
3772 client_id, TRUE, NULL);
3773 if (!target_client) {
3774 target_client = silc_idlist_find_client_by_id(server->global_list,
3775 client_id, TRUE, NULL);
3778 /* Check whether target client is on the channel */
3779 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
3780 silc_server_command_send_status_data2(cmd, SILC_COMMAND_KICK,
3781 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL,
3782 0, 2, target_idp, target_idp_len,
3787 /* Check that the target client is not channel founder. Channel founder
3788 cannot be kicked from the channel. */
3789 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3790 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3791 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3792 0, 2, tmp, tmp_len);
3797 comment = silc_argument_get_arg_type(cmd->args, 3, &clen);
3802 /* Send the reply back to the client */
3804 silc_command_reply_payload_encode_va(SILC_COMMAND_KICK,
3805 SILC_STATUS_OK, 0, ident, 2,
3807 3, target_idp, target_idp_len);
3808 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3809 packet->data, packet->len, FALSE);
3810 silc_buffer_free(packet);
3812 /* Send KICKED notify to local clients on the channel */
3813 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3814 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3815 SILC_NOTIFY_TYPE_KICKED, 3,
3816 target_idp, target_idp_len,
3817 comment, comment ? strlen(comment) : 0,
3818 idp->data, idp->len);
3819 silc_buffer_free(idp);
3821 /* Send KICKED notify to primary route */
3822 silc_server_send_notify_kicked(server, SILC_PRIMARY_ROUTE(server),
3823 SILC_BROADCAST(server), channel,
3824 target_client->id, client->id, comment);
3826 /* Remove the client from channel's invite list */
3827 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
3829 silc_argument_payload_encode_one(NULL, target_idp, target_idp_len, 3);
3830 SilcArgumentPayload args =
3831 silc_argument_payload_parse(ab->data, ab->len, 1);
3832 silc_server_inviteban_process(server, channel->invite_list, 1, args);
3833 silc_buffer_free(ab);
3834 silc_argument_payload_free(args);
3837 /* Remove the client from the channel. If the channel does not exist
3838 after removing the client then the client kicked itself off the channel
3839 and we don't have to send anything after that. */
3840 if (!silc_server_remove_from_one_channel(server, NULL, channel,
3841 target_client, FALSE))
3844 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3845 /* Re-generate channel key */
3846 if (!silc_server_create_channel_key(server, channel, 0))
3849 /* Send the channel key to the channel. The key of course is not sent
3850 to the client who was kicked off the channel. */
3851 silc_server_send_channel_key(server, target_client->connection, channel,
3852 server->server_type == SILC_ROUTER ?
3853 FALSE : !server->standalone);
3857 silc_server_command_free(cmd);
3860 /* Server side of OPER command. Client uses this comand to obtain server
3861 operator privileges to this server/router. */
3863 SILC_SERVER_CMD_FUNC(oper)
3865 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3866 SilcServer server = cmd->server;
3867 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3868 unsigned char *username = NULL, *auth;
3870 SilcServerConfigAdmin *admin;
3871 SilcIDListData idata = (SilcIDListData)client;
3872 bool result = FALSE;
3873 SilcPublicKey cached_key;
3875 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
3878 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2);
3880 /* Get the username */
3881 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3883 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3884 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3889 /* Check username */
3890 username = silc_identifier_check(username, strlen(username),
3891 SILC_STRING_UTF8, 128, &tmp_len);
3893 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3894 SILC_STATUS_ERR_BAD_USERNAME,
3899 /* Get the admin configuration */
3900 admin = silc_server_config_find_admin(server, cmd->sock->ip,
3901 username, client->nickname);
3903 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
3904 username, client->nickname);
3906 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3907 SILC_STATUS_ERR_AUTH_FAILED,
3909 SILC_LOG_INFO(("OPER authentication failed for username '%s' by "
3910 "nickname '%s' from %s", username,
3911 client->nickname, cmd->sock->hostname));
3916 /* Get the authentication payload */
3917 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
3919 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3920 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3925 /* Verify the authentication data. If both passphrase and public key
3926 is set then try both of them. */
3927 if (admin->passphrase)
3928 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
3929 admin->passphrase, admin->passphrase_len,
3930 idata->hash, client->id, SILC_ID_CLIENT);
3931 if (!result && admin->publickeys) {
3932 cached_key = silc_server_get_public_key(server, admin->publickeys);
3935 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
3936 cached_key, 0, idata->hash,
3937 client->id, SILC_ID_CLIENT);
3940 /* Authentication failed */
3941 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3942 SILC_STATUS_ERR_AUTH_FAILED,
3947 /* Client is now server operator */
3948 client->mode |= SILC_UMODE_SERVER_OPERATOR;
3950 /* Update statistics */
3951 if (SILC_IS_LOCAL(client))
3952 server->stat.my_server_ops++;
3953 if (server->server_type == SILC_ROUTER)
3954 server->stat.server_ops++;
3956 /* Send UMODE change to primary router */
3957 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
3958 SILC_BROADCAST(server), client->id,
3961 /* Check if anyone is watching this nickname */
3962 if (server->server_type == SILC_ROUTER)
3963 silc_server_check_watcher_list(server, client, NULL,
3964 SILC_NOTIFY_TYPE_UMODE_CHANGE);
3966 /* Send reply to the sender */
3967 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3971 silc_free(username);
3972 silc_server_command_free(cmd);
3975 SILC_TASK_CALLBACK(silc_server_command_detach_cb)
3977 SilcServer server = app_context;
3978 QuitInternal q = (QuitInternal)context;
3979 SilcClientID *client_id = (SilcClientID *)q->sock;
3980 SilcClientEntry client;
3981 SilcSocketConnection sock;
3983 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3985 if (client && client->connection) {
3986 sock = client->connection;
3988 /* If there is pending outgoing data for the client then purge it
3989 to the network before closing connection. */
3990 silc_server_packet_queue_purge(server, sock);
3992 /* Close the connection on our side */
3993 client->router = NULL;
3994 client->connection = NULL;
3995 sock->user_data = NULL;
3996 silc_server_close_connection(server, sock);
3999 silc_free(client_id);
4003 SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
4005 SilcServer server = app_context;
4006 QuitInternal q = (QuitInternal)context;
4007 SilcClientID *client_id = (SilcClientID *)q->sock;
4008 SilcClientEntry client;
4010 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4012 if (client && client->mode & SILC_UMODE_DETACHED) {
4013 SILC_LOG_DEBUG(("Detach timeout"));
4014 silc_server_free_client_data(server, NULL, client, TRUE,
4018 silc_free(client_id);
4022 /* Server side of DETACH command. Detached the client from the network
4023 by closing the connection but preserving the session. */
4025 SILC_SERVER_CMD_FUNC(detach)
4027 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4028 SilcServer server = cmd->server;
4029 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4032 if (server->config->detach_disabled) {
4033 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4034 SILC_STATUS_ERR_OPERATION_ALLOWED,
4039 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4042 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_DETACH, cmd, 0, 0);
4044 /* Remove operator privileges, since the client may resume in some
4045 other server which to it does not have operator privileges. */
4046 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
4047 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
4049 /* Send the user mode notify to notify that client is detached */
4050 client->mode |= SILC_UMODE_DETACHED;
4051 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
4052 client->data.status &= ~SILC_IDLIST_STATUS_NOATTR;
4053 client->last_command = 0;
4054 client->fast_command = 0;
4055 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4056 SILC_BROADCAST(server), client->id,
4058 server->stat.my_detached++;
4060 /* Check if anyone is watching this nickname */
4061 if (server->server_type == SILC_ROUTER)
4062 silc_server_check_watcher_list(server, client, NULL,
4063 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4065 q = silc_calloc(1, sizeof(*q));
4066 q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
4067 silc_schedule_task_add(server->schedule, 0, silc_server_command_detach_cb,
4068 q, 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
4070 if (server->config->detach_timeout) {
4071 q = silc_calloc(1, sizeof(*q));
4072 q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
4073 silc_schedule_task_add(server->schedule, 0,
4074 silc_server_command_detach_timeout,
4075 q, server->config->detach_timeout * 60,
4076 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
4079 /* Send reply to the sender */
4080 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4084 silc_server_command_free(cmd);
4087 /* Server side of WATCH command. */
4089 SILC_SERVER_CMD_FUNC(watch)
4091 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4092 SilcServer server = cmd->server;
4093 char *add_nick, *del_nick;
4094 SilcUInt32 add_nick_len, del_nick_len, tmp_len, pk_len;
4095 unsigned char hash[16], *tmp, *pk, *nick;
4096 SilcClientEntry client;
4097 SilcClientID *client_id = NULL;
4099 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WATCH, cmd, 1, 3);
4101 if (server->server_type != SILC_ROUTER && !server->standalone) {
4102 if (!cmd->pending) {
4103 /* Send the command to router */
4105 SilcUInt16 old_ident;
4107 SILC_LOG_DEBUG(("Forwarding WATCH to router"));
4109 old_ident = silc_command_get_ident(cmd->payload);
4110 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4111 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4113 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4114 SILC_PACKET_COMMAND, cmd->packet->flags,
4115 tmpbuf->data, tmpbuf->len, TRUE);
4117 /* Reprocess this packet after received reply from router */
4118 silc_server_command_pending(server, SILC_COMMAND_WATCH,
4119 silc_command_get_ident(cmd->payload),
4120 silc_server_command_watch,
4121 silc_server_command_dup(cmd));
4122 cmd->pending = TRUE;
4123 silc_command_set_ident(cmd->payload, old_ident);
4124 silc_buffer_free(tmpbuf);
4125 } else if (context2) {
4126 /* Received reply from router, just send same data to the client. */
4127 SilcServerCommandReplyContext reply = context2;
4130 SILC_LOG_DEBUG(("Received reply to WATCH from router"));
4131 silc_command_get_status(reply->payload, &status, NULL);
4132 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH, status,
4139 /* We are router and keep the watch list for local cell */
4141 /* Get the client ID */
4142 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4144 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4145 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4149 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
4151 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4152 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4153 0, 2, tmp, tmp_len);
4157 /* Get the client entry which must be in local list */
4158 client = silc_idlist_find_client_by_id(server->local_list,
4159 client_id, TRUE, NULL);
4161 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4162 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
4167 /* Take public key for watching by public key */
4168 pk = silc_argument_get_arg_type(cmd->args, 4, &pk_len);
4171 add_nick = silc_argument_get_arg_type(cmd->args, 2, &add_nick_len);
4172 del_nick = silc_argument_get_arg_type(cmd->args, 3, &del_nick_len);
4173 if (!add_nick && !del_nick && !pk) {
4174 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4175 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4180 if (add_nick && add_nick_len > 128) {
4181 add_nick[128] = '\0';
4184 if (del_nick && del_nick_len > 128) {
4185 del_nick[128] = '\0';
4189 /* Add new nickname to be watched in our cell */
4191 nick = silc_identifier_check(add_nick, add_nick_len, SILC_STRING_UTF8, 128,
4194 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4195 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4199 /* Hash the nick, we have the hash saved, not nicks because we can
4200 do one to one mapping to the nick from Client ID hash this way. */
4201 silc_hash_make(server->md5hash, nick, add_nick_len, hash);
4203 /* Check whether this client is already watching this nickname */
4204 if (silc_hash_table_find_by_context(server->watcher_list, hash,
4206 /* Nickname is alredy being watched for this client */
4207 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4208 SILC_STATUS_ERR_NICKNAME_IN_USE,
4214 /* Get the nickname from the watcher list and use the same key in
4215 new entries as well. If key doesn't exist then create it. */
4216 if (!silc_hash_table_find(server->watcher_list, hash, (void *)&tmp, NULL))
4217 tmp = silc_memdup(hash, CLIENTID_HASH_LEN);
4219 /* Add the client to the watcher list with the specified nickname hash. */
4220 silc_hash_table_add(server->watcher_list, tmp, client);
4224 /* Delete nickname from watch list */
4226 nick = silc_identifier_check(del_nick, del_nick_len, SILC_STRING_UTF8, 128,
4229 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4230 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4234 /* Hash the nick, we have the hash saved, not nicks because we can
4235 do one to one mapping to the nick from Client ID hash this way. */
4236 silc_hash_make(server->md5hash, nick, del_nick_len, hash);
4238 /* Check that this client is watching for this nickname */
4239 if (!silc_hash_table_find_by_context(server->watcher_list, hash,
4240 client, (void *)&tmp)) {
4241 /* Nickname is alredy being watched for this client */
4242 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4243 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
4244 2, nick, del_nick_len);
4249 /* Delete the nickname from the watcher list. */
4250 silc_hash_table_del_by_context(server->watcher_list, hash, client);
4252 /* Now check whether there still exists entries with this key, if not
4253 then free the key to not leak memory. */
4254 if (!silc_hash_table_find(server->watcher_list, hash, NULL, NULL))
4259 /* Add/del public key */
4262 SilcArgumentPayload pkargs;
4264 SilcPublicKey public_key, pkkey;
4267 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4268 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4273 /* Get the argument from the Argument List Payload */
4274 SILC_GET16_MSB(pkargc, pk);
4275 pkargs = silc_argument_payload_parse(pk + 2, pk_len - 2, pkargc);
4277 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4278 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4283 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4285 if (!silc_pkcs_public_key_payload_decode(pk, pk_len, &public_key))
4291 /* Add public key to watch list */
4293 /* Check whether this client is already watching this public key */
4294 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4295 public_key, client, NULL)) {
4296 silc_pkcs_public_key_free(public_key);
4297 silc_server_command_send_status_reply(
4298 cmd, SILC_COMMAND_WATCH,
4299 SILC_STATUS_ERR_NICKNAME_IN_USE, 0);
4303 /* Get the public key from the watcher list and use the same key in
4304 new entries as well. If key doesn't exist then create it. */
4306 if (!silc_hash_table_find(server->watcher_list_pk, public_key,
4307 (void *)&pkkey, NULL))
4310 silc_pkcs_public_key_free(public_key);
4312 /* Add the client to the watcher list with the specified public
4314 silc_hash_table_add(server->watcher_list_pk, pkkey, client);
4316 } else if (type == 0x01) {
4317 /* Delete public key from watch list */
4319 /* Check that this client is watching this public key */
4320 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4323 silc_pkcs_public_key_free(public_key);
4324 silc_server_command_send_status_reply(
4325 cmd, SILC_COMMAND_WATCH,
4326 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4330 /* Delete the public key from the watcher list. */
4331 silc_hash_table_del_by_context(server->watcher_list_pk,
4332 public_key, client);
4334 /* Now check whether there still exists entries with this key, if
4335 not then free the key to not leak memory. */
4336 if (!silc_hash_table_find(server->watcher_list_pk, hash, NULL, NULL))
4337 silc_pkcs_public_key_free(pkkey);
4338 silc_pkcs_public_key_free(public_key);
4341 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4345 /* Distribute the watch list to backup routers too */
4346 if (server->backup) {
4348 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4349 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4350 silc_server_backup_send(server, NULL, SILC_PACKET_COMMAND,
4351 cmd->packet->flags, tmpbuf->data, tmpbuf->len,
4353 silc_buffer_free(tmpbuf);
4356 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4360 silc_free(client_id);
4361 silc_server_command_free(cmd);
4364 /* Server side of SILCOPER command. Client uses this comand to obtain router
4365 operator privileges to this router. */
4367 SILC_SERVER_CMD_FUNC(silcoper)
4369 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4370 SilcServer server = cmd->server;
4371 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4372 unsigned char *username = NULL, *auth;
4374 SilcServerConfigAdmin *admin;
4375 SilcIDListData idata = (SilcIDListData)client;
4376 bool result = FALSE;
4377 SilcPublicKey cached_key;
4379 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4382 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
4384 if (server->server_type != SILC_ROUTER) {
4385 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4386 SILC_STATUS_ERR_AUTH_FAILED, 0);
4390 /* Get the username */
4391 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4393 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4394 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4399 /* Check username */
4400 username = silc_identifier_check(username, tmp_len, SILC_STRING_UTF8, 128,
4403 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4404 SILC_STATUS_ERR_BAD_USERNAME,
4409 /* Get the admin configuration */
4410 admin = silc_server_config_find_admin(server, cmd->sock->ip,
4411 username, client->nickname);
4413 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
4414 username, client->nickname);
4416 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4417 SILC_STATUS_ERR_AUTH_FAILED, 0);
4418 SILC_LOG_INFO(("SILCOPER authentication failed for username '%s' by "
4419 "nickname '%s' from %s", username,
4420 client->nickname, cmd->sock->hostname));
4425 /* Get the authentication payload */
4426 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
4428 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4429 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4434 /* Verify the authentication data. If both passphrase and public key
4435 is set then try both of them. */
4436 if (admin->passphrase)
4437 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
4438 admin->passphrase, admin->passphrase_len,
4439 idata->hash, client->id, SILC_ID_CLIENT);
4440 if (!result && admin->publickeys) {
4441 cached_key = silc_server_get_public_key(server, admin->publickeys);
4444 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
4445 cached_key, 0, idata->hash,
4446 client->id, SILC_ID_CLIENT);
4449 /* Authentication failed */
4450 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4451 SILC_STATUS_ERR_AUTH_FAILED, 0);
4455 /* Client is now router operator */
4456 client->mode |= SILC_UMODE_ROUTER_OPERATOR;
4458 /* Update statistics */
4459 if (SILC_IS_LOCAL(client))
4460 server->stat.my_router_ops++;
4461 if (server->server_type == SILC_ROUTER)
4462 server->stat.router_ops++;
4464 /* Send UMODE change to primary router */
4465 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4466 SILC_BROADCAST(server), client->id,
4469 /* Check if anyone is watching this nickname */
4470 if (server->server_type == SILC_ROUTER)
4471 silc_server_check_watcher_list(server, client, NULL,
4472 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4474 /* Send reply to the sender */
4475 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4479 silc_free(username);
4480 silc_server_command_free(cmd);
4483 /* Server side of command BAN. This is used to manage the ban list of the
4484 channel. To add clients and remove clients from the ban list. */
4486 SILC_SERVER_CMD_FUNC(ban)
4488 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4489 SilcServer server = cmd->server;
4490 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4491 SilcBuffer packet, list, tmp2;
4492 SilcChannelEntry channel;
4493 SilcChannelClientEntry chl;
4494 SilcChannelID *channel_id = NULL;
4495 unsigned char *id, *tmp, *atype = NULL;
4496 SilcUInt32 id_len, len, len2;
4497 SilcArgumentPayload args;
4498 SilcHashTableList htl;
4500 SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
4501 SilcBufferStruct blist;
4503 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4506 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_BAN, cmd, 0, 3);
4508 /* Get Channel ID */
4509 id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
4511 channel_id = silc_id_payload_parse_id(id, id_len, NULL);
4513 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4514 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4519 /* Get channel entry. The server must know about the channel since the
4520 client is expected to be on the channel. */
4521 channel = silc_idlist_find_channel_by_id(server->local_list,
4524 channel = silc_idlist_find_channel_by_id(server->global_list,
4527 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4528 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4534 /* Check whether this client is on the channel */
4535 if (!silc_server_client_on_channel(client, channel, &chl)) {
4536 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4537 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4542 /* The client must be at least channel operator. */
4543 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
4544 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4545 SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0,
4550 /* Get the ban information */
4551 tmp = silc_argument_get_arg_type(cmd->args, 3, &len2);
4552 if (tmp && len2 > 2) {
4553 /* Parse the arguments to see they are constructed correctly */
4554 SILC_GET16_MSB(argc, tmp);
4555 args = silc_argument_payload_parse(tmp + 2, len2 - 2, argc);
4557 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4558 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4563 /* Get the type of action */
4564 atype = silc_argument_get_arg_type(cmd->args, 2, &len);
4565 if (atype && len == 1) {
4566 if (atype[0] == 0x00) {
4567 /* Allocate hash table for ban list if it doesn't exist yet */
4568 if (!channel->ban_list)
4570 silc_hash_table_alloc(0, silc_hash_ptr,
4572 silc_server_inviteban_destruct, channel,
4575 /* Check for resource limit */
4576 if (silc_hash_table_count(channel->ban_list) > 64) {
4577 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4578 SILC_STATUS_ERR_RESOURCE_LIMIT,
4584 /* Now add or delete the information. */
4585 silc_server_inviteban_process(server, channel->ban_list,
4586 (SilcUInt8)atype[0], args);
4588 silc_argument_payload_free(args);
4591 /* Encode ban list */
4593 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4594 list = silc_buffer_alloc_size(2);
4595 silc_buffer_format(list,
4596 SILC_STR_UI_SHORT(silc_hash_table_count(
4597 channel->ban_list)),
4599 silc_hash_table_list(channel->ban_list, &htl);
4600 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4601 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4603 silc_hash_table_list_reset(&htl);
4606 /* Send BAN notify type to local servers (but not clients) and to
4608 if (atype && tmp && len2) {
4609 silc_buffer_set(&blist, tmp, len2);
4611 /* Send to local servers if we are router */
4612 if (server->server_type == SILC_ROUTER)
4613 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
4614 SILC_NOTIFY_TYPE_BAN, 3,
4617 tmp ? blist.data : NULL,
4618 tmp ? blist.len : 0);
4620 /* Send to network. */
4621 silc_server_send_notify_ban(server, SILC_PRIMARY_ROUTE(server),
4622 SILC_BROADCAST(server), channel, atype,
4626 /* Send the reply back to the client */
4628 silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
4629 SILC_STATUS_OK, 0, ident, 2,
4631 3, list ? list->data : NULL,
4632 list ? list->len : 0);
4633 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4634 packet->data, packet->len, FALSE);
4636 silc_buffer_free(packet);
4637 silc_buffer_free(list);
4640 silc_free(channel_id);
4641 silc_server_command_free(cmd);
4644 /* Server side command of LEAVE. Removes client from a channel. */
4646 SILC_SERVER_CMD_FUNC(leave)
4648 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4649 SilcServer server = cmd->server;
4650 SilcSocketConnection sock = cmd->sock;
4651 SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
4652 SilcChannelID *id = NULL;
4653 SilcChannelEntry channel;
4657 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !id_entry)
4660 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 2);
4662 /* Get Channel ID */
4663 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
4665 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4666 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4669 id = silc_id_payload_parse_id(tmp, len, NULL);
4671 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4672 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4676 /* Get channel entry */
4677 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4679 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4681 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4682 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4688 /* Check whether this client is on the channel */
4689 if (!silc_server_client_on_channel(id_entry, channel, NULL)) {
4690 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4691 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4696 /* Notify routers that they should remove this client from their list
4697 of clients on the channel. Send LEAVE notify type. */
4698 silc_server_send_notify_leave(server, SILC_PRIMARY_ROUTE(server),
4699 SILC_BROADCAST(server), channel, id_entry->id);
4701 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4702 SILC_STATUS_OK, 0, 2, tmp, len);
4704 /* Remove client from channel */
4705 if (!silc_server_remove_from_one_channel(server, sock, channel, id_entry,
4707 /* If the channel does not exist anymore we won't send anything */
4710 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
4711 /* Re-generate channel key */
4712 if (!silc_server_create_channel_key(server, channel, 0))
4715 /* Send the channel key */
4716 silc_server_send_channel_key(server, NULL, channel,
4717 server->server_type == SILC_ROUTER ?
4718 FALSE : !server->standalone);
4723 silc_server_command_free(cmd);
4726 /* Server side of command USERS. Resolves clients and their USERS currently
4727 joined on the requested channel. The list of Client ID's and their modes
4728 on the channel is sent back. */
4730 SILC_SERVER_CMD_FUNC(users)
4732 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4733 SilcServer server = cmd->server;
4734 SilcChannelEntry channel;
4735 SilcChannelID *id = NULL;
4736 SilcBuffer packet, idp;
4737 unsigned char *channel_id;
4738 SilcUInt32 channel_id_len;
4739 SilcBuffer client_id_list;
4740 SilcBuffer client_mode_list;
4741 unsigned char lc[4];
4742 SilcUInt32 list_count = 0;
4743 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4744 char *channel_name, *channel_namec = NULL;
4746 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2);
4748 /* Get Channel ID */
4749 channel_id = silc_argument_get_arg_type(cmd->args, 1, &channel_id_len);
4751 /* Get channel name */
4752 channel_name = silc_argument_get_arg_type(cmd->args, 2, NULL);
4754 if (!channel_id && !channel_name) {
4755 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4756 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4760 /* Check channel name */
4762 channel_namec = silc_identifier_check(channel_name, strlen(channel_name),
4763 SILC_STRING_UTF8, 256, NULL);
4764 if (!channel_namec) {
4765 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4766 SILC_STATUS_ERR_BAD_CHANNEL, 0);
4771 /* Check Channel ID */
4773 id = silc_id_payload_parse_id(channel_id, channel_id_len, NULL);
4775 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4776 SILC_STATUS_ERR_BAD_CHANNEL_ID, 0,
4777 2, channel_id, channel_id_len);
4782 /* If we are server and we don't know about this channel we will send
4783 the command to our router. If we know about the channel then we also
4784 have the list of users already. */
4786 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4788 channel = silc_idlist_find_channel_by_name(server->local_list,
4789 channel_namec, NULL);
4791 if (!channel || (!server->standalone && (channel->disabled ||
4792 !channel->users_resolved))) {
4793 if (server->server_type != SILC_ROUTER && !server->standalone &&
4797 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4798 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4800 /* Send USERS command */
4801 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4802 SILC_PACKET_COMMAND, cmd->packet->flags,
4803 tmpbuf->data, tmpbuf->len, TRUE);
4805 /* Reprocess this packet after received reply */
4806 silc_server_command_pending(server, SILC_COMMAND_USERS,
4807 silc_command_get_ident(cmd->payload),
4808 silc_server_command_users,
4809 silc_server_command_dup(cmd));
4810 cmd->pending = TRUE;
4811 silc_command_set_ident(cmd->payload, ident);
4812 silc_buffer_free(tmpbuf);
4817 /* Check the global list as well. */
4819 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4821 channel = silc_idlist_find_channel_by_name(server->global_list,
4822 channel_namec, NULL);
4824 /* Channel really does not exist */
4826 silc_server_command_send_status_data(
4827 cmd, SILC_COMMAND_USERS,
4828 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID, 0,
4829 2, channel_id, channel_id_len);
4831 silc_server_command_send_status_data(
4832 cmd, SILC_COMMAND_USERS,
4833 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
4834 2, channel_name, strlen(channel_name));
4839 /* If the channel is private or secret do not send anything, unless the
4840 user requesting this command is on the channel or is server */
4841 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
4842 if (channel->mode & (SILC_CHANNEL_MODE_PRIVATE | SILC_CHANNEL_MODE_SECRET)
4843 && !silc_server_client_on_channel(cmd->sock->user_data, channel,
4845 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4846 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
4847 2, channel->channel_name,
4848 strlen(channel->channel_name));
4853 /* Get the users list */
4854 if (!silc_server_get_users_on_channel(server, channel, &client_id_list,
4855 &client_mode_list, &list_count)) {
4857 client_id_list = NULL;
4858 client_mode_list = NULL;
4862 SILC_PUT32_MSB(list_count, lc);
4865 idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4866 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_USERS,
4867 SILC_STATUS_OK, 0, ident, 4,
4868 2, idp->data, idp->len,
4871 client_id_list->data : NULL,
4873 client_id_list->len : 0,
4874 5, client_mode_list ?
4875 client_mode_list->data : NULL,
4877 client_mode_list->len : 0);
4878 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4879 packet->data, packet->len, FALSE);
4881 silc_buffer_free(idp);
4882 silc_buffer_free(packet);
4884 silc_buffer_free(client_id_list);
4885 if (client_mode_list)
4886 silc_buffer_free(client_mode_list);
4890 silc_free(channel_namec);
4891 silc_server_command_free(cmd);
4894 /* Server side of command GETKEY. This fetches the client's public key
4895 from the server where to the client is connected. */
4897 SILC_SERVER_CMD_FUNC(getkey)
4899 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4900 SilcServer server = cmd->server;
4902 SilcClientEntry client;
4903 SilcServerEntry server_entry;
4904 SilcClientID *client_id = NULL;
4905 SilcServerID *server_id = NULL;
4906 SilcIDPayload idp = NULL;
4907 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4910 SilcBuffer pk = NULL;
4912 SilcPublicKey public_key;
4914 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4916 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
4917 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4921 idp = silc_id_payload_parse(tmp, tmp_len);
4923 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
4924 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4929 id_type = silc_id_payload_get_type(idp);
4930 if (id_type == SILC_ID_CLIENT) {
4931 client_id = silc_id_payload_get_id(idp);
4933 /* If the client is not found from local list there is no chance it
4934 would be locally connected client so send the command further. */
4935 client = silc_idlist_find_client_by_id(server->local_list,
4936 client_id, TRUE, NULL);
4938 client = silc_idlist_find_client_by_id(server->global_list,
4939 client_id, TRUE, NULL);
4941 if ((!client && !cmd->pending && !server->standalone) ||
4942 (client && !client->connection && !cmd->pending &&
4943 !(client->mode & SILC_UMODE_DETACHED)) ||
4944 (client && !client->data.public_key && !cmd->pending)) {
4946 SilcUInt16 old_ident;
4947 SilcSocketConnection dest_sock;
4949 dest_sock = silc_server_get_client_route(server, NULL, 0,
4950 client_id, NULL, NULL);
4954 old_ident = silc_command_get_ident(cmd->payload);
4955 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4956 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4958 silc_server_packet_send(server, dest_sock,
4959 SILC_PACKET_COMMAND, cmd->packet->flags,
4960 tmpbuf->data, tmpbuf->len, TRUE);
4962 /* Reprocess this packet after received reply from router */
4963 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
4964 silc_command_get_ident(cmd->payload),
4965 silc_server_command_getkey,
4966 silc_server_command_dup(cmd));
4967 cmd->pending = TRUE;
4968 silc_command_set_ident(cmd->payload, old_ident);
4969 silc_buffer_free(tmpbuf);
4974 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
4975 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4976 0, 2, tmp, tmp_len);
4980 /* The client is locally connected, just get the public key and
4981 send it back. If they key does not exist then do not send it,
4982 send just OK reply */
4983 public_key = client->data.public_key;
4985 pk = silc_pkcs_public_key_payload_encode(public_key);
4986 } else if (id_type == SILC_ID_SERVER) {
4987 server_id = silc_id_payload_get_id(idp);
4989 /* If the server is not found from local list there is no chance it
4990 would be locally connected server so send the command further. */
4991 server_entry = silc_idlist_find_server_by_id(server->local_list,
4992 server_id, TRUE, NULL);
4994 server_entry = silc_idlist_find_server_by_id(server->global_list,
4995 server_id, TRUE, NULL);
4997 if (server_entry != server->id_entry &&
4998 ((!server_entry && !cmd->pending && !server->standalone) ||
4999 (server_entry && !server_entry->connection && !cmd->pending &&
5000 !server->standalone) ||
5001 (server_entry && !server_entry->data.public_key && !cmd->pending &&
5002 !server->standalone))) {
5004 SilcUInt16 old_ident;
5006 old_ident = silc_command_get_ident(cmd->payload);
5007 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5008 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5010 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5011 SILC_PACKET_COMMAND, cmd->packet->flags,
5012 tmpbuf->data, tmpbuf->len, TRUE);
5014 /* Reprocess this packet after received reply from router */
5015 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
5016 silc_command_get_ident(cmd->payload),
5017 silc_server_command_getkey,
5018 silc_server_command_dup(cmd));
5019 cmd->pending = TRUE;
5020 silc_command_set_ident(cmd->payload, old_ident);
5021 silc_buffer_free(tmpbuf);
5025 if (!server_entry) {
5026 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
5027 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
5028 0, 2, tmp, tmp_len);
5032 /* If they key does not exist then do not send it, send just OK reply */
5033 public_key = (!server_entry->data.public_key ?
5034 (server_entry == server->id_entry ? server->public_key :
5035 NULL) : server_entry->data.public_key);
5037 pk = silc_pkcs_public_key_payload_encode(public_key);
5042 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5043 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_GETKEY,
5044 SILC_STATUS_OK, 0, ident, 2,
5046 3, pk ? pk->data : NULL,
5048 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
5049 packet->data, packet->len, FALSE);
5050 silc_buffer_free(packet);
5054 silc_id_payload_free(idp);
5055 silc_buffer_free(pk);
5056 silc_free(client_id);
5057 silc_free(server_id);
5058 silc_server_command_free(cmd);
5062 /* Private range commands, specific to this implementation */
5064 /* Server side command of CONNECT. Connects us to the specified remote
5065 server or router. */
5067 SILC_SERVER_CMD_FUNC(connect)
5069 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5070 SilcServer server = cmd->server;
5071 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5072 unsigned char *tmp, *host;
5074 SilcUInt32 port = SILC_PORT;
5076 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5079 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CONNECT, cmd, 1, 2);
5081 /* Check whether client has the permissions. */
5082 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5083 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5084 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5085 SILC_STATUS_ERR_NO_SERVER_PRIV, 0);
5089 if (server->server_type == SILC_ROUTER && !server->backup_router &&
5090 client->mode & SILC_UMODE_SERVER_OPERATOR) {
5091 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5092 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
5096 /* Get the remote server */
5097 host = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5099 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5100 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5106 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5108 SILC_GET32_MSB(port, tmp);
5110 /* Create the connection. It is done with timeout and is async. */
5111 silc_server_create_connection(server, host, port);
5113 /* Send reply to the sender */
5114 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5118 silc_server_command_free(cmd);
5121 /* Server side command of CLOSE. Closes connection to a specified server. */
5123 SILC_SERVER_CMD_FUNC(close)
5125 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5126 SilcServer server = cmd->server;
5127 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5128 SilcServerEntry server_entry;
5129 SilcSocketConnection sock;
5132 unsigned char *name;
5133 SilcUInt32 port = SILC_PORT;
5135 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5138 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CLOSE, cmd, 1, 2);
5140 /* Check whether client has the permissions. */
5141 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5142 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5143 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5144 SILC_STATUS_ERR_NO_SERVER_PRIV,
5149 /* Get the remote server */
5150 name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5152 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5153 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5159 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5161 SILC_GET32_MSB(port, tmp);
5163 server_entry = silc_idlist_find_server_by_conn(server->local_list,
5164 name, port, TRUE, NULL);
5166 server_entry = silc_idlist_find_server_by_conn(server->global_list,
5167 name, port, TRUE, NULL);
5168 if (!server_entry) {
5169 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5170 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5174 if (server_entry == server->id_entry) {
5175 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5176 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5180 /* Send reply to the sender */
5181 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5184 /* Close the connection to the server */
5185 sock = (SilcSocketConnection)server_entry->connection;
5187 if (server_entry->server_type == SILC_BACKUP_ROUTER) {
5188 server->backup_closed = TRUE;
5189 silc_server_backup_del(server, server_entry);
5192 server->backup_noswitch = TRUE;
5193 if (server->router == server_entry) {
5194 server->id_entry->router = NULL;
5195 server->router = NULL;
5196 server->standalone = TRUE;
5198 silc_server_disconnect_remote(server, sock,
5199 SILC_STATUS_ERR_BANNED_FROM_SERVER,
5200 "Closed by administrator");
5201 if (sock->user_data)
5202 silc_server_free_sock_user_data(server, sock, NULL);
5203 server->backup_noswitch = FALSE;
5206 silc_server_command_free(cmd);
5209 /* Server side command of SHUTDOWN. Shutdowns the server and closes all
5210 active connections. */
5212 SILC_SERVER_CMD_FUNC(shutdown)
5214 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5215 SilcServer server = cmd->server;
5216 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5218 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5221 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_SHUTDOWN, cmd, 0, 0);
5223 /* Check whether client has the permission. */
5224 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5225 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5226 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5227 SILC_STATUS_ERR_NO_SERVER_PRIV,
5232 /* Send reply to the sender */
5233 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5236 /* Then, gracefully, or not, bring the server down. */
5237 silc_server_stop(server);
5241 silc_server_command_free(cmd);