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 /* Reprocess this packet after received reply from router */
4127 silc_server_command_pending(server, SILC_COMMAND_WATCH,
4128 silc_command_get_ident(cmd->payload),
4129 silc_server_command_watch,
4130 silc_server_command_dup(cmd));
4131 cmd->pending = TRUE;
4132 silc_command_set_ident(cmd->payload, old_ident);
4133 silc_buffer_free(tmpbuf);
4134 } else if (context2) {
4135 /* Received reply from router, just send same data to the client. */
4136 SilcServerCommandReplyContext reply = context2;
4139 SILC_LOG_DEBUG(("Received reply to WATCH from router"));
4140 silc_command_get_status(reply->payload, &status, NULL);
4141 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH, status,
4147 /* We are router and keep the watch list for local cell */
4149 /* Get the client ID */
4150 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4152 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4153 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4157 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
4159 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4160 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4161 0, 2, tmp, tmp_len);
4165 /* Get the client entry which must be in local list */
4166 client = silc_idlist_find_client_by_id(server->local_list,
4167 client_id, TRUE, NULL);
4169 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4170 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
4175 /* Take public key for watching by public key */
4176 pk = silc_argument_get_arg_type(cmd->args, 4, &pk_len);
4179 add_nick = silc_argument_get_arg_type(cmd->args, 2, &add_nick_len);
4180 del_nick = silc_argument_get_arg_type(cmd->args, 3, &del_nick_len);
4181 if (!add_nick && !del_nick && !pk) {
4182 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4183 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4188 if (add_nick && add_nick_len > 128) {
4189 add_nick[128] = '\0';
4192 if (del_nick && del_nick_len > 128) {
4193 del_nick[128] = '\0';
4197 /* Add new nickname to be watched in our cell */
4199 nick = silc_identifier_check(add_nick, add_nick_len, SILC_STRING_UTF8, 128,
4202 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4203 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4207 /* Hash the nick, we have the hash saved, not nicks because we can
4208 do one to one mapping to the nick from Client ID hash this way. */
4209 silc_hash_make(server->md5hash, nick, add_nick_len, hash);
4211 /* Check whether this client is already watching this nickname */
4212 if (silc_hash_table_find_by_context(server->watcher_list, hash,
4214 /* Nickname is alredy being watched for this client */
4215 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4216 SILC_STATUS_ERR_NICKNAME_IN_USE,
4222 /* Get the nickname from the watcher list and use the same key in
4223 new entries as well. If key doesn't exist then create it. */
4224 if (!silc_hash_table_find(server->watcher_list, hash, (void *)&tmp, NULL))
4225 tmp = silc_memdup(hash, CLIENTID_HASH_LEN);
4227 /* Add the client to the watcher list with the specified nickname hash. */
4228 silc_hash_table_add(server->watcher_list, tmp, client);
4232 /* Delete nickname from watch list */
4234 nick = silc_identifier_check(del_nick, del_nick_len, SILC_STRING_UTF8, 128,
4237 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4238 SILC_STATUS_ERR_BAD_NICKNAME, 0);
4242 /* Hash the nick, we have the hash saved, not nicks because we can
4243 do one to one mapping to the nick from Client ID hash this way. */
4244 silc_hash_make(server->md5hash, nick, del_nick_len, hash);
4246 /* Check that this client is watching for this nickname */
4247 if (!silc_hash_table_find_by_context(server->watcher_list, hash,
4248 client, (void *)&tmp)) {
4249 /* Nickname is alredy being watched for this client */
4250 silc_server_command_send_status_data(cmd, SILC_COMMAND_WATCH,
4251 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
4252 2, nick, del_nick_len);
4257 /* Delete the nickname from the watcher list. */
4258 silc_hash_table_del_by_context(server->watcher_list, hash, client);
4260 /* Now check whether there still exists entries with this key, if not
4261 then free the key to not leak memory. */
4262 if (!silc_hash_table_find(server->watcher_list, hash, NULL, NULL))
4267 /* Add/del public key */
4270 SilcArgumentPayload pkargs;
4272 SilcPublicKey public_key, pkkey;
4275 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4276 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4281 /* Get the argument from the Argument List Payload */
4282 SILC_GET16_MSB(pkargc, pk);
4283 pkargs = silc_argument_payload_parse(pk + 2, pk_len - 2, pkargc);
4285 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4286 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4291 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4293 if (!silc_pkcs_public_key_payload_decode(pk, pk_len, &public_key))
4299 /* Add public key to watch list */
4301 /* Check whether this client is already watching this public key */
4302 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4303 public_key, client, NULL)) {
4304 silc_pkcs_public_key_free(public_key);
4305 silc_server_command_send_status_reply(
4306 cmd, SILC_COMMAND_WATCH,
4307 SILC_STATUS_ERR_NICKNAME_IN_USE, 0);
4311 /* Get the public key from the watcher list and use the same key in
4312 new entries as well. If key doesn't exist then create it. */
4314 if (!silc_hash_table_find(server->watcher_list_pk, public_key,
4315 (void *)&pkkey, NULL))
4318 silc_pkcs_public_key_free(public_key);
4320 /* Add the client to the watcher list with the specified public
4322 silc_hash_table_add(server->watcher_list_pk, pkkey, client);
4324 } else if (type == 0x01) {
4325 /* Delete public key from watch list */
4327 /* Check that this client is watching this public key */
4328 if (silc_hash_table_find_by_context(server->watcher_list_pk,
4331 silc_pkcs_public_key_free(public_key);
4332 silc_server_command_send_status_reply(
4333 cmd, SILC_COMMAND_WATCH,
4334 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4338 /* Delete the public key from the watcher list. */
4339 silc_hash_table_del_by_context(server->watcher_list_pk,
4340 public_key, client);
4342 /* Now check whether there still exists entries with this key, if
4343 not then free the key to not leak memory. */
4344 if (!silc_hash_table_find(server->watcher_list_pk, hash, NULL, NULL))
4345 silc_pkcs_public_key_free(pkkey);
4346 silc_pkcs_public_key_free(public_key);
4349 pk = silc_argument_get_next_arg(pkargs, &type, &pk_len);
4353 /* Distribute the watch list to backup routers too */
4354 if (server->backup) {
4356 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4357 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4358 silc_server_backup_send(server, cmd->sock->user_data, SILC_PACKET_COMMAND,
4359 cmd->packet->flags, tmpbuf->data, tmpbuf->len,
4361 silc_buffer_free(tmpbuf);
4364 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
4368 silc_free(client_id);
4369 silc_server_command_free(cmd);
4372 /* Server side of SILCOPER command. Client uses this comand to obtain router
4373 operator privileges to this router. */
4375 SILC_SERVER_CMD_FUNC(silcoper)
4377 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4378 SilcServer server = cmd->server;
4379 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4380 unsigned char *username = NULL, *auth;
4382 SilcServerConfigAdmin *admin;
4383 SilcIDListData idata = (SilcIDListData)client;
4384 bool result = FALSE;
4385 SilcPublicKey cached_key;
4387 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4390 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
4392 if (server->server_type != SILC_ROUTER) {
4393 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4394 SILC_STATUS_ERR_AUTH_FAILED, 0);
4398 /* Get the username */
4399 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4401 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4402 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4407 /* Check username */
4408 username = silc_identifier_check(username, tmp_len, SILC_STRING_UTF8, 128,
4411 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4412 SILC_STATUS_ERR_BAD_USERNAME,
4417 /* Get the admin configuration */
4418 admin = silc_server_config_find_admin(server, cmd->sock->ip,
4419 username, client->nickname);
4421 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
4422 username, client->nickname);
4424 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4425 SILC_STATUS_ERR_AUTH_FAILED, 0);
4426 SILC_LOG_INFO(("SILCOPER authentication failed for username '%s' by "
4427 "nickname '%s' from %s", username,
4428 client->nickname, cmd->sock->hostname));
4433 /* Get the authentication payload */
4434 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
4436 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4437 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4442 /* Verify the authentication data. If both passphrase and public key
4443 is set then try both of them. */
4444 if (admin->passphrase)
4445 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
4446 admin->passphrase, admin->passphrase_len,
4447 idata->hash, client->id, SILC_ID_CLIENT);
4448 if (!result && admin->publickeys) {
4449 cached_key = silc_server_get_public_key(server, admin->publickeys);
4452 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
4453 cached_key, 0, idata->hash,
4454 client->id, SILC_ID_CLIENT);
4457 /* Authentication failed */
4458 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4459 SILC_STATUS_ERR_AUTH_FAILED, 0);
4463 /* Client is now router operator */
4464 client->mode |= SILC_UMODE_ROUTER_OPERATOR;
4466 /* Update statistics */
4467 if (SILC_IS_LOCAL(client))
4468 server->stat.my_router_ops++;
4469 if (server->server_type == SILC_ROUTER)
4470 server->stat.router_ops++;
4472 /* Send UMODE change to primary router */
4473 silc_server_send_notify_umode(server, SILC_PRIMARY_ROUTE(server),
4474 SILC_BROADCAST(server), client->id,
4477 /* Check if anyone is watching this nickname */
4478 if (server->server_type == SILC_ROUTER)
4479 silc_server_check_watcher_list(server, client, NULL,
4480 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4482 /* Send reply to the sender */
4483 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
4487 silc_free(username);
4488 silc_server_command_free(cmd);
4491 /* Server side of command BAN. This is used to manage the ban list of the
4492 channel. To add clients and remove clients from the ban list. */
4494 SILC_SERVER_CMD_FUNC(ban)
4496 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4497 SilcServer server = cmd->server;
4498 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4499 SilcBuffer packet, list, tmp2;
4500 SilcChannelEntry channel;
4501 SilcChannelClientEntry chl;
4502 SilcChannelID *channel_id = NULL;
4503 unsigned char *id, *tmp, *atype = NULL;
4504 SilcUInt32 id_len, len, len2;
4505 SilcArgumentPayload args;
4506 SilcHashTableList htl;
4508 SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
4509 SilcBufferStruct blist;
4511 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
4514 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_BAN, cmd, 0, 3);
4516 /* Get Channel ID */
4517 id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
4519 channel_id = silc_id_payload_parse_id(id, id_len, NULL);
4521 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4522 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4527 /* Get channel entry. The server must know about the channel since the
4528 client is expected to be on the channel. */
4529 channel = silc_idlist_find_channel_by_id(server->local_list,
4532 channel = silc_idlist_find_channel_by_id(server->global_list,
4535 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4536 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4542 /* Check whether this client is on the channel */
4543 if (!silc_server_client_on_channel(client, channel, &chl)) {
4544 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4545 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4550 /* The client must be at least channel operator. */
4551 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
4552 silc_server_command_send_status_data(cmd, SILC_COMMAND_BAN,
4553 SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0,
4558 /* Get the ban information */
4559 tmp = silc_argument_get_arg_type(cmd->args, 3, &len2);
4560 if (tmp && len2 > 2) {
4561 /* Parse the arguments to see they are constructed correctly */
4562 SILC_GET16_MSB(argc, tmp);
4563 args = silc_argument_payload_parse(tmp + 2, len2 - 2, argc);
4565 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4566 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4571 /* Get the type of action */
4572 atype = silc_argument_get_arg_type(cmd->args, 2, &len);
4573 if (atype && len == 1) {
4574 if (atype[0] == 0x00) {
4575 /* Allocate hash table for ban list if it doesn't exist yet */
4576 if (!channel->ban_list)
4578 silc_hash_table_alloc(0, silc_hash_ptr,
4580 silc_server_inviteban_destruct, channel,
4583 /* Check for resource limit */
4584 if (silc_hash_table_count(channel->ban_list) > 64) {
4585 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
4586 SILC_STATUS_ERR_RESOURCE_LIMIT,
4592 /* Now add or delete the information. */
4593 silc_server_inviteban_process(server, channel->ban_list,
4594 (SilcUInt8)atype[0], args);
4596 silc_argument_payload_free(args);
4599 /* Encode ban list */
4601 if (channel->ban_list && silc_hash_table_count(channel->ban_list)) {
4602 list = silc_buffer_alloc_size(2);
4603 silc_buffer_format(list,
4604 SILC_STR_UI_SHORT(silc_hash_table_count(
4605 channel->ban_list)),
4607 silc_hash_table_list(channel->ban_list, &htl);
4608 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
4609 list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
4611 silc_hash_table_list_reset(&htl);
4614 /* Send BAN notify type to local servers (but not clients) and to
4616 if (atype && tmp && len2) {
4617 silc_buffer_set(&blist, tmp, len2);
4619 /* Send to local servers if we are router */
4620 if (server->server_type == SILC_ROUTER)
4621 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
4622 SILC_NOTIFY_TYPE_BAN, 3,
4625 tmp ? blist.data : NULL,
4626 tmp ? blist.len : 0);
4628 /* Send to network. */
4629 silc_server_send_notify_ban(server, SILC_PRIMARY_ROUTE(server),
4630 SILC_BROADCAST(server), channel, atype,
4634 /* Send the reply back to the client */
4636 silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
4637 SILC_STATUS_OK, 0, ident, 2,
4639 3, list ? list->data : NULL,
4640 list ? list->len : 0);
4641 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4642 packet->data, packet->len, FALSE);
4644 silc_buffer_free(packet);
4645 silc_buffer_free(list);
4648 silc_free(channel_id);
4649 silc_server_command_free(cmd);
4652 /* Server side command of LEAVE. Removes client from a channel. */
4654 SILC_SERVER_CMD_FUNC(leave)
4656 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4657 SilcServer server = cmd->server;
4658 SilcSocketConnection sock = cmd->sock;
4659 SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
4660 SilcChannelID *id = NULL;
4661 SilcChannelEntry channel;
4665 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !id_entry)
4668 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 2);
4670 /* Get Channel ID */
4671 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
4673 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4674 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4677 id = silc_id_payload_parse_id(tmp, len, NULL);
4679 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
4680 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4684 /* Get channel entry */
4685 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4687 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4689 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4690 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
4696 /* Check whether this client is on the channel */
4697 if (!silc_server_client_on_channel(id_entry, channel, NULL)) {
4698 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4699 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0,
4704 /* Notify routers that they should remove this client from their list
4705 of clients on the channel. Send LEAVE notify type. */
4706 silc_server_send_notify_leave(server, SILC_PRIMARY_ROUTE(server),
4707 SILC_BROADCAST(server), channel, id_entry->id);
4709 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
4710 SILC_STATUS_OK, 0, 2, tmp, len);
4712 /* Remove client from channel */
4713 if (!silc_server_remove_from_one_channel(server, sock, channel, id_entry,
4715 /* If the channel does not exist anymore we won't send anything */
4718 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
4719 /* Re-generate channel key */
4720 if (!silc_server_create_channel_key(server, channel, 0))
4723 /* Send the channel key */
4724 silc_server_send_channel_key(server, NULL, channel,
4725 server->server_type == SILC_ROUTER ?
4726 FALSE : !server->standalone);
4731 silc_server_command_free(cmd);
4734 /* Server side of command USERS. Resolves clients and their USERS currently
4735 joined on the requested channel. The list of Client ID's and their modes
4736 on the channel is sent back. */
4738 SILC_SERVER_CMD_FUNC(users)
4740 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4741 SilcServer server = cmd->server;
4742 SilcChannelEntry channel;
4743 SilcChannelID *id = NULL;
4744 SilcBuffer packet, idp;
4745 unsigned char *channel_id;
4746 SilcUInt32 channel_id_len;
4747 SilcBuffer client_id_list;
4748 SilcBuffer client_mode_list;
4749 unsigned char lc[4];
4750 SilcUInt32 list_count = 0;
4751 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4752 char *channel_name, *channel_namec = NULL;
4754 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2);
4756 /* Get Channel ID */
4757 channel_id = silc_argument_get_arg_type(cmd->args, 1, &channel_id_len);
4759 /* Get channel name */
4760 channel_name = silc_argument_get_arg_type(cmd->args, 2, NULL);
4762 if (!channel_id && !channel_name) {
4763 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4764 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4768 /* Check channel name */
4770 channel_namec = silc_identifier_check(channel_name, strlen(channel_name),
4771 SILC_STRING_UTF8, 256, NULL);
4772 if (!channel_namec) {
4773 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
4774 SILC_STATUS_ERR_BAD_CHANNEL, 0);
4779 /* Check Channel ID */
4781 id = silc_id_payload_parse_id(channel_id, channel_id_len, NULL);
4783 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4784 SILC_STATUS_ERR_BAD_CHANNEL_ID, 0,
4785 2, channel_id, channel_id_len);
4790 /* If we are server and we don't know about this channel we will send
4791 the command to our router. If we know about the channel then we also
4792 have the list of users already. */
4794 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
4796 channel = silc_idlist_find_channel_by_name(server->local_list,
4797 channel_namec, NULL);
4799 if (!channel || (!server->standalone && (channel->disabled ||
4800 !channel->users_resolved))) {
4801 if (server->server_type != SILC_ROUTER && !server->standalone &&
4805 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4806 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4808 /* Send USERS command */
4809 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
4810 SILC_PACKET_COMMAND, cmd->packet->flags,
4811 tmpbuf->data, tmpbuf->len, TRUE);
4813 /* Reprocess this packet after received reply */
4814 silc_server_command_pending(server, SILC_COMMAND_USERS,
4815 silc_command_get_ident(cmd->payload),
4816 silc_server_command_users,
4817 silc_server_command_dup(cmd));
4818 cmd->pending = TRUE;
4819 silc_command_set_ident(cmd->payload, ident);
4820 silc_buffer_free(tmpbuf);
4825 /* Check the global list as well. */
4827 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
4829 channel = silc_idlist_find_channel_by_name(server->global_list,
4830 channel_namec, NULL);
4832 /* Channel really does not exist */
4834 silc_server_command_send_status_data(
4835 cmd, SILC_COMMAND_USERS,
4836 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID, 0,
4837 2, channel_id, channel_id_len);
4839 silc_server_command_send_status_data(
4840 cmd, SILC_COMMAND_USERS,
4841 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
4842 2, channel_name, strlen(channel_name));
4847 /* If the channel is private or secret do not send anything, unless the
4848 user requesting this command is on the channel or is server */
4849 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
4850 if (channel->mode & (SILC_CHANNEL_MODE_PRIVATE | SILC_CHANNEL_MODE_SECRET)
4851 && !silc_server_client_on_channel(cmd->sock->user_data, channel,
4853 silc_server_command_send_status_data(cmd, SILC_COMMAND_USERS,
4854 SILC_STATUS_ERR_NO_SUCH_CHANNEL, 0,
4855 2, channel->channel_name,
4856 strlen(channel->channel_name));
4861 /* Get the users list */
4862 if (!silc_server_get_users_on_channel(server, channel, &client_id_list,
4863 &client_mode_list, &list_count)) {
4865 client_id_list = NULL;
4866 client_mode_list = NULL;
4870 SILC_PUT32_MSB(list_count, lc);
4873 idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
4874 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_USERS,
4875 SILC_STATUS_OK, 0, ident, 4,
4876 2, idp->data, idp->len,
4879 client_id_list->data : NULL,
4881 client_id_list->len : 0,
4882 5, client_mode_list ?
4883 client_mode_list->data : NULL,
4885 client_mode_list->len : 0);
4886 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4887 packet->data, packet->len, FALSE);
4889 silc_buffer_free(idp);
4890 silc_buffer_free(packet);
4892 silc_buffer_free(client_id_list);
4893 if (client_mode_list)
4894 silc_buffer_free(client_mode_list);
4898 silc_free(channel_namec);
4899 silc_server_command_free(cmd);
4902 /* Server side of command GETKEY. This fetches the client's public key
4903 from the server where to the client is connected. */
4905 SILC_SERVER_CMD_FUNC(getkey)
4907 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4908 SilcServer server = cmd->server;
4910 SilcClientEntry client;
4911 SilcServerEntry server_entry;
4912 SilcClientID *client_id = NULL;
4913 SilcServerID *server_id = NULL;
4914 SilcIDPayload idp = NULL;
4915 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4918 SilcBuffer pk = NULL;
4920 SilcPublicKey public_key;
4922 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4924 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
4925 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4929 idp = silc_id_payload_parse(tmp, tmp_len);
4931 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
4932 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4937 id_type = silc_id_payload_get_type(idp);
4938 if (id_type == SILC_ID_CLIENT) {
4939 client_id = silc_id_payload_get_id(idp);
4941 /* If the client is not found from local list there is no chance it
4942 would be locally connected client so send the command further. */
4943 client = silc_idlist_find_client_by_id(server->local_list,
4944 client_id, TRUE, NULL);
4946 client = silc_idlist_find_client_by_id(server->global_list,
4947 client_id, TRUE, NULL);
4949 if ((!client && !cmd->pending && !server->standalone) ||
4950 (client && !client->connection && !cmd->pending &&
4951 !(client->mode & SILC_UMODE_DETACHED)) ||
4952 (client && !client->data.public_key && !cmd->pending)) {
4954 SilcUInt16 old_ident;
4955 SilcSocketConnection dest_sock;
4957 dest_sock = silc_server_get_client_route(server, NULL, 0,
4958 client_id, NULL, NULL);
4962 old_ident = silc_command_get_ident(cmd->payload);
4963 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
4964 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
4966 silc_server_packet_send(server, dest_sock,
4967 SILC_PACKET_COMMAND, cmd->packet->flags,
4968 tmpbuf->data, tmpbuf->len, TRUE);
4970 /* Reprocess this packet after received reply from router */
4971 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
4972 silc_command_get_ident(cmd->payload),
4973 silc_server_command_getkey,
4974 silc_server_command_dup(cmd));
4975 cmd->pending = TRUE;
4976 silc_command_set_ident(cmd->payload, old_ident);
4977 silc_buffer_free(tmpbuf);
4982 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
4983 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
4984 0, 2, tmp, tmp_len);
4988 /* The client is locally connected, just get the public key and
4989 send it back. If they key does not exist then do not send it,
4990 send just OK reply */
4991 public_key = client->data.public_key;
4993 pk = silc_pkcs_public_key_payload_encode(public_key);
4994 } else if (id_type == SILC_ID_SERVER) {
4995 server_id = silc_id_payload_get_id(idp);
4997 /* If the server is not found from local list there is no chance it
4998 would be locally connected server so send the command further. */
4999 server_entry = silc_idlist_find_server_by_id(server->local_list,
5000 server_id, TRUE, NULL);
5002 server_entry = silc_idlist_find_server_by_id(server->global_list,
5003 server_id, TRUE, NULL);
5005 if (server_entry != server->id_entry &&
5006 ((!server_entry && !cmd->pending && !server->standalone) ||
5007 (server_entry && !server_entry->connection && !cmd->pending &&
5008 !server->standalone) ||
5009 (server_entry && !server_entry->data.public_key && !cmd->pending &&
5010 !server->standalone))) {
5012 SilcUInt16 old_ident;
5014 old_ident = silc_command_get_ident(cmd->payload);
5015 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5016 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5018 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
5019 SILC_PACKET_COMMAND, cmd->packet->flags,
5020 tmpbuf->data, tmpbuf->len, TRUE);
5022 /* Reprocess this packet after received reply from router */
5023 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
5024 silc_command_get_ident(cmd->payload),
5025 silc_server_command_getkey,
5026 silc_server_command_dup(cmd));
5027 cmd->pending = TRUE;
5028 silc_command_set_ident(cmd->payload, old_ident);
5029 silc_buffer_free(tmpbuf);
5033 if (!server_entry) {
5034 silc_server_command_send_status_data(cmd, SILC_COMMAND_GETKEY,
5035 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
5036 0, 2, tmp, tmp_len);
5040 /* If they key does not exist then do not send it, send just OK reply */
5041 public_key = (!server_entry->data.public_key ?
5042 (server_entry == server->id_entry ? server->public_key :
5043 NULL) : server_entry->data.public_key);
5045 pk = silc_pkcs_public_key_payload_encode(public_key);
5050 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5051 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_GETKEY,
5052 SILC_STATUS_OK, 0, ident, 2,
5054 3, pk ? pk->data : NULL,
5056 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
5057 packet->data, packet->len, FALSE);
5058 silc_buffer_free(packet);
5062 silc_id_payload_free(idp);
5063 silc_buffer_free(pk);
5064 silc_free(client_id);
5065 silc_free(server_id);
5066 silc_server_command_free(cmd);
5070 /* Private range commands, specific to this implementation */
5072 /* Server side command of CONNECT. Connects us to the specified remote
5073 server or router. */
5075 SILC_SERVER_CMD_FUNC(connect)
5077 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5078 SilcServer server = cmd->server;
5079 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5080 unsigned char *tmp, *host;
5082 SilcUInt32 port = SILC_PORT;
5084 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5087 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CONNECT, cmd, 1, 2);
5089 /* Check whether client has the permissions. */
5090 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5091 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5092 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5093 SILC_STATUS_ERR_NO_SERVER_PRIV, 0);
5097 if (server->server_type == SILC_ROUTER && !server->backup_router &&
5098 client->mode & SILC_UMODE_SERVER_OPERATOR) {
5099 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5100 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
5104 /* Get the remote server */
5105 host = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5107 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5108 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5114 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5116 SILC_GET32_MSB(port, tmp);
5118 /* Create the connection. It is done with timeout and is async. */
5119 silc_server_create_connection(server, host, port);
5121 /* Send reply to the sender */
5122 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5126 silc_server_command_free(cmd);
5129 /* Server side command of CLOSE. Closes connection to a specified server. */
5131 SILC_SERVER_CMD_FUNC(close)
5133 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5134 SilcServer server = cmd->server;
5135 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5136 SilcServerEntry server_entry;
5137 SilcSocketConnection sock;
5140 unsigned char *name;
5141 SilcUInt32 port = SILC_PORT;
5143 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5146 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CLOSE, cmd, 1, 2);
5148 /* Check whether client has the permissions. */
5149 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5150 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5151 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5152 SILC_STATUS_ERR_NO_SERVER_PRIV,
5157 /* Get the remote server */
5158 name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5160 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5161 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5167 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5169 SILC_GET32_MSB(port, tmp);
5171 server_entry = silc_idlist_find_server_by_conn(server->local_list,
5172 name, port, TRUE, NULL);
5174 server_entry = silc_idlist_find_server_by_conn(server->global_list,
5175 name, port, TRUE, NULL);
5176 if (!server_entry) {
5177 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5178 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5182 if (server_entry == server->id_entry) {
5183 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5184 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5188 /* Send reply to the sender */
5189 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5192 /* Close the connection to the server */
5193 sock = (SilcSocketConnection)server_entry->connection;
5195 if (server_entry->server_type == SILC_BACKUP_ROUTER) {
5196 server->backup_closed = TRUE;
5197 silc_server_backup_del(server, server_entry);
5200 server->backup_noswitch = TRUE;
5201 if (server->router == server_entry) {
5202 server->id_entry->router = NULL;
5203 server->router = NULL;
5204 server->standalone = TRUE;
5206 silc_server_disconnect_remote(server, sock,
5207 SILC_STATUS_ERR_BANNED_FROM_SERVER,
5208 "Closed by administrator");
5209 if (sock->user_data)
5210 silc_server_free_sock_user_data(server, sock, NULL);
5211 server->backup_noswitch = FALSE;
5214 silc_server_command_free(cmd);
5217 /* Server side command of SHUTDOWN. Shutdowns the server and closes all
5218 active connections. */
5220 SILC_SERVER_CMD_FUNC(shutdown)
5222 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5223 SilcServer server = cmd->server;
5224 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5226 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
5229 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_SHUTDOWN, cmd, 0, 0);
5231 /* Check whether client has the permission. */
5232 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5233 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5234 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5235 SILC_STATUS_ERR_NO_SERVER_PRIV,
5240 /* Send reply to the sender */
5241 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
5244 /* Then, gracefully, or not, bring the server down. */
5245 silc_server_stop(server);
5249 silc_server_command_free(cmd);