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 = strdup(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_free(channel_namec);
2571 silc_server_command_free(cmd);
2574 /* Server side of command MOTD. Sends server's current "message of the
2575 day" to the client. */
2577 SILC_SERVER_CMD_FUNC(motd)
2579 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2580 SilcServer server = cmd->server;
2581 SilcBuffer packet, idp;
2582 char *motd, *dest_server = NULL;
2583 SilcUInt32 motd_len;
2584 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2586 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_MOTD, cmd, 1, 1);
2588 /* Get server name */
2589 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2591 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
2592 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2597 /* Check server name */
2598 dest_server = silc_identifier_check(dest_server, strlen(dest_server),
2599 SILC_STRING_UTF8, 256, NULL);
2601 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
2602 SILC_STATUS_ERR_BAD_SERVER,
2607 if (!memcmp(dest_server, server->server_name, strlen(dest_server))) {
2610 idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
2612 if (server->config && server->config->server_info &&
2613 server->config->server_info->motd_file) {
2615 motd = silc_file_readfile(server->config->server_info->motd_file,
2621 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
2624 2, idp->data, idp->len,
2628 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
2631 2, idp->data, idp->len);
2634 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2635 packet->data, packet->len, FALSE);
2636 silc_buffer_free(packet);
2637 silc_buffer_free(idp);
2639 SilcServerEntry entry;
2641 /* Check whether we have this server cached */
2642 entry = silc_idlist_find_server_by_name(server->global_list,
2643 dest_server, TRUE, NULL);
2645 entry = silc_idlist_find_server_by_name(server->local_list,
2646 dest_server, TRUE, NULL);
2649 if (server->server_type != SILC_SERVER && !cmd->pending &&
2650 entry && !entry->motd) {
2651 /* Send to the server */
2653 SilcUInt16 old_ident;
2655 old_ident = silc_command_get_ident(cmd->payload);
2656 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2657 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2659 silc_server_packet_send(server, entry->connection,
2660 SILC_PACKET_COMMAND, cmd->packet->flags,
2661 tmpbuf->data, tmpbuf->len, TRUE);
2663 /* Reprocess this packet after received reply from router */
2664 silc_server_command_pending(server, SILC_COMMAND_MOTD,
2665 silc_command_get_ident(cmd->payload),
2666 silc_server_command_motd,
2667 silc_server_command_dup(cmd));
2668 cmd->pending = TRUE;
2669 silc_command_set_ident(cmd->payload, old_ident);
2670 silc_buffer_free(tmpbuf);
2674 /* Send to primary router only if we don't know the server
2675 * the client requested or if the server is not locally connected */
2676 if ((!entry || !(entry->data.status & SILC_IDLIST_STATUS_LOCAL))
2677 && !cmd->pending && !server->standalone) {
2678 /* Send to the primary router */
2680 SilcUInt16 old_ident;
2682 old_ident = silc_command_get_ident(cmd->payload);
2683 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2684 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2686 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2687 SILC_PACKET_COMMAND, cmd->packet->flags,
2688 tmpbuf->data, tmpbuf->len, TRUE);
2690 /* Reprocess this packet after received reply from router */
2691 silc_server_command_pending(server, SILC_COMMAND_MOTD,
2692 silc_command_get_ident(cmd->payload),
2693 silc_server_command_motd,
2694 silc_server_command_dup(cmd));
2695 cmd->pending = TRUE;
2696 silc_command_set_ident(cmd->payload, old_ident);
2697 silc_buffer_free(tmpbuf);
2702 silc_free(dest_server);
2703 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2704 silc_server_command_send_status_data(cmd, SILC_COMMAND_MOTD,
2705 SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
2707 strlen(dest_server));
2712 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
2713 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
2714 SILC_STATUS_OK, 0, ident, 2,
2715 2, idp->data, idp->len,
2718 strlen(entry->motd) : 0);
2719 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2720 packet->data, packet->len, FALSE);
2721 silc_buffer_free(packet);
2722 silc_buffer_free(idp);
2726 silc_free(dest_server);
2727 silc_server_command_free(cmd);
2730 /* Server side of command UMODE. Client can use this command to set/unset
2731 user mode. Client actually cannot set itself to be as server/router
2732 operator so this can be used only to unset the modes. */
2734 SILC_SERVER_CMD_FUNC(umode)
2736 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2737 SilcServer server = cmd->server;
2738 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2740 unsigned char *tmp_mask, m[4];
2741 SilcUInt32 mask = 0;
2742 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2743 bool set_mask = FALSE;
2745 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
2748 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_UMODE, cmd, 1, 2);
2750 /* Get the client's mode mask */
2751 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
2753 SILC_GET32_MSB(mask, tmp_mask);
2758 /* Check that mode changing is allowed. */
2759 if (!silc_server_check_umode_rights(server, client, mask)) {
2760 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
2761 SILC_STATUS_ERR_PERM_DENIED, 0);
2765 /* Anonymous mode cannot be set by client */
2766 if (mask & SILC_UMODE_ANONYMOUS &&
2767 !(client->mode & SILC_UMODE_ANONYMOUS)) {
2768 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
2769 SILC_STATUS_ERR_PERM_DENIED, 0);
2773 /* Update statistics */
2774 if (mask & SILC_UMODE_GONE) {
2775 if (!(client->mode & SILC_UMODE_GONE))
2776 server->stat.my_aways++;
2778 if (client->mode & SILC_UMODE_GONE)
2779 server->stat.my_aways--;
2782 /* If the client has anonymous mode set, preserve it. */
2783 if (client->mode & SILC_UMODE_ANONYMOUS)
2784 mask |= SILC_UMODE_ANONYMOUS;
2786 /* Change the mode */
2787 client->mode = mask;
2789 /* Send UMODE change to primary router */
2790 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
2791 SILC_BROADCAST(server), client->id,
2794 /* Check if anyone is watching this nickname */
2795 if (server->server_type == SILC_ROUTER)
2796 silc_server_check_watcher_list(server, client, NULL,
2797 SILC_NOTIFY_TYPE_UMODE_CHANGE);
2800 /* Send command reply to sender */
2801 SILC_PUT32_MSB(client->mode, m);
2802 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_UMODE,
2803 SILC_STATUS_OK, 0, ident, 1,
2805 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2806 packet->data, packet->len, FALSE);
2807 silc_buffer_free(packet);
2810 silc_server_command_free(cmd);
2813 /* Server side command of CMODE. Changes channel mode */
2815 SILC_SERVER_CMD_FUNC(cmode)
2817 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2818 SilcServer server = cmd->server;
2819 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2820 SilcIDListData idata = (SilcIDListData)client;
2821 SilcChannelID *channel_id = NULL;
2822 SilcChannelEntry channel;
2823 SilcChannelClientEntry chl;
2824 SilcBuffer packet, cidp;
2825 unsigned char *tmp, *tmp_id, *tmp_mask, *chpkdata = NULL;
2826 char *cipher = NULL, *hmac = NULL, *passphrase = NULL, ulimit[4];
2827 SilcUInt32 mode_mask = 0, old_mask = 0, tmp_len, tmp_len2, chpklen;
2828 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2829 bool set_mask = FALSE, set_chpk = FALSE;
2830 SilcPublicKey founder_key = NULL;
2831 SilcBuffer fkey = NULL, chpklist = NULL;
2832 SilcBufferStruct chpk;
2835 silc_server_command_free(cmd);
2839 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 9);
2841 /* Get Channel ID */
2842 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
2844 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2845 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2846 silc_server_command_free(cmd);
2849 channel_id = silc_id_payload_parse_id(tmp_id, tmp_len2, NULL);
2851 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2852 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2853 silc_server_command_free(cmd);
2857 /* Get channel entry */
2858 channel = silc_idlist_find_channel_by_id(server->local_list,
2861 channel = silc_idlist_find_channel_by_id(server->global_list,
2864 silc_server_command_send_status_data(cmd, SILC_COMMAND_CMODE,
2865 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
2866 0, 2, tmp_id, tmp_len2);
2867 silc_free(channel_id);
2868 silc_server_command_free(cmd);
2872 old_mask = channel->mode;
2874 /* Get the channel mode mask */
2875 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
2877 SILC_GET32_MSB(mode_mask, tmp_mask);
2881 /* Check whether this client is on the channel */
2882 if (!silc_server_client_on_channel(client, channel, &chl)) {
2883 silc_server_command_send_status_data(cmd, SILC_COMMAND_CMODE,
2884 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
2885 2, tmp_id, tmp_len2);
2889 /* Check that client has rights to change any requested channel modes */
2890 if (set_mask && !silc_server_check_cmode_rights(server, channel, chl,
2892 SILC_LOG_DEBUG(("Client does not have rights to change mode"));
2893 silc_server_command_send_status_data(
2894 cmd, SILC_COMMAND_CMODE,
2895 (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) ?
2896 SILC_STATUS_ERR_NO_CHANNEL_PRIV :
2897 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV), 0,
2898 2, tmp_id, tmp_len2);
2902 /* If mode mask was not sent as argument then merely return the current
2903 mode mask, founder key and channel public key list to the sender. */
2906 SILC_PUT32_MSB(channel->mode, m);
2907 if (channel->founder_key)
2908 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
2909 if (channel->channel_pubkeys)
2910 chpklist = silc_server_get_channel_pk_list(server, channel,
2913 silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
2914 SILC_STATUS_OK, 0, ident, 4,
2915 2, tmp_id, tmp_len2,
2917 4, fkey ? fkey->data : NULL,
2918 fkey ? fkey->len : 0,
2919 5, chpklist ? chpklist->data : NULL,
2920 chpklist ? chpklist->len : 0);
2921 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2922 packet->data, packet->len, FALSE);
2923 silc_buffer_free(packet);
2928 * Check the modes. Modes that requires nothing special operation are
2932 if (mode_mask & SILC_CHANNEL_MODE_PRIVKEY) {
2933 /* Channel uses private keys to protect traffic. Client(s) has set the
2934 key locally they want to use, server does not know that key. */
2935 /* Nothing interesting to do here */
2937 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
2938 /* The mode is removed and we need to generate and distribute
2939 new channel key. Clients are not using private channel keys
2940 anymore after this. */
2942 /* Re-generate channel key */
2943 if (!silc_server_create_channel_key(server, channel, 0))
2946 /* Send the channel key. This sends it to our local clients and if
2947 we are normal server to our router as well. */
2948 silc_server_send_channel_key(server, NULL, channel,
2949 server->server_type == SILC_ROUTER ?
2950 FALSE : !server->standalone);
2952 cipher = (char *)silc_cipher_get_name(channel->channel_key);
2953 hmac = (char *)silc_hmac_get_name(channel->hmac);
2957 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT) {
2958 /* User limit is set on channel */
2959 SilcUInt32 user_limit;
2961 /* Get user limit */
2962 tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
2964 if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT)) {
2965 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2966 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
2970 SILC_GET32_MSB(user_limit, tmp);
2971 channel->user_limit = user_limit;
2974 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2975 /* User limit mode is unset. Remove user limit */
2976 channel->user_limit = 0;
2979 if (mode_mask & SILC_CHANNEL_MODE_PASSPHRASE) {
2980 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
2981 /* Passphrase has been set to channel */
2983 /* Get the passphrase */
2984 tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
2986 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2987 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
2991 /* Save the passphrase */
2992 passphrase = channel->passphrase = silc_memdup(tmp, strlen(tmp));
2995 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
2996 /* Passphrase mode is unset. remove the passphrase */
2997 silc_free(channel->passphrase);
2998 channel->passphrase = NULL;
3002 if (mode_mask & SILC_CHANNEL_MODE_CIPHER) {
3003 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
3004 /* Cipher to use protect the traffic */
3005 SilcCipher newkey, oldkey;
3008 cipher = silc_argument_get_arg_type(cmd->args, 5, NULL);
3010 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3011 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3015 /* Delete old cipher and allocate the new one */
3016 if (!silc_cipher_alloc(cipher, &newkey)) {
3017 silc_server_command_send_status_data(
3018 cmd, SILC_COMMAND_CMODE,
3019 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3020 2, cipher, strlen(cipher));
3024 oldkey = channel->channel_key;
3025 channel->channel_key = newkey;
3027 /* Re-generate channel key */
3028 if (!silc_server_create_channel_key(server, channel, 0)) {
3029 /* We don't have new key, revert to old one */
3030 channel->channel_key = oldkey;
3034 /* Remove old channel key for good */
3035 silc_cipher_free(oldkey);
3037 /* Send the channel key. This sends it to our local clients and if
3038 we are normal server to our router as well. */
3039 silc_server_send_channel_key(server, NULL, channel,
3040 server->server_type == SILC_ROUTER ?
3041 FALSE : !server->standalone);
3044 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
3045 /* Cipher mode is unset. Remove the cipher and revert back to
3047 SilcCipher newkey, oldkey;
3048 cipher = channel->cipher;
3050 /* Delete old cipher and allocate default one */
3051 if (!silc_cipher_alloc(cipher ? cipher : SILC_DEFAULT_CIPHER, &newkey)) {
3052 silc_server_command_send_status_data(
3053 cmd, SILC_COMMAND_CMODE,
3054 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3055 2, cipher, strlen(cipher));
3059 oldkey = channel->channel_key;
3060 channel->channel_key = newkey;
3062 /* Re-generate channel key */
3063 if (!silc_server_create_channel_key(server, channel, 0)) {
3064 /* We don't have new key, revert to old one */
3065 channel->channel_key = oldkey;
3069 /* Remove old channel key for good */
3070 silc_cipher_free(oldkey);
3072 /* Send the channel key. This sends it to our local clients and if
3073 we are normal server to our router as well. */
3074 silc_server_send_channel_key(server, NULL, channel,
3075 server->server_type == SILC_ROUTER ?
3076 FALSE : !server->standalone);
3080 if (mode_mask & SILC_CHANNEL_MODE_HMAC) {
3081 if (!(channel->mode & SILC_CHANNEL_MODE_HMAC)) {
3082 /* HMAC to use protect the traffic */
3083 unsigned char hash[32];
3087 hmac = silc_argument_get_arg_type(cmd->args, 6, NULL);
3089 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3090 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3094 /* Delete old hmac and allocate the new one */
3095 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3096 silc_server_command_send_status_data(
3097 cmd, SILC_COMMAND_CMODE,
3098 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3099 2, hmac, strlen(hmac));
3103 silc_hmac_free(channel->hmac);
3104 channel->hmac = newhmac;
3106 /* Set the HMAC key out of current channel key. The client must do
3108 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
3109 channel->key_len / 8, hash);
3110 silc_hmac_set_key(channel->hmac, hash,
3111 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3112 memset(hash, 0, sizeof(hash));
3115 if (channel->mode & SILC_CHANNEL_MODE_HMAC) {
3116 /* Hmac mode is unset. Remove the hmac and revert back to
3119 unsigned char hash[32];
3120 hmac = channel->hmac_name;
3122 /* Delete old hmac and allocate default one */
3123 if (!silc_hmac_alloc(hmac ? hmac : SILC_DEFAULT_HMAC, NULL, &newhmac)) {
3124 silc_server_command_send_status_data(
3125 cmd, SILC_COMMAND_CMODE,
3126 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3127 2, hmac, strlen(hmac));
3131 silc_hmac_free(channel->hmac);
3132 channel->hmac = newhmac;
3134 /* Set the HMAC key out of current channel key. The client must do
3136 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
3137 channel->key_len / 8,
3139 silc_hmac_set_key(channel->hmac, hash,
3140 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3141 memset(hash, 0, sizeof(hash));
3145 if (mode_mask & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3146 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3147 /* Check if the founder public key was received */
3148 founder_key = idata->public_key;
3149 tmp = silc_argument_get_arg_type(cmd->args, 8, &tmp_len);
3151 if (!silc_pkcs_public_key_payload_decode(tmp, tmp_len, &founder_key)) {
3152 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3153 SILC_STATUS_ERR_AUTH_FAILED,
3158 /* If key was not sent and the channel mode has already founder
3159 then the key was not to be changed. */
3160 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
3164 /* Set the founder authentication */
3165 tmp = silc_argument_get_arg_type(cmd->args, 7, &tmp_len);
3167 silc_server_command_send_status_reply(
3168 cmd, SILC_COMMAND_CMODE,
3169 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3173 /* Verify the payload before setting the mode */
3174 if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY,
3175 founder_key, 0, server->sha1hash,
3176 client->id, SILC_ID_CLIENT)) {
3177 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3178 SILC_STATUS_ERR_AUTH_FAILED,
3183 /* Save the public key */
3184 if (channel->founder_key)
3185 silc_pkcs_public_key_free(channel->founder_key);
3186 if (silc_argument_get_arg_type(cmd->args, 8, NULL))
3187 channel->founder_key = founder_key;
3189 channel->founder_key = silc_pkcs_public_key_copy(founder_key);
3190 if (!channel->founder_key) {
3191 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3192 SILC_STATUS_ERR_AUTH_FAILED,
3197 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
3199 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3200 SILC_STATUS_ERR_AUTH_FAILED,
3202 silc_pkcs_public_key_free(channel->founder_key);
3203 channel->founder_key = NULL;
3208 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3209 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3210 if (channel->founder_key)
3211 silc_pkcs_public_key_free(channel->founder_key);
3212 channel->founder_key = NULL;
3218 if (mode_mask & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
3219 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3222 chpkdata = silc_argument_get_arg_type(cmd->args, 9, &chpklen);
3224 if (!chpkdata && channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
3229 /* Process the channel public key(s) */
3230 st = silc_server_set_channel_pk_list(server, NULL, channel,
3232 if (st != SILC_STATUS_OK) {
3233 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, st, 0);
3238 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3239 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
3240 if (channel->channel_pubkeys)
3241 silc_hash_table_free(channel->channel_pubkeys);
3242 channel->channel_pubkeys = NULL;
3249 /* Finally, set the mode */
3250 old_mask = channel->mode = mode_mask;
3252 /* Send CMODE_CHANGE notify. */
3253 cidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3254 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT)
3255 SILC_PUT32_MSB(channel->user_limit, ulimit);
3256 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3257 SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
3258 cidp->data, cidp->len,
3260 cipher, cipher ? strlen(cipher) : 0,
3261 hmac, hmac ? strlen(hmac) : 0,
3262 passphrase, passphrase ?
3263 strlen(passphrase) : 0,
3264 fkey ? fkey->data : NULL,
3265 fkey ? fkey->len : 0,
3266 chpkdata ? chpkdata : NULL,
3267 chpkdata ? chpklen : 0,
3268 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
3270 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
3271 sizeof(ulimit) : 0);
3273 /* Set CMODE notify type to network */
3274 if (chpkdata && chpklen)
3275 silc_buffer_set(&chpk, chpkdata, chpklen);
3276 silc_server_send_notify_cmode(server, SILC_PRIMARY_ROUTE(server),
3277 SILC_BROADCAST(server), channel,
3278 mode_mask, client->id, SILC_ID_CLIENT,
3279 cipher, hmac, passphrase, founder_key,
3280 chpkdata ? &chpk : NULL);
3283 chpklist = silc_server_get_channel_pk_list(server, channel, FALSE, FALSE);
3285 /* Send command reply to sender */
3286 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
3287 SILC_STATUS_OK, 0, ident, 5,
3288 2, tmp_id, tmp_len2,
3290 4, fkey ? fkey->data : NULL,
3291 fkey ? fkey->len : 0,
3292 5, chpklist ? chpklist->data :
3293 NULL, chpklist ? chpklist->len
3296 SILC_CHANNEL_MODE_ULIMIT ?
3299 SILC_CHANNEL_MODE_ULIMIT ?
3300 sizeof(ulimit) : 0));
3302 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3303 packet->data, packet->len, FALSE);
3305 silc_buffer_free(packet);
3306 silc_buffer_free(cidp);
3309 channel->mode = old_mask;
3310 silc_buffer_free(chpklist);
3311 silc_buffer_free(fkey);
3312 silc_free(channel_id);
3313 silc_server_command_free(cmd);
3316 /* Server side of CUMODE command. Changes client's mode on a channel. */
3318 SILC_SERVER_CMD_FUNC(cumode)
3320 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3321 SilcServer server = cmd->server;
3322 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3323 SilcChannelID *channel_id = NULL;
3324 SilcClientID *client_id = NULL;
3325 SilcChannelEntry channel;
3326 SilcClientEntry target_client;
3327 SilcChannelClientEntry chl;
3328 SilcBuffer packet, idp;
3329 unsigned char *tmp_id, *tmp_ch_id, *tmp_mask;
3330 SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
3332 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3333 SilcPublicKey founder_key = NULL;
3334 SilcBuffer fkey = NULL;
3339 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4);
3341 /* Get Channel ID */
3342 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3344 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3345 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3348 channel_id = silc_id_payload_parse_id(tmp_ch_id, tmp_ch_len, NULL);
3350 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3351 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3355 /* Get channel entry */
3356 channel = silc_idlist_find_channel_by_id(server->local_list,
3359 channel = silc_idlist_find_channel_by_id(server->global_list,
3362 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3363 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
3364 0, 2, tmp_ch_id, tmp_ch_len);
3369 /* Check whether sender is on the channel */
3370 if (!silc_server_client_on_channel(client, channel, &chl)) {
3371 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3372 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
3373 2, tmp_ch_id, tmp_ch_len);
3376 sender_mask = chl->mode;
3378 /* Get the target client's channel mode mask */
3379 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
3381 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3382 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3386 SILC_GET32_MSB(target_mask, tmp_mask);
3388 /* Get target Client ID */
3389 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3391 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3392 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3395 client_id = silc_id_payload_parse_id(tmp_id, tmp_len, NULL);
3397 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3398 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3402 /* Get target client's entry */
3403 target_client = silc_idlist_find_client_by_id(server->local_list,
3404 client_id, TRUE, NULL);
3406 target_client = silc_idlist_find_client_by_id(server->global_list,
3407 client_id, TRUE, NULL);
3409 if (target_client != client &&
3410 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO) &&
3411 !(sender_mask & SILC_CHANNEL_UMODE_CHANOP)) {
3412 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3413 SILC_STATUS_ERR_NOT_YOU, 0,
3414 2, tmp_ch_id, tmp_ch_len);
3418 /* Check whether target client is on the channel */
3419 if (target_client != client) {
3420 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
3421 silc_server_command_send_status_data2(
3422 cmd, SILC_COMMAND_CUMODE,
3423 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL, 0,
3425 3, tmp_ch_id, tmp_ch_len);
3434 /* If the target client is founder, no one else can change their mode
3436 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && client != target_client) {
3437 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3438 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3439 0, 2, tmp_ch_id, tmp_ch_len);
3443 if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
3444 if (target_client != client) {
3445 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3446 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3451 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
3452 /* The client tries to claim the founder rights. */
3453 unsigned char *tmp_auth;
3454 SilcUInt32 tmp_auth_len;
3455 SilcChannelClientEntry chl2;
3456 SilcHashTableList htl;
3458 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
3459 !channel->founder_key) {
3460 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3461 SILC_STATUS_ERR_AUTH_FAILED, 0);
3465 tmp_auth = silc_argument_get_arg_type(cmd->args, 4, &tmp_auth_len);
3467 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3468 SILC_STATUS_ERR_AUTH_FAILED, 0);
3472 /* Verify the authentication payload */
3473 if (!silc_auth_verify_data(tmp_auth, tmp_auth_len, SILC_AUTH_PUBLIC_KEY,
3474 channel->founder_key, 0, server->sha1hash,
3475 client->id, SILC_ID_CLIENT)) {
3476 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3477 SILC_STATUS_ERR_AUTH_FAILED, 0);
3482 founder_key = channel->founder_key;
3483 fkey = silc_pkcs_public_key_payload_encode(founder_key);
3485 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3486 SILC_STATUS_ERR_AUTH_FAILED, 0);
3490 /* There cannot be anyone else as founder on the channel now. This
3491 client is definitely the founder due to this authentication. This
3492 is done only on router, not on server, since server cannot know
3493 whether router will accept this mode change or not. XXX This
3494 probably shouldn't be done anymore at all, may cause problems in
3495 router-router connections too (maybe just AUTH_FAILED error should
3496 be returned). -Pekka */
3497 if (server->server_type == SILC_ROUTER) {
3498 silc_hash_table_list(channel->user_list, &htl);
3499 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
3500 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
3501 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3502 silc_server_force_cumode_change(server, NULL, channel, chl2,
3506 silc_hash_table_list_reset(&htl);
3509 sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
3512 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3513 if (target_client == client) {
3514 /* Remove channel founder rights from itself */
3515 chl->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3518 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3519 SILC_STATUS_ERR_NOT_YOU, 0);
3525 if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
3526 /* Promote to operator */
3527 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
3528 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
3529 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
3530 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3531 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3532 0, 2, tmp_ch_id, tmp_ch_len);
3536 chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
3540 if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
3541 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
3542 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
3543 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3544 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3545 0, 2, tmp_ch_id, tmp_ch_len);
3549 /* Demote to normal user */
3550 chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
3555 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
3556 if (target_client != client) {
3557 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3558 SILC_STATUS_ERR_NOT_YOU, 0);
3562 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)) {
3563 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
3567 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
3568 if (target_client != client) {
3569 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3570 SILC_STATUS_ERR_NOT_YOU, 0);
3574 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
3579 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
3580 if (target_client != client) {
3581 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3582 SILC_STATUS_ERR_NOT_YOU, 0);
3586 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)) {
3587 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
3591 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
3592 if (target_client != client) {
3593 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3594 SILC_STATUS_ERR_NOT_YOU, 0);
3598 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
3603 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
3604 if (target_client != client) {
3605 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3606 SILC_STATUS_ERR_NOT_YOU, 0);
3610 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)) {
3611 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
3615 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
3616 if (target_client != client) {
3617 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3618 SILC_STATUS_ERR_NOT_YOU, 0);
3622 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
3627 if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
3628 if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
3629 if (client == target_client) {
3630 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3631 SILC_STATUS_ERR_PERM_DENIED, 0);
3634 chl->mode |= SILC_CHANNEL_UMODE_QUIET;
3638 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
3639 if (client == target_client) {
3640 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3641 SILC_STATUS_ERR_PERM_DENIED, 0);
3644 chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
3649 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3650 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3652 /* Send notify to channel, notify only if mode was actually changed. */
3654 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3655 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
3656 idp->data, idp->len,
3659 fkey ? fkey->data : NULL,
3660 fkey ? fkey->len : 0);
3662 /* Set CUMODE notify type to network */
3663 silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
3664 SILC_BROADCAST(server), channel,
3665 target_mask, client->id, SILC_ID_CLIENT,
3666 target_client->id, founder_key);
3669 /* Send command reply to sender */
3670 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CUMODE,
3671 SILC_STATUS_OK, 0, ident, 3,
3673 3, tmp_ch_id, tmp_ch_len,
3674 4, tmp_id, tmp_len);
3675 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3676 packet->data, packet->len, FALSE);
3678 silc_buffer_free(packet);
3679 silc_buffer_free(idp);
3682 silc_free(channel_id);
3683 silc_free(client_id);
3684 silc_buffer_free(fkey);
3685 silc_server_command_free(cmd);
3688 /* Server side of KICK command. Kicks client out of channel. */
3690 SILC_SERVER_CMD_FUNC(kick)
3692 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3693 SilcServer server = cmd->server;
3694 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3695 SilcClientEntry target_client;
3696 SilcChannelID *channel_id;
3697 SilcClientID *client_id;
3698 SilcChannelEntry channel;
3699 SilcChannelClientEntry chl;
3700 SilcBuffer idp, packet;
3701 SilcUInt32 tmp_len, target_idp_len, clen;
3702 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3703 unsigned char *tmp, *comment, *target_idp;
3708 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 3);
3710 /* Get Channel ID */
3711 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3713 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
3714 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3717 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
3719 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3720 SILC_STATUS_ERR_BAD_CHANNEL_ID, 0,
3725 /* Get channel entry */
3726 channel = silc_idlist_find_channel_by_id(server->local_list,
3729 channel = silc_idlist_find_channel_by_id(server->local_list,
3732 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3733 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
3734 0, 2, tmp, tmp_len);
3739 /* Check whether sender is on the channel */
3740 if (!silc_server_client_on_channel(client, channel, &chl)) {
3741 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3742 SILC_STATUS_ERR_NOT_ON_CHANNEL,
3743 0, 2, tmp, tmp_len);
3747 /* Check that the kicker is channel operator or channel founder */
3748 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
3749 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
3750 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3751 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3752 0, 2, tmp, tmp_len);
3756 /* Get target Client ID */
3757 target_idp = silc_argument_get_arg_type(cmd->args, 2, &target_idp_len);
3759 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
3760 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3763 client_id = silc_id_payload_parse_id(target_idp, target_idp_len, NULL);
3765 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3766 SILC_STATUS_ERR_BAD_CLIENT_ID,
3767 0, 2, target_idp, target_idp_len);
3771 /* Get target client's entry */
3772 target_client = silc_idlist_find_client_by_id(server->local_list,
3773 client_id, TRUE, NULL);
3774 if (!target_client) {
3775 target_client = silc_idlist_find_client_by_id(server->global_list,
3776 client_id, TRUE, NULL);
3779 /* Check whether target client is on the channel */
3780 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
3781 silc_server_command_send_status_data2(cmd, SILC_COMMAND_KICK,
3782 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL,
3783 0, 2, target_idp, target_idp_len,
3788 /* Check that the target client is not channel founder. Channel founder
3789 cannot be kicked from the channel. */
3790 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3791 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3792 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3793 0, 2, tmp, tmp_len);
3798 comment = silc_argument_get_arg_type(cmd->args, 3, &clen);
3803 /* Send the reply back to the client */
3805 silc_command_reply_payload_encode_va(SILC_COMMAND_KICK,
3806 SILC_STATUS_OK, 0, ident, 2,
3808 3, target_idp, target_idp_len);
3809 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3810 packet->data, packet->len, FALSE);
3811 silc_buffer_free(packet);
3813 /* Send KICKED notify to local clients on the channel */
3814 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3815 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3816 SILC_NOTIFY_TYPE_KICKED, 3,
3817 target_idp, target_idp_len,
3818 comment, comment ? strlen(comment) : 0,
3819 idp->data, idp->len);
3820 silc_buffer_free(idp);
3822 /* Send KICKED notify to primary route */
3823 silc_server_send_notify_kicked(server, SILC_PRIMARY_ROUTE(server),
3824 SILC_BROADCAST(server), channel,
3825 target_client->id, client->id, comment);
3827 /* Remove the client from channel's invite list */
3828 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
3830 silc_argument_payload_encode_one(NULL, target_idp, target_idp_len, 3);
3831 SilcArgumentPayload args =
3832 silc_argument_payload_parse(ab->data, ab->len, 1);
3833 silc_server_inviteban_process(server, channel->invite_list, 1, args);
3834 silc_buffer_free(ab);
3835 silc_argument_payload_free(args);
3838 /* Remove the client from the channel. If the channel does not exist
3839 after removing the client then the client kicked itself off the channel
3840 and we don't have to send anything after that. */
3841 if (!silc_server_remove_from_one_channel(server, NULL, channel,
3842 target_client, FALSE))
3845 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3846 /* Re-generate channel key */
3847 if (!silc_server_create_channel_key(server, channel, 0))
3850 /* Send the channel key to the channel. The key of course is not sent
3851 to the client who was kicked off the channel. */
3852 silc_server_send_channel_key(server, target_client->connection, channel,
3853 server->server_type == SILC_ROUTER ?
3854 FALSE : !server->standalone);
3858 silc_server_command_free(cmd);
3861 /* Server side of OPER command. Client uses this comand to obtain server
3862 operator privileges to this server/router. */
3864 SILC_SERVER_CMD_FUNC(oper)
3866 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3867 SilcServer server = cmd->server;
3868 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3869 unsigned char *username = NULL, *auth;
3871 SilcServerConfigAdmin *admin;
3872 SilcIDListData idata = (SilcIDListData)client;
3873 bool result = FALSE;
3874 SilcPublicKey cached_key;
3876 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
3879 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2);
3881 /* Get the username */
3882 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3884 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3885 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3890 /* Check username */
3891 username = silc_identifier_check(username, strlen(username),
3892 SILC_STRING_UTF8, 128, &tmp_len);
3894 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3895 SILC_STATUS_ERR_BAD_USERNAME,
3900 /* Get the admin configuration */
3901 admin = silc_server_config_find_admin(server, cmd->sock->ip,
3902 username, client->nickname);
3904 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
3905 username, client->nickname);
3907 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3908 SILC_STATUS_ERR_AUTH_FAILED,
3910 SILC_LOG_INFO(("OPER authentication failed for username '%s' by "
3911 "nickname '%s' from %s", username,
3912 client->nickname, cmd->sock->hostname));
3917 /* Get the authentication payload */
3918 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
3920 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3921 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3926 /* Verify the authentication data. If both passphrase and public key
3927 is set then try both of them. */
3928 if (admin->passphrase)
3929 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
3930 admin->passphrase, admin->passphrase_len,
3931 idata->hash, client->id, SILC_ID_CLIENT);
3932 if (!result && admin->publickeys) {
3933 cached_key = silc_server_get_public_key(server, admin->publickeys);
3936 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
3937 cached_key, 0, idata->hash,
3938 client->id, SILC_ID_CLIENT);
3941 /* Authentication failed */
3942 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3943 SILC_STATUS_ERR_AUTH_FAILED,
3948 /* Client is now server operator */
3949 client->mode |= SILC_UMODE_SERVER_OPERATOR;
3951 /* Update statistics */
3952 if (SILC_IS_LOCAL(client))
3953 server->stat.my_server_ops++;
3954 if (server->server_type == SILC_ROUTER)
3955 server->stat.server_ops++;
3957 /* Send UMODE change to primary router */
3958 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
3959 SILC_BROADCAST(server), client->id,
3962 /* Check if anyone is watching this nickname */
3963 if (server->server_type == SILC_ROUTER)
3964 silc_server_check_watcher_list(server, client, NULL,
3965 SILC_NOTIFY_TYPE_UMODE_CHANGE);
3967 /* Send reply to the sender */
3968 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3972 silc_free(username);
3973 silc_server_command_free(cmd);
3976 SILC_TASK_CALLBACK(silc_server_command_detach_cb)
3978 SilcServer server = app_context;
3979 QuitInternal q = (QuitInternal)context;
3980 SilcClientID *client_id = (SilcClientID *)q->sock;
3981 SilcClientEntry client;
3982 SilcSocketConnection sock;
3984 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3986 if (client && client->connection) {
3987 sock = client->connection;
3989 /* If there is pending outgoing data for the client then purge it
3990 to the network before closing connection. */
3991 silc_server_packet_queue_purge(server, sock);
3993 /* Close the connection on our side */
3994 client->router = NULL;
3995 client->connection = NULL;
3996 sock->user_data = NULL;
3997 silc_server_close_connection(server, sock);
4000 silc_free(client_id);
4004 SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
4006 SilcServer server = app_context;
4007 QuitInternal q = (QuitInternal)context;
4008 SilcClientID *client_id = (SilcClientID *)q->sock;
4009 SilcClientEntry client;
4011 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4013 if (client && client->mode & SILC_UMODE_DETACHED) {
4014 SILC_LOG_DEBUG(("Detach timeout"));
4015 silc_server_free_client_data(server, NULL, client, TRUE,
4019 silc_free(client_id);
4023 /* Server side of DETACH command. Detached the client from the network
4024 by closing the connection but preserving the session. */
4026 SILC_SERVER_CMD_FUNC(detach)
4028 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4029 SilcServer server = cmd->server;
4030 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4033 if (server->config->detach_disabled) {
4034 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4035 SILC_STATUS_ERR_OPERATION_ALLOWED,
4040 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4043 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_DETACH, cmd, 0, 0);
4045 /* Remove operator privileges, since the client may resume in some
4046 other server which to it does not have operator privileges. */
4047 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
4048 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
4050 /* Send the user mode notify to notify that client is detached */
4051 client->mode |= SILC_UMODE_DETACHED;
4052 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
4053 client->data.status &= ~SILC_IDLIST_STATUS_NOATTR;
4054 client->last_command = 0;
4055 client->fast_command = 0;
4056 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4057 SILC_BROADCAST(server), client->id,
4059 server->stat.my_detached++;
4061 /* Check if anyone is watching this nickname */
4062 if (server->server_type == SILC_ROUTER)
4063 silc_server_check_watcher_list(server, client, NULL,
4064 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4066 q = silc_calloc(1, sizeof(*q));
4067 q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
4068 silc_schedule_task_add(server->schedule, 0, silc_server_command_detach_cb,
4069 q, 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
4071 if (server->config->detach_timeout) {
4072 q = silc_calloc(1, sizeof(*q));
4073 q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
4074 silc_schedule_task_add(server->schedule, 0,
4075 silc_server_command_detach_timeout,
4076 q, server->config->detach_timeout * 60,
4077 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
4080 /* Send reply to the sender */
4081 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4085 silc_server_command_free(cmd);
4088 /* Server side of WATCH command. */
4090 SILC_SERVER_CMD_FUNC(watch)
4092 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4093 SilcServer server = cmd->server;
4094 char *add_nick, *del_nick;
4095 SilcUInt32 add_nick_len, del_nick_len, tmp_len, pk_len;
4096 unsigned char hash[16], *tmp, *pk, *nick;
4097 SilcClientEntry client;
4098 SilcClientID *client_id = NULL;
4100 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WATCH, cmd, 1, 3);
4102 if (server->server_type != SILC_ROUTER && !server->standalone) {
4103 if (!cmd->pending) {
4104 /* Send the command to router */
4106 SilcUInt16 old_ident;
4108 SILC_LOG_DEBUG(("Forwarding WATCH to router"));
4110 old_ident = silc_command_get_ident(cmd->payload);
4111 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4112 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4114 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4115 SILC_PACKET_COMMAND, cmd->packet->flags,
4116 tmpbuf->data, tmpbuf->len, TRUE);
4118 /* Reprocess this packet after received reply from router */
4119 silc_server_command_pending(server, SILC_COMMAND_WATCH,
4120 silc_command_get_ident(cmd->payload),
4121 silc_server_command_watch,
4122 silc_server_command_dup(cmd));
4123 cmd->pending = TRUE;
4124 silc_command_set_ident(cmd->payload, old_ident);
4125 silc_buffer_free(tmpbuf);
4126 } else if (context2) {
4127 /* Received reply from router, just send same data to the client. */
4128 SilcServerCommandReplyContext reply = context2;
4131 SILC_LOG_DEBUG(("Received reply to WATCH from router"));
4132 silc_command_get_status(reply->payload, &status, NULL);
4133 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH, status,
4140 /* We are router and keep the watch list for local cell */
4142 /* Get the client ID */
4143 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4145 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4146 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4150 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
4152 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4153 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4154 0, 2, tmp, tmp_len);
4158 /* Get the client entry which must be in local list */
4159 client = silc_idlist_find_client_by_id(server->local_list,
4160 client_id, TRUE, NULL);
4162 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4163 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
4168 /* Take public key for watching by public key */
4169 pk = silc_argument_get_arg_type(cmd->args, 4, &pk_len);
4172 add_nick = silc_argument_get_arg_type(cmd->args, 2, &add_nick_len);
4173 del_nick = silc_argument_get_arg_type(cmd->args, 3, &del_nick_len);
4174 if (!add_nick && !del_nick && !pk) {
4175 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4176 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4181 if (add_nick && add_nick_len > 128) {
4182 add_nick[128] = '\0';
4185 if (del_nick && del_nick_len > 128) {
4186 del_nick[128] = '\0';
4190 /* Add new nickname to be watched in our cell */
4192 nick = silc_identifier_check(add_nick, add_nick_len, SILC_STRING_UTF8, 128,
4195 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4196 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4200 /* Hash the nick, we have the hash saved, not nicks because we can
4201 do one to one mapping to the nick from Client ID hash this way. */
4202 silc_hash_make(server->md5hash, nick, add_nick_len, hash);
4204 /* Check whether this client is already watching this nickname */
4205 if (silc_hash_table_find_by_context(server->watcher_list, hash,
4207 /* Nickname is alredy being watched for this client */
4208 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4209 SILC_STATUS_ERR_NICKNAME_IN_USE,
4215 /* Get the nickname from the watcher list and use the same key in
4216 new entries as well. If key doesn't exist then create it. */
4217 if (!silc_hash_table_find(server->watcher_list, hash, (void *)&tmp, NULL))
4218 tmp = silc_memdup(hash, CLIENTID_HASH_LEN);
4220 /* Add the client to the watcher list with the specified nickname hash. */
4221 silc_hash_table_add(server->watcher_list, tmp, client);
4225 /* Delete nickname from watch list */
4227 nick = silc_identifier_check(del_nick, del_nick_len, SILC_STRING_UTF8, 128,
4230 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4231 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4235 /* Hash the nick, we have the hash saved, not nicks because we can
4236 do one to one mapping to the nick from Client ID hash this way. */
4237 silc_hash_make(server->md5hash, nick, del_nick_len, hash);
4239 /* Check that this client is watching for this nickname */
4240 if (!silc_hash_table_find_by_context(server->watcher_list, hash,
4241 client, (void *)&tmp)) {
4242 /* Nickname is alredy being watched for this client */
4243 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4244 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
4245 2, nick, del_nick_len);
4250 /* Delete the nickname from the watcher list. */
4251 silc_hash_table_del_by_context(server->watcher_list, hash, client);
4253 /* Now check whether there still exists entries with this key, if not
4254 then free the key to not leak memory. */
4255 if (!silc_hash_table_find(server->watcher_list, hash, NULL, NULL))
4260 /* Add/del public key */
4263 SilcArgumentPayload pkargs;
4265 SilcPublicKey public_key, pkkey;
4268 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4269 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4274 /* Get the argument from the Argument List Payload */
4275 SILC_GET16_MSB(pkargc, pk);
4276 pkargs = silc_argument_payload_parse(pk + 2, pk_len - 2, pkargc);
4278 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4279 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4284 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4286 if (!silc_pkcs_public_key_payload_decode(pk, pk_len, &public_key))
4292 /* Add public key to watch list */
4294 /* Check whether this client is already watching this public key */
4295 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4296 public_key, client, NULL)) {
4297 silc_pkcs_public_key_free(public_key);
4298 silc_server_command_send_status_reply(
4299 cmd, SILC_COMMAND_WATCH,
4300 SILC_STATUS_ERR_NICKNAME_IN_USE, 0);
4304 /* Get the public key from the watcher list and use the same key in
4305 new entries as well. If key doesn't exist then create it. */
4307 if (!silc_hash_table_find(server->watcher_list_pk, public_key,
4308 (void *)&pkkey, NULL))
4311 silc_pkcs_public_key_free(public_key);
4313 /* Add the client to the watcher list with the specified public
4315 silc_hash_table_add(server->watcher_list_pk, pkkey, client);
4317 } else if (type == 0x01) {
4318 /* Delete public key from watch list */
4320 /* Check that this client is watching this public key */
4321 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4324 silc_pkcs_public_key_free(public_key);
4325 silc_server_command_send_status_reply(
4326 cmd, SILC_COMMAND_WATCH,
4327 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4331 /* Delete the public key from the watcher list. */
4332 silc_hash_table_del_by_context(server->watcher_list_pk,
4333 public_key, client);
4335 /* Now check whether there still exists entries with this key, if
4336 not then free the key to not leak memory. */
4337 if (!silc_hash_table_find(server->watcher_list_pk, hash, NULL, NULL))
4338 silc_pkcs_public_key_free(pkkey);
4339 silc_pkcs_public_key_free(public_key);
4342 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4346 /* Distribute the watch list to backup routers too */
4347 if (server->backup) {
4349 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4350 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4351 silc_server_backup_send(server, NULL, SILC_PACKET_COMMAND,
4352 cmd->packet->flags, tmpbuf->data, tmpbuf->len,
4354 silc_buffer_free(tmpbuf);
4357 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4361 silc_free(client_id);
4362 silc_server_command_free(cmd);
4365 /* Server side of SILCOPER command. Client uses this comand to obtain router
4366 operator privileges to this router. */
4368 SILC_SERVER_CMD_FUNC(silcoper)
4370 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4371 SilcServer server = cmd->server;
4372 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4373 unsigned char *username = NULL, *auth;
4375 SilcServerConfigAdmin *admin;
4376 SilcIDListData idata = (SilcIDListData)client;
4377 bool result = FALSE;
4378 SilcPublicKey cached_key;
4380 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4383 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
4385 if (server->server_type != SILC_ROUTER) {
4386 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4387 SILC_STATUS_ERR_AUTH_FAILED, 0);
4391 /* Get the username */
4392 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4394 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4395 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4400 /* Check username */
4401 username = silc_identifier_check(username, tmp_len, SILC_STRING_UTF8, 128,
4404 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4405 SILC_STATUS_ERR_BAD_USERNAME,
4410 /* Get the admin configuration */
4411 admin = silc_server_config_find_admin(server, cmd->sock->ip,
4412 username, client->nickname);
4414 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
4415 username, client->nickname);
4417 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4418 SILC_STATUS_ERR_AUTH_FAILED, 0);
4419 SILC_LOG_INFO(("SILCOPER authentication failed for username '%s' by "
4420 "nickname '%s' from %s", username,
4421 client->nickname, cmd->sock->hostname));
4426 /* Get the authentication payload */
4427 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
4429 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4430 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4435 /* Verify the authentication data. If both passphrase and public key
4436 is set then try both of them. */
4437 if (admin->passphrase)
4438 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
4439 admin->passphrase, admin->passphrase_len,
4440 idata->hash, client->id, SILC_ID_CLIENT);
4441 if (!result && admin->publickeys) {
4442 cached_key = silc_server_get_public_key(server, admin->publickeys);
4445 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
4446 cached_key, 0, idata->hash,
4447 client->id, SILC_ID_CLIENT);
4450 /* Authentication failed */
4451 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4452 SILC_STATUS_ERR_AUTH_FAILED, 0);
4456 /* Client is now router operator */
4457 client->mode |= SILC_UMODE_ROUTER_OPERATOR;
4459 /* Update statistics */
4460 if (SILC_IS_LOCAL(client))
4461 server->stat.my_router_ops++;
4462 if (server->server_type == SILC_ROUTER)
4463 server->stat.router_ops++;
4465 /* Send UMODE change to primary router */
4466 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4467 SILC_BROADCAST(server), client->id,
4470 /* Check if anyone is watching this nickname */
4471 if (server->server_type == SILC_ROUTER)
4472 silc_server_check_watcher_list(server, client, NULL,
4473 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4475 /* Send reply to the sender */
4476 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4480 silc_free(username);
4481 silc_server_command_free(cmd);
4484 /* Server side of command BAN. This is used to manage the ban list of the
4485 channel. To add clients and remove clients from the ban list. */
4487 SILC_SERVER_CMD_FUNC(ban)
4489 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4490 SilcServer server = cmd->server;
4491 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4492 SilcBuffer packet, list, tmp2;
4493 SilcChannelEntry channel;
4494 SilcChannelClientEntry chl;
4495 SilcChannelID *channel_id = NULL;
4496 unsigned char *id, *tmp, *atype = NULL;
4497 SilcUInt32 id_len, len, len2;
4498 SilcArgumentPayload args;
4499 SilcHashTableList htl;
4501 SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
4502 SilcBufferStruct blist;
4504 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4507 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_BAN, cmd, 0, 3);
4509 /* Get Channel ID */
4510 id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
4512 channel_id = silc_id_payload_parse_id(id, id_len, NULL);
4514 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4515 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4520 /* Get channel entry. The server must know about the channel since the
4521 client is expected to be on the channel. */
4522 channel = silc_idlist_find_channel_by_id(server->local_list,
4525 channel = silc_idlist_find_channel_by_id(server->global_list,
4528 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4529 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4535 /* Check whether this client is on the channel */
4536 if (!silc_server_client_on_channel(client, channel, &chl)) {
4537 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4538 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4543 /* The client must be at least channel operator. */
4544 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
4545 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4546 SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0,
4551 /* Get the ban information */
4552 tmp = silc_argument_get_arg_type(cmd->args, 3, &len2);
4553 if (tmp && len2 > 2) {
4554 /* Parse the arguments to see they are constructed correctly */
4555 SILC_GET16_MSB(argc, tmp);
4556 args = silc_argument_payload_parse(tmp + 2, len2 - 2, argc);
4558 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4559 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4564 /* Get the type of action */
4565 atype = silc_argument_get_arg_type(cmd->args, 2, &len);
4566 if (atype && len == 1) {
4567 if (atype[0] == 0x00) {
4568 /* Allocate hash table for ban list if it doesn't exist yet */
4569 if (!channel->ban_list)
4571 silc_hash_table_alloc(0, silc_hash_ptr,
4573 silc_server_inviteban_destruct, channel,
4576 /* Check for resource limit */
4577 if (silc_hash_table_count(channel->ban_list) > 64) {
4578 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4579 SILC_STATUS_ERR_RESOURCE_LIMIT,
4585 /* Now add or delete the information. */
4586 silc_server_inviteban_process(server, channel->ban_list,
4587 (SilcUInt8)atype[0], args);
4589 silc_argument_payload_free(args);
4592 /* Encode ban list */
4594 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4595 list = silc_buffer_alloc_size(2);
4596 silc_buffer_format(list,
4597 SILC_STR_UI_SHORT(silc_hash_table_count(
4598 channel->ban_list)),
4600 silc_hash_table_list(channel->ban_list, &htl);
4601 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4602 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4604 silc_hash_table_list_reset(&htl);
4607 /* Send BAN notify type to local servers (but not clients) and to
4609 if (atype && tmp && len2) {
4610 silc_buffer_set(&blist, tmp, len2);
4612 /* Send to local servers if we are router */
4613 if (server->server_type == SILC_ROUTER)
4614 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
4615 SILC_NOTIFY_TYPE_BAN, 3,
4618 tmp ? blist.data : NULL,
4619 tmp ? blist.len : 0);
4621 /* Send to network. */
4622 silc_server_send_notify_ban(server, SILC_PRIMARY_ROUTE(server),
4623 SILC_BROADCAST(server), channel, atype,
4627 /* Send the reply back to the client */
4629 silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
4630 SILC_STATUS_OK, 0, ident, 2,
4632 3, list ? list->data : NULL,
4633 list ? list->len : 0);
4634 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4635 packet->data, packet->len, FALSE);
4637 silc_buffer_free(packet);
4638 silc_buffer_free(list);
4641 silc_free(channel_id);
4642 silc_server_command_free(cmd);
4645 /* Server side command of LEAVE. Removes client from a channel. */
4647 SILC_SERVER_CMD_FUNC(leave)
4649 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4650 SilcServer server = cmd->server;
4651 SilcSocketConnection sock = cmd->sock;
4652 SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
4653 SilcChannelID *id = NULL;
4654 SilcChannelEntry channel;
4658 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !id_entry)
4661 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 2);
4663 /* Get Channel ID */
4664 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
4666 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4667 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4670 id = silc_id_payload_parse_id(tmp, len, NULL);
4672 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4673 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4677 /* Get channel entry */
4678 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4680 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4682 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4683 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4689 /* Check whether this client is on the channel */
4690 if (!silc_server_client_on_channel(id_entry, channel, NULL)) {
4691 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4692 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4697 /* Notify routers that they should remove this client from their list
4698 of clients on the channel. Send LEAVE notify type. */
4699 silc_server_send_notify_leave(server, SILC_PRIMARY_ROUTE(server),
4700 SILC_BROADCAST(server), channel, id_entry->id);
4702 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4703 SILC_STATUS_OK, 0, 2, tmp, len);
4705 /* Remove client from channel */
4706 if (!silc_server_remove_from_one_channel(server, sock, channel, id_entry,
4708 /* If the channel does not exist anymore we won't send anything */
4711 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
4712 /* Re-generate channel key */
4713 if (!silc_server_create_channel_key(server, channel, 0))
4716 /* Send the channel key */
4717 silc_server_send_channel_key(server, NULL, channel,
4718 server->server_type == SILC_ROUTER ?
4719 FALSE : !server->standalone);
4724 silc_server_command_free(cmd);
4727 /* Server side of command USERS. Resolves clients and their USERS currently
4728 joined on the requested channel. The list of Client ID's and their modes
4729 on the channel is sent back. */
4731 SILC_SERVER_CMD_FUNC(users)
4733 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4734 SilcServer server = cmd->server;
4735 SilcChannelEntry channel;
4736 SilcChannelID *id = NULL;
4737 SilcBuffer packet, idp;
4738 unsigned char *channel_id;
4739 SilcUInt32 channel_id_len;
4740 SilcBuffer client_id_list;
4741 SilcBuffer client_mode_list;
4742 unsigned char lc[4];
4743 SilcUInt32 list_count = 0;
4744 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4745 char *channel_name, *channel_namec = NULL;
4747 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2);
4749 /* Get Channel ID */
4750 channel_id = silc_argument_get_arg_type(cmd->args, 1, &channel_id_len);
4752 /* Get channel name */
4753 channel_name = silc_argument_get_arg_type(cmd->args, 2, NULL);
4755 if (!channel_id && !channel_name) {
4756 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4757 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4761 /* Check channel name */
4763 channel_namec = silc_identifier_check(channel_name, strlen(channel_name),
4764 SILC_STRING_UTF8, 256, NULL);
4765 if (!channel_namec) {
4766 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4767 SILC_STATUS_ERR_BAD_CHANNEL, 0);
4772 /* Check Channel ID */
4774 id = silc_id_payload_parse_id(channel_id, channel_id_len, NULL);
4776 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4777 SILC_STATUS_ERR_BAD_CHANNEL_ID, 0,
4778 2, channel_id, channel_id_len);
4783 /* If we are server and we don't know about this channel we will send
4784 the command to our router. If we know about the channel then we also
4785 have the list of users already. */
4787 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4789 channel = silc_idlist_find_channel_by_name(server->local_list,
4790 channel_namec, NULL);
4792 if (!channel || (!server->standalone && (channel->disabled ||
4793 !channel->users_resolved))) {
4794 if (server->server_type != SILC_ROUTER && !server->standalone &&
4798 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4799 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4801 /* Send USERS command */
4802 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4803 SILC_PACKET_COMMAND, cmd->packet->flags,
4804 tmpbuf->data, tmpbuf->len, TRUE);
4806 /* Reprocess this packet after received reply */
4807 silc_server_command_pending(server, SILC_COMMAND_USERS,
4808 silc_command_get_ident(cmd->payload),
4809 silc_server_command_users,
4810 silc_server_command_dup(cmd));
4811 cmd->pending = TRUE;
4812 silc_command_set_ident(cmd->payload, ident);
4813 silc_buffer_free(tmpbuf);
4818 /* Check the global list as well. */
4820 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4822 channel = silc_idlist_find_channel_by_name(server->global_list,
4823 channel_namec, NULL);
4825 /* Channel really does not exist */
4827 silc_server_command_send_status_data(
4828 cmd, SILC_COMMAND_USERS,
4829 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID, 0,
4830 2, channel_id, channel_id_len);
4832 silc_server_command_send_status_data(
4833 cmd, SILC_COMMAND_USERS,
4834 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
4835 2, channel_name, strlen(channel_name));
4840 /* If the channel is private or secret do not send anything, unless the
4841 user requesting this command is on the channel or is server */
4842 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
4843 if (channel->mode & (SILC_CHANNEL_MODE_PRIVATE | SILC_CHANNEL_MODE_SECRET)
4844 && !silc_server_client_on_channel(cmd->sock->user_data, channel,
4846 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4847 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
4848 2, channel->channel_name,
4849 strlen(channel->channel_name));
4854 /* Get the users list */
4855 if (!silc_server_get_users_on_channel(server, channel, &client_id_list,
4856 &client_mode_list, &list_count)) {
4858 client_id_list = NULL;
4859 client_mode_list = NULL;
4863 SILC_PUT32_MSB(list_count, lc);
4866 idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4867 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_USERS,
4868 SILC_STATUS_OK, 0, ident, 4,
4869 2, idp->data, idp->len,
4872 client_id_list->data : NULL,
4874 client_id_list->len : 0,
4875 5, client_mode_list ?
4876 client_mode_list->data : NULL,
4878 client_mode_list->len : 0);
4879 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4880 packet->data, packet->len, FALSE);
4882 silc_buffer_free(idp);
4883 silc_buffer_free(packet);
4885 silc_buffer_free(client_id_list);
4886 if (client_mode_list)
4887 silc_buffer_free(client_mode_list);
4891 silc_free(channel_namec);
4892 silc_server_command_free(cmd);
4895 /* Server side of command GETKEY. This fetches the client's public key
4896 from the server where to the client is connected. */
4898 SILC_SERVER_CMD_FUNC(getkey)
4900 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4901 SilcServer server = cmd->server;
4903 SilcClientEntry client;
4904 SilcServerEntry server_entry;
4905 SilcClientID *client_id = NULL;
4906 SilcServerID *server_id = NULL;
4907 SilcIDPayload idp = NULL;
4908 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4911 SilcBuffer pk = NULL;
4913 SilcPublicKey public_key;
4915 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4917 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
4918 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4922 idp = silc_id_payload_parse(tmp, tmp_len);
4924 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
4925 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4930 id_type = silc_id_payload_get_type(idp);
4931 if (id_type == SILC_ID_CLIENT) {
4932 client_id = silc_id_payload_get_id(idp);
4934 /* If the client is not found from local list there is no chance it
4935 would be locally connected client so send the command further. */
4936 client = silc_idlist_find_client_by_id(server->local_list,
4937 client_id, TRUE, NULL);
4939 client = silc_idlist_find_client_by_id(server->global_list,
4940 client_id, TRUE, NULL);
4942 if ((!client && !cmd->pending && !server->standalone) ||
4943 (client && !client->connection && !cmd->pending &&
4944 !(client->mode & SILC_UMODE_DETACHED)) ||
4945 (client && !client->data.public_key && !cmd->pending)) {
4947 SilcUInt16 old_ident;
4948 SilcSocketConnection dest_sock;
4950 dest_sock = silc_server_get_client_route(server, NULL, 0,
4951 client_id, NULL, NULL);
4955 old_ident = silc_command_get_ident(cmd->payload);
4956 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4957 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4959 silc_server_packet_send(server, dest_sock,
4960 SILC_PACKET_COMMAND, cmd->packet->flags,
4961 tmpbuf->data, tmpbuf->len, TRUE);
4963 /* Reprocess this packet after received reply from router */
4964 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
4965 silc_command_get_ident(cmd->payload),
4966 silc_server_command_getkey,
4967 silc_server_command_dup(cmd));
4968 cmd->pending = TRUE;
4969 silc_command_set_ident(cmd->payload, old_ident);
4970 silc_buffer_free(tmpbuf);
4975 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
4976 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4977 0, 2, tmp, tmp_len);
4981 /* The client is locally connected, just get the public key and
4982 send it back. If they key does not exist then do not send it,
4983 send just OK reply */
4984 public_key = client->data.public_key;
4986 pk = silc_pkcs_public_key_payload_encode(public_key);
4987 } else if (id_type == SILC_ID_SERVER) {
4988 server_id = silc_id_payload_get_id(idp);
4990 /* If the server is not found from local list there is no chance it
4991 would be locally connected server so send the command further. */
4992 server_entry = silc_idlist_find_server_by_id(server->local_list,
4993 server_id, TRUE, NULL);
4995 server_entry = silc_idlist_find_server_by_id(server->global_list,
4996 server_id, TRUE, NULL);
4998 if (server_entry != server->id_entry &&
4999 ((!server_entry && !cmd->pending && !server->standalone) ||
5000 (server_entry && !server_entry->connection && !cmd->pending &&
5001 !server->standalone) ||
5002 (server_entry && !server_entry->data.public_key && !cmd->pending &&
5003 !server->standalone))) {
5005 SilcUInt16 old_ident;
5007 old_ident = silc_command_get_ident(cmd->payload);
5008 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5009 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5011 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5012 SILC_PACKET_COMMAND, cmd->packet->flags,
5013 tmpbuf->data, tmpbuf->len, TRUE);
5015 /* Reprocess this packet after received reply from router */
5016 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
5017 silc_command_get_ident(cmd->payload),
5018 silc_server_command_getkey,
5019 silc_server_command_dup(cmd));
5020 cmd->pending = TRUE;
5021 silc_command_set_ident(cmd->payload, old_ident);
5022 silc_buffer_free(tmpbuf);
5026 if (!server_entry) {
5027 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
5028 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
5029 0, 2, tmp, tmp_len);
5033 /* If they key does not exist then do not send it, send just OK reply */
5034 public_key = (!server_entry->data.public_key ?
5035 (server_entry == server->id_entry ? server->public_key :
5036 NULL) : server_entry->data.public_key);
5038 pk = silc_pkcs_public_key_payload_encode(public_key);
5043 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5044 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_GETKEY,
5045 SILC_STATUS_OK, 0, ident, 2,
5047 3, pk ? pk->data : NULL,
5049 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
5050 packet->data, packet->len, FALSE);
5051 silc_buffer_free(packet);
5055 silc_id_payload_free(idp);
5056 silc_buffer_free(pk);
5057 silc_free(client_id);
5058 silc_free(server_id);
5059 silc_server_command_free(cmd);
5063 /* Private range commands, specific to this implementation */
5065 /* Server side command of CONNECT. Connects us to the specified remote
5066 server or router. */
5068 SILC_SERVER_CMD_FUNC(connect)
5070 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5071 SilcServer server = cmd->server;
5072 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5073 unsigned char *tmp, *host;
5075 SilcUInt32 port = SILC_PORT;
5077 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5080 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CONNECT, cmd, 1, 2);
5082 /* Check whether client has the permissions. */
5083 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5084 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5085 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5086 SILC_STATUS_ERR_NO_SERVER_PRIV, 0);
5090 if (server->server_type == SILC_ROUTER && !server->backup_router &&
5091 client->mode & SILC_UMODE_SERVER_OPERATOR) {
5092 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5093 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
5097 /* Get the remote server */
5098 host = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5100 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5101 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5107 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5109 SILC_GET32_MSB(port, tmp);
5111 /* Create the connection. It is done with timeout and is async. */
5112 silc_server_create_connection(server, host, port);
5114 /* Send reply to the sender */
5115 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5119 silc_server_command_free(cmd);
5122 /* Server side command of CLOSE. Closes connection to a specified server. */
5124 SILC_SERVER_CMD_FUNC(close)
5126 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5127 SilcServer server = cmd->server;
5128 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5129 SilcServerEntry server_entry;
5130 SilcSocketConnection sock;
5133 unsigned char *name;
5134 SilcUInt32 port = SILC_PORT;
5136 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5139 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CLOSE, cmd, 1, 2);
5141 /* Check whether client has the permissions. */
5142 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5143 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5144 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5145 SILC_STATUS_ERR_NO_SERVER_PRIV,
5150 /* Get the remote server */
5151 name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5153 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5154 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5160 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5162 SILC_GET32_MSB(port, tmp);
5164 server_entry = silc_idlist_find_server_by_conn(server->local_list,
5165 name, port, TRUE, NULL);
5167 server_entry = silc_idlist_find_server_by_conn(server->global_list,
5168 name, port, TRUE, NULL);
5169 if (!server_entry) {
5170 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5171 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5175 if (server_entry == server->id_entry) {
5176 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5177 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5181 /* Send reply to the sender */
5182 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5185 /* Close the connection to the server */
5186 sock = (SilcSocketConnection)server_entry->connection;
5188 if (server_entry->server_type == SILC_BACKUP_ROUTER) {
5189 server->backup_closed = TRUE;
5190 silc_server_backup_del(server, server_entry);
5193 server->backup_noswitch = TRUE;
5194 if (server->router == server_entry) {
5195 server->id_entry->router = NULL;
5196 server->router = NULL;
5197 server->standalone = TRUE;
5199 silc_server_disconnect_remote(server, sock,
5200 SILC_STATUS_ERR_BANNED_FROM_SERVER,
5201 "Closed by administrator");
5202 if (sock->user_data)
5203 silc_server_free_sock_user_data(server, sock, NULL);
5204 server->backup_noswitch = FALSE;
5207 silc_server_command_free(cmd);
5210 /* Server side command of SHUTDOWN. Shutdowns the server and closes all
5211 active connections. */
5213 SILC_SERVER_CMD_FUNC(shutdown)
5215 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5216 SilcServer server = cmd->server;
5217 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5219 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5222 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_SHUTDOWN, cmd, 0, 0);
5224 /* Check whether client has the permission. */
5225 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5226 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5227 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5228 SILC_STATUS_ERR_NO_SERVER_PRIV,
5233 /* Send reply to the sender */
5234 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5237 /* Then, gracefully, or not, bring the server down. */
5238 silc_server_stop(server);
5242 silc_server_command_free(cmd);