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 if (!silc_utf8_valid(tmp, strlen(tmp))) {
998 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
999 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1004 /* See whether the client is on channel and has rights to change topic */
1005 if (!silc_server_client_on_channel(client, channel, &chl)) {
1006 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1007 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
1008 SILC_STATUS_ERR_NOT_ON_CHANNEL,
1009 0, 2, tmp, tmp_len);
1013 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
1014 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1015 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1016 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1017 silc_server_command_send_status_data(cmd, SILC_COMMAND_TOPIC,
1018 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
1019 0, 2, tmp, tmp_len);
1023 if (!channel->topic || strcmp(channel->topic, tmp)) {
1024 /* Set the topic for channel */
1025 silc_free(channel->topic);
1026 channel->topic = strdup(tmp);
1028 /* Send TOPIC_SET notify type to the network */
1029 silc_server_send_notify_topic_set(server, SILC_PRIMARY_ROUTE(server),
1030 SILC_BROADCAST(server), channel,
1031 client->id, SILC_ID_CLIENT,
1034 /* Send notify about topic change to all clients on the channel */
1035 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
1036 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
1037 SILC_NOTIFY_TYPE_TOPIC_SET, 2,
1038 idp->data, idp->len,
1040 strlen(channel->topic));
1041 silc_buffer_free(idp);
1045 /* Send the topic to client as reply packet */
1046 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
1047 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_TOPIC,
1048 SILC_STATUS_OK, 0, ident, 2,
1049 2, idp->data, idp->len,
1052 strlen(channel->topic) : 0);
1053 silc_server_packet_send(cmd->server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
1054 0, packet->data, packet->len, FALSE);
1056 silc_buffer_free(packet);
1057 silc_buffer_free(idp);
1058 silc_free(channel_id);
1061 silc_server_command_free(cmd);
1064 /* Server side of INVITE command. Invites some client to join some channel.
1065 This command is also used to manage the invite list of the channel. */
1067 SILC_SERVER_CMD_FUNC(invite)
1069 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1070 SilcServer server = cmd->server;
1071 SilcSocketConnection sock = cmd->sock, dest_sock;
1072 SilcChannelClientEntry chl;
1073 SilcClientEntry sender, dest;
1074 SilcClientID *dest_id = NULL;
1075 SilcChannelEntry channel;
1076 SilcChannelID *channel_id = NULL;
1077 SilcIDListData idata;
1078 SilcArgumentPayload args;
1079 SilcHashTableList htl;
1080 SilcBuffer packet, list, tmp2;
1081 SilcBufferStruct alist;
1082 unsigned char *tmp, *atype = NULL;
1083 SilcUInt32 len, type, len2;
1084 SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
1086 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INVITE, cmd, 1, 4);
1088 /* Get Channel ID */
1089 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1091 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1092 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
1095 channel_id = silc_id_payload_parse_id(tmp, len, NULL);
1097 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1098 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
1102 /* Get the channel entry */
1103 channel = silc_idlist_find_channel_by_id(server->local_list,
1106 channel = silc_idlist_find_channel_by_id(server->global_list,
1109 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1110 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
1116 /* Check whether the sender of this command is on the channel. */
1117 sender = (SilcClientEntry)sock->user_data;
1118 if (!sender || !silc_server_client_on_channel(sender, channel, &chl)) {
1119 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1120 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
1125 /* Check whether the channel is invite-only channel. If yes then the
1126 sender of this command must be at least channel operator. */
1127 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
1128 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1129 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1130 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1131 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
1136 /* Get destination client ID */
1137 tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
1141 dest_id = silc_id_payload_parse_id(tmp, len, NULL);
1143 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1144 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
1148 /* Get the client entry */
1149 dest = silc_server_query_client(server, dest_id, FALSE, &resolve);
1151 if (server->server_type != SILC_SERVER || !resolve || cmd->pending) {
1152 silc_server_command_send_status_data(
1153 cmd, SILC_COMMAND_INVITE,
1154 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1159 /* The client info is being resolved. Reprocess this packet after
1160 receiving the reply to the query. */
1161 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
1163 silc_server_command_invite,
1164 silc_server_command_dup(cmd));
1165 cmd->pending = TRUE;
1169 /* Check whether the requested client is already on the channel. */
1170 if (silc_server_client_on_channel(dest, channel, NULL)) {
1171 atype = silc_argument_get_arg_type(cmd->args, 1, &len2);
1172 silc_server_command_send_status_data2(cmd, SILC_COMMAND_INVITE,
1173 SILC_STATUS_ERR_USER_ON_CHANNEL,
1179 /* Get route to the client */
1180 dest_sock = silc_server_get_client_route(server, NULL, 0, dest_id,
1183 silc_server_command_send_status_data(cmd, SILC_COMMAND_INVITE,
1184 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1189 /* Add the client to the invite list */
1191 /* Allocate hash table for invite list if it doesn't exist yet */
1192 if (!channel->invite_list)
1193 channel->invite_list =
1194 silc_hash_table_alloc(0, silc_hash_ptr,
1196 silc_server_inviteban_destruct, channel, TRUE);
1198 /* Check if the ID is in the list already */
1199 silc_hash_table_list(channel->invite_list, &htl);
1200 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
1201 if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
1206 silc_hash_table_list_reset(&htl);
1208 /* Add new Client ID to invite list */
1210 list = silc_buffer_alloc_size(len);
1211 silc_buffer_put(list, tmp, len);
1212 silc_hash_table_add(channel->invite_list, (void *)3, list);
1215 if (!(dest->mode & SILC_UMODE_BLOCK_INVITE)) {
1216 /* Send notify to the client that is invited to the channel */
1217 SilcBuffer idp, idp2;
1218 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
1219 idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
1220 silc_server_send_notify_dest(server, dest_sock, FALSE, dest_id,
1222 SILC_NOTIFY_TYPE_INVITE, 3,
1223 idp->data, idp->len,
1224 channel->channel_name,
1225 strlen(channel->channel_name),
1226 idp2->data, idp2->len);
1227 silc_buffer_free(idp);
1228 silc_buffer_free(idp2);
1232 /* Get the invite information */
1233 tmp = silc_argument_get_arg_type(cmd->args, 4, &len2);
1234 if (tmp && len2 > 2) {
1235 /* Parse the arguments to see they are constructed correctly */
1236 SILC_GET16_MSB(argc, tmp);
1237 args = silc_argument_payload_parse(tmp + 2, len2 - 2, argc);
1239 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1240 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1245 /* Get the type of action */
1246 atype = silc_argument_get_arg_type(cmd->args, 3, &len);
1247 if (atype && len == 1) {
1248 if (atype[0] == 0x00) {
1249 /* Allocate hash table for invite list if it doesn't exist yet */
1250 if (!channel->invite_list)
1251 channel->invite_list =
1252 silc_hash_table_alloc(0, silc_hash_ptr,
1254 silc_server_inviteban_destruct, channel,
1257 /* Check for resource limit */
1258 if (silc_hash_table_count(channel->invite_list) > 64) {
1259 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
1260 SILC_STATUS_ERR_RESOURCE_LIMIT,
1266 /* Now add or delete the information. */
1267 silc_server_inviteban_process(server, channel->invite_list,
1268 (SilcUInt8)atype[0], args);
1270 silc_argument_payload_free(args);
1273 /* Encode invite list */
1275 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
1276 list = silc_buffer_alloc_size(2);
1277 silc_buffer_format(list,
1278 SILC_STR_UI_SHORT(silc_hash_table_count(
1279 channel->invite_list)),
1281 silc_hash_table_list(channel->invite_list, &htl);
1282 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
1283 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
1285 silc_hash_table_list_reset(&htl);
1288 /* The notify is sent to local servers (not clients), and to network. */
1289 if (atype && tmp && len2) {
1290 silc_buffer_set(&alist, tmp, len2);
1292 /* Send to local servers if we are router */
1293 if (server->server_type == SILC_ROUTER) {
1294 SilcBuffer idp, idp2;
1295 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
1296 idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
1297 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
1298 SILC_NOTIFY_TYPE_INVITE, 5,
1299 idp->data, idp->len,
1300 channel->channel_name,
1301 strlen(channel->channel_name),
1302 idp2->data, idp2->len,
1304 tmp ? alist.data : NULL,
1305 tmp ? alist.len : 0);
1306 silc_buffer_free(idp);
1307 silc_buffer_free(idp2);
1310 /* Send to network */
1311 silc_server_send_notify_invite(server, SILC_PRIMARY_ROUTE(server),
1312 SILC_BROADCAST(server), channel,
1314 tmp ? &alist : NULL);
1317 /* Send invite list back only if the list was modified, or no arguments
1320 argc = silc_argument_get_arg_num(cmd->args);
1323 if (silc_argument_get_arg_type(cmd->args, 3, &len))
1326 /* Send command reply */
1327 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1328 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
1329 SILC_STATUS_OK, 0, ident, 2,
1333 type && list ? list->len : 0);
1334 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
1335 packet->data, packet->len, FALSE);
1336 silc_buffer_free(packet);
1337 silc_buffer_free(list);
1341 silc_free(channel_id);
1342 silc_server_command_free(cmd);
1346 SilcSocketConnection sock;
1350 /* Quits connection to client. This gets called if client won't
1351 close the connection even when it has issued QUIT command. */
1353 SILC_TASK_CALLBACK(silc_server_command_quit_cb)
1355 SilcServer server = app_context;
1356 QuitInternal q = (QuitInternal)context;
1358 if (q->sock->user_data) {
1359 /* Free all client specific data, such as client entry and entires
1360 on channels this client may be on. */
1361 silc_server_free_client_data(server, q->sock, q->sock->user_data,
1363 q->sock->user_data = NULL;
1366 if (!SILC_IS_DISCONNECTED(q->sock))
1367 /* Close the connection on our side */
1368 silc_server_close_connection(server, q->sock);
1370 silc_socket_free(q->sock);
1371 silc_free(q->signoff);
1375 /* Quits SILC session. This is the normal way to disconnect client. */
1377 SILC_SERVER_CMD_FUNC(quit)
1379 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1380 SilcServer server = cmd->server;
1381 SilcSocketConnection sock = cmd->sock;
1383 unsigned char *tmp = NULL;
1386 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_QUIT, cmd, 0, 1);
1388 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
1392 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1396 q = silc_calloc(1, sizeof(*q));
1397 q->sock = silc_socket_dup(sock);
1398 q->signoff = tmp ? strdup(tmp) : NULL;
1400 /* We quit the connection with little timeout */
1401 silc_schedule_task_add(server->schedule, sock->sock,
1402 silc_server_command_quit_cb, (void *)q,
1403 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
1406 silc_server_command_free(cmd);
1409 /* Server side of command KILL. This command is used by router operator
1410 to remove an client from the SILC Network temporarily. */
1412 SILC_SERVER_CMD_FUNC(kill)
1414 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1415 SilcServer server = cmd->server;
1416 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
1417 SilcClientEntry remote_client;
1418 SilcClientID *client_id = NULL;
1419 unsigned char *tmp, *comment, *auth;
1420 SilcUInt32 tmp_len, tmp_len2, auth_len;
1422 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 3);
1424 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
1427 /* Get authentication payload if present */
1428 auth = silc_argument_get_arg_type(cmd->args, 3, &auth_len);
1431 /* Router operator killing */
1433 /* KILL command works only on router */
1434 if (server->server_type != SILC_ROUTER) {
1435 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1436 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
1440 /* Check whether client has the permissions. */
1441 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1442 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1443 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
1448 /* Get the client ID */
1449 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1451 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1452 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1456 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1458 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1459 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1460 0, 2, tmp, tmp_len);
1464 /* Get the client entry */
1465 remote_client = silc_idlist_find_client_by_id(server->local_list,
1466 client_id, TRUE, NULL);
1467 if (!remote_client) {
1468 remote_client = silc_idlist_find_client_by_id(server->global_list,
1469 client_id, TRUE, NULL);
1470 if (!remote_client) {
1471 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1472 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1473 0, 2, tmp, tmp_len);
1479 comment = silc_argument_get_arg_type(cmd->args, 2, &tmp_len2);
1480 if (comment && tmp_len2 > 128) {
1482 comment[127] = '\0';
1485 /* If authentication data is provided then verify that killing is
1487 if (auth && auth_len) {
1488 SilcSocketConnection sock;
1490 if (!SILC_IS_LOCAL(remote_client) || !remote_client->data.public_key) {
1491 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1492 SILC_STATUS_ERR_OPERATION_ALLOWED,
1497 /* Verify the signature */
1498 if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
1499 remote_client->data.public_key, 0,
1500 server->sha1hash, remote_client->id,
1502 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
1503 SILC_STATUS_ERR_AUTH_FAILED, 0);
1507 /* Send reply to the sender */
1508 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1512 /* Do normal signoff for the destination client */
1513 sock = remote_client->connection;
1514 silc_server_remove_from_channels(server, NULL, remote_client,
1515 TRUE, (char *)"Killed", TRUE, TRUE);
1516 silc_server_free_client_data(server, NULL, remote_client, TRUE,
1518 (unsigned char *)"Killed");
1520 silc_server_close_connection(server, sock);
1522 /* Router operator killing */
1524 /* Send reply to the sender */
1525 silc_server_command_send_status_data(cmd, SILC_COMMAND_KILL,
1529 /* Check if anyone is watching this nickname */
1530 if (server->server_type == SILC_ROUTER)
1531 silc_server_check_watcher_list(server, client, NULL,
1532 SILC_NOTIFY_TYPE_KILLED);
1534 /* Now do the killing */
1535 silc_server_kill_client(server, remote_client, comment, client->id,
1540 silc_free(client_id);
1541 silc_server_command_free(cmd);
1544 /* Server side of command INFO. This sends information about us to
1545 the client. If client requested specific server we will send the
1546 command to that server. */
1548 SILC_SERVER_CMD_FUNC(info)
1550 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1551 SilcServer server = cmd->server;
1552 SilcBuffer packet, idp;
1555 char *dest_server = NULL, *server_info = NULL, *server_name;
1556 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1557 SilcServerEntry entry = NULL;
1558 SilcServerID *server_id = NULL;
1560 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INFO, cmd, 0, 2);
1562 /* Get server name */
1563 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
1565 /* Check server name. */
1566 dest_server = silc_identifier_check(dest_server, strlen(dest_server),
1567 SILC_STRING_UTF8, 256, &tmp_len);
1569 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
1570 SILC_STATUS_ERR_BAD_SERVER, 0);
1576 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
1578 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1580 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
1581 SILC_STATUS_ERR_NO_SERVER_ID, 0);
1587 /* Check whether we have this server cached */
1588 entry = silc_idlist_find_server_by_id(server->local_list,
1589 server_id, TRUE, NULL);
1591 entry = silc_idlist_find_server_by_id(server->global_list,
1592 server_id, TRUE, NULL);
1593 if (!entry && server->server_type != SILC_SERVER) {
1594 silc_server_command_send_status_data(cmd, SILC_COMMAND_INFO,
1595 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
1596 0, 2, tmp, tmp_len);
1602 /* Some buggy servers has sent request to router about themselves. */
1603 if (server->server_type != SILC_SERVER && cmd->sock->user_data == entry)
1606 if ((!dest_server && !server_id && !entry) || (entry &&
1607 entry == server->id_entry) ||
1608 (dest_server && !cmd->pending &&
1609 !memcmp(dest_server, server->server_name, strlen(dest_server)))) {
1610 /* Send our reply */
1611 char info_string[256];
1613 memset(info_string, 0, sizeof(info_string));
1614 snprintf(info_string, sizeof(info_string),
1615 "location: %s server: %s admin: %s <%s>",
1616 server->config->server_info->location,
1617 server->config->server_info->server_type,
1618 server->config->server_info->admin,
1619 server->config->server_info->email);
1621 server_info = info_string;
1622 entry = server->id_entry;
1624 /* Check whether we have this server cached */
1625 if (!entry && dest_server) {
1626 entry = silc_idlist_find_server_by_name(server->global_list,
1627 dest_server, TRUE, NULL);
1629 entry = silc_idlist_find_server_by_name(server->local_list,
1630 dest_server, TRUE, NULL);
1634 if (!cmd->pending &&
1635 server->server_type != SILC_SERVER && entry && !entry->server_info) {
1636 /* Send to the server */
1638 SilcUInt16 old_ident;
1640 old_ident = silc_command_get_ident(cmd->payload);
1641 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1642 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1644 silc_server_packet_send(server, entry->connection,
1645 SILC_PACKET_COMMAND, cmd->packet->flags,
1646 tmpbuf->data, tmpbuf->len, TRUE);
1648 /* Reprocess this packet after received reply from router */
1649 silc_server_command_pending(server, SILC_COMMAND_INFO,
1650 silc_command_get_ident(cmd->payload),
1651 silc_server_command_info,
1652 silc_server_command_dup(cmd));
1653 cmd->pending = TRUE;
1654 silc_command_set_ident(cmd->payload, old_ident);
1655 silc_buffer_free(tmpbuf);
1659 if (!entry && !cmd->pending && !server->standalone) {
1660 /* Send to the primary router */
1662 SilcUInt16 old_ident;
1664 old_ident = silc_command_get_ident(cmd->payload);
1665 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1666 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1668 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
1669 SILC_PACKET_COMMAND, cmd->packet->flags,
1670 tmpbuf->data, tmpbuf->len, TRUE);
1672 /* Reprocess this packet after received reply from router */
1673 silc_server_command_pending(server, SILC_COMMAND_INFO,
1674 silc_command_get_ident(cmd->payload),
1675 silc_server_command_info,
1676 silc_server_command_dup(cmd));
1677 cmd->pending = TRUE;
1678 silc_command_set_ident(cmd->payload, old_ident);
1679 silc_buffer_free(tmpbuf);
1684 silc_free(server_id);
1688 silc_free(dest_server);
1689 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
1690 silc_server_command_send_status_data(cmd, SILC_COMMAND_INFO,
1691 SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
1693 strlen(dest_server));
1699 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
1701 server_info = entry->server_info;
1702 server_name = entry->server_name;
1704 /* Send the reply */
1705 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO,
1706 SILC_STATUS_OK, 0, ident, 3,
1707 2, idp->data, idp->len,
1709 strlen(server_name),
1712 strlen(server_info) : 0);
1713 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
1714 packet->data, packet->len, FALSE);
1716 silc_buffer_free(packet);
1717 silc_buffer_free(idp);
1720 silc_free(dest_server);
1721 silc_server_command_free(cmd);
1724 /* Server side of command PING. This just replies to the ping. */
1726 SILC_SERVER_CMD_FUNC(ping)
1728 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1729 SilcServer server = cmd->server;
1732 SilcServerID *server_id = NULL;
1734 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PING, cmd, 1, 1);
1737 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1739 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
1740 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1744 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1748 if (SILC_ID_SERVER_COMPARE(server_id, server->id)) {
1749 /* Send our reply */
1750 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
1753 silc_server_command_send_status_data(cmd, SILC_COMMAND_PING,
1754 SILC_STATUS_ERR_NO_SUCH_SERVER_ID, 0,
1760 silc_free(server_id);
1761 silc_server_command_free(cmd);
1764 /* Server side of command STATS. */
1766 SILC_SERVER_CMD_FUNC(stats)
1768 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1769 SilcServer server = cmd->server;
1770 SilcServerID *server_id;
1773 SilcBuffer packet, stats;
1774 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1777 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_STATS, cmd, 1, 1);
1780 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
1782 silc_server_command_send_status_reply(cmd, SILC_COMMAND_STATS,
1783 SILC_STATUS_ERR_NO_SERVER_ID, 0);
1786 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1790 /* The ID must be ours */
1791 if (!SILC_ID_SERVER_COMPARE(server->id, server_id)) {
1792 silc_server_command_send_status_data(cmd, SILC_COMMAND_STATS,
1793 SILC_STATUS_ERR_NO_SUCH_SERVER_ID, 0,
1795 silc_free(server_id);
1798 silc_free(server_id);
1800 /* If we are router then just send everything we got. If we are normal
1801 server then we'll send this to our router to get all the latest
1802 statistical information. */
1803 if (!cmd->pending && server->server_type != SILC_ROUTER &&
1804 !server->standalone) {
1805 /* Send request to our router */
1806 SilcBuffer idp = silc_id_payload_encode(server->router->id,
1808 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
1809 ++server->cmd_ident, 1,
1810 1, idp->data, idp->len);
1811 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
1812 SILC_PACKET_COMMAND, 0, packet->data,
1813 packet->len, FALSE);
1815 /* Reprocess this packet after received reply from router */
1816 silc_server_command_pending(server, SILC_COMMAND_STATS,
1818 silc_server_command_stats,
1819 silc_server_command_dup(cmd));
1820 cmd->pending = TRUE;
1821 silc_buffer_free(packet);
1822 silc_buffer_free(idp);
1826 /* Send our reply to sender */
1827 uptime = time(NULL) - server->starttime;
1829 stats = silc_buffer_alloc_size(60);
1830 silc_buffer_format(stats,
1831 SILC_STR_UI_INT(server->starttime),
1832 SILC_STR_UI_INT(uptime),
1833 SILC_STR_UI_INT(server->stat.my_clients),
1834 SILC_STR_UI_INT(server->stat.my_channels),
1835 SILC_STR_UI_INT(server->stat.my_server_ops),
1836 SILC_STR_UI_INT(server->stat.my_router_ops),
1837 SILC_STR_UI_INT(server->stat.cell_clients),
1838 SILC_STR_UI_INT(server->stat.cell_channels),
1839 SILC_STR_UI_INT(server->stat.cell_servers),
1840 SILC_STR_UI_INT(server->stat.clients),
1841 SILC_STR_UI_INT(server->stat.channels),
1842 SILC_STR_UI_INT(server->stat.servers),
1843 SILC_STR_UI_INT(server->stat.routers),
1844 SILC_STR_UI_INT(server->stat.server_ops),
1845 SILC_STR_UI_INT(server->stat.router_ops),
1848 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_STATS,
1849 SILC_STATUS_OK, 0, ident, 2,
1851 3, stats->data, stats->len);
1852 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
1853 0, packet->data, packet->len, FALSE);
1854 silc_buffer_free(packet);
1855 silc_buffer_free(stats);
1858 silc_server_command_free(cmd);
1861 /* Internal routine to join channel. The channel sent to this function
1862 has been either created or resolved from ID lists. This joins the sent
1863 client to the channel. */
1865 static void silc_server_command_join_channel(SilcServer server,
1866 SilcServerCommandContext cmd,
1867 SilcChannelEntry channel,
1868 SilcClientID *client_id,
1872 const unsigned char *auth,
1873 SilcUInt32 auth_len,
1874 const unsigned char *cauth,
1875 SilcUInt32 cauth_len)
1877 SilcSocketConnection sock = cmd->sock;
1879 SilcUInt32 tmp_len, user_count;
1880 unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4], ulimit[4];
1881 SilcClientEntry client;
1882 SilcChannelClientEntry chl;
1883 SilcBuffer reply, chidp, clidp, keyp = NULL;
1884 SilcBuffer user_list, mode_list, invite_list, ban_list;
1885 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1886 char check[512], check2[512];
1887 bool founder = FALSE;
1889 SilcBuffer fkey = NULL, chpklist = NULL;
1892 SILC_LOG_DEBUG(("Joining client to channel"));
1897 /* Get the client entry */
1898 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
1899 client = (SilcClientEntry)sock->user_data;
1903 client = silc_server_query_client(server, client_id, FALSE,
1906 if (!resolve || cmd->pending) {
1907 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
1908 silc_server_command_send_status_data(
1909 cmd, SILC_COMMAND_JOIN,
1910 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1915 /* The client info is being resolved. Reprocess this packet after
1916 receiving the reply to the query. */
1917 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
1919 silc_server_command_join,
1920 silc_server_command_dup(cmd));
1921 cmd->pending = TRUE;
1925 if (!client->data.public_key &&
1926 (auth || cauth || channel->ban_list ||
1927 (channel->mode & SILC_CHANNEL_MODE_INVITE))) {
1928 if (cmd->pending == 2)
1931 /* We must retrieve the client's public key by sending
1932 GETKEY command. Reprocess this packet after receiving the key */
1933 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
1934 silc_server_send_command(server, cmd->sock,
1935 SILC_COMMAND_GETKEY, ++server->cmd_ident,
1936 1, 1, clidp->data, clidp->len);
1937 silc_buffer_free(clidp);
1938 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
1940 silc_server_command_join,
1941 silc_server_command_dup(cmd));
1946 cmd->pending = FALSE;
1950 * Check founder auth payload if provided. If client can gain founder
1951 * privileges it can override various conditions on joining the channel,
1952 * and can have directly the founder mode set on the channel.
1954 if (auth && auth_len && channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1955 SilcIDListData idata = (SilcIDListData)client;
1956 SilcChannelClientEntry chl2;
1957 SilcHashTableList htl;
1959 if (channel->founder_key && idata->public_key &&
1960 silc_pkcs_public_key_compare(channel->founder_key,
1961 idata->public_key)) {
1962 /* Check whether the client is to become founder */
1963 if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
1964 channel->founder_key, 0, server->sha1hash,
1965 client->id, SILC_ID_CLIENT)) {
1967 /* There cannot be anyone else as founder on the channel now. This
1968 client is definitely the founder due to this authentication */
1969 silc_hash_table_list(channel->user_list, &htl);
1970 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
1971 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
1972 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
1973 silc_server_force_cumode_change(server, NULL, channel, chl2,
1977 silc_hash_table_list_reset(&htl);
1979 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
1986 * Check channel modes
1990 memset(check, 0, sizeof(check));
1991 memset(check2, 0, sizeof(check2));
1992 silc_strncat(check, sizeof(check),
1993 client->nickname, strlen(client->nickname));
1994 silc_strncat(check, sizeof(check), "!", 1);
1995 silc_strncat(check, sizeof(check),
1996 client->username, strlen(client->username));
1997 if (!strchr(client->username, '@')) {
1998 silc_strncat(check, sizeof(check), "@", 1);
1999 silc_strncat(check, sizeof(check),
2000 cmd->sock->hostname, strlen(cmd->sock->hostname));
2003 silc_strncat(check2, sizeof(check2),
2004 client->nickname, strlen(client->nickname));
2005 if (!strchr(client->nickname, '@')) {
2006 silc_strncat(check2, sizeof(check2), "@", 1);
2007 silc_strncat(check2, sizeof(check2),
2008 SILC_IS_LOCAL(client) ? server->server_name :
2009 client->router->server_name,
2010 SILC_IS_LOCAL(client) ? strlen(server->server_name) :
2011 strlen(client->router->server_name));
2013 silc_strncat(check2, sizeof(check2), "!", 1);
2014 silc_strncat(check2, sizeof(check2),
2015 client->username, strlen(client->username));
2016 if (!strchr(client->username, '@')) {
2017 silc_strncat(check2, sizeof(check2), "@", 1);
2018 silc_strncat(check2, sizeof(check2),
2019 cmd->sock->hostname, strlen(cmd->sock->hostname));
2022 /* Check invite list if channel is invite-only channel */
2023 if (channel->mode & SILC_CHANNEL_MODE_INVITE) {
2024 if (!channel->invite_list ||
2025 !silc_hash_table_count(channel->invite_list) ||
2026 (!silc_server_inviteban_match(server, channel->invite_list,
2028 !silc_server_inviteban_match(server, channel->invite_list,
2029 2, client->data.public_key) &&
2030 !silc_server_inviteban_match(server, channel->invite_list,
2031 1, client->nickname) &&
2032 !silc_server_inviteban_match(server, channel->invite_list,
2034 !silc_server_inviteban_match(server, channel->invite_list,
2036 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2037 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2038 SILC_STATUS_ERR_NOT_INVITED, 0,
2039 2, chidp->data, chidp->len);
2040 silc_buffer_free(chidp);
2045 /* Check ban list if it exists. If the client's nickname, server,
2046 username and/or hostname is in the ban list the access to the
2047 channel is denied. */
2048 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
2049 if (silc_server_inviteban_match(server, channel->ban_list,
2051 silc_server_inviteban_match(server, channel->ban_list,
2052 2, client->data.public_key) ||
2053 silc_server_inviteban_match(server, channel->ban_list,
2054 1, client->nickname) ||
2055 silc_server_inviteban_match(server, channel->ban_list,
2057 silc_server_inviteban_match(server, channel->ban_list,
2059 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2060 silc_server_command_send_status_data(
2061 cmd, SILC_COMMAND_JOIN,
2062 SILC_STATUS_ERR_BANNED_FROM_CHANNEL, 0,
2063 2, chidp->data, chidp->len);
2064 silc_buffer_free(chidp);
2069 /* Check user count limit if set. */
2070 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT) {
2071 if (silc_hash_table_count(channel->user_list) + 1 >
2072 channel->user_limit) {
2073 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2074 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2075 SILC_STATUS_ERR_CHANNEL_IS_FULL,
2076 0, 2, chidp->data, chidp->len);
2077 silc_buffer_free(chidp);
2083 /* Check the channel passphrase if set. */
2084 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
2085 /* Get passphrase */
2086 tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
2088 passphrase = silc_memdup(tmp, tmp_len);
2090 if (!passphrase || !channel->passphrase ||
2091 memcmp(passphrase, channel->passphrase, strlen(channel->passphrase))) {
2092 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2093 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2094 SILC_STATUS_ERR_BAD_PASSWORD, 0,
2095 2, chidp->data, chidp->len);
2096 silc_buffer_free(chidp);
2101 /* Verify channel authentication with channel public keys if set. */
2102 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
2103 if (!silc_server_verify_channel_auth(server, channel, client->id,
2104 cauth, cauth_len)) {
2105 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2106 SILC_STATUS_ERR_PERM_DENIED, 0);
2112 * Client is allowed to join to the channel. Make it happen.
2115 /* Check whether the client already is on the channel */
2116 if (silc_server_client_on_channel(client, channel, NULL)) {
2117 clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
2118 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2119 silc_server_command_send_status_data2(cmd, SILC_COMMAND_JOIN,
2120 SILC_STATUS_ERR_USER_ON_CHANNEL, 0,
2121 2, clidp->data, clidp->len,
2122 3, chidp->data, chidp->len);
2123 silc_buffer_free(clidp);
2124 silc_buffer_free(chidp);
2128 /* Generate new channel key as protocol dictates */
2130 if (!silc_server_create_channel_key(server, channel, 0))
2133 /* Send the channel key. This is broadcasted to the channel but is not
2134 sent to the client who is joining to the channel. */
2135 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
2136 silc_server_send_channel_key(server, NULL, channel,
2137 server->server_type == SILC_ROUTER ?
2138 FALSE : !server->standalone);
2141 /* Join the client to the channel by adding it to channel's user list.
2142 Add also the channel to client entry's channels list for fast cross-
2144 chl = silc_calloc(1, sizeof(*chl));
2146 chl->client = client;
2147 chl->channel = channel;
2148 silc_hash_table_add(channel->user_list, client, chl);
2149 silc_hash_table_add(client->channels, channel, chl);
2150 channel->user_count++;
2151 channel->disabled = FALSE;
2153 /* Get users on the channel */
2154 silc_server_get_users_on_channel(server, channel, &user_list, &mode_list,
2157 /* Encode Client ID Payload of the original client who wants to join */
2158 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2160 /* Encode command reply packet */
2161 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
2162 SILC_PUT32_MSB(channel->mode, mode);
2163 SILC_PUT32_MSB(created, tmp2);
2164 SILC_PUT32_MSB(user_count, tmp3);
2165 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2166 SILC_PUT32_MSB(channel->user_limit, ulimit);
2168 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2169 tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2170 cipher = silc_cipher_get_name(channel->channel_key);
2171 keyp = silc_channel_key_payload_encode(silc_id_get_len(channel->id,
2174 strlen(cipher), cipher,
2175 channel->key_len / 8, channel->key);
2179 if (channel->founder_key)
2180 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
2182 /* Encode invite list */
2184 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
2185 SilcHashTableList htl;
2187 invite_list = silc_buffer_alloc_size(2);
2188 silc_buffer_format(invite_list,
2189 SILC_STR_UI_SHORT(silc_hash_table_count(
2190 channel->invite_list)),
2193 silc_hash_table_list(channel->invite_list, &htl);
2194 while (silc_hash_table_get(&htl, (void *)&tmp_len, (void *)&reply))
2195 invite_list = silc_argument_payload_encode_one(invite_list,
2197 reply->len, tmp_len);
2198 silc_hash_table_list_reset(&htl);
2201 /* Encode ban list */
2203 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
2204 SilcHashTableList htl;
2206 ban_list = silc_buffer_alloc_size(2);
2207 silc_buffer_format(ban_list,
2208 SILC_STR_UI_SHORT(silc_hash_table_count(
2209 channel->ban_list)),
2212 silc_hash_table_list(channel->ban_list, &htl);
2213 while (silc_hash_table_get(&htl, (void *)&tmp_len, (void *)&reply))
2214 ban_list = silc_argument_payload_encode_one(ban_list,
2216 reply->len, tmp_len);
2217 silc_hash_table_list_reset(&htl);
2220 if (channel->channel_pubkeys)
2221 chpklist = silc_server_get_channel_pk_list(server, channel, FALSE, FALSE);
2224 silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
2225 SILC_STATUS_OK, 0, ident, 16,
2226 2, channel->channel_name,
2227 strlen(channel->channel_name),
2228 3, chidp->data, chidp->len,
2229 4, clidp->data, clidp->len,
2232 7, keyp ? keyp->data : NULL,
2233 keyp ? keyp->len : 0,
2234 8, ban_list ? ban_list->data : NULL,
2235 ban_list ? ban_list->len : 0,
2236 9, invite_list ? invite_list->data :
2238 invite_list ? invite_list->len : 0,
2241 strlen(channel->topic) : 0,
2242 11, silc_hmac_get_name(channel->hmac),
2243 strlen(silc_hmac_get_name(channel->
2246 13, user_list->data, user_list->len,
2247 14, mode_list->data,
2249 15, fkey ? fkey->data : NULL,
2250 fkey ? fkey->len : 0,
2251 16, chpklist ? chpklist->data : NULL,
2252 chpklist ? chpklist->len : 0,
2253 17, (channel->mode &
2254 SILC_CHANNEL_MODE_ULIMIT ?
2257 SILC_CHANNEL_MODE_ULIMIT ?
2258 sizeof(ulimit) : 0));
2260 /* Send command reply */
2261 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
2262 reply->data, reply->len, FALSE);
2264 /* Send JOIN notify to locally connected clients on the channel. If
2265 we are normal server then router will send or have sent JOIN notify
2266 already. However since we've added the client already to our channel
2267 we'll ignore it (in packet_receive.c) so we must send it here. If
2268 we are router then this will send it to local clients and local
2270 SILC_LOG_DEBUG(("Send JOIN notify to channel"));
2271 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2272 SILC_NOTIFY_TYPE_JOIN, 2,
2273 clidp->data, clidp->len,
2274 chidp->data, chidp->len);
2276 /* Update statistics */
2277 server->stat.my_chanclients++;
2278 if (server->server_type == SILC_ROUTER) {
2279 server->stat.cell_chanclients++;
2280 server->stat.chanclients++;
2283 if (!cmd->pending) {
2284 /* Send JOIN notify packet to our primary router */
2285 silc_server_send_notify_join(server, SILC_PRIMARY_ROUTE(server),
2286 SILC_BROADCAST(server), channel, client->id);
2289 /* Distribute the channel key to all backup routers. */
2290 silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
2291 keyp->data, keyp->len, FALSE, TRUE);
2293 /* If client became founder by providing correct founder auth data
2294 notify the mode change to the channel. */
2296 SILC_PUT32_MSB(chl->mode, mode);
2297 SILC_LOG_DEBUG(("Send CUMODE_CHANGE notify to channel"));
2298 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2299 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
2300 clidp->data, clidp->len,
2301 mode, 4, clidp->data, clidp->len,
2302 fkey ? fkey->data : NULL,
2303 fkey ? fkey->len : 0);
2307 /* Set CUMODE notify type to network */
2309 silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
2310 SILC_BROADCAST(server), channel,
2311 chl->mode, client->id, SILC_ID_CLIENT,
2312 client->id, channel->founder_key);
2314 silc_buffer_free(reply);
2315 silc_buffer_free(clidp);
2316 silc_buffer_free(chidp);
2317 silc_buffer_free(keyp);
2318 silc_buffer_free(user_list);
2319 silc_buffer_free(mode_list);
2320 silc_buffer_free(fkey);
2321 silc_buffer_free(chpklist);
2322 silc_buffer_free(invite_list);
2323 silc_buffer_free(ban_list);
2327 memset(passphrase, 0, strlen(passphrase));
2328 silc_free(passphrase);
2331 /* Server side of command JOIN. Joins client into requested channel. If
2332 the channel does not exist it will be created. */
2334 SILC_SERVER_CMD_FUNC(join)
2336 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2337 SilcServer server = cmd->server;
2338 unsigned char *auth, *cauth;
2339 SilcUInt32 tmp_len, auth_len, cauth_len;
2340 char *tmp, *channel_name, *channel_namec = NULL, *cipher, *hmac;
2341 SilcChannelEntry channel;
2342 SilcUInt32 umode = 0;
2343 bool created = FALSE, create_key = TRUE;
2344 SilcClientID *client_id;
2346 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_JOIN, cmd, 2, 7);
2348 /* Get channel name */
2349 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
2351 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2352 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2357 /* Truncate over long channel names */
2358 if (tmp_len > 256) {
2364 /* Check for valid channel name. This is cached, the original is saved
2365 in the channel context. */
2366 channel_namec = silc_identifier_check(tmp, tmp_len, SILC_STRING_UTF8, 256,
2368 if (!channel_namec) {
2369 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2370 SILC_STATUS_ERR_BAD_CHANNEL, 0);
2374 /* Get Client ID of the client who is joining to the channel */
2375 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
2377 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2378 SILC_STATUS_ERR_NO_CLIENT_ID,
2382 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
2384 silc_server_command_send_status_data(cmd, SILC_COMMAND_JOIN,
2385 SILC_STATUS_ERR_BAD_CLIENT_ID, 0,
2390 /* Get cipher, hmac name and auth payload */
2391 cipher = silc_argument_get_arg_type(cmd->args, 4, NULL);
2392 hmac = silc_argument_get_arg_type(cmd->args, 5, NULL);
2393 auth = silc_argument_get_arg_type(cmd->args, 6, &auth_len);
2394 cauth = silc_argument_get_arg_type(cmd->args, 7, &cauth_len);
2396 /* See if the channel exists */
2397 channel = silc_idlist_find_channel_by_name(server->local_list,
2398 channel_namec, NULL);
2400 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
2401 SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
2403 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
2404 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2409 silc_free(client_id);
2410 client_id = silc_id_dup(entry->id, SILC_ID_CLIENT);
2413 (channel->disabled && server->server_type != SILC_ROUTER)) {
2414 /* Channel not found or not valid */
2416 /* If we are standalone server we don't have a router, we just create
2417 the channel by ourselves (unless it existed). */
2418 if (server->standalone) {
2420 channel = silc_server_create_new_channel(server, server->id, cipher,
2421 hmac, channel_name, TRUE);
2423 silc_server_command_send_status_data(
2424 cmd, SILC_COMMAND_JOIN,
2425 SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
2426 0, 2, cipher, strlen(cipher));
2427 silc_free(client_id);
2431 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2437 /* The channel does not exist on our server. If we are normal server
2438 we will send JOIN command to our router which will handle the
2439 joining procedure (either creates the channel if it doesn't exist
2440 or joins the client to it). */
2441 if (server->server_type != SILC_ROUTER) {
2443 SilcUInt16 old_ident;
2445 /* If this is pending command callback then we've resolved
2446 it and it didn't work, return since we've notified the
2447 client already in the command reply callback. */
2449 silc_free(client_id);
2453 old_ident = silc_command_get_ident(cmd->payload);
2454 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2455 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2457 /* Send JOIN command to our router */
2458 silc_server_packet_send(server, (SilcSocketConnection)
2459 SILC_PRIMARY_ROUTE(server),
2460 SILC_PACKET_COMMAND, cmd->packet->flags,
2461 tmpbuf->data, tmpbuf->len, TRUE);
2463 /* Reprocess this packet after received reply from router */
2464 silc_server_command_pending(server, SILC_COMMAND_JOIN,
2465 silc_command_get_ident(cmd->payload),
2466 silc_server_command_join,
2467 silc_server_command_dup(cmd));
2468 cmd->pending = TRUE;
2469 silc_command_set_ident(cmd->payload, old_ident);
2470 silc_buffer_free(tmpbuf);
2471 silc_free(client_id);
2475 /* We are router and the channel does not seem exist so we will check
2476 our global list as well for the channel. */
2477 channel = silc_idlist_find_channel_by_name(server->global_list,
2478 channel_namec, NULL);
2480 /* Channel really does not exist, create it */
2481 channel = silc_server_create_new_channel(server, server->id, cipher,
2482 hmac, channel_name, TRUE);
2484 silc_server_command_send_status_data(
2485 cmd, SILC_COMMAND_JOIN,
2486 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
2487 2, cipher, strlen(cipher));
2488 silc_free(client_id);
2492 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2500 /* Channel not found */
2502 /* If the command came from router and we are normal server then
2503 something went wrong with the joining as the channel was not found.
2504 We can't do anything else but ignore this. */
2505 if (cmd->sock->type == SILC_SOCKET_TYPE_ROUTER ||
2506 server->server_type != SILC_ROUTER) {
2507 silc_free(client_id);
2511 /* We are router and the channel does not seem exist so we will check
2512 our global list as well for the channel. */
2513 channel = silc_idlist_find_channel_by_name(server->global_list,
2514 channel_namec, NULL);
2516 /* Channel really does not exist, create it */
2517 channel = silc_server_create_new_channel(server, server->id, cipher,
2518 hmac, channel_name, TRUE);
2520 silc_server_command_send_status_data(
2521 cmd, SILC_COMMAND_JOIN,
2522 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
2523 2, cipher, strlen(cipher));
2524 silc_free(client_id);
2528 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2535 /* Check whether the channel was created by our router */
2536 if (cmd->pending && context2) {
2537 SilcServerCommandReplyContext reply = context2;
2539 if (silc_command_get(reply->payload) == SILC_COMMAND_JOIN) {
2540 tmp = silc_argument_get_arg_type(reply->args, 6, NULL);
2541 SILC_GET32_MSB(created, tmp);
2542 if (silc_argument_get_arg_type(reply->args, 7, NULL))
2543 create_key = FALSE; /* Router returned the key already */
2545 if (silc_command_get_status(reply->payload, NULL, NULL) &&
2546 channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
2547 /* Save channel passphrase, if user provided it successfully */
2550 pa = silc_argument_get_arg_type(cmd->args, 3, &pa_len);
2552 silc_free(channel->passphrase);
2553 channel->passphrase = silc_memdup(pa, pa_len);
2558 if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
2559 !channel->disabled && !silc_hash_table_count(channel->user_list))
2563 /* If the channel does not have global users and is also empty the client
2564 will be the channel founder and operator. */
2565 if (!channel->disabled &&
2566 !channel->global_users && !silc_hash_table_count(channel->user_list))
2567 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
2569 /* Join to the channel */
2570 silc_server_command_join_channel(server, cmd, channel, client_id,
2571 created, create_key, umode,
2572 auth, auth_len, cauth, cauth_len);
2574 silc_free(client_id);
2577 silc_free(channel_namec);
2578 silc_server_command_free(cmd);
2581 /* Server side of command MOTD. Sends server's current "message of the
2582 day" to the client. */
2584 SILC_SERVER_CMD_FUNC(motd)
2586 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2587 SilcServer server = cmd->server;
2588 SilcBuffer packet, idp;
2589 char *motd, *dest_server = NULL;
2590 SilcUInt32 motd_len;
2591 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2593 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_MOTD, cmd, 1, 1);
2595 /* Get server name */
2596 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2598 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
2599 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2604 /* Check server name */
2605 dest_server = silc_identifier_check(dest_server, strlen(dest_server),
2606 SILC_STRING_UTF8, 256, NULL);
2608 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
2609 SILC_STATUS_ERR_BAD_SERVER,
2614 if (!memcmp(dest_server, server->server_name, strlen(dest_server))) {
2617 idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
2619 if (server->config && server->config->server_info &&
2620 server->config->server_info->motd_file) {
2622 motd = silc_file_readfile(server->config->server_info->motd_file,
2628 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
2631 2, idp->data, idp->len,
2635 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
2638 2, idp->data, idp->len);
2641 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2642 packet->data, packet->len, FALSE);
2643 silc_buffer_free(packet);
2644 silc_buffer_free(idp);
2646 SilcServerEntry entry;
2648 /* Check whether we have this server cached */
2649 entry = silc_idlist_find_server_by_name(server->global_list,
2650 dest_server, TRUE, NULL);
2652 entry = silc_idlist_find_server_by_name(server->local_list,
2653 dest_server, TRUE, NULL);
2656 if (server->server_type != SILC_SERVER && !cmd->pending &&
2657 entry && !entry->motd) {
2658 /* Send to the server */
2660 SilcUInt16 old_ident;
2662 old_ident = silc_command_get_ident(cmd->payload);
2663 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2664 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2666 silc_server_packet_send(server, entry->connection,
2667 SILC_PACKET_COMMAND, cmd->packet->flags,
2668 tmpbuf->data, tmpbuf->len, TRUE);
2670 /* Reprocess this packet after received reply from router */
2671 silc_server_command_pending(server, SILC_COMMAND_MOTD,
2672 silc_command_get_ident(cmd->payload),
2673 silc_server_command_motd,
2674 silc_server_command_dup(cmd));
2675 cmd->pending = TRUE;
2676 silc_command_set_ident(cmd->payload, old_ident);
2677 silc_buffer_free(tmpbuf);
2681 /* Send to primary router only if we don't know the server
2682 * the client requested or if the server is not locally connected */
2683 if ((!entry || !(entry->data.status & SILC_IDLIST_STATUS_LOCAL))
2684 && !cmd->pending && !server->standalone) {
2685 /* Send to the primary router */
2687 SilcUInt16 old_ident;
2689 old_ident = silc_command_get_ident(cmd->payload);
2690 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2691 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2693 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2694 SILC_PACKET_COMMAND, cmd->packet->flags,
2695 tmpbuf->data, tmpbuf->len, TRUE);
2697 /* Reprocess this packet after received reply from router */
2698 silc_server_command_pending(server, SILC_COMMAND_MOTD,
2699 silc_command_get_ident(cmd->payload),
2700 silc_server_command_motd,
2701 silc_server_command_dup(cmd));
2702 cmd->pending = TRUE;
2703 silc_command_set_ident(cmd->payload, old_ident);
2704 silc_buffer_free(tmpbuf);
2709 silc_free(dest_server);
2710 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2711 silc_server_command_send_status_data(cmd, SILC_COMMAND_MOTD,
2712 SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
2714 strlen(dest_server));
2719 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
2720 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
2721 SILC_STATUS_OK, 0, ident, 2,
2722 2, idp->data, idp->len,
2725 strlen(entry->motd) : 0);
2726 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2727 packet->data, packet->len, FALSE);
2728 silc_buffer_free(packet);
2729 silc_buffer_free(idp);
2733 silc_free(dest_server);
2734 silc_server_command_free(cmd);
2737 /* Server side of command UMODE. Client can use this command to set/unset
2738 user mode. Client actually cannot set itself to be as server/router
2739 operator so this can be used only to unset the modes. */
2741 SILC_SERVER_CMD_FUNC(umode)
2743 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2744 SilcServer server = cmd->server;
2745 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2747 unsigned char *tmp_mask, m[4];
2748 SilcUInt32 mask = 0;
2749 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2750 bool set_mask = FALSE;
2752 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
2755 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_UMODE, cmd, 1, 2);
2757 /* Get the client's mode mask */
2758 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
2760 SILC_GET32_MSB(mask, tmp_mask);
2765 /* Check that mode changing is allowed. */
2766 if (!silc_server_check_umode_rights(server, client, mask)) {
2767 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
2768 SILC_STATUS_ERR_PERM_DENIED, 0);
2772 /* Anonymous mode cannot be set by client */
2773 if (mask & SILC_UMODE_ANONYMOUS &&
2774 !(client->mode & SILC_UMODE_ANONYMOUS)) {
2775 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
2776 SILC_STATUS_ERR_PERM_DENIED, 0);
2780 /* Update statistics */
2781 if (mask & SILC_UMODE_GONE) {
2782 if (!(client->mode & SILC_UMODE_GONE))
2783 server->stat.my_aways++;
2785 if (client->mode & SILC_UMODE_GONE)
2786 server->stat.my_aways--;
2789 /* If the client has anonymous mode set, preserve it. */
2790 if (client->mode & SILC_UMODE_ANONYMOUS)
2791 mask |= SILC_UMODE_ANONYMOUS;
2793 /* Change the mode */
2794 client->mode = mask;
2796 /* Send UMODE change to primary router */
2797 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
2798 SILC_BROADCAST(server), client->id,
2801 /* Check if anyone is watching this nickname */
2802 if (server->server_type == SILC_ROUTER)
2803 silc_server_check_watcher_list(server, client, NULL,
2804 SILC_NOTIFY_TYPE_UMODE_CHANGE);
2807 /* Send command reply to sender */
2808 SILC_PUT32_MSB(client->mode, m);
2809 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_UMODE,
2810 SILC_STATUS_OK, 0, ident, 1,
2812 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2813 packet->data, packet->len, FALSE);
2814 silc_buffer_free(packet);
2817 silc_server_command_free(cmd);
2820 /* Server side command of CMODE. Changes channel mode */
2822 SILC_SERVER_CMD_FUNC(cmode)
2824 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2825 SilcServer server = cmd->server;
2826 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2827 SilcIDListData idata = (SilcIDListData)client;
2828 SilcChannelID *channel_id = NULL;
2829 SilcChannelEntry channel;
2830 SilcChannelClientEntry chl;
2831 SilcBuffer packet, cidp;
2832 unsigned char *tmp, *tmp_id, *tmp_mask, *chpkdata = NULL;
2833 char *cipher = NULL, *hmac = NULL, *passphrase = NULL, ulimit[4];
2834 SilcUInt32 mode_mask = 0, old_mask = 0, tmp_len, tmp_len2, chpklen;
2835 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2836 bool set_mask = FALSE, set_chpk = FALSE;
2837 SilcPublicKey founder_key = NULL;
2838 SilcBuffer fkey = NULL, chpklist = NULL;
2839 SilcBufferStruct chpk;
2842 silc_server_command_free(cmd);
2846 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 9);
2848 /* Get Channel ID */
2849 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
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);
2856 channel_id = silc_id_payload_parse_id(tmp_id, tmp_len2, NULL);
2858 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2859 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2860 silc_server_command_free(cmd);
2864 /* Get channel entry */
2865 channel = silc_idlist_find_channel_by_id(server->local_list,
2868 channel = silc_idlist_find_channel_by_id(server->global_list,
2871 silc_server_command_send_status_data(cmd, SILC_COMMAND_CMODE,
2872 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
2873 0, 2, tmp_id, tmp_len2);
2874 silc_free(channel_id);
2875 silc_server_command_free(cmd);
2879 old_mask = channel->mode;
2881 /* Get the channel mode mask */
2882 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
2884 SILC_GET32_MSB(mode_mask, tmp_mask);
2888 /* Check whether this client is on the channel */
2889 if (!silc_server_client_on_channel(client, channel, &chl)) {
2890 silc_server_command_send_status_data(cmd, SILC_COMMAND_CMODE,
2891 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
2892 2, tmp_id, tmp_len2);
2896 /* Check that client has rights to change any requested channel modes */
2897 if (set_mask && !silc_server_check_cmode_rights(server, channel, chl,
2899 SILC_LOG_DEBUG(("Client does not have rights to change mode"));
2900 silc_server_command_send_status_data(
2901 cmd, SILC_COMMAND_CMODE,
2902 (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) ?
2903 SILC_STATUS_ERR_NO_CHANNEL_PRIV :
2904 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV), 0,
2905 2, tmp_id, tmp_len2);
2909 /* If mode mask was not sent as argument then merely return the current
2910 mode mask, founder key and channel public key list to the sender. */
2913 SILC_PUT32_MSB(channel->mode, m);
2914 if (channel->founder_key)
2915 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
2916 if (channel->channel_pubkeys)
2917 chpklist = silc_server_get_channel_pk_list(server, channel,
2920 silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
2921 SILC_STATUS_OK, 0, ident, 4,
2922 2, tmp_id, tmp_len2,
2924 4, fkey ? fkey->data : NULL,
2925 fkey ? fkey->len : 0,
2926 5, chpklist ? chpklist->data : NULL,
2927 chpklist ? chpklist->len : 0);
2928 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2929 packet->data, packet->len, FALSE);
2930 silc_buffer_free(packet);
2935 * Check the modes. Modes that requires nothing special operation are
2939 if (mode_mask & SILC_CHANNEL_MODE_PRIVKEY) {
2940 /* Channel uses private keys to protect traffic. Client(s) has set the
2941 key locally they want to use, server does not know that key. */
2942 /* Nothing interesting to do here */
2944 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
2945 /* The mode is removed and we need to generate and distribute
2946 new channel key. Clients are not using private channel keys
2947 anymore after this. */
2949 /* Re-generate channel key */
2950 if (!silc_server_create_channel_key(server, channel, 0))
2953 /* Send the channel key. This sends it to our local clients and if
2954 we are normal server to our router as well. */
2955 silc_server_send_channel_key(server, NULL, channel,
2956 server->server_type == SILC_ROUTER ?
2957 FALSE : !server->standalone);
2959 cipher = (char *)silc_cipher_get_name(channel->channel_key);
2960 hmac = (char *)silc_hmac_get_name(channel->hmac);
2964 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT) {
2965 /* User limit is set on channel */
2966 SilcUInt32 user_limit;
2968 /* Get user limit */
2969 tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
2971 if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT)) {
2972 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2973 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
2977 SILC_GET32_MSB(user_limit, tmp);
2978 channel->user_limit = user_limit;
2981 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2982 /* User limit mode is unset. Remove user limit */
2983 channel->user_limit = 0;
2986 if (mode_mask & SILC_CHANNEL_MODE_PASSPHRASE) {
2987 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
2988 /* Passphrase has been set to channel */
2990 /* Get the passphrase */
2991 tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
2993 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
2994 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
2998 /* Save the passphrase */
2999 passphrase = channel->passphrase = silc_memdup(tmp, strlen(tmp));
3002 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
3003 /* Passphrase mode is unset. remove the passphrase */
3004 silc_free(channel->passphrase);
3005 channel->passphrase = NULL;
3009 if (mode_mask & SILC_CHANNEL_MODE_CIPHER) {
3010 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
3011 /* Cipher to use protect the traffic */
3012 SilcCipher newkey, oldkey;
3015 cipher = silc_argument_get_arg_type(cmd->args, 5, NULL);
3017 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3018 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3022 /* Delete old cipher and allocate the new one */
3023 if (!silc_cipher_alloc(cipher, &newkey)) {
3024 silc_server_command_send_status_data(
3025 cmd, SILC_COMMAND_CMODE,
3026 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3027 2, cipher, strlen(cipher));
3031 oldkey = channel->channel_key;
3032 channel->channel_key = newkey;
3034 /* Re-generate channel key */
3035 if (!silc_server_create_channel_key(server, channel, 0)) {
3036 /* We don't have new key, revert to old one */
3037 channel->channel_key = oldkey;
3041 /* Remove old channel key for good */
3042 silc_cipher_free(oldkey);
3044 /* Send the channel key. This sends it to our local clients and if
3045 we are normal server to our router as well. */
3046 silc_server_send_channel_key(server, NULL, channel,
3047 server->server_type == SILC_ROUTER ?
3048 FALSE : !server->standalone);
3051 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
3052 /* Cipher mode is unset. Remove the cipher and revert back to
3054 SilcCipher newkey, oldkey;
3055 cipher = channel->cipher;
3057 /* Delete old cipher and allocate default one */
3058 if (!silc_cipher_alloc(cipher ? cipher : SILC_DEFAULT_CIPHER, &newkey)) {
3059 silc_server_command_send_status_data(
3060 cmd, SILC_COMMAND_CMODE,
3061 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3062 2, cipher, strlen(cipher));
3066 oldkey = channel->channel_key;
3067 channel->channel_key = newkey;
3069 /* Re-generate channel key */
3070 if (!silc_server_create_channel_key(server, channel, 0)) {
3071 /* We don't have new key, revert to old one */
3072 channel->channel_key = oldkey;
3076 /* Remove old channel key for good */
3077 silc_cipher_free(oldkey);
3079 /* Send the channel key. This sends it to our local clients and if
3080 we are normal server to our router as well. */
3081 silc_server_send_channel_key(server, NULL, channel,
3082 server->server_type == SILC_ROUTER ?
3083 FALSE : !server->standalone);
3087 if (mode_mask & SILC_CHANNEL_MODE_HMAC) {
3088 if (!(channel->mode & SILC_CHANNEL_MODE_HMAC)) {
3089 /* HMAC to use protect the traffic */
3090 unsigned char hash[32];
3094 hmac = silc_argument_get_arg_type(cmd->args, 6, NULL);
3096 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3097 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3101 /* Delete old hmac and allocate the new one */
3102 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
3103 silc_server_command_send_status_data(
3104 cmd, SILC_COMMAND_CMODE,
3105 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3106 2, hmac, strlen(hmac));
3110 silc_hmac_free(channel->hmac);
3111 channel->hmac = newhmac;
3113 /* Set the HMAC key out of current channel key. The client must do
3115 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
3116 channel->key_len / 8, hash);
3117 silc_hmac_set_key(channel->hmac, hash,
3118 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3119 memset(hash, 0, sizeof(hash));
3122 if (channel->mode & SILC_CHANNEL_MODE_HMAC) {
3123 /* Hmac mode is unset. Remove the hmac and revert back to
3126 unsigned char hash[32];
3127 hmac = channel->hmac_name;
3129 /* Delete old hmac and allocate default one */
3130 if (!silc_hmac_alloc(hmac ? hmac : SILC_DEFAULT_HMAC, NULL, &newhmac)) {
3131 silc_server_command_send_status_data(
3132 cmd, SILC_COMMAND_CMODE,
3133 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
3134 2, hmac, strlen(hmac));
3138 silc_hmac_free(channel->hmac);
3139 channel->hmac = newhmac;
3141 /* Set the HMAC key out of current channel key. The client must do
3143 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
3144 channel->key_len / 8,
3146 silc_hmac_set_key(channel->hmac, hash,
3147 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
3148 memset(hash, 0, sizeof(hash));
3152 if (mode_mask & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3153 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3154 /* Check if the founder public key was received */
3155 founder_key = idata->public_key;
3156 tmp = silc_argument_get_arg_type(cmd->args, 8, &tmp_len);
3158 if (!silc_pkcs_public_key_payload_decode(tmp, tmp_len, &founder_key)) {
3159 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3160 SILC_STATUS_ERR_AUTH_FAILED,
3165 /* If key was not sent and the channel mode has already founder
3166 then the key was not to be changed. */
3167 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
3171 /* Set the founder authentication */
3172 tmp = silc_argument_get_arg_type(cmd->args, 7, &tmp_len);
3174 silc_server_command_send_status_reply(
3175 cmd, SILC_COMMAND_CMODE,
3176 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3180 /* Verify the payload before setting the mode */
3181 if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY,
3182 founder_key, 0, server->sha1hash,
3183 client->id, SILC_ID_CLIENT)) {
3184 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3185 SILC_STATUS_ERR_AUTH_FAILED,
3190 /* Save the public key */
3191 if (channel->founder_key)
3192 silc_pkcs_public_key_free(channel->founder_key);
3193 if (silc_argument_get_arg_type(cmd->args, 8, NULL))
3194 channel->founder_key = founder_key;
3196 channel->founder_key = silc_pkcs_public_key_copy(founder_key);
3197 if (!channel->founder_key) {
3198 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3199 SILC_STATUS_ERR_AUTH_FAILED,
3204 fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
3206 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3207 SILC_STATUS_ERR_AUTH_FAILED,
3209 silc_pkcs_public_key_free(channel->founder_key);
3210 channel->founder_key = NULL;
3215 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3216 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3217 if (channel->founder_key)
3218 silc_pkcs_public_key_free(channel->founder_key);
3219 channel->founder_key = NULL;
3225 if (mode_mask & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
3226 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3229 chpkdata = silc_argument_get_arg_type(cmd->args, 9, &chpklen);
3231 if (!chpkdata && channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
3236 /* Process the channel public key(s) */
3237 st = silc_server_set_channel_pk_list(server, NULL, channel,
3239 if (st != SILC_STATUS_OK) {
3240 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, st, 0);
3245 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3246 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
3247 if (channel->channel_pubkeys)
3248 silc_hash_table_free(channel->channel_pubkeys);
3249 channel->channel_pubkeys = NULL;
3256 /* Finally, set the mode */
3257 old_mask = channel->mode = mode_mask;
3259 /* Send CMODE_CHANGE notify. */
3260 cidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3261 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT)
3262 SILC_PUT32_MSB(channel->user_limit, ulimit);
3263 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3264 SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
3265 cidp->data, cidp->len,
3267 cipher, cipher ? strlen(cipher) : 0,
3268 hmac, hmac ? strlen(hmac) : 0,
3269 passphrase, passphrase ?
3270 strlen(passphrase) : 0,
3271 fkey ? fkey->data : NULL,
3272 fkey ? fkey->len : 0,
3273 chpkdata ? chpkdata : NULL,
3274 chpkdata ? chpklen : 0,
3275 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
3277 mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
3278 sizeof(ulimit) : 0);
3280 /* Set CMODE notify type to network */
3281 if (chpkdata && chpklen)
3282 silc_buffer_set(&chpk, chpkdata, chpklen);
3283 silc_server_send_notify_cmode(server, SILC_PRIMARY_ROUTE(server),
3284 SILC_BROADCAST(server), channel,
3285 mode_mask, client->id, SILC_ID_CLIENT,
3286 cipher, hmac, passphrase, founder_key,
3287 chpkdata ? &chpk : NULL);
3290 chpklist = silc_server_get_channel_pk_list(server, channel, FALSE, FALSE);
3292 /* Send command reply to sender */
3293 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
3294 SILC_STATUS_OK, 0, ident, 5,
3295 2, tmp_id, tmp_len2,
3297 4, fkey ? fkey->data : NULL,
3298 fkey ? fkey->len : 0,
3299 5, chpklist ? chpklist->data :
3300 NULL, chpklist ? chpklist->len
3303 SILC_CHANNEL_MODE_ULIMIT ?
3306 SILC_CHANNEL_MODE_ULIMIT ?
3307 sizeof(ulimit) : 0));
3309 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3310 packet->data, packet->len, FALSE);
3312 silc_buffer_free(packet);
3313 silc_buffer_free(cidp);
3316 channel->mode = old_mask;
3317 silc_buffer_free(chpklist);
3318 silc_buffer_free(fkey);
3319 silc_free(channel_id);
3320 silc_server_command_free(cmd);
3323 /* Server side of CUMODE command. Changes client's mode on a channel. */
3325 SILC_SERVER_CMD_FUNC(cumode)
3327 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3328 SilcServer server = cmd->server;
3329 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3330 SilcChannelID *channel_id = NULL;
3331 SilcClientID *client_id = NULL;
3332 SilcChannelEntry channel;
3333 SilcClientEntry target_client;
3334 SilcChannelClientEntry chl;
3335 SilcBuffer packet, idp;
3336 unsigned char *tmp_id, *tmp_ch_id, *tmp_mask;
3337 SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
3339 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3340 SilcPublicKey founder_key = NULL;
3341 SilcBuffer fkey = NULL;
3346 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4);
3348 /* Get Channel ID */
3349 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
3351 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3352 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3355 channel_id = silc_id_payload_parse_id(tmp_ch_id, tmp_ch_len, NULL);
3357 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3358 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3362 /* Get channel entry */
3363 channel = silc_idlist_find_channel_by_id(server->local_list,
3366 channel = silc_idlist_find_channel_by_id(server->global_list,
3369 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3370 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
3371 0, 2, tmp_ch_id, tmp_ch_len);
3376 /* Check whether sender is on the channel */
3377 if (!silc_server_client_on_channel(client, channel, &chl)) {
3378 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3379 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
3380 2, tmp_ch_id, tmp_ch_len);
3383 sender_mask = chl->mode;
3385 /* Get the target client's channel mode mask */
3386 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
3388 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3389 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3393 SILC_GET32_MSB(target_mask, tmp_mask);
3395 /* Get target Client ID */
3396 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3398 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3399 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3402 client_id = silc_id_payload_parse_id(tmp_id, tmp_len, NULL);
3404 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3405 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3409 /* Get target client's entry */
3410 target_client = silc_idlist_find_client_by_id(server->local_list,
3411 client_id, TRUE, NULL);
3413 target_client = silc_idlist_find_client_by_id(server->global_list,
3414 client_id, TRUE, NULL);
3416 if (target_client != client &&
3417 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO) &&
3418 !(sender_mask & SILC_CHANNEL_UMODE_CHANOP)) {
3419 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3420 SILC_STATUS_ERR_NOT_YOU, 0,
3421 2, tmp_ch_id, tmp_ch_len);
3425 /* Check whether target client is on the channel */
3426 if (target_client != client) {
3427 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
3428 silc_server_command_send_status_data2(
3429 cmd, SILC_COMMAND_CUMODE,
3430 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL, 0,
3432 3, tmp_ch_id, tmp_ch_len);
3441 /* If the target client is founder, no one else can change their mode
3443 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && client != target_client) {
3444 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3445 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3446 0, 2, tmp_ch_id, tmp_ch_len);
3450 if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
3451 if (target_client != client) {
3452 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3453 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3458 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
3459 /* The client tries to claim the founder rights. */
3460 unsigned char *tmp_auth;
3461 SilcUInt32 tmp_auth_len;
3462 SilcChannelClientEntry chl2;
3463 SilcHashTableList htl;
3465 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
3466 !channel->founder_key) {
3467 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3468 SILC_STATUS_ERR_AUTH_FAILED, 0);
3472 tmp_auth = silc_argument_get_arg_type(cmd->args, 4, &tmp_auth_len);
3474 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3475 SILC_STATUS_ERR_AUTH_FAILED, 0);
3479 /* Verify the authentication payload */
3480 if (!silc_auth_verify_data(tmp_auth, tmp_auth_len, SILC_AUTH_PUBLIC_KEY,
3481 channel->founder_key, 0, server->sha1hash,
3482 client->id, SILC_ID_CLIENT)) {
3483 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3484 SILC_STATUS_ERR_AUTH_FAILED, 0);
3489 founder_key = channel->founder_key;
3490 fkey = silc_pkcs_public_key_payload_encode(founder_key);
3492 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3493 SILC_STATUS_ERR_AUTH_FAILED, 0);
3497 /* There cannot be anyone else as founder on the channel now. This
3498 client is definitely the founder due to this authentication. This
3499 is done only on router, not on server, since server cannot know
3500 whether router will accept this mode change or not. XXX This
3501 probably shouldn't be done anymore at all, may cause problems in
3502 router-router connections too (maybe just AUTH_FAILED error should
3503 be returned). -Pekka */
3504 if (server->server_type == SILC_ROUTER) {
3505 silc_hash_table_list(channel->user_list, &htl);
3506 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
3507 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
3508 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3509 silc_server_force_cumode_change(server, NULL, channel, chl2,
3513 silc_hash_table_list_reset(&htl);
3516 sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
3519 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3520 if (target_client == client) {
3521 /* Remove channel founder rights from itself */
3522 chl->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3525 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3526 SILC_STATUS_ERR_NOT_YOU, 0);
3532 if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
3533 /* Promote to operator */
3534 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
3535 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
3536 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
3537 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3538 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3539 0, 2, tmp_ch_id, tmp_ch_len);
3543 chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
3547 if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
3548 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
3549 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
3550 silc_server_command_send_status_data(cmd, SILC_COMMAND_CUMODE,
3551 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3552 0, 2, tmp_ch_id, tmp_ch_len);
3556 /* Demote to normal user */
3557 chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
3562 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
3563 if (target_client != client) {
3564 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3565 SILC_STATUS_ERR_NOT_YOU, 0);
3569 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)) {
3570 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
3574 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
3575 if (target_client != client) {
3576 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3577 SILC_STATUS_ERR_NOT_YOU, 0);
3581 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
3586 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
3587 if (target_client != client) {
3588 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3589 SILC_STATUS_ERR_NOT_YOU, 0);
3593 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)) {
3594 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
3598 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
3599 if (target_client != client) {
3600 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3601 SILC_STATUS_ERR_NOT_YOU, 0);
3605 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
3610 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
3611 if (target_client != client) {
3612 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3613 SILC_STATUS_ERR_NOT_YOU, 0);
3617 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)) {
3618 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
3622 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
3623 if (target_client != client) {
3624 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3625 SILC_STATUS_ERR_NOT_YOU, 0);
3629 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
3634 if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
3635 if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
3636 if (client == target_client) {
3637 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3638 SILC_STATUS_ERR_PERM_DENIED, 0);
3641 chl->mode |= SILC_CHANNEL_UMODE_QUIET;
3645 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
3646 if (client == target_client) {
3647 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
3648 SILC_STATUS_ERR_PERM_DENIED, 0);
3651 chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
3656 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3657 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3659 /* Send notify to channel, notify only if mode was actually changed. */
3661 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3662 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
3663 idp->data, idp->len,
3666 fkey ? fkey->data : NULL,
3667 fkey ? fkey->len : 0);
3669 /* Set CUMODE notify type to network */
3670 silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
3671 SILC_BROADCAST(server), channel,
3672 target_mask, client->id, SILC_ID_CLIENT,
3673 target_client->id, founder_key);
3676 /* Send command reply to sender */
3677 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CUMODE,
3678 SILC_STATUS_OK, 0, ident, 3,
3680 3, tmp_ch_id, tmp_ch_len,
3681 4, tmp_id, tmp_len);
3682 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3683 packet->data, packet->len, FALSE);
3685 silc_buffer_free(packet);
3686 silc_buffer_free(idp);
3689 silc_free(channel_id);
3690 silc_free(client_id);
3691 silc_buffer_free(fkey);
3692 silc_server_command_free(cmd);
3695 /* Server side of KICK command. Kicks client out of channel. */
3697 SILC_SERVER_CMD_FUNC(kick)
3699 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3700 SilcServer server = cmd->server;
3701 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3702 SilcClientEntry target_client;
3703 SilcChannelID *channel_id;
3704 SilcClientID *client_id;
3705 SilcChannelEntry channel;
3706 SilcChannelClientEntry chl;
3707 SilcBuffer idp, packet;
3708 SilcUInt32 tmp_len, target_idp_len, clen;
3709 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3710 unsigned char *tmp, *comment, *target_idp;
3715 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 3);
3717 /* Get Channel ID */
3718 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3720 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
3721 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3724 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
3726 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3727 SILC_STATUS_ERR_BAD_CHANNEL_ID, 0,
3732 /* Get channel entry */
3733 channel = silc_idlist_find_channel_by_id(server->local_list,
3736 channel = silc_idlist_find_channel_by_id(server->local_list,
3739 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3740 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
3741 0, 2, tmp, tmp_len);
3746 /* Check whether sender is on the channel */
3747 if (!silc_server_client_on_channel(client, channel, &chl)) {
3748 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3749 SILC_STATUS_ERR_NOT_ON_CHANNEL,
3750 0, 2, tmp, tmp_len);
3754 /* Check that the kicker is channel operator or channel founder */
3755 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
3756 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
3757 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3758 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
3759 0, 2, tmp, tmp_len);
3763 /* Get target Client ID */
3764 target_idp = silc_argument_get_arg_type(cmd->args, 2, &target_idp_len);
3766 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
3767 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
3770 client_id = silc_id_payload_parse_id(target_idp, target_idp_len, NULL);
3772 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3773 SILC_STATUS_ERR_BAD_CLIENT_ID,
3774 0, 2, target_idp, target_idp_len);
3778 /* Get target client's entry */
3779 target_client = silc_idlist_find_client_by_id(server->local_list,
3780 client_id, TRUE, NULL);
3781 if (!target_client) {
3782 target_client = silc_idlist_find_client_by_id(server->global_list,
3783 client_id, TRUE, NULL);
3786 /* Check whether target client is on the channel */
3787 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
3788 silc_server_command_send_status_data2(cmd, SILC_COMMAND_KICK,
3789 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL,
3790 0, 2, target_idp, target_idp_len,
3795 /* Check that the target client is not channel founder. Channel founder
3796 cannot be kicked from the channel. */
3797 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
3798 silc_server_command_send_status_data(cmd, SILC_COMMAND_KICK,
3799 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
3800 0, 2, tmp, tmp_len);
3805 comment = silc_argument_get_arg_type(cmd->args, 3, &clen);
3810 /* Send the reply back to the client */
3812 silc_command_reply_payload_encode_va(SILC_COMMAND_KICK,
3813 SILC_STATUS_OK, 0, ident, 2,
3815 3, target_idp, target_idp_len);
3816 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3817 packet->data, packet->len, FALSE);
3818 silc_buffer_free(packet);
3820 /* Send KICKED notify to local clients on the channel */
3821 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3822 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
3823 SILC_NOTIFY_TYPE_KICKED, 3,
3824 target_idp, target_idp_len,
3825 comment, comment ? strlen(comment) : 0,
3826 idp->data, idp->len);
3827 silc_buffer_free(idp);
3829 /* Send KICKED notify to primary route */
3830 silc_server_send_notify_kicked(server, SILC_PRIMARY_ROUTE(server),
3831 SILC_BROADCAST(server), channel,
3832 target_client->id, client->id, comment);
3834 /* Remove the client from channel's invite list */
3835 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
3837 silc_argument_payload_encode_one(NULL, target_idp, target_idp_len, 3);
3838 SilcArgumentPayload args =
3839 silc_argument_payload_parse(ab->data, ab->len, 1);
3840 silc_server_inviteban_process(server, channel->invite_list, 1, args);
3841 silc_buffer_free(ab);
3842 silc_argument_payload_free(args);
3845 /* Remove the client from the channel. If the channel does not exist
3846 after removing the client then the client kicked itself off the channel
3847 and we don't have to send anything after that. */
3848 if (!silc_server_remove_from_one_channel(server, NULL, channel,
3849 target_client, FALSE))
3852 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3853 /* Re-generate channel key */
3854 if (!silc_server_create_channel_key(server, channel, 0))
3857 /* Send the channel key to the channel. The key of course is not sent
3858 to the client who was kicked off the channel. */
3859 silc_server_send_channel_key(server, target_client->connection, channel,
3860 server->server_type == SILC_ROUTER ?
3861 FALSE : !server->standalone);
3865 silc_server_command_free(cmd);
3868 /* Server side of OPER command. Client uses this comand to obtain server
3869 operator privileges to this server/router. */
3871 SILC_SERVER_CMD_FUNC(oper)
3873 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3874 SilcServer server = cmd->server;
3875 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3876 unsigned char *username = NULL, *auth;
3878 SilcServerConfigAdmin *admin;
3879 SilcIDListData idata = (SilcIDListData)client;
3880 bool result = FALSE;
3881 SilcPublicKey cached_key;
3883 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
3886 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2);
3888 /* Get the username */
3889 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3891 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3892 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3897 /* Check username */
3898 username = silc_identifier_check(username, strlen(username),
3899 SILC_STRING_UTF8, 128, &tmp_len);
3901 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3902 SILC_STATUS_ERR_BAD_USERNAME,
3907 /* Get the admin configuration */
3908 admin = silc_server_config_find_admin(server, cmd->sock->ip,
3909 username, client->nickname);
3911 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
3912 username, client->nickname);
3914 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3915 SILC_STATUS_ERR_AUTH_FAILED,
3917 SILC_LOG_INFO(("OPER authentication failed for username '%s' by "
3918 "nickname '%s' from %s", username,
3919 client->nickname, cmd->sock->hostname));
3924 /* Get the authentication payload */
3925 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
3927 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3928 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3933 /* Verify the authentication data. If both passphrase and public key
3934 is set then try both of them. */
3935 if (admin->passphrase)
3936 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
3937 admin->passphrase, admin->passphrase_len,
3938 idata->hash, client->id, SILC_ID_CLIENT);
3939 if (!result && admin->publickeys) {
3940 cached_key = silc_server_get_public_key(server, admin->publickeys);
3943 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
3944 cached_key, 0, idata->hash,
3945 client->id, SILC_ID_CLIENT);
3948 /* Authentication failed */
3949 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3950 SILC_STATUS_ERR_AUTH_FAILED,
3955 /* Client is now server operator */
3956 client->mode |= SILC_UMODE_SERVER_OPERATOR;
3958 /* Update statistics */
3959 if (SILC_IS_LOCAL(client))
3960 server->stat.my_server_ops++;
3961 if (server->server_type == SILC_ROUTER)
3962 server->stat.server_ops++;
3964 /* Send UMODE change to primary router */
3965 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
3966 SILC_BROADCAST(server), client->id,
3969 /* Check if anyone is watching this nickname */
3970 if (server->server_type == SILC_ROUTER)
3971 silc_server_check_watcher_list(server, client, NULL,
3972 SILC_NOTIFY_TYPE_UMODE_CHANGE);
3974 /* Send reply to the sender */
3975 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
3979 silc_free(username);
3980 silc_server_command_free(cmd);
3983 SILC_TASK_CALLBACK(silc_server_command_detach_cb)
3985 SilcServer server = app_context;
3986 QuitInternal q = (QuitInternal)context;
3987 SilcClientID *client_id = (SilcClientID *)q->sock;
3988 SilcClientEntry client;
3989 SilcSocketConnection sock;
3991 client = silc_idlist_find_client_by_id(server->local_list, client_id,
3993 if (client && client->connection) {
3994 sock = client->connection;
3996 /* If there is pending outgoing data for the client then purge it
3997 to the network before closing connection. */
3998 silc_server_packet_queue_purge(server, sock);
4000 /* Close the connection on our side */
4001 client->router = NULL;
4002 client->connection = NULL;
4003 sock->user_data = NULL;
4004 silc_server_close_connection(server, sock);
4007 silc_free(client_id);
4011 SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
4013 SilcServer server = app_context;
4014 QuitInternal q = (QuitInternal)context;
4015 SilcClientID *client_id = (SilcClientID *)q->sock;
4016 SilcClientEntry client;
4018 client = silc_idlist_find_client_by_id(server->local_list, client_id,
4020 if (client && client->mode & SILC_UMODE_DETACHED) {
4021 SILC_LOG_DEBUG(("Detach timeout"));
4022 silc_server_free_client_data(server, NULL, client, TRUE,
4026 silc_free(client_id);
4030 /* Server side of DETACH command. Detached the client from the network
4031 by closing the connection but preserving the session. */
4033 SILC_SERVER_CMD_FUNC(detach)
4035 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4036 SilcServer server = cmd->server;
4037 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4040 if (server->config->detach_disabled) {
4041 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4042 SILC_STATUS_ERR_OPERATION_ALLOWED,
4047 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4050 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_DETACH, cmd, 0, 0);
4052 /* Remove operator privileges, since the client may resume in some
4053 other server which to it does not have operator privileges. */
4054 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
4055 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
4057 /* Send the user mode notify to notify that client is detached */
4058 client->mode |= SILC_UMODE_DETACHED;
4059 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
4060 client->data.status &= ~SILC_IDLIST_STATUS_NOATTR;
4061 client->last_command = 0;
4062 client->fast_command = 0;
4063 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4064 SILC_BROADCAST(server), client->id,
4066 server->stat.my_detached++;
4068 /* Check if anyone is watching this nickname */
4069 if (server->server_type == SILC_ROUTER)
4070 silc_server_check_watcher_list(server, client, NULL,
4071 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4073 q = silc_calloc(1, sizeof(*q));
4074 q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
4075 silc_schedule_task_add(server->schedule, 0, silc_server_command_detach_cb,
4076 q, 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
4078 if (server->config->detach_timeout) {
4079 q = silc_calloc(1, sizeof(*q));
4080 q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
4081 silc_schedule_task_add(server->schedule, 0,
4082 silc_server_command_detach_timeout,
4083 q, server->config->detach_timeout * 60,
4084 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
4087 /* Send reply to the sender */
4088 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4092 silc_server_command_free(cmd);
4095 /* Server side of WATCH command. */
4097 SILC_SERVER_CMD_FUNC(watch)
4099 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4100 SilcServerEntry server_entry;
4101 SilcServer server = cmd->server;
4102 char *add_nick, *del_nick;
4103 SilcUInt32 add_nick_len, del_nick_len, tmp_len, pk_len;
4104 unsigned char hash[16], *tmp, *pk, *nick;
4105 SilcClientEntry client;
4106 SilcClientID *client_id = NULL;
4108 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WATCH, cmd, 1, 3);
4110 if (server->server_type != SILC_ROUTER && !server->standalone) {
4111 if (!cmd->pending) {
4112 /* Send the command to router */
4114 SilcUInt16 old_ident;
4116 SILC_LOG_DEBUG(("Forwarding WATCH to router"));
4118 old_ident = silc_command_get_ident(cmd->payload);
4119 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4120 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4122 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4123 SILC_PACKET_COMMAND, cmd->packet->flags,
4124 tmpbuf->data, tmpbuf->len, TRUE);
4126 /* If we are backup router, we're not expecting reply as router
4127 won't be sending it. */
4128 if (server->server_type != SILC_BACKUP_ROUTER) {
4129 /* Reprocess this packet after received reply from router */
4130 silc_server_command_pending(server, SILC_COMMAND_WATCH,
4131 silc_command_get_ident(cmd->payload),
4132 silc_server_command_watch,
4133 silc_server_command_dup(cmd));
4134 cmd->pending = TRUE;
4135 silc_command_set_ident(cmd->payload, old_ident);
4136 silc_buffer_free(tmpbuf);
4140 silc_command_set_ident(cmd->payload, old_ident);
4141 silc_buffer_free(tmpbuf);
4142 } else if (context2) {
4143 /* Received reply from router, just send same data to the client. */
4144 SilcServerCommandReplyContext reply = context2;
4147 SILC_LOG_DEBUG(("Received reply to WATCH from router"));
4148 silc_command_get_status(reply->payload, &status, NULL);
4149 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH, status,
4155 /* We are router and keep the watch list for local cell */
4157 /* Get the client ID */
4158 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4160 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4161 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4165 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
4167 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4168 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4169 0, 2, tmp, tmp_len);
4173 /* Get the client entry which must be in local list */
4174 client = silc_idlist_find_client_by_id(server->local_list,
4175 client_id, TRUE, NULL);
4177 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4178 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
4183 /* Take public key for watching by public key */
4184 pk = silc_argument_get_arg_type(cmd->args, 4, &pk_len);
4187 add_nick = silc_argument_get_arg_type(cmd->args, 2, &add_nick_len);
4188 del_nick = silc_argument_get_arg_type(cmd->args, 3, &del_nick_len);
4189 if (!add_nick && !del_nick && !pk) {
4190 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4191 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4196 if (add_nick && add_nick_len > 128) {
4197 add_nick[128] = '\0';
4200 if (del_nick && del_nick_len > 128) {
4201 del_nick[128] = '\0';
4205 /* Add new nickname to be watched in our cell */
4207 nick = silc_identifier_check(add_nick, add_nick_len, SILC_STRING_UTF8, 128,
4210 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4211 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4215 /* Hash the nick, we have the hash saved, not nicks because we can
4216 do one to one mapping to the nick from Client ID hash this way. */
4217 silc_hash_make(server->md5hash, nick, add_nick_len, hash);
4219 /* Check whether this client is already watching this nickname */
4220 if (silc_hash_table_find_by_context(server->watcher_list, hash,
4222 /* Nickname is alredy being watched for this client */
4223 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4224 SILC_STATUS_ERR_NICKNAME_IN_USE,
4230 /* Get the nickname from the watcher list and use the same key in
4231 new entries as well. If key doesn't exist then create it. */
4232 if (!silc_hash_table_find(server->watcher_list, hash, (void *)&tmp, NULL))
4233 tmp = silc_memdup(hash, CLIENTID_HASH_LEN);
4235 /* Add the client to the watcher list with the specified nickname hash. */
4236 silc_hash_table_add(server->watcher_list, tmp, client);
4240 /* Delete nickname from watch list */
4242 nick = silc_identifier_check(del_nick, del_nick_len, SILC_STRING_UTF8, 128,
4245 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4246 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4250 /* Hash the nick, we have the hash saved, not nicks because we can
4251 do one to one mapping to the nick from Client ID hash this way. */
4252 silc_hash_make(server->md5hash, nick, del_nick_len, hash);
4254 /* Check that this client is watching for this nickname */
4255 if (!silc_hash_table_find_by_context(server->watcher_list, hash,
4256 client, (void *)&tmp)) {
4257 /* Nickname is alredy being watched for this client */
4258 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4259 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
4260 2, nick, del_nick_len);
4265 /* Delete the nickname from the watcher list. */
4266 silc_hash_table_del_by_context(server->watcher_list, hash, client);
4268 /* Now check whether there still exists entries with this key, if not
4269 then free the key to not leak memory. */
4270 if (!silc_hash_table_find(server->watcher_list, hash, NULL, NULL))
4275 /* Add/del public key */
4278 SilcArgumentPayload pkargs;
4280 SilcPublicKey public_key, pkkey;
4283 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4284 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4289 /* Get the argument from the Argument List Payload */
4290 SILC_GET16_MSB(pkargc, pk);
4291 pkargs = silc_argument_payload_parse(pk + 2, pk_len - 2, pkargc);
4293 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4294 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4299 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4301 if (!silc_pkcs_public_key_payload_decode(pk, pk_len, &public_key))
4307 /* Add public key to watch list */
4309 /* Check whether this client is already watching this public key */
4310 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4311 public_key, client, NULL)) {
4312 silc_pkcs_public_key_free(public_key);
4313 silc_server_command_send_status_reply(
4314 cmd, SILC_COMMAND_WATCH,
4315 SILC_STATUS_ERR_NICKNAME_IN_USE, 0);
4319 /* Get the public key from the watcher list and use the same key in
4320 new entries as well. If key doesn't exist then create it. */
4322 if (!silc_hash_table_find(server->watcher_list_pk, public_key,
4323 (void *)&pkkey, NULL))
4326 silc_pkcs_public_key_free(public_key);
4328 /* Add the client to the watcher list with the specified public
4330 silc_hash_table_add(server->watcher_list_pk, pkkey, client);
4332 } else if (type == 0x01) {
4333 /* Delete public key from watch list */
4335 /* Check that this client is watching this public key */
4336 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4339 silc_pkcs_public_key_free(public_key);
4340 silc_server_command_send_status_reply(
4341 cmd, SILC_COMMAND_WATCH,
4342 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4346 /* Delete the public key from the watcher list. */
4347 silc_hash_table_del_by_context(server->watcher_list_pk,
4348 public_key, client);
4350 /* Now check whether there still exists entries with this key, if
4351 not then free the key to not leak memory. */
4352 if (!silc_hash_table_find(server->watcher_list_pk, hash, NULL, NULL))
4353 silc_pkcs_public_key_free(pkkey);
4354 silc_pkcs_public_key_free(public_key);
4357 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4361 /* Distribute the watch list to backup routers too */
4362 if (server->backup) {
4364 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4365 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4366 silc_server_backup_send(server, cmd->sock->user_data, SILC_PACKET_COMMAND,
4367 cmd->packet->flags, tmpbuf->data, tmpbuf->len,
4369 silc_buffer_free(tmpbuf);
4372 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4376 silc_free(client_id);
4377 silc_server_command_free(cmd);
4380 /* Server side of SILCOPER command. Client uses this comand to obtain router
4381 operator privileges to this router. */
4383 SILC_SERVER_CMD_FUNC(silcoper)
4385 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4386 SilcServer server = cmd->server;
4387 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4388 unsigned char *username = NULL, *auth;
4390 SilcServerConfigAdmin *admin;
4391 SilcIDListData idata = (SilcIDListData)client;
4392 bool result = FALSE;
4393 SilcPublicKey cached_key;
4395 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4398 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
4400 if (server->server_type != SILC_ROUTER) {
4401 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4402 SILC_STATUS_ERR_AUTH_FAILED, 0);
4406 /* Get the username */
4407 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4409 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4410 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4415 /* Check username */
4416 username = silc_identifier_check(username, tmp_len, SILC_STRING_UTF8, 128,
4419 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4420 SILC_STATUS_ERR_BAD_USERNAME,
4425 /* Get the admin configuration */
4426 admin = silc_server_config_find_admin(server, cmd->sock->ip,
4427 username, client->nickname);
4429 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
4430 username, client->nickname);
4432 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4433 SILC_STATUS_ERR_AUTH_FAILED, 0);
4434 SILC_LOG_INFO(("SILCOPER authentication failed for username '%s' by "
4435 "nickname '%s' from %s", username,
4436 client->nickname, cmd->sock->hostname));
4441 /* Get the authentication payload */
4442 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
4444 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4445 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4450 /* Verify the authentication data. If both passphrase and public key
4451 is set then try both of them. */
4452 if (admin->passphrase)
4453 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
4454 admin->passphrase, admin->passphrase_len,
4455 idata->hash, client->id, SILC_ID_CLIENT);
4456 if (!result && admin->publickeys) {
4457 cached_key = silc_server_get_public_key(server, admin->publickeys);
4460 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
4461 cached_key, 0, idata->hash,
4462 client->id, SILC_ID_CLIENT);
4465 /* Authentication failed */
4466 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4467 SILC_STATUS_ERR_AUTH_FAILED, 0);
4471 /* Client is now router operator */
4472 client->mode |= SILC_UMODE_ROUTER_OPERATOR;
4474 /* Update statistics */
4475 if (SILC_IS_LOCAL(client))
4476 server->stat.my_router_ops++;
4477 if (server->server_type == SILC_ROUTER)
4478 server->stat.router_ops++;
4480 /* Send UMODE change to primary router */
4481 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4482 SILC_BROADCAST(server), client->id,
4485 /* Check if anyone is watching this nickname */
4486 if (server->server_type == SILC_ROUTER)
4487 silc_server_check_watcher_list(server, client, NULL,
4488 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4490 /* Send reply to the sender */
4491 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4495 silc_free(username);
4496 silc_server_command_free(cmd);
4499 /* Server side of command BAN. This is used to manage the ban list of the
4500 channel. To add clients and remove clients from the ban list. */
4502 SILC_SERVER_CMD_FUNC(ban)
4504 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4505 SilcServer server = cmd->server;
4506 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4507 SilcBuffer packet, list, tmp2;
4508 SilcChannelEntry channel;
4509 SilcChannelClientEntry chl;
4510 SilcChannelID *channel_id = NULL;
4511 unsigned char *id, *tmp, *atype = NULL;
4512 SilcUInt32 id_len, len, len2;
4513 SilcArgumentPayload args;
4514 SilcHashTableList htl;
4516 SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
4517 SilcBufferStruct blist;
4519 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4522 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_BAN, cmd, 0, 3);
4524 /* Get Channel ID */
4525 id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
4527 channel_id = silc_id_payload_parse_id(id, id_len, NULL);
4529 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4530 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4535 /* Get channel entry. The server must know about the channel since the
4536 client is expected to be on the channel. */
4537 channel = silc_idlist_find_channel_by_id(server->local_list,
4540 channel = silc_idlist_find_channel_by_id(server->global_list,
4543 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4544 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4550 /* Check whether this client is on the channel */
4551 if (!silc_server_client_on_channel(client, channel, &chl)) {
4552 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4553 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4558 /* The client must be at least channel operator. */
4559 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
4560 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4561 SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0,
4566 /* Get the ban information */
4567 tmp = silc_argument_get_arg_type(cmd->args, 3, &len2);
4568 if (tmp && len2 > 2) {
4569 /* Parse the arguments to see they are constructed correctly */
4570 SILC_GET16_MSB(argc, tmp);
4571 args = silc_argument_payload_parse(tmp + 2, len2 - 2, argc);
4573 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4574 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4579 /* Get the type of action */
4580 atype = silc_argument_get_arg_type(cmd->args, 2, &len);
4581 if (atype && len == 1) {
4582 if (atype[0] == 0x00) {
4583 /* Allocate hash table for ban list if it doesn't exist yet */
4584 if (!channel->ban_list)
4586 silc_hash_table_alloc(0, silc_hash_ptr,
4588 silc_server_inviteban_destruct, channel,
4591 /* Check for resource limit */
4592 if (silc_hash_table_count(channel->ban_list) > 64) {
4593 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4594 SILC_STATUS_ERR_RESOURCE_LIMIT,
4600 /* Now add or delete the information. */
4601 silc_server_inviteban_process(server, channel->ban_list,
4602 (SilcUInt8)atype[0], args);
4604 silc_argument_payload_free(args);
4607 /* Encode ban list */
4609 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4610 list = silc_buffer_alloc_size(2);
4611 silc_buffer_format(list,
4612 SILC_STR_UI_SHORT(silc_hash_table_count(
4613 channel->ban_list)),
4615 silc_hash_table_list(channel->ban_list, &htl);
4616 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4617 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4619 silc_hash_table_list_reset(&htl);
4622 /* Send BAN notify type to local servers (but not clients) and to
4624 if (atype && tmp && len2) {
4625 silc_buffer_set(&blist, tmp, len2);
4627 /* Send to local servers if we are router */
4628 if (server->server_type == SILC_ROUTER)
4629 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
4630 SILC_NOTIFY_TYPE_BAN, 3,
4633 tmp ? blist.data : NULL,
4634 tmp ? blist.len : 0);
4636 /* Send to network. */
4637 silc_server_send_notify_ban(server, SILC_PRIMARY_ROUTE(server),
4638 SILC_BROADCAST(server), channel, atype,
4642 /* Send the reply back to the client */
4644 silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
4645 SILC_STATUS_OK, 0, ident, 2,
4647 3, list ? list->data : NULL,
4648 list ? list->len : 0);
4649 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4650 packet->data, packet->len, FALSE);
4652 silc_buffer_free(packet);
4653 silc_buffer_free(list);
4656 silc_free(channel_id);
4657 silc_server_command_free(cmd);
4660 /* Server side command of LEAVE. Removes client from a channel. */
4662 SILC_SERVER_CMD_FUNC(leave)
4664 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4665 SilcServer server = cmd->server;
4666 SilcSocketConnection sock = cmd->sock;
4667 SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
4668 SilcChannelID *id = NULL;
4669 SilcChannelEntry channel;
4673 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !id_entry)
4676 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 2);
4678 /* Get Channel ID */
4679 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
4681 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4682 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4685 id = silc_id_payload_parse_id(tmp, len, NULL);
4687 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4688 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4692 /* Get channel entry */
4693 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4695 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4697 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4698 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4704 /* Check whether this client is on the channel */
4705 if (!silc_server_client_on_channel(id_entry, channel, NULL)) {
4706 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4707 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4712 /* Notify routers that they should remove this client from their list
4713 of clients on the channel. Send LEAVE notify type. */
4714 silc_server_send_notify_leave(server, SILC_PRIMARY_ROUTE(server),
4715 SILC_BROADCAST(server), channel, id_entry->id);
4717 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4718 SILC_STATUS_OK, 0, 2, tmp, len);
4720 /* Remove client from channel */
4721 if (!silc_server_remove_from_one_channel(server, sock, channel, id_entry,
4723 /* If the channel does not exist anymore we won't send anything */
4726 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
4727 /* Re-generate channel key */
4728 if (!silc_server_create_channel_key(server, channel, 0))
4731 /* Send the channel key */
4732 silc_server_send_channel_key(server, NULL, channel,
4733 server->server_type == SILC_ROUTER ?
4734 FALSE : !server->standalone);
4739 silc_server_command_free(cmd);
4742 /* Server side of command USERS. Resolves clients and their USERS currently
4743 joined on the requested channel. The list of Client ID's and their modes
4744 on the channel is sent back. */
4746 SILC_SERVER_CMD_FUNC(users)
4748 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4749 SilcServer server = cmd->server;
4750 SilcChannelEntry channel;
4751 SilcChannelID *id = NULL;
4752 SilcBuffer packet, idp;
4753 unsigned char *channel_id;
4754 SilcUInt32 channel_id_len;
4755 SilcBuffer client_id_list;
4756 SilcBuffer client_mode_list;
4757 unsigned char lc[4];
4758 SilcUInt32 list_count = 0;
4759 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4760 char *channel_name, *channel_namec = NULL;
4762 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2);
4764 /* Get Channel ID */
4765 channel_id = silc_argument_get_arg_type(cmd->args, 1, &channel_id_len);
4767 /* Get channel name */
4768 channel_name = silc_argument_get_arg_type(cmd->args, 2, NULL);
4770 if (!channel_id && !channel_name) {
4771 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4772 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4776 /* Check channel name */
4778 channel_namec = silc_identifier_check(channel_name, strlen(channel_name),
4779 SILC_STRING_UTF8, 256, NULL);
4780 if (!channel_namec) {
4781 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4782 SILC_STATUS_ERR_BAD_CHANNEL, 0);
4787 /* Check Channel ID */
4789 id = silc_id_payload_parse_id(channel_id, channel_id_len, NULL);
4791 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4792 SILC_STATUS_ERR_BAD_CHANNEL_ID, 0,
4793 2, channel_id, channel_id_len);
4798 /* If we are server and we don't know about this channel we will send
4799 the command to our router. If we know about the channel then we also
4800 have the list of users already. */
4802 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4804 channel = silc_idlist_find_channel_by_name(server->local_list,
4805 channel_namec, NULL);
4807 if (!channel || (!server->standalone && (channel->disabled ||
4808 !channel->users_resolved))) {
4809 if (server->server_type != SILC_ROUTER && !server->standalone &&
4813 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4814 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4816 /* Send USERS command */
4817 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4818 SILC_PACKET_COMMAND, cmd->packet->flags,
4819 tmpbuf->data, tmpbuf->len, TRUE);
4821 /* Reprocess this packet after received reply */
4822 silc_server_command_pending(server, SILC_COMMAND_USERS,
4823 silc_command_get_ident(cmd->payload),
4824 silc_server_command_users,
4825 silc_server_command_dup(cmd));
4826 cmd->pending = TRUE;
4827 silc_command_set_ident(cmd->payload, ident);
4828 silc_buffer_free(tmpbuf);
4833 /* Check the global list as well. */
4835 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4837 channel = silc_idlist_find_channel_by_name(server->global_list,
4838 channel_namec, NULL);
4840 /* Channel really does not exist */
4842 silc_server_command_send_status_data(
4843 cmd, SILC_COMMAND_USERS,
4844 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID, 0,
4845 2, channel_id, channel_id_len);
4847 silc_server_command_send_status_data(
4848 cmd, SILC_COMMAND_USERS,
4849 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
4850 2, channel_name, strlen(channel_name));
4855 /* If the channel is private or secret do not send anything, unless the
4856 user requesting this command is on the channel or is server */
4857 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
4858 if (channel->mode & (SILC_CHANNEL_MODE_PRIVATE | SILC_CHANNEL_MODE_SECRET)
4859 && !silc_server_client_on_channel(cmd->sock->user_data, channel,
4861 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4862 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
4863 2, channel->channel_name,
4864 strlen(channel->channel_name));
4869 /* Get the users list */
4870 if (!silc_server_get_users_on_channel(server, channel, &client_id_list,
4871 &client_mode_list, &list_count)) {
4873 client_id_list = NULL;
4874 client_mode_list = NULL;
4878 SILC_PUT32_MSB(list_count, lc);
4881 idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4882 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_USERS,
4883 SILC_STATUS_OK, 0, ident, 4,
4884 2, idp->data, idp->len,
4887 client_id_list->data : NULL,
4889 client_id_list->len : 0,
4890 5, client_mode_list ?
4891 client_mode_list->data : NULL,
4893 client_mode_list->len : 0);
4894 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4895 packet->data, packet->len, FALSE);
4897 silc_buffer_free(idp);
4898 silc_buffer_free(packet);
4900 silc_buffer_free(client_id_list);
4901 if (client_mode_list)
4902 silc_buffer_free(client_mode_list);
4906 silc_free(channel_namec);
4907 silc_server_command_free(cmd);
4910 /* Server side of command GETKEY. This fetches the client's public key
4911 from the server where to the client is connected. */
4913 SILC_SERVER_CMD_FUNC(getkey)
4915 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4916 SilcServer server = cmd->server;
4918 SilcClientEntry client;
4919 SilcServerEntry server_entry;
4920 SilcClientID *client_id = NULL;
4921 SilcServerID *server_id = NULL;
4922 SilcIDPayload idp = NULL;
4923 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4926 SilcBuffer pk = NULL;
4928 SilcPublicKey public_key;
4930 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4932 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
4933 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4937 idp = silc_id_payload_parse(tmp, tmp_len);
4939 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
4940 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4945 id_type = silc_id_payload_get_type(idp);
4946 if (id_type == SILC_ID_CLIENT) {
4947 client_id = silc_id_payload_get_id(idp);
4949 /* If the client is not found from local list there is no chance it
4950 would be locally connected client so send the command further. */
4951 client = silc_idlist_find_client_by_id(server->local_list,
4952 client_id, TRUE, NULL);
4954 client = silc_idlist_find_client_by_id(server->global_list,
4955 client_id, TRUE, NULL);
4957 if ((!client && !cmd->pending && !server->standalone) ||
4958 (client && !client->connection && !cmd->pending &&
4959 !(client->mode & SILC_UMODE_DETACHED)) ||
4960 (client && !client->data.public_key && !cmd->pending)) {
4962 SilcUInt16 old_ident;
4963 SilcSocketConnection dest_sock;
4965 dest_sock = silc_server_get_client_route(server, NULL, 0,
4966 client_id, NULL, NULL);
4970 old_ident = silc_command_get_ident(cmd->payload);
4971 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4972 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4974 silc_server_packet_send(server, dest_sock,
4975 SILC_PACKET_COMMAND, cmd->packet->flags,
4976 tmpbuf->data, tmpbuf->len, TRUE);
4978 /* Reprocess this packet after received reply from router */
4979 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
4980 silc_command_get_ident(cmd->payload),
4981 silc_server_command_getkey,
4982 silc_server_command_dup(cmd));
4983 cmd->pending = TRUE;
4984 silc_command_set_ident(cmd->payload, old_ident);
4985 silc_buffer_free(tmpbuf);
4990 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
4991 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4992 0, 2, tmp, tmp_len);
4996 /* The client is locally connected, just get the public key and
4997 send it back. If they key does not exist then do not send it,
4998 send just OK reply */
4999 public_key = client->data.public_key;
5001 pk = silc_pkcs_public_key_payload_encode(public_key);
5002 } else if (id_type == SILC_ID_SERVER) {
5003 server_id = silc_id_payload_get_id(idp);
5005 /* If the server is not found from local list there is no chance it
5006 would be locally connected server so send the command further. */
5007 server_entry = silc_idlist_find_server_by_id(server->local_list,
5008 server_id, TRUE, NULL);
5010 server_entry = silc_idlist_find_server_by_id(server->global_list,
5011 server_id, TRUE, NULL);
5013 if (server_entry != server->id_entry &&
5014 ((!server_entry && !cmd->pending && !server->standalone) ||
5015 (server_entry && !server_entry->connection && !cmd->pending &&
5016 !server->standalone) ||
5017 (server_entry && !server_entry->data.public_key && !cmd->pending &&
5018 !server->standalone))) {
5020 SilcUInt16 old_ident;
5022 old_ident = silc_command_get_ident(cmd->payload);
5023 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5024 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5026 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5027 SILC_PACKET_COMMAND, cmd->packet->flags,
5028 tmpbuf->data, tmpbuf->len, TRUE);
5030 /* Reprocess this packet after received reply from router */
5031 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
5032 silc_command_get_ident(cmd->payload),
5033 silc_server_command_getkey,
5034 silc_server_command_dup(cmd));
5035 cmd->pending = TRUE;
5036 silc_command_set_ident(cmd->payload, old_ident);
5037 silc_buffer_free(tmpbuf);
5041 if (!server_entry) {
5042 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
5043 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
5044 0, 2, tmp, tmp_len);
5048 /* If they key does not exist then do not send it, send just OK reply */
5049 public_key = (!server_entry->data.public_key ?
5050 (server_entry == server->id_entry ? server->public_key :
5051 NULL) : server_entry->data.public_key);
5053 pk = silc_pkcs_public_key_payload_encode(public_key);
5058 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5059 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_GETKEY,
5060 SILC_STATUS_OK, 0, ident, 2,
5062 3, pk ? pk->data : NULL,
5064 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
5065 packet->data, packet->len, FALSE);
5066 silc_buffer_free(packet);
5070 silc_id_payload_free(idp);
5071 silc_buffer_free(pk);
5072 silc_free(client_id);
5073 silc_free(server_id);
5074 silc_server_command_free(cmd);
5078 /* Private range commands, specific to this implementation */
5080 /* Server side command of CONNECT. Connects us to the specified remote
5081 server or router. */
5083 SILC_SERVER_CMD_FUNC(connect)
5085 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5086 SilcServer server = cmd->server;
5087 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5088 unsigned char *tmp, *host;
5090 SilcUInt32 port = SILC_PORT;
5092 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5095 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CONNECT, cmd, 1, 2);
5097 /* Check whether client has the permissions. */
5098 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5099 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5100 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5101 SILC_STATUS_ERR_NO_SERVER_PRIV, 0);
5105 if (server->server_type == SILC_ROUTER && !server->backup_router &&
5106 client->mode & SILC_UMODE_SERVER_OPERATOR) {
5107 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5108 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
5112 /* Get the remote server */
5113 host = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5115 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5116 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5122 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5124 SILC_GET32_MSB(port, tmp);
5126 /* Create the connection. It is done with timeout and is async. */
5127 silc_server_create_connection(server, host, port);
5129 /* Send reply to the sender */
5130 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5134 silc_server_command_free(cmd);
5137 /* Server side command of CLOSE. Closes connection to a specified server. */
5139 SILC_SERVER_CMD_FUNC(close)
5141 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5142 SilcServer server = cmd->server;
5143 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5144 SilcServerEntry server_entry;
5145 SilcSocketConnection sock;
5148 unsigned char *name;
5149 SilcUInt32 port = SILC_PORT;
5151 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5154 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CLOSE, cmd, 1, 2);
5156 /* Check whether client has the permissions. */
5157 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5158 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5159 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5160 SILC_STATUS_ERR_NO_SERVER_PRIV,
5165 /* Get the remote server */
5166 name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5168 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5169 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5175 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5177 SILC_GET32_MSB(port, tmp);
5179 server_entry = silc_idlist_find_server_by_conn(server->local_list,
5180 name, port, TRUE, NULL);
5182 server_entry = silc_idlist_find_server_by_conn(server->global_list,
5183 name, port, TRUE, NULL);
5184 if (!server_entry) {
5185 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5186 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5190 if (server_entry == server->id_entry) {
5191 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5192 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5196 /* Send reply to the sender */
5197 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5200 /* Close the connection to the server */
5201 sock = (SilcSocketConnection)server_entry->connection;
5203 if (server_entry->server_type == SILC_BACKUP_ROUTER) {
5204 server->backup_closed = TRUE;
5205 silc_server_backup_del(server, server_entry);
5208 server->backup_noswitch = TRUE;
5209 if (server->router == server_entry) {
5210 server->id_entry->router = NULL;
5211 server->router = NULL;
5212 server->standalone = TRUE;
5214 silc_server_disconnect_remote(server, sock,
5215 SILC_STATUS_ERR_BANNED_FROM_SERVER,
5216 "Closed by administrator");
5217 if (sock->user_data)
5218 silc_server_free_sock_user_data(server, sock, NULL);
5219 server->backup_noswitch = FALSE;
5222 silc_server_command_free(cmd);
5225 /* Server side command of SHUTDOWN. Shutdowns the server and closes all
5226 active connections. */
5228 SILC_SERVER_CMD_FUNC(shutdown)
5230 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5231 SilcServer server = cmd->server;
5232 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5234 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5237 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_SHUTDOWN, cmd, 0, 0);
5239 /* Check whether client has the permission. */
5240 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5241 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5242 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5243 SILC_STATUS_ERR_NO_SERVER_PRIV,
5248 /* Send reply to the sender */
5249 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5252 /* Then, gracefully, or not, bring the server down. */
5253 silc_server_stop(server);
5257 silc_server_command_free(cmd);