5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 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; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
22 #include "serverincludes.h"
23 #include "server_internal.h"
25 static int silc_server_is_registered(SilcServer server,
26 SilcSocketConnection sock,
27 SilcServerCommandContext cmd,
30 silc_server_command_send_status_reply(SilcServerCommandContext cmd,
35 silc_server_command_send_status_data(SilcServerCommandContext cmd,
40 const unsigned char *arg,
43 silc_server_command_pending_error_check(SilcServerCommandContext cmd,
44 SilcServerCommandReplyContext cmdr,
46 SILC_TASK_CALLBACK(silc_server_command_process_timeout);
48 /* Server command list. */
49 SilcServerCommand silc_command_list[] =
51 SILC_SERVER_CMD(whois, WHOIS, SILC_CF_LAG | SILC_CF_REG),
52 SILC_SERVER_CMD(whowas, WHOWAS, SILC_CF_LAG | SILC_CF_REG),
53 SILC_SERVER_CMD(identify, IDENTIFY, SILC_CF_LAG | SILC_CF_REG),
54 SILC_SERVER_CMD(nick, NICK, SILC_CF_LAG_STRICT | SILC_CF_REG),
55 SILC_SERVER_CMD(list, LIST, SILC_CF_LAG_STRICT | SILC_CF_REG),
56 SILC_SERVER_CMD(topic, TOPIC, SILC_CF_LAG | SILC_CF_REG),
57 SILC_SERVER_CMD(invite, INVITE, SILC_CF_LAG | SILC_CF_REG),
58 SILC_SERVER_CMD(quit, QUIT, SILC_CF_LAG | SILC_CF_REG),
59 SILC_SERVER_CMD(kill, KILL, SILC_CF_LAG_STRICT | SILC_CF_REG | SILC_CF_OPER),
60 SILC_SERVER_CMD(info, INFO, SILC_CF_LAG | SILC_CF_REG),
61 SILC_SERVER_CMD(stats, STATS, SILC_CF_LAG | SILC_CF_REG),
62 SILC_SERVER_CMD(ping, PING, SILC_CF_LAG | SILC_CF_REG),
63 SILC_SERVER_CMD(oper, OPER, SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
64 SILC_SERVER_CMD(join, JOIN, SILC_CF_LAG_STRICT | SILC_CF_REG),
65 SILC_SERVER_CMD(motd, MOTD, SILC_CF_LAG | SILC_CF_REG),
66 SILC_SERVER_CMD(umode, UMODE, SILC_CF_LAG | SILC_CF_REG),
67 SILC_SERVER_CMD(cmode, CMODE, SILC_CF_LAG_STRICT | SILC_CF_REG),
68 SILC_SERVER_CMD(cumode, CUMODE, SILC_CF_LAG | SILC_CF_REG),
69 SILC_SERVER_CMD(kick, KICK, SILC_CF_LAG_STRICT | SILC_CF_REG),
70 SILC_SERVER_CMD(ban, BAN, SILC_CF_LAG_STRICT | SILC_CF_REG),
71 SILC_SERVER_CMD(detach, DETACH, SILC_CF_LAG_STRICT | SILC_CF_REG),
72 SILC_SERVER_CMD(watch, WATCH, SILC_CF_LAG | SILC_CF_REG),
73 SILC_SERVER_CMD(silcoper, SILCOPER,
74 SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER),
75 SILC_SERVER_CMD(leave, LEAVE, SILC_CF_LAG_STRICT | SILC_CF_REG),
76 SILC_SERVER_CMD(users, USERS, SILC_CF_LAG | SILC_CF_REG),
77 SILC_SERVER_CMD(getkey, GETKEY, SILC_CF_LAG | SILC_CF_REG),
79 SILC_SERVER_CMD(connect, PRIV_CONNECT,
80 SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
81 SILC_SERVER_CMD(close, PRIV_CLOSE,
82 SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
83 SILC_SERVER_CMD(shutdown, PRIV_SHUTDOWN, SILC_CF_LAG | SILC_CF_REG |
89 /* Performs several checks to the command. It first checks whether this
90 command was called as pending command callback. If it was then it checks
91 whether error occurred in the command reply where the pending command
94 It also checks that the requested command includes correct amount
96 #define SILC_SERVER_COMMAND_CHECK(command, context, min, max) \
100 SILC_LOG_DEBUG(("Start")); \
102 if (silc_server_command_pending_error_check(cmd, context2, command)) { \
103 silc_server_command_free(cmd); \
107 _argc = silc_argument_get_arg_num(cmd->args); \
109 silc_server_command_send_status_reply(cmd, command, \
110 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, \
112 silc_server_command_free(cmd); \
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_server_command_free(timeout->ctx);
164 /* Update access time */
165 client->last_command = time(NULL);
167 if (!(timeout->cmd->flags & SILC_CF_REG))
168 timeout->cmd->cb(timeout->ctx, NULL);
169 else if (silc_server_is_registered(timeout->ctx->server,
173 timeout->cmd->cb(timeout->ctx, NULL);
175 silc_server_command_free(timeout->ctx);
180 /* Processes received command packet. */
182 void silc_server_command_process(SilcServer server,
183 SilcSocketConnection sock,
184 SilcPacketContext *packet)
186 SilcServerCommandContext ctx;
187 SilcServerCommand *cmd;
190 SILC_LOG_DEBUG(("Start"));
192 /* Allocate command context. This must be free'd by the
193 command routine receiving it. */
194 ctx = silc_server_command_alloc();
195 ctx->server = server;
196 ctx->sock = silc_socket_dup(sock);
197 ctx->packet = silc_packet_context_dup(packet); /* Save original packet */
199 /* Parse the command payload in the packet */
200 ctx->payload = silc_command_payload_parse(packet->buffer->data,
201 packet->buffer->len);
203 SILC_LOG_ERROR(("Bad command payload, packet dropped"));
204 silc_packet_context_free(packet);
205 silc_socket_free(ctx->sock);
209 ctx->args = silc_command_get_args(ctx->payload);
211 /* Get the command */
212 command = silc_command_get(ctx->payload);
213 for (cmd = silc_command_list; cmd->cb; cmd++)
214 if (cmd->cmd == command)
217 if (!cmd || !cmd->cb) {
218 silc_server_command_send_status_reply(ctx, command,
219 SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
220 silc_server_command_free(ctx);
224 /* Execute client's commands always with timeout. Normally they are
225 executed with zero (0) timeout but if client is sending command more
226 frequently than once in 2 seconds, then the timeout may be 0 to 2
228 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
229 SilcClientEntry client = (SilcClientEntry)sock->user_data;
230 SilcServerCommandTimeout timeout = silc_calloc(1, sizeof(*timeout));
236 if (client->last_command && (time(NULL) - client->last_command) < 2) {
237 client->fast_command++;
240 if (client->fast_command - 2 <= 0)
241 client->fast_command = 0;
243 client->fast_command -= 2;
247 if (!fast && ((cmd->flags & SILC_CF_LAG_STRICT) ||
248 (client->fast_command > 5 && cmd->flags & SILC_CF_LAG)))
249 silc_schedule_task_add(server->schedule, sock->sock,
250 silc_server_command_process_timeout, timeout,
251 (client->fast_command < 3 ? 0 :
252 2 - (time(NULL) - client->last_command)),
253 (client->fast_command < 3 ? 200000 : 0),
254 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
256 silc_schedule_task_add(server->schedule, sock->sock,
257 silc_server_command_process_timeout, timeout,
258 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
262 /* Execute for server */
264 if (!(cmd->flags & SILC_CF_REG))
266 else if (silc_server_is_registered(server, sock, ctx, cmd->cmd))
269 silc_server_command_free(ctx);
272 /* Allocate Command Context */
274 SilcServerCommandContext silc_server_command_alloc()
276 SilcServerCommandContext ctx = silc_calloc(1, sizeof(*ctx));
281 /* Free's the command context allocated before executing the command */
283 void silc_server_command_free(SilcServerCommandContext ctx)
286 SILC_LOG_DEBUG(("Command context %p refcnt %d->%d", ctx, ctx->users + 1,
288 if (ctx->users < 1) {
290 silc_command_payload_free(ctx->payload);
292 silc_packet_context_free(ctx->packet);
294 silc_socket_free(ctx->sock); /* Decrease reference counter */
299 /* Duplicate Command Context by adding reference counter. The context won't
300 be free'd untill it hits zero. */
302 SilcServerCommandContext
303 silc_server_command_dup(SilcServerCommandContext ctx)
306 SILC_LOG_DEBUG(("Command context %p refcnt %d->%d", ctx, ctx->users - 1,
311 /* Add new pending command to be executed when reply to a command has been
312 received. The `reply_cmd' is the command that will call the `callback'
313 with `context' when reply has been received. It can be SILC_COMMAND_NONE
314 to match any command with the `ident'. If `ident' is non-zero
315 the `callback' will be executed when received reply with command
316 identifier `ident'. If there already exists pending command for the
317 specified command, ident, callback and context this function has no
320 bool silc_server_command_pending(SilcServer server,
321 SilcCommand reply_cmd,
323 SilcCommandCb callback,
326 SilcServerCommandPending *reply;
328 /* Check whether identical pending already exists for same command,
329 ident, callback and callback context. If it does then it would be
330 error to register it again. */
331 silc_dlist_start(server->pending_commands);
332 while ((reply = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
333 if (reply->reply_cmd == reply_cmd && reply->ident == ident &&
334 reply->callback == callback && reply->context == context)
338 reply = silc_calloc(1, sizeof(*reply));
339 reply->reply_cmd = reply_cmd;
340 reply->ident = ident;
341 reply->context = context;
342 reply->callback = callback;
343 silc_dlist_add(server->pending_commands, reply);
348 /* Deletes pending command by reply command type. */
350 void silc_server_command_pending_del(SilcServer server,
351 SilcCommand reply_cmd,
354 SilcServerCommandPending *r;
356 silc_dlist_start(server->pending_commands);
357 while ((r = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
358 if (r->reply_cmd == reply_cmd && r->ident == ident) {
359 silc_dlist_del(server->pending_commands, r);
365 /* Checks for pending commands and marks callbacks to be called from
366 the command reply function. Returns TRUE if there were pending command. */
368 SilcServerCommandPendingCallbacks
369 silc_server_command_pending_check(SilcServer server,
370 SilcServerCommandReplyContext ctx,
373 SilcUInt32 *callbacks_count)
375 SilcServerCommandPending *r;
376 SilcServerCommandPendingCallbacks callbacks = NULL;
379 silc_dlist_start(server->pending_commands);
380 while ((r = silc_dlist_get(server->pending_commands)) != SILC_LIST_END) {
381 if ((r->reply_cmd == command || r->reply_cmd == SILC_COMMAND_NONE)
382 && r->ident == ident) {
383 callbacks = silc_realloc(callbacks, sizeof(*callbacks) * (i + 1));
384 callbacks[i].context = r->context;
385 callbacks[i].callback = r->callback;
391 *callbacks_count = i;
395 /* Sends simple status message as command reply packet */
398 silc_server_command_send_status_reply(SilcServerCommandContext cmd,
405 SILC_LOG_DEBUG(("Sending command status %d", status));
408 silc_command_reply_payload_encode_va(command, status, error,
409 silc_command_get_ident(cmd->payload),
411 silc_server_packet_send(cmd->server, cmd->sock,
412 SILC_PACKET_COMMAND_REPLY, 0,
413 buffer->data, buffer->len, FALSE);
414 silc_buffer_free(buffer);
417 /* Sends command status reply with one extra argument. The argument
418 type must be sent as argument. */
421 silc_server_command_send_status_data(SilcServerCommandContext cmd,
426 const unsigned char *arg,
431 SILC_LOG_DEBUG(("Sending command status %d", status));
434 silc_command_reply_payload_encode_va(command, status, 0,
435 silc_command_get_ident(cmd->payload),
436 1, arg_type, arg, arg_len);
437 silc_server_packet_send(cmd->server, cmd->sock,
438 SILC_PACKET_COMMAND_REPLY, 0,
439 buffer->data, buffer->len, FALSE);
440 silc_buffer_free(buffer);
443 /* This function can be called to check whether in the command reply
444 an error occurred. This function has no effect if this is called
445 when the command function was not called as pending command callback.
446 This returns TRUE if error had occurred. */
449 silc_server_command_pending_error_check(SilcServerCommandContext cmd,
450 SilcServerCommandReplyContext cmdr,
453 if (!cmd->pending || !cmdr)
456 if (!silc_command_get_status(cmdr->payload, NULL, NULL)) {
459 /* Send the same command reply payload */
460 silc_command_set_ident(cmdr->payload,
461 silc_command_get_ident(cmd->payload));
462 buffer = silc_command_payload_encode_payload(cmdr->payload);
463 silc_server_packet_send(cmd->server, cmd->sock,
464 SILC_PACKET_COMMAND_REPLY, 0,
465 buffer->data, buffer->len, FALSE);
466 silc_buffer_free(buffer);
473 /******************************************************************************
477 ******************************************************************************/
486 #define ADD_ERROR(errptr, errptr_count, _id, _id_type, _index, _status) \
488 errptr = silc_realloc(errptr, sizeof(*errptr) * (errptr_count + 1)); \
491 errptr[errptr_count].id = _id; \
492 errptr[errptr_count].id_type = _id_type; \
493 errptr[errptr_count].index = _index; \
494 errptr[errptr_count].error = _status; \
499 silc_server_command_whois_parse(SilcServerCommandContext cmd,
500 SilcClientID ***client_id,
501 SilcUInt32 *client_id_count,
505 ResolveError *error_client,
506 SilcUInt32 *error_client_count)
510 SilcUInt32 argc = silc_argument_get_arg_num(cmd->args);
514 /* If client ID is in the command it must be used instead of nickname */
515 tmp = silc_argument_get_arg_type(cmd->args, 4, &len);
517 /* No ID, get the nickname@server string and parse it. */
518 tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
520 silc_parse_userfqdn(tmp, nickname, server_name);
522 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WHOIS,
523 SILC_STATUS_ERR_BAD_NICKNAME, 0);
527 /* Command includes ID, we must use that. Take all ID's from the
529 for (k = 0, i = 0; i < argc; i++) {
530 tmp = silc_argument_get_arg_type(cmd->args, i + 4, &len);
533 id = silc_id_payload_parse_id(tmp, len, NULL);
535 *client_id = silc_realloc(*client_id, sizeof(**client_id) *
536 (*client_id_count + 1));
537 (*client_id)[k] = id;
538 (*client_id_count)++;
541 ADD_ERROR((*error_client), (*error_client_count), NULL, 0, i + 4,
542 SILC_STATUS_ERR_BAD_CLIENT_ID);
547 /* Get the max count of reply messages allowed */
548 tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
550 SILC_GET32_MSB(*count, tmp);
557 /* Resolve context used by both WHOIS and IDENTIFY commands */
559 SilcServerEntry router;
561 unsigned char **res_argv;
562 SilcUInt32 *res_argv_lens;
563 SilcUInt32 *res_argv_types;
565 } *SilcServerResolveContext;
568 silc_server_command_whois_check(SilcServerCommandContext cmd,
569 SilcClientEntry *clients,
570 SilcUInt32 clients_count)
572 SilcServer server = cmd->server;
573 SilcClientEntry entry;
574 SilcServerResolveContext resolve = NULL, r = NULL;
575 SilcUInt32 resolve_count = 0;
579 SILC_LOG_DEBUG(("Start"));
581 for (i = 0; i < clients_count; i++) {
586 if ((entry->nickname && entry->username && entry->userinfo) ||
587 !(entry->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
591 /* If we are normal server, and we've not resolved this client from
592 router and it is global client, we'll check whether it is on some
593 channel. If not then we cannot be sure about its validity, and
594 we'll resolve it from router. */
595 if (cmd->server->server_type != SILC_SERVER || cmd->pending ||
596 entry->connection || silc_hash_table_count(entry->channels))
600 /* We need to resolve this entry since it is not complete */
602 if (!cmd->pending && entry->data.status & SILC_IDLIST_STATUS_RESOLVING) {
603 /* The entry is being resolved (and we are not the resolver) so attach
604 to the command reply and we're done with this one. */
605 silc_server_command_pending(server, SILC_COMMAND_NONE,
606 entry->resolve_cmd_ident,
607 silc_server_command_whois,
608 silc_server_command_dup(cmd));
611 if (entry->data.status & SILC_IDLIST_STATUS_RESOLVING) {
612 /* We've resolved this and it still is not ready. We'll return
613 and are that this will be handled again after it is resolved. */
614 for (i = 0; i < resolve_count; i++) {
615 for (k = 0; k < r->res_argc; k++)
616 silc_free(r->res_argv[k]);
617 silc_free(r->res_argv);
618 silc_free(r->res_argv_lens);
619 silc_free(r->res_argv_types);
624 /* We'll resolve this client */
628 for (k = 0; k < resolve_count; k++) {
629 if (resolve[k].router == entry->router) {
636 resolve = silc_realloc(resolve, sizeof(*resolve) *
637 (resolve_count + 1));
638 r = &resolve[resolve_count];
639 memset(r, 0, sizeof(*r));
640 r->router = entry->router;
641 r->ident = ++server->cmd_ident;
645 r->res_argv = silc_realloc(r->res_argv, sizeof(*r->res_argv) *
647 r->res_argv_lens = silc_realloc(r->res_argv_lens,
648 sizeof(*r->res_argv_lens) *
650 r->res_argv_types = silc_realloc(r->res_argv_types,
651 sizeof(*r->res_argv_types) *
653 idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
654 r->res_argv[r->res_argc] = silc_calloc(idp->len,
655 sizeof(**r->res_argv));
656 memcpy(r->res_argv[r->res_argc], idp->data, idp->len);
657 r->res_argv_lens[r->res_argc] = idp->len;
658 r->res_argv_types[r->res_argc] = r->res_argc + 4;
660 silc_buffer_free(idp);
662 entry->resolve_cmd_ident = r->ident;
663 entry->data.status |= SILC_IDLIST_STATUS_RESOLVING;
664 entry->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
669 /* Do the resolving */
670 for (i = 0; i < resolve_count; i++) {
675 /* Send WHOIS request. We send WHOIS since we're doing the requesting
676 now anyway so make it a good one. */
677 res_cmd = silc_command_payload_encode(SILC_COMMAND_WHOIS,
678 r->res_argc, r->res_argv,
682 silc_server_packet_send(server, r->router->connection,
683 SILC_PACKET_COMMAND, cmd->packet->flags,
684 res_cmd->data, res_cmd->len, FALSE);
686 /* Reprocess this packet after received reply */
687 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
689 silc_server_command_whois,
690 silc_server_command_dup(cmd));
693 silc_buffer_free(res_cmd);
694 for (k = 0; k < r->res_argc; k++)
695 silc_free(r->res_argv[k]);
696 silc_free(r->res_argv);
697 silc_free(r->res_argv_lens);
698 silc_free(r->res_argv_types);
707 silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
708 SilcClientEntry *clients,
709 SilcUInt32 clients_count,
711 SilcUInt32 errors_count,
712 int count, const char *nickname,
713 SilcClientID **client_ids)
715 SilcServer server = cmd->server;
717 int i, k, valid_count = clients_count;
719 SilcBuffer packet, idp, channels, umode_list = NULL;
720 SilcClientEntry entry;
722 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
723 char nh[256], uh[256];
724 unsigned char idle[4], mode[4];
725 unsigned char *fingerprint;
726 SilcSocketConnection hsock;
729 /* Process only valid clients and ignore those that are not registered.
730 This is checked with nickname only because when resolved client IDs
731 we check that they are registered earlier. */
733 for (i = 0; i < clients_count; i++)
734 if (clients[i]->data.status & SILC_IDLIST_STATUS_REGISTERED)
740 silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
741 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
742 3, nickname, strlen(nickname));
747 /* Start processing found clients. */
748 status = SILC_STATUS_OK;
750 status = SILC_STATUS_LIST_START;
752 for (i = 0, k = 0; i < clients_count; i++) {
758 status = SILC_STATUS_LIST_ITEM;
759 if (valid_count > 1 && k == valid_count - 1 && !errors_count)
760 status = SILC_STATUS_LIST_END;
761 if (count && k - 1 == count)
762 status = SILC_STATUS_LIST_END;
764 /* Send WHOIS reply */
765 idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
766 tmp = silc_argument_get_first_arg(cmd->args, NULL);
768 memset(uh, 0, sizeof(uh));
769 memset(nh, 0, sizeof(nh));
770 memset(idle, 0, sizeof(idle));
772 strncat(nh, entry->nickname, strlen(entry->nickname));
773 if (!strchr(entry->nickname, '@')) {
775 if (entry->servername) {
776 strncat(nh, entry->servername, strlen(entry->servername));
778 len = entry->router ? strlen(entry->router->server_name) :
779 strlen(server->server_name);
780 strncat(nh, entry->router ? entry->router->server_name :
781 server->server_name, len);
785 strncat(uh, entry->username, strlen(entry->username));
786 if (!strchr(entry->username, '@') && entry->connection) {
788 hsock = (SilcSocketConnection)entry->connection;
789 len = strlen(hsock->hostname);
790 strncat(uh, hsock->hostname, len);
793 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT)
794 channels = silc_server_get_client_channel_list(server, entry, FALSE,
797 channels = silc_server_get_client_channel_list(server, entry, TRUE,
800 if (entry->data.fingerprint[0] != 0 && entry->data.fingerprint[1] != 0)
801 fingerprint = entry->data.fingerprint;
805 SILC_PUT32_MSB(entry->mode, mode);
806 if (entry->connection)
807 SILC_PUT32_MSB((time(NULL) - entry->data.last_receive), idle);
810 silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
812 2, idp->data, idp->len,
816 strlen(entry->userinfo),
817 6, channels ? channels->data : NULL,
818 channels ? channels->len : 0,
822 fingerprint ? 20 : 0,
823 10, umode_list ? umode_list->data :
824 NULL, umode_list ? umode_list->len :
827 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
828 0, packet->data, packet->len, FALSE);
830 silc_buffer_free(packet);
831 silc_buffer_free(idp);
833 silc_buffer_free(channels);
835 silc_buffer_free(umode_list);
839 if (status == SILC_STATUS_LIST_END)
844 /* Send error replies */
845 if (status == SILC_STATUS_OK && errors_count > 1)
846 status = SILC_STATUS_LIST_START;
849 for (i = 0, k = 0; i < errors_count; i++) {
851 idp = silc_id_payload_encode(errors[i].id, SILC_ID_CLIENT);
855 tmp = silc_argument_get_arg_type(cmd->args, errors[i].index, &len);
859 status = SILC_STATUS_LIST_ITEM;
860 if (errors_count > 1 && k == errors_count - 1)
861 status = SILC_STATUS_LIST_END;
862 if (count && k - 1 == count)
863 status = SILC_STATUS_LIST_END;
866 silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
867 (status == SILC_STATUS_OK ?
868 errors[i].error : status),
869 (status == SILC_STATUS_OK ?
870 0 : errors[i].error),
872 silc_buffer_free(idp);
875 if (status == SILC_STATUS_LIST_END)
882 silc_server_command_whois_send_router(SilcServerCommandContext cmd)
884 SilcServer server = cmd->server;
886 SilcUInt16 old_ident;
888 old_ident = silc_command_get_ident(cmd->payload);
889 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
890 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
892 /* Send WHOIS command to our router */
893 silc_server_packet_send(server, (SilcSocketConnection)
894 server->router->connection,
895 SILC_PACKET_COMMAND, cmd->packet->flags,
896 tmpbuf->data, tmpbuf->len, TRUE);
898 /* Reprocess this packet after received reply from router */
899 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
900 silc_command_get_ident(cmd->payload),
901 silc_server_command_whois,
902 silc_server_command_dup(cmd));
904 silc_command_set_ident(cmd->payload, old_ident);
905 silc_buffer_free(tmpbuf);
909 silc_server_command_whois_process(SilcServerCommandContext cmd)
911 SilcServer server = cmd->server;
912 char *nick = NULL, *server_name = NULL;
914 SilcClientEntry *clients = NULL, entry;
915 SilcClientID **client_id = NULL;
916 SilcUInt32 client_id_count = 0, clients_count = 0, error_client_count = 0;
917 ResolveError error_client = NULL;
919 bool check_global = FALSE;
921 /* Parse the whois request */
922 if (!silc_server_command_whois_parse(cmd, &client_id, &client_id_count,
923 &nick, &server_name, &count,
924 &error_client, &error_client_count))
927 /* Send the WHOIS request to the router only if it included nickname.
928 Since nicknames can be expanded into many clients we need to send it
929 to router. If the WHOIS included only client ID's we will check them
930 first locally since we just might have them. */
931 if (nick && !client_id_count && cmd->sock->type == SILC_SOCKET_TYPE_CLIENT &&
932 server->server_type == SILC_SERVER && !cmd->pending &&
933 !server->standalone) {
934 silc_server_command_whois_send_router(cmd);
939 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT)
941 else if (server->server_type != SILC_SERVER)
944 /* Get all clients matching that ID or nickname from local list */
945 if (client_id_count) {
946 /* Check all Client ID's received in the command packet */
947 for (i = 0; i < client_id_count; i++) {
948 entry = silc_idlist_find_client_by_id(server->local_list,
949 client_id[i], TRUE, NULL);
950 if (!entry && check_global)
951 entry = silc_idlist_find_client_by_id(server->global_list,
952 client_id[i], TRUE, NULL);
954 clients = silc_realloc(clients, sizeof(*clients) *
955 (clients_count + 1));
956 clients[clients_count++] = entry;
958 /* If we are normal server and did not send the request first to router
959 do it now, since we do not have the Client ID information. */
960 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT &&
961 server->server_type == SILC_SERVER && !cmd->pending &&
962 !server->standalone) {
963 silc_server_command_whois_send_router(cmd);
968 ADD_ERROR(error_client, error_client_count, client_id[i],
969 SILC_ID_CLIENT, 0, SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
973 /* Find by nickname */
974 if (!silc_idlist_get_clients_by_hash(server->local_list,
975 nick, server->md5hash,
976 &clients, &clients_count))
977 silc_idlist_get_clients_by_nickname(server->local_list,
979 &clients, &clients_count);
981 if (!silc_idlist_get_clients_by_hash(server->global_list,
982 nick, server->md5hash,
983 &clients, &clients_count))
984 silc_idlist_get_clients_by_nickname(server->global_list,
986 &clients, &clients_count);
990 if (!clients && (client_id_count || nick)) {
991 /* If we are normal server and did not send the request first to router
992 do it now, since we do not have the information. */
993 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT &&
994 server->server_type == SILC_SERVER && !cmd->pending &&
995 !server->standalone) {
996 silc_server_command_whois_send_router(cmd);
1001 /* Such client(s) really does not exist in the SILC network. */
1002 if (!client_id_count)
1003 silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
1004 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
1005 3, nick, strlen(nick));
1007 silc_server_command_whois_send_reply(cmd, NULL, 0,
1008 error_client, error_client_count,
1013 /* Router always finds the client entry if it exists in the SILC network.
1014 However, it might be incomplete entry and does not include all the
1015 mandatory fields that WHOIS command reply requires. Check for these and
1016 make query from the server who owns the client if some fields are
1018 if (!silc_server_command_whois_check(cmd, clients, clients_count)) {
1023 /* Send the command reply */
1024 silc_server_command_whois_send_reply(cmd, clients, clients_count,
1025 error_client, error_client_count,
1026 count, nick, client_id);
1029 if (client_id_count) {
1030 for (i = 0; i < client_id_count; i++)
1031 silc_free(client_id[i]);
1032 silc_free(client_id);
1035 silc_free(error_client);
1037 silc_free(server_name);
1042 /* Server side of command WHOIS. Processes user's query and sends found
1043 results as command replies back to the client. */
1045 SILC_SERVER_CMD_FUNC(whois)
1047 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1050 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WHOIS, cmd, 1, 3328);
1052 ret = silc_server_command_whois_process(cmd);
1053 silc_server_command_free(cmd);
1056 /******************************************************************************
1060 ******************************************************************************/
1063 silc_server_command_whowas_parse(SilcServerCommandContext cmd,
1071 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
1073 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WHOWAS,
1074 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1079 /* Get the nickname@server string and parse it. */
1080 silc_parse_userfqdn(tmp, nickname, server_name);
1082 /* Get the max count of reply messages allowed */
1083 tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
1085 SILC_GET32_MSB(*count, tmp);
1093 silc_server_command_whowas_check(SilcServerCommandContext cmd,
1094 SilcClientEntry *clients,
1095 SilcUInt32 clients_count)
1097 SilcServer server = cmd->server;
1099 SilcClientEntry entry;
1101 for (i = 0; i < clients_count; i++) {
1104 if (!entry->nickname || !entry->username) {
1106 SilcUInt16 old_ident;
1111 old_ident = silc_command_get_ident(cmd->payload);
1112 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1113 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1115 /* Send WHOWAS command */
1116 silc_server_packet_send(server, entry->router->connection,
1117 SILC_PACKET_COMMAND, cmd->packet->flags,
1118 tmpbuf->data, tmpbuf->len, TRUE);
1120 /* Reprocess this packet after received reply */
1121 silc_server_command_pending(server, SILC_COMMAND_WHOWAS,
1122 silc_command_get_ident(cmd->payload),
1123 silc_server_command_whowas,
1124 silc_server_command_dup(cmd));
1125 cmd->pending = TRUE;
1126 silc_command_set_ident(cmd->payload, old_ident);
1128 silc_buffer_free(tmpbuf);
1137 silc_server_command_whowas_send_reply(SilcServerCommandContext cmd,
1138 SilcClientEntry *clients,
1139 SilcUInt32 clients_count)
1141 SilcServer server = cmd->server;
1143 int i, k, count = 0, len;
1144 SilcBuffer packet, idp;
1145 SilcClientEntry entry = NULL;
1147 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1148 char nh[256], uh[256];
1151 status = SILC_STATUS_OK;
1153 /* Process only entries that are not registered anymore. */
1155 for (i = 0; i < clients_count; i++) {
1156 if (clients[i]->data.status & SILC_IDLIST_STATUS_REGISTERED)
1163 /* No valid entries found at all, just send error */
1164 tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
1165 silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOWAS,
1166 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
1167 3, tmp, tmp ? strlen(tmp) : 0);
1171 if (valid_count > 1)
1172 status = SILC_STATUS_LIST_START;
1174 for (i = 0, k = 0; i < clients_count; i++) {
1180 status = SILC_STATUS_LIST_ITEM;
1181 if (valid_count > 1 && k == valid_count - 1)
1182 status = SILC_STATUS_LIST_END;
1183 if (count && k - 1 == count)
1184 status = SILC_STATUS_LIST_END;
1186 /* Send WHOWAS reply */
1187 idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
1188 tmp = silc_argument_get_first_arg(cmd->args, NULL);
1189 memset(uh, 0, sizeof(uh));
1190 memset(nh, 0, sizeof(nh));
1192 strncat(nh, entry->nickname, strlen(entry->nickname));
1193 if (!strchr(entry->nickname, '@')) {
1194 strncat(nh, "@", 1);
1195 if (entry->servername) {
1196 strncat(nh, entry->servername, strlen(entry->servername));
1198 len = entry->router ? strlen(entry->router->server_name) :
1199 strlen(server->server_name);
1200 strncat(nh, entry->router ? entry->router->server_name :
1201 server->server_name, len);
1205 strncat(uh, entry->username, strlen(entry->username));
1206 if (!strchr(entry->username, '@')) {
1207 strncat(uh, "@", 1);
1208 strcat(uh, "*private*");
1212 silc_command_reply_payload_encode_va(SILC_COMMAND_WHOWAS,
1213 status, 0, ident, 4,
1214 2, idp->data, idp->len,
1219 strlen(entry->userinfo) : 0);
1220 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
1221 0, packet->data, packet->len, FALSE);
1223 silc_buffer_free(packet);
1224 silc_buffer_free(idp);
1226 if (status == SILC_STATUS_LIST_END)
1233 silc_server_command_whowas_process(SilcServerCommandContext cmd)
1235 SilcServer server = cmd->server;
1236 char *nick = NULL, *server_name = NULL;
1238 SilcClientEntry *clients = NULL;
1239 SilcUInt32 clients_count = 0;
1241 bool check_global = FALSE;
1243 /* Protocol dictates that we must always send the received WHOWAS request
1244 to our router if we are normal server, so let's do it now unless we
1245 are standalone. We will not send any replies to the client until we
1246 have received reply from the router. */
1247 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT &&
1248 server->server_type == SILC_SERVER && !cmd->pending &&
1249 !server->standalone) {
1251 SilcUInt16 old_ident;
1253 old_ident = silc_command_get_ident(cmd->payload);
1254 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1255 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1257 /* Send WHOWAS command to our router */
1258 silc_server_packet_send(server, (SilcSocketConnection)
1259 server->router->connection,
1260 SILC_PACKET_COMMAND, cmd->packet->flags,
1261 tmpbuf->data, tmpbuf->len, TRUE);
1263 /* Reprocess this packet after received reply from router */
1264 silc_server_command_pending(server, SILC_COMMAND_WHOWAS,
1265 silc_command_get_ident(cmd->payload),
1266 silc_server_command_whowas,
1267 silc_server_command_dup(cmd));
1268 cmd->pending = TRUE;
1269 silc_command_set_ident(cmd->payload, old_ident);
1271 silc_buffer_free(tmpbuf);
1276 /* We are ready to process the command request. Let's search for the
1277 requested client and send reply to the requesting client. */
1279 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT)
1280 check_global = TRUE;
1281 else if (server->server_type != SILC_SERVER)
1282 check_global = TRUE;
1284 /* Parse the whowas request */
1285 if (!silc_server_command_whowas_parse(cmd, &nick, &server_name, &count))
1288 /* Get all clients matching that nickname from local list */
1289 if (!silc_idlist_get_clients_by_nickname(server->local_list,
1291 &clients, &clients_count))
1292 silc_idlist_get_clients_by_hash(server->local_list,
1293 nick, server->md5hash,
1294 &clients, &clients_count);
1296 /* Check global list as well */
1298 if (!silc_idlist_get_clients_by_nickname(server->global_list,
1300 &clients, &clients_count))
1301 silc_idlist_get_clients_by_hash(server->global_list,
1302 nick, server->md5hash,
1303 &clients, &clients_count);
1307 /* Such a client really does not exist in the SILC network. */
1308 silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOWAS,
1309 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
1310 3, nick, strlen(nick));
1314 if (!silc_server_command_whowas_check(cmd, clients, clients_count)) {
1319 /* Send the command reply to the client */
1320 silc_server_command_whowas_send_reply(cmd, clients, clients_count);
1325 silc_free(server_name);
1329 /* Server side of command WHOWAS. */
1331 SILC_SERVER_CMD_FUNC(whowas)
1333 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
1336 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WHOWAS, cmd, 1, 2);
1338 ret = silc_server_command_whowas_process(cmd);
1339 silc_server_command_free(cmd);
1342 /******************************************************************************
1346 ******************************************************************************/
1349 silc_server_command_identify_send_router(SilcServerCommandContext cmd)
1351 SilcServer server = cmd->server;
1353 SilcUInt16 old_ident;
1355 old_ident = silc_command_get_ident(cmd->payload);
1356 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
1357 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
1359 /* Send IDENTIFY command to our router */
1360 silc_server_packet_send(server, (SilcSocketConnection)
1361 server->router->connection,
1362 SILC_PACKET_COMMAND, cmd->packet->flags,
1363 tmpbuf->data, tmpbuf->len, TRUE);
1365 /* Reprocess this packet after received reply from router */
1366 silc_server_command_pending(server, SILC_COMMAND_IDENTIFY,
1367 silc_command_get_ident(cmd->payload),
1368 silc_server_command_identify,
1369 silc_server_command_dup(cmd));
1370 cmd->pending = TRUE;
1371 silc_command_set_ident(cmd->payload, old_ident);
1372 silc_buffer_free(tmpbuf);
1376 silc_server_command_identify_parse(SilcServerCommandContext cmd,
1377 SilcClientEntry **clients,
1378 SilcUInt32 *clients_count,
1379 SilcServerEntry **servers,
1380 SilcUInt32 *servers_count,
1381 SilcChannelEntry **channels,
1382 SilcUInt32 *channels_count,
1384 ResolveError *error_id,
1385 SilcUInt32 *error_id_count)
1387 SilcServer server = cmd->server;
1390 SilcUInt32 argc = silc_argument_get_arg_num(cmd->args);
1392 bool check_global = FALSE;
1396 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT)
1397 check_global = TRUE;
1398 else if (server->server_type != SILC_SERVER)
1399 check_global = TRUE;
1401 /* If ID Payload is in the command it must be used instead of names */
1402 tmp = silc_argument_get_arg_type(cmd->args, 5, &len);
1404 /* No ID, get the names. */
1406 /* If we are normal server and have not resolved information from
1407 router yet, do so now. */
1408 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT &&
1409 server->server_type == SILC_SERVER && !cmd->pending &&
1410 !server->standalone) {
1411 silc_server_command_identify_send_router(cmd);
1415 /* Try to get nickname@server. */
1416 tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
1419 char *nick_server = NULL;
1421 silc_parse_userfqdn(tmp, &nick, &nick_server);
1423 if (!silc_idlist_get_clients_by_hash(server->local_list,
1424 nick, server->md5hash,
1425 clients, clients_count))
1426 silc_idlist_get_clients_by_nickname(server->local_list,
1428 clients, clients_count);
1430 if (!silc_idlist_get_clients_by_hash(server->global_list,
1431 nick, server->md5hash,
1432 clients, clients_count))
1433 silc_idlist_get_clients_by_nickname(server->global_list,
1435 clients, clients_count);
1439 silc_free(nick_server);
1442 /* the nickname does not exist, send error reply */
1443 silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
1444 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
1445 3, tmp, strlen(tmp));
1450 /* Try to get server name */
1451 tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
1453 entry = silc_idlist_find_server_by_name(server->local_list,
1455 if (!entry && check_global)
1456 entry = silc_idlist_find_server_by_name(server->global_list,
1459 *servers = silc_realloc(*servers, sizeof(**servers) *
1460 (*servers_count + 1));
1461 (*servers)[(*servers_count)++] = entry;
1465 /* the server does not exist, send error reply */
1466 silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
1467 SILC_STATUS_ERR_NO_SUCH_SERVER,
1468 0, 3, tmp, strlen(tmp));
1473 /* Try to get channel name */
1474 tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
1476 entry = silc_idlist_find_channel_by_name(server->local_list,
1478 if (!entry && check_global)
1479 entry = silc_idlist_find_channel_by_name(server->global_list,
1482 *channels = silc_realloc(*channels, sizeof(**channels) *
1483 (*channels_count + 1));
1484 (*channels)[(*channels_count)++] = entry;
1488 /* The channel does not exist, send error reply */
1489 silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
1490 SILC_STATUS_ERR_NO_SUCH_CHANNEL,
1491 0, 3, tmp, strlen(tmp));
1496 if (!(*clients) && !(*servers) && !(*channels)) {
1497 silc_server_command_send_status_reply(cmd, SILC_COMMAND_IDENTIFY,
1498 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
1503 /* Command includes ID, we must use that. Also check whether the command
1504 has more than one ID set - take them all. */
1506 /* Take all ID's from the command packet */
1507 for (i = 0; i < argc; i++) {
1510 tmp = silc_argument_get_arg_type(cmd->args, i + 5, &len);
1514 idp = silc_id_payload_parse(tmp, len);
1516 ADD_ERROR((*error_id), (*error_id_count), NULL, 0, i + 5,
1517 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
1519 id = silc_id_payload_get_id(idp);
1520 switch (silc_id_payload_get_type(idp)) {
1522 case SILC_ID_CLIENT:
1523 entry = silc_idlist_find_client_by_id(server->local_list,
1525 if (!entry && check_global)
1526 entry = silc_idlist_find_client_by_id(server->global_list,
1529 *clients = silc_realloc(*clients, sizeof(**clients) *
1530 (*clients_count + 1));
1531 (*clients)[(*clients_count)++] = (SilcClientEntry)entry;
1533 /* If we are normal server and have not resolved information from
1534 router yet, do so now. */
1535 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT &&
1536 server->server_type == SILC_SERVER && !cmd->pending &&
1537 !server->standalone) {
1538 silc_server_command_identify_send_router(cmd);
1539 silc_free(*clients);
1540 silc_free(*servers);
1541 silc_free(*channels);
1542 silc_free(*error_id);
1546 ADD_ERROR((*error_id), (*error_id_count), NULL, 0, i + 5,
1547 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
1552 case SILC_ID_SERVER:
1553 entry = silc_idlist_find_server_by_id(server->local_list,
1555 if (!entry && check_global)
1556 entry = silc_idlist_find_server_by_id(server->global_list,
1559 *servers = silc_realloc(*servers, sizeof(**servers) *
1560 (*servers_count + 1));
1561 (*servers)[(*servers_count)++] = (SilcServerEntry)entry;
1563 /* If we are normal server and have not resolved information from
1564 router yet, do so now. */
1565 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT &&
1566 server->server_type == SILC_SERVER && !cmd->pending &&
1567 !server->standalone) {
1568 silc_server_command_identify_send_router(cmd);
1569 silc_free(*clients);
1570 silc_free(*servers);
1571 silc_free(*channels);
1572 silc_free(*error_id);
1576 ADD_ERROR((*error_id), (*error_id_count), NULL, 0, i + 5,
1577 SILC_STATUS_ERR_NO_SUCH_SERVER_ID);
1581 case SILC_ID_CHANNEL:
1582 entry = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1583 if (!entry && check_global)
1584 entry = silc_idlist_find_channel_by_id(server->global_list, id,
1587 *channels = silc_realloc(*channels, sizeof(**channels) *
1588 (*channels_count + 1));
1589 (*channels)[(*channels_count)++] = (SilcChannelEntry)entry;
1591 /* If we are normal server and have not resolved information from
1592 router yet, do so now. */
1593 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT &&
1594 server->server_type == SILC_SERVER && !cmd->pending &&
1595 !server->standalone) {
1596 silc_server_command_identify_send_router(cmd);
1597 silc_free(*clients);
1598 silc_free(*servers);
1599 silc_free(*channels);
1600 silc_free(*error_id);
1604 ADD_ERROR((*error_id), (*error_id_count), NULL, 0, i + 5,
1605 SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID);
1614 /* Get the max count of reply messages allowed */
1615 tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
1617 SILC_GET32_MSB(*count, tmp);
1624 /* Checks that all mandatory fields in client entry are present. If not
1625 then send WHOIS request to the server who owns the client. We use
1626 WHOIS because we want to get as much information as possible at once. */
1629 silc_server_command_identify_check_client(SilcServerCommandContext cmd,
1630 SilcClientEntry *clients,
1631 SilcUInt32 clients_count)
1633 SilcServer server = cmd->server;
1634 SilcClientEntry entry;
1635 SilcServerResolveContext resolve = NULL, r = NULL;
1636 SilcUInt32 resolve_count = 0;
1640 for (i = 0; i < clients_count; i++) {
1645 if (entry->nickname ||
1646 !(entry->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
1650 /* If we are normal server, and we've not resolved this client from
1651 router and it is global client, we'll check whether it is on some
1652 channel. If not then we cannot be sure about its validity, and
1653 we'll resolve it from router. */
1654 if (cmd->server->server_type != SILC_SERVER || cmd->pending ||
1655 entry->connection || silc_hash_table_count(entry->channels))
1659 /* We need to resolve this entry since it is not complete */
1661 if (!cmd->pending && entry->data.status & SILC_IDLIST_STATUS_RESOLVING) {
1662 /* The entry is being resolved (and we are not the resolver) so attach
1663 to the command reply and we're done with this one. */
1664 silc_server_command_pending(server, SILC_COMMAND_NONE,
1665 entry->resolve_cmd_ident,
1666 silc_server_command_identify,
1667 silc_server_command_dup(cmd));
1670 if (entry->data.status & SILC_IDLIST_STATUS_RESOLVING) {
1671 /* We've resolved this and it still is not ready. We'll return
1672 and are that this will be handled again after it is resolved. */
1673 for (i = 0; i < resolve_count; i++) {
1674 for (k = 0; k < r->res_argc; k++)
1675 silc_free(r->res_argv[k]);
1676 silc_free(r->res_argv);
1677 silc_free(r->res_argv_lens);
1678 silc_free(r->res_argv_types);
1683 /* We'll resolve this client */
1687 for (k = 0; k < resolve_count; k++) {
1688 if (resolve[k].router == entry->router) {
1695 resolve = silc_realloc(resolve, sizeof(*resolve) *
1696 (resolve_count + 1));
1697 r = &resolve[resolve_count];
1698 memset(r, 0, sizeof(*r));
1699 r->router = entry->router;
1700 r->ident = ++server->cmd_ident;
1704 r->res_argv = silc_realloc(r->res_argv, sizeof(*r->res_argv) *
1706 r->res_argv_lens = silc_realloc(r->res_argv_lens,
1707 sizeof(*r->res_argv_lens) *
1709 r->res_argv_types = silc_realloc(r->res_argv_types,
1710 sizeof(*r->res_argv_types) *
1712 idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
1713 r->res_argv[r->res_argc] = silc_calloc(idp->len,
1714 sizeof(**r->res_argv));
1715 memcpy(r->res_argv[r->res_argc], idp->data, idp->len);
1716 r->res_argv_lens[r->res_argc] = idp->len;
1717 r->res_argv_types[r->res_argc] = r->res_argc + 4;
1719 silc_buffer_free(idp);
1721 entry->resolve_cmd_ident = r->ident;
1722 entry->data.status |= SILC_IDLIST_STATUS_RESOLVING;
1723 entry->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
1728 /* Do the resolving */
1729 for (i = 0; i < resolve_count; i++) {
1734 /* Send WHOIS request. We send WHOIS since we're doing the requesting
1735 now anyway so make it a good one. */
1736 res_cmd = silc_command_payload_encode(SILC_COMMAND_WHOIS,
1737 r->res_argc, r->res_argv,
1741 silc_server_packet_send(server, r->router->connection,
1742 SILC_PACKET_COMMAND, cmd->packet->flags,
1743 res_cmd->data, res_cmd->len, FALSE);
1745 /* Reprocess this packet after received reply */
1746 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
1748 silc_server_command_identify,
1749 silc_server_command_dup(cmd));
1750 cmd->pending = TRUE;
1752 silc_buffer_free(res_cmd);
1753 for (k = 0; k < r->res_argc; k++)
1754 silc_free(r->res_argv[k]);
1755 silc_free(r->res_argv);
1756 silc_free(r->res_argv_lens);
1757 silc_free(r->res_argv_types);
1766 silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
1767 SilcClientEntry *clients,
1768 SilcUInt32 clients_count,
1769 SilcServerEntry *servers,
1770 SilcUInt32 servers_count,
1771 SilcChannelEntry *channels,
1772 SilcUInt32 channels_count,
1773 ResolveError errors,
1774 SilcUInt32 errors_count,
1777 SilcServer server = cmd->server;
1778 int i, k, valid_count;
1780 SilcBuffer packet, idp;
1782 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
1783 char nh[256], uh[256];
1784 SilcSocketConnection hsock;
1787 status = SILC_STATUS_OK;
1790 SilcClientEntry entry;
1791 valid_count = clients_count;
1793 if (silc_argument_get_arg_type(cmd->args, 1, NULL)) {
1794 /* Process only valid clients and ignore those that are not registered.
1795 This is checked with nickname only because when resolved client IDs
1796 we check that they are registered earlier. */
1798 for (i = 0; i < clients_count; i++) {
1799 if (clients[i]->data.status & SILC_IDLIST_STATUS_REGISTERED)
1806 /* No valid entries found at all, just send error */
1807 tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
1808 silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
1809 SILC_STATUS_ERR_NO_SUCH_NICK, 0,
1810 3, tmp, tmp ? strlen(tmp) : 0);
1815 /* Process all valid client entries and send command replies */
1817 if (valid_count > 1)
1818 status = SILC_STATUS_LIST_START;
1820 for (i = 0, k = 0; i < clients_count; i++) {
1826 status = SILC_STATUS_LIST_ITEM;
1827 if (valid_count > 1 && k == valid_count - 1
1828 && !servers_count && !channels_count && !errors_count)
1829 status = SILC_STATUS_LIST_END;
1830 if (count && k - 1 == count)
1831 status = SILC_STATUS_LIST_END;
1833 /* Send IDENTIFY reply */
1835 idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
1836 memset(uh, 0, sizeof(uh));
1837 memset(nh, 0, sizeof(nh));
1838 strncat(nh, entry->nickname, strlen(entry->nickname));
1839 if (!strchr(entry->nickname, '@')) {
1840 strncat(nh, "@", 1);
1841 if (entry->servername) {
1842 strncat(nh, entry->servername, strlen(entry->servername));
1844 len = entry->router ? strlen(entry->router->server_name) :
1845 strlen(server->server_name);
1846 strncat(nh, entry->router ? entry->router->server_name :
1847 server->server_name, len);
1851 if (!entry->username) {
1852 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
1853 status, 0, ident, 2,
1854 2, idp->data, idp->len,
1857 strncat(uh, entry->username, strlen(entry->username));
1858 if (!strchr(entry->username, '@') && entry->connection) {
1859 strncat(uh, "@", 1);
1860 hsock = (SilcSocketConnection)entry->connection;
1861 len = strlen(hsock->hostname);
1862 strncat(uh, hsock->hostname, len);
1865 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
1866 status, 0, ident, 3,
1867 2, idp->data, idp->len,
1872 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
1873 0, packet->data, packet->len, FALSE);
1875 silc_buffer_free(packet);
1876 silc_buffer_free(idp);
1878 if (status == SILC_STATUS_LIST_END)
1885 SilcServerEntry entry;
1887 if (status == SILC_STATUS_OK && servers_count > 1)
1888 status = SILC_STATUS_LIST_START;
1890 for (i = 0, k = 0; i < servers_count; i++) {
1894 status = SILC_STATUS_LIST_ITEM;
1895 if (servers_count > 1 && k == servers_count - 1 && !channels_count &&
1897 status = SILC_STATUS_LIST_END;
1898 if (count && k - 1 == count)
1899 status = SILC_STATUS_LIST_END;
1901 /* Send IDENTIFY reply */
1902 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
1904 silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
1905 status, 0, ident, 2,
1906 2, idp->data, idp->len,
1907 3, entry->server_name,
1908 entry->server_name ?
1909 strlen(entry->server_name) : 0);
1910 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
1911 0, packet->data, packet->len, FALSE);
1913 silc_buffer_free(packet);
1914 silc_buffer_free(idp);
1916 if (status == SILC_STATUS_LIST_END)
1923 SilcChannelEntry entry;
1925 if (status == SILC_STATUS_OK && channels_count > 1)
1926 status = SILC_STATUS_LIST_START;
1928 for (i = 0, k = 0; i < channels_count; i++) {
1929 entry = channels[i];
1932 status = SILC_STATUS_LIST_ITEM;
1933 if (channels_count > 1 && k == channels_count - 1 && !errors_count)
1934 status = SILC_STATUS_LIST_END;
1935 if (count && k - 1 == count)
1936 status = SILC_STATUS_LIST_END;
1938 /* Send IDENTIFY reply */
1939 idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
1941 silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY,
1942 status, 0, ident, 2,
1943 2, idp->data, idp->len,
1944 3, entry->channel_name,
1945 entry->channel_name ?
1946 strlen(entry->channel_name): 0);
1947 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
1948 0, packet->data, packet->len, FALSE);
1950 silc_buffer_free(packet);
1951 silc_buffer_free(idp);
1953 if (status == SILC_STATUS_LIST_END)
1959 /* Send error replies */
1961 if (status == SILC_STATUS_OK && errors_count > 1)
1962 status = SILC_STATUS_LIST_START;
1965 for (i = 0, k = 0; i < errors_count; i++) {
1967 idp = silc_id_payload_encode(errors[i].id, SILC_ID_CLIENT);
1971 tmp = silc_argument_get_arg_type(cmd->args, errors[i].index, &len);
1975 status = SILC_STATUS_LIST_ITEM;
1976 if (errors_count > 1 && k == errors_count - 1)
1977 status = SILC_STATUS_LIST_END;
1978 if (count && k - 1 == count)
1979 status = SILC_STATUS_LIST_END;
1982 silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
1983 (status == SILC_STATUS_OK ?
1984 errors[i].error : status),
1985 (status == SILC_STATUS_OK ?
1986 0 : errors[i].error),
1988 silc_buffer_free(idp);
1991 if (status == SILC_STATUS_LIST_END)
1999 silc_server_command_identify_process(SilcServerCommandContext cmd)
2001 SilcUInt32 count = 0;
2003 SilcClientEntry *clients = NULL;
2004 SilcServerEntry *servers = NULL;
2005 SilcChannelEntry *channels = NULL;
2006 SilcUInt32 clients_count = 0, servers_count = 0, channels_count = 0;
2007 SilcUInt32 errors_count = 0;
2008 ResolveError errors = NULL;
2010 /* Parse the IDENTIFY request */
2011 ret = silc_server_command_identify_parse(cmd,
2012 &clients, &clients_count,
2013 &servers, &servers_count,
2014 &channels, &channels_count,
2015 &count, &errors, &errors_count);
2020 /* Check that all mandatory fields are present and request those data
2021 from the server who owns the client if necessary. */
2022 if (!silc_server_command_identify_check_client(cmd, clients,
2028 /* Send the command reply to the client */
2029 silc_server_command_identify_send_reply(cmd,
2030 clients, clients_count,
2031 servers, servers_count,
2032 channels, channels_count,
2033 errors, errors_count,
2039 silc_free(channels);
2044 SILC_SERVER_CMD_FUNC(identify)
2046 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2049 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_IDENTIFY, cmd, 1, 3328);
2051 ret = silc_server_command_identify_process(cmd);
2052 silc_server_command_free(cmd);
2055 /* Server side of command NICK. Sets nickname for user. Setting
2056 nickname causes generation of a new client ID for the client. The
2057 new client ID is sent to the client after changing the nickname. */
2059 SILC_SERVER_CMD_FUNC(nick)
2061 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2062 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2063 SilcServer server = cmd->server;
2064 SilcBuffer packet, nidp, oidp = NULL;
2065 SilcClientID *new_id;
2066 SilcUInt32 nick_len;
2068 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2071 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
2074 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_NICK, cmd, 1, 1);
2076 /* Check nickname */
2077 nick = silc_argument_get_arg_type(cmd->args, 1, &nick_len);
2080 if (silc_server_name_bad_chars(nick, nick_len) == TRUE) {
2081 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
2082 SILC_STATUS_ERR_BAD_NICKNAME, 0);
2086 /* Check for same nickname */
2087 if (!strcmp(client->nickname, nick)) {
2088 nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2092 /* Create new Client ID */
2093 while (!silc_id_create_client_id(cmd->server, cmd->server->id,
2095 cmd->server->md5hash, nick,
2099 silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
2100 SILC_STATUS_ERR_BAD_NICKNAME, 0);
2103 snprintf(&nick[strlen(nick) - 1], 1, "%d", nickfail);
2106 /* Send notify about nickname change to our router. We send the new
2107 ID and ask to replace it with the old one. If we are router the
2108 packet is broadcasted. Send NICK_CHANGE notify. */
2109 if (!server->standalone)
2110 silc_server_send_notify_nick_change(server, server->router->connection,
2111 server->server_type == SILC_SERVER ?
2112 FALSE : TRUE, client->id,
2115 /* Check if anyone is watching the old nickname */
2116 if (server->server_type == SILC_ROUTER)
2117 silc_server_check_watcher_list(server, client, nick,
2118 SILC_NOTIFY_TYPE_NICK_CHANGE);
2120 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2122 /* Remove old cache entry */
2123 silc_idcache_del_by_context(server->local_list->clients, client);
2125 silc_free(client->id);
2126 client->id = new_id;
2128 silc_free(client->nickname);
2129 client->nickname = strdup(nick);
2131 /* Update client cache */
2132 silc_idcache_add(server->local_list->clients, client->nickname,
2133 client->id, (void *)client, 0, NULL);
2135 nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2137 /* Send NICK_CHANGE notify to the client's channels */
2138 silc_server_send_notify_on_channels(server, NULL, client,
2139 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
2140 oidp->data, oidp->len,
2141 nidp->data, nidp->len,
2143 strlen(client->nickname));
2145 /* Check if anyone is watching the new nickname */
2146 if (server->server_type == SILC_ROUTER)
2147 silc_server_check_watcher_list(server, client, NULL,
2148 SILC_NOTIFY_TYPE_NICK_CHANGE);
2151 /* Send the new Client ID as reply command back to client */
2152 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_NICK,
2153 SILC_STATUS_OK, 0, ident, 2,
2154 2, nidp->data, nidp->len,
2155 3, nick, strlen(nick));
2156 silc_server_packet_send(cmd->server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
2157 0, packet->data, packet->len, FALSE);
2159 silc_buffer_free(packet);
2160 silc_buffer_free(nidp);
2162 silc_buffer_free(oidp);
2165 silc_server_command_free(cmd);
2168 /* Sends the LIST command reply */
2171 silc_server_command_list_send_reply(SilcServerCommandContext cmd,
2172 SilcChannelEntry *lch,
2173 SilcUInt32 lch_count,
2174 SilcChannelEntry *gch,
2175 SilcUInt32 gch_count)
2178 SilcBuffer packet, idp;
2179 SilcChannelEntry entry;
2181 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2183 unsigned char usercount[4];
2185 int valid_lcount = 0, valid_rcount = 0;
2187 for (i = 0; i < lch_count; i++) {
2188 if (lch[i]->mode & SILC_CHANNEL_MODE_SECRET)
2193 for (i = 0; i < gch_count; i++) {
2194 if (gch[i]->mode & SILC_CHANNEL_MODE_SECRET)
2200 status = SILC_STATUS_OK;
2201 if ((lch_count + gch_count) > 1)
2202 status = SILC_STATUS_LIST_START;
2205 for (i = 0, k = 0; i < lch_count; i++) {
2211 status = SILC_STATUS_LIST_ITEM;
2212 if (valid_lcount > 1 && k == valid_lcount - 1 && !valid_rcount)
2213 status = SILC_STATUS_LIST_END;
2215 idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
2217 if (entry->mode & SILC_CHANNEL_MODE_PRIVATE) {
2218 topic = "*private*";
2219 memset(usercount, 0, sizeof(usercount));
2221 topic = entry->topic;
2222 users = silc_hash_table_count(entry->user_list);
2223 SILC_PUT32_MSB(users, usercount);
2226 /* Send the reply */
2228 silc_command_reply_payload_encode_va(SILC_COMMAND_LIST,
2229 status, 0, ident, 4,
2230 2, idp->data, idp->len,
2231 3, entry->channel_name,
2232 strlen(entry->channel_name),
2233 4, topic, topic ? strlen(topic) : 0,
2235 silc_server_packet_send(cmd->server, cmd->sock,
2236 SILC_PACKET_COMMAND_REPLY, 0, packet->data,
2237 packet->len, FALSE);
2238 silc_buffer_free(packet);
2239 silc_buffer_free(idp);
2244 for (i = 0, k = 0; i < gch_count; i++) {
2250 status = SILC_STATUS_LIST_ITEM;
2251 if (valid_rcount > 1 && k == valid_rcount - 1)
2252 status = SILC_STATUS_LIST_END;
2254 idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
2256 if (entry->mode & SILC_CHANNEL_MODE_PRIVATE) {
2257 topic = "*private*";
2258 memset(usercount, 0, sizeof(usercount));
2260 topic = entry->topic;
2261 users = entry->user_count;
2262 SILC_PUT32_MSB(users, usercount);
2265 /* Send the reply */
2267 silc_command_reply_payload_encode_va(SILC_COMMAND_LIST,
2268 status, 0, ident, 4,
2269 2, idp->data, idp->len,
2270 3, entry->channel_name,
2271 strlen(entry->channel_name),
2272 4, topic, topic ? strlen(topic) : 0,
2274 silc_server_packet_send(cmd->server, cmd->sock,
2275 SILC_PACKET_COMMAND_REPLY, 0, packet->data,
2276 packet->len, FALSE);
2277 silc_buffer_free(packet);
2278 silc_buffer_free(idp);
2283 /* Server side of LIST command. This lists the channel of the requested
2284 server. Secret channels are not listed. */
2286 SILC_SERVER_CMD_FUNC(list)
2288 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2289 SilcServer server = cmd->server;
2290 SilcChannelID *channel_id = NULL;
2293 SilcChannelEntry *lchannels = NULL, *gchannels = NULL;
2294 SilcUInt32 lch_count = 0, gch_count = 0;
2296 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LIST, cmd, 0, 1);
2298 /* If we are normal server, send the command to router, since we
2299 want to know all channels in the network. */
2300 if (!cmd->pending && server->server_type == SILC_SERVER &&
2301 !server->standalone) {
2303 SilcUInt16 old_ident;
2305 old_ident = silc_command_get_ident(cmd->payload);
2306 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2307 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2308 silc_server_packet_send(server, server->router->connection,
2309 SILC_PACKET_COMMAND, cmd->packet->flags,
2310 tmpbuf->data, tmpbuf->len, TRUE);
2312 /* Reprocess this packet after received reply from router */
2313 silc_server_command_pending(server, SILC_COMMAND_LIST,
2314 silc_command_get_ident(cmd->payload),
2315 silc_server_command_list,
2316 silc_server_command_dup(cmd));
2317 cmd->pending = TRUE;
2318 silc_command_set_ident(cmd->payload, old_ident);
2319 silc_buffer_free(tmpbuf);
2323 /* Get Channel ID */
2324 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
2326 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
2328 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LIST,
2329 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2334 /* Get the channels from local list */
2335 lchannels = silc_idlist_get_channels(server->local_list, channel_id,
2338 /* Get the channels from global list */
2339 gchannels = silc_idlist_get_channels(server->global_list, channel_id,
2342 /* Send the reply */
2343 silc_server_command_list_send_reply(cmd, lchannels, lch_count,
2344 gchannels, gch_count);
2346 silc_free(lchannels);
2347 silc_free(gchannels);
2350 silc_server_command_free(cmd);
2353 /* Server side of TOPIC command. Sets topic for channel and/or returns
2354 current topic to client. */
2356 SILC_SERVER_CMD_FUNC(topic)
2358 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2359 SilcServer server = cmd->server;
2360 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2361 SilcChannelID *channel_id;
2362 SilcChannelEntry channel;
2363 SilcChannelClientEntry chl;
2364 SilcBuffer packet, idp;
2366 SilcUInt32 argc, tmp_len;
2367 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2369 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_TOPIC, cmd, 1, 2);
2371 argc = silc_argument_get_arg_num(cmd->args);
2373 /* Get Channel ID */
2374 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
2376 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
2377 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2380 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
2382 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
2383 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2387 /* Check whether the channel exists */
2388 channel = silc_idlist_find_channel_by_id(server->local_list,
2391 channel = silc_idlist_find_channel_by_id(server->global_list,
2394 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
2395 SILC_STATUS_ERR_NO_SUCH_CHANNEL,
2403 tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
2405 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
2406 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2411 if (strlen(tmp) > 256) {
2412 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
2413 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2418 /* See whether the client is on channel and has rights to change topic */
2419 if (!silc_server_client_on_channel(client, channel, &chl)) {
2420 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
2421 SILC_STATUS_ERR_NOT_ON_CHANNEL,
2426 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
2427 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
2428 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2429 silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
2430 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
2435 /* Set the topic for channel */
2436 silc_free(channel->topic);
2437 channel->topic = strdup(tmp);
2439 /* Send TOPIC_SET notify type to the network */
2440 if (!server->standalone)
2441 silc_server_send_notify_topic_set(server, server->router->connection,
2442 server->server_type == SILC_ROUTER ?
2443 TRUE : FALSE, channel,
2444 client->id, SILC_ID_CLIENT,
2447 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2449 /* Send notify about topic change to all clients on the channel */
2450 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
2451 SILC_NOTIFY_TYPE_TOPIC_SET, 2,
2452 idp->data, idp->len,
2453 channel->topic, strlen(channel->topic));
2454 silc_buffer_free(idp);
2457 /* Send the topic to client as reply packet */
2458 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
2459 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_TOPIC,
2460 SILC_STATUS_OK, 0, ident, 2,
2461 2, idp->data, idp->len,
2464 strlen(channel->topic) : 0);
2465 silc_server_packet_send(cmd->server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
2466 0, packet->data, packet->len, FALSE);
2468 silc_buffer_free(packet);
2469 silc_buffer_free(idp);
2470 silc_free(channel_id);
2473 silc_server_command_free(cmd);
2476 /* Server side of INVITE command. Invites some client to join some channel.
2477 This command is also used to manage the invite list of the channel. */
2479 SILC_SERVER_CMD_FUNC(invite)
2481 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2482 SilcServer server = cmd->server;
2483 SilcSocketConnection sock = cmd->sock, dest_sock;
2484 SilcChannelClientEntry chl;
2485 SilcClientEntry sender, dest;
2486 SilcClientID *dest_id = NULL;
2487 SilcChannelEntry channel;
2488 SilcChannelID *channel_id = NULL;
2489 SilcIDListData idata;
2490 SilcBuffer idp, idp2, packet;
2491 unsigned char *tmp, *add, *del;
2493 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2495 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INVITE, cmd, 1, 4);
2497 /* Get Channel ID */
2498 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
2500 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
2501 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2504 channel_id = silc_id_payload_parse_id(tmp, len, NULL);
2506 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
2507 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
2511 /* Get the channel entry */
2512 channel = silc_idlist_find_channel_by_id(server->local_list,
2515 channel = silc_idlist_find_channel_by_id(server->global_list,
2518 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
2519 SILC_STATUS_ERR_NO_SUCH_CHANNEL,
2525 /* Check whether the sender of this command is on the channel. */
2526 sender = (SilcClientEntry)sock->user_data;
2527 if (!silc_server_client_on_channel(sender, channel, &chl)) {
2528 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
2529 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
2533 /* Check whether the channel is invite-only channel. If yes then the
2534 sender of this command must be at least channel operator. */
2535 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
2536 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
2537 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2538 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
2539 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
2544 /* Get destination client ID */
2545 tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
2550 dest_id = silc_id_payload_parse_id(tmp, len, NULL);
2552 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
2553 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
2557 /* Get the client entry */
2558 dest = silc_server_get_client_resolve(server, dest_id, FALSE, &resolve);
2560 if (server->server_type != SILC_SERVER || !resolve) {
2561 silc_server_command_send_status_reply(
2562 cmd, SILC_COMMAND_INVITE,
2563 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0);
2567 /* The client info is being resolved. Reprocess this packet after
2568 receiving the reply to the query. */
2569 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
2571 silc_server_command_invite,
2572 silc_server_command_dup(cmd));
2573 cmd->pending = TRUE;
2574 silc_free(channel_id);
2579 /* Check whether the requested client is already on the channel. */
2580 if (silc_server_client_on_channel(dest, channel, NULL)) {
2581 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
2582 SILC_STATUS_ERR_USER_ON_CHANNEL,
2587 /* Get route to the client */
2588 dest_sock = silc_server_get_client_route(server, NULL, 0, dest_id,
2591 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
2592 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
2597 memset(invite, 0, sizeof(invite));
2598 strncat(invite, dest->nickname, strlen(dest->nickname));
2599 strncat(invite, "!", 1);
2600 strncat(invite, dest->username, strlen(dest->username));
2601 if (!strchr(dest->username, '@')) {
2602 strncat(invite, "@", 1);
2603 strncat(invite, cmd->sock->hostname, strlen(cmd->sock->hostname));
2606 len = strlen(invite);
2607 if (!channel->invite_list)
2608 channel->invite_list = silc_calloc(len + 2,
2609 sizeof(*channel->invite_list));
2611 channel->invite_list = silc_realloc(channel->invite_list,
2612 sizeof(*channel->invite_list) *
2614 strlen(channel->invite_list) + 2));
2615 strncat(channel->invite_list, invite, len);
2616 strncat(channel->invite_list, ",", 1);
2618 if (!(dest->mode & SILC_UMODE_BLOCK_INVITE)) {
2619 /* Send notify to the client that is invited to the channel */
2620 idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
2621 idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
2622 silc_server_send_notify_dest(server, dest_sock, FALSE, dest_id,
2624 SILC_NOTIFY_TYPE_INVITE, 3,
2625 idp->data, idp->len,
2626 channel->channel_name,
2627 strlen(channel->channel_name),
2628 idp2->data, idp2->len);
2629 silc_buffer_free(idp);
2630 silc_buffer_free(idp2);
2634 /* Add the client to the invite list of the channel */
2635 add = silc_argument_get_arg_type(cmd->args, 3, &len);
2637 if (!channel->invite_list)
2638 channel->invite_list = silc_calloc(len + 2,
2639 sizeof(*channel->invite_list));
2641 channel->invite_list = silc_realloc(channel->invite_list,
2642 sizeof(*channel->invite_list) *
2644 strlen(channel->invite_list) + 2));
2645 if (add[len - 1] == ',')
2646 add[len - 1] = '\0';
2648 strncat(channel->invite_list, add, len);
2649 strncat(channel->invite_list, ",", 1);
2652 /* Get the invite to be removed and remove it from the list */
2653 del = silc_argument_get_arg_type(cmd->args, 4, &len);
2654 if (del && channel->invite_list) {
2655 char *start, *end, *n;
2657 if (!strncmp(channel->invite_list, del,
2658 strlen(channel->invite_list) - 1)) {
2659 silc_free(channel->invite_list);
2660 channel->invite_list = NULL;
2662 start = strstr(channel->invite_list, del);
2663 if (start && strlen(start) >= len) {
2665 n = silc_calloc(strlen(channel->invite_list) - len, sizeof(*n));
2666 strncat(n, channel->invite_list, start - channel->invite_list);
2667 strncat(n, end + 1, ((channel->invite_list +
2668 strlen(channel->invite_list)) - end) - 1);
2669 silc_free(channel->invite_list);
2670 channel->invite_list = n;
2675 /* Send notify to the primary router */
2676 if (!server->standalone)
2677 silc_server_send_notify_invite(server, server->router->connection,
2678 server->server_type == SILC_ROUTER ?
2679 TRUE : FALSE, channel,
2680 sender->id, add, del);
2682 /* Send command reply */
2683 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
2687 silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
2688 SILC_STATUS_OK, 0, ident, 2,
2690 3, channel->invite_list,
2691 channel->invite_list ?
2692 strlen(channel->invite_list) : 0);
2695 silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
2696 SILC_STATUS_OK, 0, ident, 1,
2698 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
2699 packet->data, packet->len, FALSE);
2700 silc_buffer_free(packet);
2704 silc_free(channel_id);
2705 silc_server_command_free(cmd);
2710 SilcSocketConnection sock;
2714 /* Quits connection to client. This gets called if client won't
2715 close the connection even when it has issued QUIT command. */
2717 SILC_TASK_CALLBACK(silc_server_command_quit_cb)
2719 QuitInternal q = (QuitInternal)context;
2721 /* Free all client specific data, such as client entry and entires
2722 on channels this client may be on. */
2723 silc_server_free_client_data(q->server, q->sock, q->sock->user_data,
2725 q->sock->user_data = NULL;
2727 /* Close the connection on our side */
2728 silc_server_close_connection(q->server, q->sock);
2730 silc_free(q->signoff);
2734 /* Quits SILC session. This is the normal way to disconnect client. */
2736 SILC_SERVER_CMD_FUNC(quit)
2738 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2739 SilcServer server = cmd->server;
2740 SilcSocketConnection sock = cmd->sock;
2742 unsigned char *tmp = NULL;
2745 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_QUIT, cmd, 0, 1);
2747 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
2751 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
2755 q = silc_calloc(1, sizeof(*q));
2758 q->signoff = tmp ? strdup(tmp) : NULL;
2760 /* We quit the connection with little timeout */
2761 silc_schedule_task_add(server->schedule, sock->sock,
2762 silc_server_command_quit_cb, (void *)q,
2763 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
2766 silc_server_command_free(cmd);
2769 /* Server side of command KILL. This command is used by router operator
2770 to remove an client from the SILC Network temporarily. */
2772 SILC_SERVER_CMD_FUNC(kill)
2774 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2775 SilcServer server = cmd->server;
2776 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
2777 SilcClientEntry remote_client;
2778 SilcClientID *client_id;
2779 unsigned char *tmp, *comment;
2780 SilcUInt32 tmp_len, tmp_len2;
2783 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 2);
2785 if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
2788 /* KILL command works only on router */
2789 if (server->server_type != SILC_ROUTER) {
2790 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
2791 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
2795 /* Check whether client has the permissions. */
2796 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
2797 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
2798 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
2802 /* Get the client ID */
2803 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
2805 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
2806 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
2810 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
2812 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
2813 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
2818 /* Get the client entry */
2819 remote_client = silc_idlist_find_client_by_id(server->local_list,
2820 client_id, TRUE, NULL);
2822 if (!remote_client) {
2823 remote_client = silc_idlist_find_client_by_id(server->global_list,
2824 client_id, TRUE, NULL);
2826 if (!remote_client) {
2827 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
2828 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
2835 comment = silc_argument_get_arg_type(cmd->args, 2, &tmp_len2);
2839 /* Send reply to the sender */
2840 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
2843 /* Check if anyone is watching this nickname */
2844 if (server->server_type == SILC_ROUTER)
2845 silc_server_check_watcher_list(server, client, NULL,
2846 SILC_NOTIFY_TYPE_KILLED);
2848 /* Now do the killing */
2849 silc_server_kill_client(server, remote_client, comment, client->id,
2853 silc_server_command_free(cmd);
2856 /* Server side of command INFO. This sends information about us to
2857 the client. If client requested specific server we will send the
2858 command to that server. */
2860 SILC_SERVER_CMD_FUNC(info)
2862 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
2863 SilcServer server = cmd->server;
2864 SilcBuffer packet, idp;
2867 char *dest_server, *server_info = NULL, *server_name;
2868 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
2869 SilcServerEntry entry = NULL;
2870 SilcServerID *server_id = NULL;
2872 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INFO, cmd, 0, 2);
2874 /* Get server name */
2875 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
2878 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
2880 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
2882 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
2883 SILC_STATUS_ERR_NO_SERVER_ID, 0);
2889 /* Check whether we have this server cached */
2890 entry = silc_idlist_find_server_by_id(server->local_list,
2891 server_id, TRUE, NULL);
2893 entry = silc_idlist_find_server_by_id(server->global_list,
2894 server_id, TRUE, NULL);
2895 if (!entry && server->server_type != SILC_SERVER) {
2896 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
2897 SILC_STATUS_ERR_NO_SUCH_SERVER,
2904 /* Some buggy servers has sent request to router about themselves. */
2905 if (server->server_type != SILC_SERVER && cmd->sock->user_data == entry)
2908 if ((!dest_server && !server_id && !entry) || (entry &&
2909 entry == server->id_entry) ||
2910 (dest_server && !cmd->pending &&
2911 !strncasecmp(dest_server, server->server_name, strlen(dest_server)))) {
2912 /* Send our reply */
2913 char info_string[256];
2915 memset(info_string, 0, sizeof(info_string));
2916 snprintf(info_string, sizeof(info_string),
2917 "location: %s server: %s admin: %s <%s>",
2918 server->config->server_info->location,
2919 server->config->server_info->server_type,
2920 server->config->server_info->admin,
2921 server->config->server_info->email);
2923 server_info = info_string;
2924 entry = server->id_entry;
2926 /* Check whether we have this server cached */
2927 if (!entry && dest_server) {
2928 entry = silc_idlist_find_server_by_name(server->global_list,
2929 dest_server, TRUE, NULL);
2931 entry = silc_idlist_find_server_by_name(server->local_list,
2932 dest_server, TRUE, NULL);
2936 if (!cmd->pending &&
2937 server->server_type != SILC_SERVER && entry && !entry->server_info) {
2938 /* Send to the server */
2940 SilcUInt16 old_ident;
2942 old_ident = silc_command_get_ident(cmd->payload);
2943 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2944 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2946 silc_server_packet_send(server, entry->connection,
2947 SILC_PACKET_COMMAND, cmd->packet->flags,
2948 tmpbuf->data, tmpbuf->len, TRUE);
2950 /* Reprocess this packet after received reply from router */
2951 silc_server_command_pending(server, SILC_COMMAND_INFO,
2952 silc_command_get_ident(cmd->payload),
2953 silc_server_command_info,
2954 silc_server_command_dup(cmd));
2955 cmd->pending = TRUE;
2956 silc_command_set_ident(cmd->payload, old_ident);
2957 silc_buffer_free(tmpbuf);
2961 if (!entry && !cmd->pending && !server->standalone) {
2962 /* Send to the primary router */
2964 SilcUInt16 old_ident;
2966 old_ident = silc_command_get_ident(cmd->payload);
2967 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
2968 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
2970 silc_server_packet_send(server, server->router->connection,
2971 SILC_PACKET_COMMAND, cmd->packet->flags,
2972 tmpbuf->data, tmpbuf->len, TRUE);
2974 /* Reprocess this packet after received reply from router */
2975 silc_server_command_pending(server, SILC_COMMAND_INFO,
2976 silc_command_get_ident(cmd->payload),
2977 silc_server_command_info,
2978 silc_server_command_dup(cmd));
2979 cmd->pending = TRUE;
2980 silc_command_set_ident(cmd->payload, old_ident);
2981 silc_buffer_free(tmpbuf);
2986 silc_free(server_id);
2989 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
2990 SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
2994 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
2996 server_info = entry->server_info;
2997 server_name = entry->server_name;
2999 /* Send the reply */
3000 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO,
3001 SILC_STATUS_OK, 0, ident, 3,
3002 2, idp->data, idp->len,
3004 strlen(server_name),
3007 strlen(server_info) : 0);
3008 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3009 packet->data, packet->len, FALSE);
3011 silc_buffer_free(packet);
3012 silc_buffer_free(idp);
3015 silc_server_command_free(cmd);
3018 /* Server side of command PING. This just replies to the ping. */
3020 SILC_SERVER_CMD_FUNC(ping)
3022 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3023 SilcServer server = cmd->server;
3028 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INFO, cmd, 1, 2);
3031 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
3033 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
3034 SILC_STATUS_ERR_NO_SERVER_ID, 0);
3037 id = silc_id_str2id(tmp, len, SILC_ID_SERVER);
3041 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
3042 /* Send our reply */
3043 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
3046 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
3047 SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
3054 silc_server_command_free(cmd);
3057 /* Server side of command STATS. */
3059 SILC_SERVER_CMD_FUNC(stats)
3061 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3062 SilcServer server = cmd->server;
3063 SilcServerID *server_id;
3066 SilcBuffer packet, stats;
3067 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3070 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_STATS, cmd, 1, 1);
3073 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3075 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
3076 SILC_STATUS_ERR_NO_SERVER_ID, 0);
3079 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
3083 /* The ID must be ours */
3084 if (!SILC_ID_SERVER_COMPARE(server->id, server_id)) {
3085 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
3086 SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
3087 silc_free(server_id);
3090 silc_free(server_id);
3092 /* If we are router then just send everything we got. If we are normal
3093 server then we'll send this to our router to get all the latest
3094 statistical information. */
3095 if (!cmd->pending && server->server_type != SILC_ROUTER &&
3096 !server->standalone) {
3097 /* Send request to our router */
3098 SilcBuffer idp = silc_id_payload_encode(server->router->id,
3100 packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
3101 ++server->cmd_ident, 1,
3102 1, idp->data, idp->len);
3103 silc_server_packet_send(server, server->router->connection,
3104 SILC_PACKET_COMMAND, 0, packet->data,
3105 packet->len, FALSE);
3107 /* Reprocess this packet after received reply from router */
3108 silc_server_command_pending(server, SILC_COMMAND_STATS,
3110 silc_server_command_stats,
3111 silc_server_command_dup(cmd));
3112 cmd->pending = TRUE;
3113 silc_buffer_free(packet);
3114 silc_buffer_free(idp);
3118 /* Send our reply to sender */
3119 uptime = time(NULL) - server->starttime;
3121 stats = silc_buffer_alloc_size(60);
3122 silc_buffer_format(stats,
3123 SILC_STR_UI_INT(server->starttime),
3124 SILC_STR_UI_INT(uptime),
3125 SILC_STR_UI_INT(server->stat.my_clients),
3126 SILC_STR_UI_INT(server->stat.my_channels),
3127 SILC_STR_UI_INT(server->stat.my_server_ops),
3128 SILC_STR_UI_INT(server->stat.my_router_ops),
3129 SILC_STR_UI_INT(server->stat.cell_clients),
3130 SILC_STR_UI_INT(server->stat.cell_channels),
3131 SILC_STR_UI_INT(server->stat.cell_servers),
3132 SILC_STR_UI_INT(server->stat.clients),
3133 SILC_STR_UI_INT(server->stat.channels),
3134 SILC_STR_UI_INT(server->stat.servers),
3135 SILC_STR_UI_INT(server->stat.routers),
3136 SILC_STR_UI_INT(server->stat.server_ops),
3137 SILC_STR_UI_INT(server->stat.router_ops),
3140 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_STATS,
3141 SILC_STATUS_OK, 0, ident, 2,
3143 3, stats->data, stats->len);
3144 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
3145 0, packet->data, packet->len, FALSE);
3146 silc_buffer_free(packet);
3147 silc_buffer_free(stats);
3150 silc_server_command_free(cmd);
3153 /* Internal routine to join channel. The channel sent to this function
3154 has been either created or resolved from ID lists. This joins the sent
3155 client to the channel. */
3157 static void silc_server_command_join_channel(SilcServer server,
3158 SilcServerCommandContext cmd,
3159 SilcChannelEntry channel,
3160 SilcClientID *client_id,
3164 const unsigned char *auth,
3165 SilcUInt32 auth_len)
3167 SilcSocketConnection sock = cmd->sock;
3169 SilcUInt32 tmp_len, user_count;
3170 unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4];
3171 SilcClientEntry client;
3172 SilcChannelClientEntry chl;
3173 SilcBuffer reply, chidp, clidp, keyp = NULL, user_list, mode_list;
3174 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3175 char check[512], check2[512];
3176 bool founder = FALSE;
3178 unsigned char *fkey = NULL;
3179 SilcUInt32 fkey_len = 0;
3181 SILC_LOG_DEBUG(("Start"));
3186 /* Get the client entry */
3187 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
3188 client = (SilcClientEntry)sock->user_data;
3190 client = silc_server_get_client_resolve(server, client_id, FALSE,
3197 silc_server_command_send_status_reply(
3198 cmd, SILC_COMMAND_JOIN,
3199 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
3203 /* The client info is being resolved. Reprocess this packet after
3204 receiving the reply to the query. */
3205 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3207 silc_server_command_join,
3208 silc_server_command_dup(cmd));
3209 cmd->pending = TRUE;
3213 cmd->pending = FALSE;
3217 * Check founder auth payload if provided. If client can gain founder
3218 * privileges it can override various conditions on joining the channel,
3219 * and can have directly the founder mode set on the channel.
3221 if (auth && auth_len && channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
3222 SilcIDListData idata = (SilcIDListData)client;
3223 SilcChannelClientEntry chl2;
3224 SilcHashTableList htl;
3226 if (channel->founder_key && idata->public_key &&
3227 silc_pkcs_public_key_compare(channel->founder_key,
3228 idata->public_key)) {
3229 /* Check whether the client is to become founder */
3230 if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3231 channel->founder_key, 0, server->sha1hash,
3232 client->id, SILC_ID_CLIENT)) {
3234 /* There cannot be anyone else as founder on the channel now. This
3235 client is definitely the founder due to this authentication */
3236 silc_hash_table_list(channel->user_list, &htl);
3237 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
3238 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
3239 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
3240 silc_server_force_cumode_change(server, NULL, channel, chl2,
3244 silc_hash_table_list_reset(&htl);
3246 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
3253 * Check channel modes
3257 memset(check, 0, sizeof(check));
3258 memset(check2, 0, sizeof(check2));
3259 strncat(check, client->nickname, strlen(client->nickname));
3260 strncat(check, "!", 1);
3261 strncat(check, client->username, strlen(client->username));
3262 if (!strchr(client->username, '@')) {
3263 strncat(check, "@", 1);
3264 strncat(check, cmd->sock->hostname, strlen(cmd->sock->hostname));
3267 strncat(check2, client->nickname, strlen(client->nickname));
3268 if (!strchr(client->nickname, '@')) {
3269 strncat(check2, "@", 1);
3270 strncat(check2, server->server_name, strlen(server->server_name));
3272 strncat(check2, "!", 1);
3273 strncat(check2, client->username, strlen(client->username));
3274 if (!strchr(client->username, '@')) {
3275 strncat(check2, "@", 1);
3276 strncat(check2, cmd->sock->hostname, strlen(cmd->sock->hostname));
3279 /* Check invite list if channel is invite-only channel */
3280 if (channel->mode & SILC_CHANNEL_MODE_INVITE) {
3281 if (!channel->invite_list ||
3282 (!silc_string_match(channel->invite_list, check) &&
3283 !silc_string_match(channel->invite_list, check2))) {
3284 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
3285 SILC_STATUS_ERR_NOT_INVITED, 0);
3290 /* Check ban list if it exists. If the client's nickname, server,
3291 username and/or hostname is in the ban list the access to the
3292 channel is denied. */
3293 if (channel->ban_list) {
3294 if (silc_string_match(channel->ban_list, check) ||
3295 silc_string_match(channel->ban_list, check2)) {
3296 silc_server_command_send_status_reply(
3297 cmd, SILC_COMMAND_JOIN,
3298 SILC_STATUS_ERR_BANNED_FROM_CHANNEL, 0);
3303 /* Check user count limit if set. */
3304 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT) {
3305 if (silc_hash_table_count(channel->user_list) + 1 >
3306 channel->user_limit) {
3307 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
3308 SILC_STATUS_ERR_CHANNEL_IS_FULL,
3315 /* Check the channel passphrase if set. */
3316 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
3317 /* Get passphrase */
3318 tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
3320 passphrase = silc_memdup(tmp, tmp_len);
3322 if (!passphrase || !channel->passphrase ||
3323 memcmp(passphrase, channel->passphrase, strlen(channel->passphrase))) {
3324 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
3325 SILC_STATUS_ERR_BAD_PASSWORD, 0);
3331 * Client is allowed to join to the channel. Make it happen.
3334 /* Check whether the client already is on the channel */
3335 if (silc_server_client_on_channel(client, channel, NULL)) {
3336 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
3337 SILC_STATUS_ERR_USER_ON_CHANNEL, 0);
3341 /* Generate new channel key as protocol dictates */
3343 if (!silc_server_create_channel_key(server, channel, 0))
3346 /* Send the channel key. This is broadcasted to the channel but is not
3347 sent to the client who is joining to the channel. */
3348 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
3349 silc_server_send_channel_key(server, NULL, channel,
3350 server->server_type == SILC_ROUTER ?
3351 FALSE : !server->standalone);
3354 /* Join the client to the channel by adding it to channel's user list.
3355 Add also the channel to client entry's channels list for fast cross-
3357 chl = silc_calloc(1, sizeof(*chl));
3359 chl->client = client;
3360 chl->channel = channel;
3361 silc_hash_table_add(channel->user_list, client, chl);
3362 silc_hash_table_add(client->channels, channel, chl);
3363 channel->user_count++;
3364 channel->disabled = FALSE;
3366 /* Get users on the channel */
3367 silc_server_get_users_on_channel(server, channel, &user_list, &mode_list,
3370 /* Encode Client ID Payload of the original client who wants to join */
3371 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3373 /* Encode command reply packet */
3374 chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
3375 SILC_PUT32_MSB(channel->mode, mode);
3376 SILC_PUT32_MSB(created, tmp2);
3377 SILC_PUT32_MSB(user_count, tmp3);
3379 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3380 tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3381 keyp = silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3384 strlen(channel->channel_key->
3386 channel->channel_key->cipher->name,
3387 channel->key_len / 8, channel->key);
3391 if (channel->founder_key)
3392 fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
3395 silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
3396 SILC_STATUS_OK, 0, ident, 14,
3397 2, channel->channel_name,
3398 strlen(channel->channel_name),
3399 3, chidp->data, chidp->len,
3400 4, clidp->data, clidp->len,
3403 7, keyp ? keyp->data : NULL,
3404 keyp ? keyp->len : 0,
3405 8, channel->ban_list,
3407 strlen(channel->ban_list) : 0,
3408 9, channel->invite_list,
3409 channel->invite_list ?
3410 strlen(channel->invite_list) : 0,
3413 strlen(channel->topic) : 0,
3414 11, silc_hmac_get_name(channel->hmac),
3415 strlen(silc_hmac_get_name(channel->
3418 13, user_list->data, user_list->len,
3419 14, mode_list->data,
3421 15, fkey, fkey_len);
3423 /* Send command reply */
3424 silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
3425 reply->data, reply->len, FALSE);
3427 /* Send JOIN notify to locally connected clients on the channel. If
3428 we are normal server then router will send or have sent JOIN notify
3429 already. However since we've added the client already to our channel
3430 we'll ignore it (in packet_receive.c) so we must send it here. If
3431 we are router then this will send it to local clients and local
3433 SILC_LOG_DEBUG(("Send JOIN notify to channel"));
3434 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
3435 SILC_NOTIFY_TYPE_JOIN, 2,
3436 clidp->data, clidp->len,
3437 chidp->data, chidp->len);
3439 /* Update statistics */
3440 server->stat.my_chanclients++;
3441 if (server->server_type == SILC_ROUTER) {
3442 server->stat.cell_chanclients++;
3443 server->stat.chanclients++;
3446 if (!cmd->pending) {
3447 /* Send JOIN notify packet to our primary router */
3448 if (!server->standalone)
3449 silc_server_send_notify_join(server, server->router->connection,
3450 server->server_type == SILC_ROUTER ?
3451 TRUE : FALSE, channel, client->id);
3454 /* Distribute the channel key to all backup routers. */
3455 silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
3456 keyp->data, keyp->len, FALSE, TRUE);
3458 /* If client became founder by providing correct founder auth data
3459 notify the mode change to the channel. */
3461 SILC_PUT32_MSB(chl->mode, mode);
3462 SILC_LOG_DEBUG(("Send CUMODE_CHANGE notify to channel"));
3463 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
3464 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
3465 clidp->data, clidp->len,
3466 mode, 4, clidp->data, clidp->len,
3471 /* Set CUMODE notify type to network */
3472 if (founder && !server->standalone)
3473 silc_server_send_notify_cumode(server, server->router->connection,
3474 server->server_type == SILC_ROUTER ?
3475 TRUE : FALSE, channel,
3476 chl->mode, client->id, SILC_ID_CLIENT,
3477 client->id, channel->founder_key);
3479 silc_buffer_free(reply);
3480 silc_buffer_free(clidp);
3481 silc_buffer_free(chidp);
3482 silc_buffer_free(keyp);
3483 silc_buffer_free(user_list);
3484 silc_buffer_free(mode_list);
3488 silc_free(passphrase);
3491 /* Server side of command JOIN. Joins client into requested channel. If
3492 the channel does not exist it will be created. */
3494 SILC_SERVER_CMD_FUNC(join)
3496 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3497 SilcServer server = cmd->server;
3498 unsigned char *auth;
3499 SilcUInt32 tmp_len, auth_len;
3500 char *tmp, *channel_name = NULL, *cipher, *hmac;
3501 SilcChannelEntry channel;
3502 SilcUInt32 umode = 0;
3503 bool created = FALSE, create_key = TRUE;
3504 SilcClientID *client_id;
3506 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_JOIN, cmd, 2, 6);
3508 /* Get channel name */
3509 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
3511 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
3512 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3519 channel_name[255] = '\0';
3521 if (silc_server_name_bad_chars(channel_name, tmp_len) == TRUE) {
3522 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
3523 SILC_STATUS_ERR_BAD_CHANNEL, 0);
3527 /* Get Client ID of the client who is joining to the channel */
3528 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
3530 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
3531 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3535 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
3537 silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
3538 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
3543 /* Get cipher, hmac name and auth payload */
3544 cipher = silc_argument_get_arg_type(cmd->args, 4, NULL);
3545 hmac = silc_argument_get_arg_type(cmd->args, 5, NULL);
3546 auth = silc_argument_get_arg_type(cmd->args, 6, &auth_len);
3548 /* See if the channel exists */
3549 channel = silc_idlist_find_channel_by_name(server->local_list,
3550 channel_name, NULL);
3552 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
3553 SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
3554 silc_free(client_id);
3555 client_id = silc_id_dup(entry->id, SILC_ID_CLIENT);
3558 (channel->disabled && server->server_type != SILC_ROUTER)) {
3559 /* Channel not found */
3561 /* If we are standalone server we don't have a router, we just create
3562 the channel by ourselves. */
3563 if (server->standalone) {
3564 channel = silc_server_create_new_channel(server, server->id, cipher,
3565 hmac, channel_name, TRUE);
3567 silc_server_command_send_status_reply(
3568 cmd, SILC_COMMAND_JOIN,
3569 SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
3571 silc_free(client_id);
3575 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
3581 /* The channel does not exist on our server. If we are normal server
3582 we will send JOIN command to our router which will handle the
3583 joining procedure (either creates the channel if it doesn't exist
3584 or joins the client to it). */
3585 if (server->server_type != SILC_ROUTER) {
3587 SilcUInt16 old_ident;
3589 /* If this is pending command callback then we've resolved
3590 it and it didn't work, return since we've notified the
3591 client already in the command reply callback. */
3593 silc_free(client_id);
3597 old_ident = silc_command_get_ident(cmd->payload);
3598 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
3599 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
3601 /* Send JOIN command to our router */
3602 silc_server_packet_send(server, (SilcSocketConnection)
3603 server->router->connection,
3604 SILC_PACKET_COMMAND, cmd->packet->flags,
3605 tmpbuf->data, tmpbuf->len, TRUE);
3607 /* Reprocess this packet after received reply from router */
3608 silc_server_command_pending(server, SILC_COMMAND_JOIN,
3609 silc_command_get_ident(cmd->payload),
3610 silc_server_command_join,
3611 silc_server_command_dup(cmd));
3612 cmd->pending = TRUE;
3613 silc_command_set_ident(cmd->payload, old_ident);
3614 silc_buffer_free(tmpbuf);
3615 silc_free(client_id);
3619 /* We are router and the channel does not seem exist so we will check
3620 our global list as well for the channel. */
3621 channel = silc_idlist_find_channel_by_name(server->global_list,
3622 channel_name, NULL);
3624 /* Channel really does not exist, create it */
3625 channel = silc_server_create_new_channel(server, server->id, cipher,
3626 hmac, channel_name, TRUE);
3628 silc_server_command_send_status_reply(
3629 cmd, SILC_COMMAND_JOIN,
3630 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
3631 silc_free(client_id);
3635 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
3643 /* Channel not found */
3645 /* If the command came from router and we are normal server then
3646 something went wrong with the joining as the channel was not found.
3647 We can't do anything else but ignore this. */
3648 if (cmd->sock->type == SILC_SOCKET_TYPE_ROUTER ||
3649 server->server_type != SILC_ROUTER) {
3650 silc_free(client_id);
3654 /* We are router and the channel does not seem exist so we will check
3655 our global list as well for the channel. */
3656 channel = silc_idlist_find_channel_by_name(server->global_list,
3657 channel_name, NULL);
3659 /* Channel really does not exist, create it */
3660 channel = silc_server_create_new_channel(server, server->id, cipher,
3661 hmac, channel_name, TRUE);
3663 silc_server_command_send_status_reply(
3664 cmd, SILC_COMMAND_JOIN,
3665 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
3666 silc_free(client_id);
3670 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
3677 /* Check whether the channel was created by our router */
3678 if (cmd->pending && context2) {
3679 SilcServerCommandReplyContext reply = context2;
3681 if (silc_command_get(reply->payload) == SILC_COMMAND_JOIN) {
3682 tmp = silc_argument_get_arg_type(reply->args, 6, NULL);
3683 SILC_GET32_MSB(created, tmp);
3684 if (silc_argument_get_arg_type(reply->args, 7, NULL))
3685 create_key = FALSE; /* Router returned the key already */
3688 if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
3689 !channel->disabled && !silc_hash_table_count(channel->user_list))
3693 /* If the channel does not have global users and is also empty the client
3694 will be the channel founder and operator. */
3695 if (!channel->disabled &&
3696 !channel->global_users && !silc_hash_table_count(channel->user_list))
3697 umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
3699 /* Join to the channel */
3700 silc_server_command_join_channel(server, cmd, channel, client_id,
3701 created, create_key, umode,
3704 silc_free(client_id);
3707 silc_server_command_free(cmd);
3710 /* Server side of command MOTD. Sends server's current "message of the
3711 day" to the client. */
3713 SILC_SERVER_CMD_FUNC(motd)
3715 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3716 SilcServer server = cmd->server;
3717 SilcBuffer packet, idp;
3718 char *motd, *dest_server;
3719 SilcUInt32 motd_len;
3720 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3722 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_MOTD, cmd, 1, 1);
3724 /* Get server name */
3725 dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
3727 silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
3728 SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
3732 if (!strncasecmp(dest_server, server->server_name, strlen(dest_server))) {
3735 idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
3737 if (server->config && server->config->server_info &&
3738 server->config->server_info->motd_file) {
3740 motd = silc_file_readfile(server->config->server_info->motd_file,
3746 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
3753 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
3759 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3760 packet->data, packet->len, FALSE);
3761 silc_buffer_free(packet);
3762 silc_buffer_free(idp);
3764 SilcServerEntry entry;
3766 /* Check whether we have this server cached */
3767 entry = silc_idlist_find_server_by_name(server->global_list,
3768 dest_server, TRUE, NULL);
3770 entry = silc_idlist_find_server_by_name(server->local_list,
3771 dest_server, TRUE, NULL);
3774 if (server->server_type != SILC_SERVER && !cmd->pending &&
3775 entry && !entry->motd) {
3776 /* Send to the server */
3778 SilcUInt16 old_ident;
3780 old_ident = silc_command_get_ident(cmd->payload);
3781 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
3782 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
3784 silc_server_packet_send(server, entry->connection,
3785 SILC_PACKET_COMMAND, cmd->packet->flags,
3786 tmpbuf->data, tmpbuf->len, TRUE);
3788 /* Reprocess this packet after received reply from router */
3789 silc_server_command_pending(server, SILC_COMMAND_MOTD,
3790 silc_command_get_ident(cmd->payload),
3791 silc_server_command_motd,
3792 silc_server_command_dup(cmd));
3793 cmd->pending = TRUE;
3794 silc_command_set_ident(cmd->payload, old_ident);
3795 silc_buffer_free(tmpbuf);
3799 if (!entry && !cmd->pending && !server->standalone) {
3800 /* Send to the primary router */
3802 SilcUInt16 old_ident;
3804 old_ident = silc_command_get_ident(cmd->payload);
3805 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
3806 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
3808 silc_server_packet_send(server, server->router->connection,
3809 SILC_PACKET_COMMAND, cmd->packet->flags,
3810 tmpbuf->data, tmpbuf->len, TRUE);
3812 /* Reprocess this packet after received reply from router */
3813 silc_server_command_pending(server, SILC_COMMAND_MOTD,
3814 silc_command_get_ident(cmd->payload),
3815 silc_server_command_motd,
3816 silc_server_command_dup(cmd));
3817 cmd->pending = TRUE;
3818 silc_command_set_ident(cmd->payload, old_ident);
3819 silc_buffer_free(tmpbuf);
3824 silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
3825 SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
3829 idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
3830 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD,
3831 SILC_STATUS_OK, 0, ident, 2,
3835 strlen(entry->motd) : 0);
3836 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3837 packet->data, packet->len, FALSE);
3838 silc_buffer_free(packet);
3839 silc_buffer_free(idp);
3843 silc_server_command_free(cmd);
3846 /* Server side of command UMODE. Client can use this command to set/unset
3847 user mode. Client actually cannot set itself to be as server/router
3848 operator so this can be used only to unset the modes. */
3850 SILC_SERVER_CMD_FUNC(umode)
3852 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3853 SilcServer server = cmd->server;
3854 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3856 unsigned char *tmp_mask, m[4];
3857 SilcUInt32 mask = 0;
3858 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3859 bool set_mask = FALSE;
3861 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
3864 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_UMODE, cmd, 1, 2);
3866 /* Get the client's mode mask */
3867 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
3869 SILC_GET32_MSB(mask, tmp_mask);
3874 /* Check that mode changing is allowed. */
3875 if (!silc_server_check_umode_rights(server, client, mask)) {
3876 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
3877 SILC_STATUS_ERR_PERM_DENIED, 0);
3881 /* Anonymous mode cannot be set by client */
3882 if (mask & SILC_UMODE_ANONYMOUS) {
3883 if (!(client->mode & SILC_UMODE_ANONYMOUS)) {
3884 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
3885 SILC_STATUS_ERR_PERM_DENIED, 0);
3889 if (client->mode & SILC_UMODE_ANONYMOUS) {
3890 silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
3891 SILC_STATUS_ERR_PERM_DENIED, 0);
3896 /* Update statistics */
3897 if (mask & SILC_UMODE_GONE) {
3898 if (!(client->mode & SILC_UMODE_GONE))
3899 server->stat.my_aways++;
3901 if (client->mode & SILC_UMODE_GONE)
3902 server->stat.my_aways--;
3905 /* Change the mode */
3906 client->mode = mask;
3908 /* Send UMODE change to primary router */
3909 if (!server->standalone)
3910 silc_server_send_notify_umode(server, server->router->connection, TRUE,
3911 client->id, client->mode);
3913 /* Check if anyone is watching this nickname */
3914 if (server->server_type == SILC_ROUTER)
3915 silc_server_check_watcher_list(server, client, NULL,
3916 SILC_NOTIFY_TYPE_UMODE_CHANGE);
3919 /* Send command reply to sender */
3920 SILC_PUT32_MSB(client->mode, m);
3921 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_UMODE,
3922 SILC_STATUS_OK, 0, ident, 1,
3924 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
3925 packet->data, packet->len, FALSE);
3926 silc_buffer_free(packet);
3929 silc_server_command_free(cmd);
3932 /* Server side command of CMODE. Changes channel mode */
3934 SILC_SERVER_CMD_FUNC(cmode)
3936 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
3937 SilcServer server = cmd->server;
3938 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
3939 SilcIDListData idata = (SilcIDListData)client;
3940 SilcChannelID *channel_id = NULL;
3941 SilcChannelEntry channel;
3942 SilcChannelClientEntry chl;
3943 SilcBuffer packet, cidp;
3944 unsigned char *tmp, *tmp_id, *tmp_mask;
3945 char *cipher = NULL, *hmac = NULL, *passphrase = NULL;
3946 SilcUInt32 mode_mask = 0, tmp_len, tmp_len2;
3947 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
3948 bool set_mask = FALSE;
3949 SilcPublicKey founder_key = NULL;
3950 unsigned char *fkey = NULL;
3951 SilcUInt32 fkey_len = 0;
3953 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 7);
3955 /* Get Channel ID */
3956 tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
3958 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3959 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3962 channel_id = silc_id_payload_parse_id(tmp_id, tmp_len2, NULL);
3964 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3965 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
3969 /* Get the channel mode mask */
3970 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
3972 SILC_GET32_MSB(mode_mask, tmp_mask);
3976 /* Get channel entry */
3977 channel = silc_idlist_find_channel_by_id(server->local_list,
3980 channel = silc_idlist_find_channel_by_id(server->global_list,
3983 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3984 SILC_STATUS_ERR_NO_SUCH_CHANNEL,
3990 /* Check whether this client is on the channel */
3991 if (!silc_server_client_on_channel(client, channel, &chl)) {
3992 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
3993 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
3997 /* Check that client has rights to change any requested channel modes */
3998 if (set_mask && !silc_server_check_cmode_rights(server, channel, chl,
4000 silc_server_command_send_status_reply(
4001 cmd, SILC_COMMAND_CMODE,
4002 (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) ?
4003 SILC_STATUS_ERR_NO_CHANNEL_PRIV :
4004 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV), 0);
4008 /* If mode mask was not sent as argument then merely return the current
4009 mode mask to the sender. */
4012 SILC_PUT32_MSB(channel->mode, m);
4013 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
4014 SILC_STATUS_OK, 0, ident, 2,
4015 2, tmp_id, tmp_len2,
4017 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4018 packet->data, packet->len, FALSE);
4019 silc_buffer_free(packet);
4024 * Check the modes. Modes that requires nothing special operation are
4028 if (mode_mask & SILC_CHANNEL_MODE_PRIVKEY) {
4029 /* Channel uses private keys to protect traffic. Client(s) has set the
4030 key locally they want to use, server does not know that key. */
4031 /* Nothing interesting to do here */
4033 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
4034 /* The mode is removed and we need to generate and distribute
4035 new channel key. Clients are not using private channel keys
4036 anymore after this. */
4038 /* Re-generate channel key */
4039 if (!silc_server_create_channel_key(server, channel, 0))
4042 /* Send the channel key. This sends it to our local clients and if
4043 we are normal server to our router as well. */
4044 silc_server_send_channel_key(server, NULL, channel,
4045 server->server_type == SILC_ROUTER ?
4046 FALSE : !server->standalone);
4048 cipher = channel->channel_key->cipher->name;
4049 hmac = (char *)silc_hmac_get_name(channel->hmac);
4053 if (mode_mask & SILC_CHANNEL_MODE_ULIMIT) {
4054 /* User limit is set on channel */
4055 SilcUInt32 user_limit;
4057 /* Get user limit */
4058 tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
4060 if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT)) {
4061 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4062 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4066 SILC_GET32_MSB(user_limit, tmp);
4067 channel->user_limit = user_limit;
4070 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
4071 /* User limit mode is unset. Remove user limit */
4072 channel->user_limit = 0;
4075 if (mode_mask & SILC_CHANNEL_MODE_PASSPHRASE) {
4076 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
4077 /* Passphrase has been set to channel */
4079 /* Get the passphrase */
4080 tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
4082 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4083 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4087 /* Save the passphrase */
4088 passphrase = channel->passphrase = silc_memdup(tmp, strlen(tmp));
4091 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
4092 /* Passphrase mode is unset. remove the passphrase */
4093 silc_free(channel->passphrase);
4094 channel->passphrase = NULL;
4098 if (mode_mask & SILC_CHANNEL_MODE_CIPHER) {
4099 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
4100 /* Cipher to use protect the traffic */
4101 SilcCipher newkey, oldkey;
4104 cipher = silc_argument_get_arg_type(cmd->args, 5, NULL);
4106 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4107 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4111 /* Delete old cipher and allocate the new one */
4112 if (!silc_cipher_alloc(cipher, &newkey)) {
4113 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4114 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
4118 oldkey = channel->channel_key;
4119 channel->channel_key = newkey;
4121 /* Re-generate channel key */
4122 if (!silc_server_create_channel_key(server, channel, 0)) {
4123 /* We don't have new key, revert to old one */
4124 channel->channel_key = oldkey;
4128 /* Remove old channel key for good */
4129 silc_cipher_free(oldkey);
4131 /* Send the channel key. This sends it to our local clients and if
4132 we are normal server to our router as well. */
4133 silc_server_send_channel_key(server, NULL, channel,
4134 server->server_type == SILC_ROUTER ?
4135 FALSE : !server->standalone);
4138 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
4139 /* Cipher mode is unset. Remove the cipher and revert back to
4141 SilcCipher newkey, oldkey;
4142 cipher = channel->cipher;
4144 /* Delete old cipher and allocate default one */
4145 if (!silc_cipher_alloc(cipher ? cipher : SILC_DEFAULT_CIPHER, &newkey)) {
4146 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4147 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
4151 oldkey = channel->channel_key;
4152 channel->channel_key = newkey;
4154 /* Re-generate channel key */
4155 if (!silc_server_create_channel_key(server, channel, 0)) {
4156 /* We don't have new key, revert to old one */
4157 channel->channel_key = oldkey;
4161 /* Remove old channel key for good */
4162 silc_cipher_free(oldkey);
4164 /* Send the channel key. This sends it to our local clients and if
4165 we are normal server to our router as well. */
4166 silc_server_send_channel_key(server, NULL, channel,
4167 server->server_type == SILC_ROUTER ?
4168 FALSE : !server->standalone);
4172 if (mode_mask & SILC_CHANNEL_MODE_HMAC) {
4173 if (!(channel->mode & SILC_CHANNEL_MODE_HMAC)) {
4174 /* HMAC to use protect the traffic */
4175 unsigned char hash[32];
4179 hmac = silc_argument_get_arg_type(cmd->args, 6, NULL);
4181 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4182 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4186 /* Delete old hmac and allocate the new one */
4187 if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
4188 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4189 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
4193 silc_hmac_free(channel->hmac);
4194 channel->hmac = newhmac;
4196 /* Set the HMAC key out of current channel key. The client must do
4198 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
4199 channel->key_len / 8, hash);
4200 silc_hmac_set_key(channel->hmac, hash,
4201 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4202 memset(hash, 0, sizeof(hash));
4205 if (channel->mode & SILC_CHANNEL_MODE_HMAC) {
4206 /* Hmac mode is unset. Remove the hmac and revert back to
4209 unsigned char hash[32];
4210 hmac = channel->hmac_name;
4212 /* Delete old hmac and allocate default one */
4213 silc_hmac_free(channel->hmac);
4214 if (!silc_hmac_alloc(hmac ? hmac : SILC_DEFAULT_HMAC, NULL, &newhmac)) {
4215 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4216 SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
4220 silc_hmac_free(channel->hmac);
4221 channel->hmac = newhmac;
4223 /* Set the HMAC key out of current channel key. The client must do
4225 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
4226 channel->key_len / 8,
4228 silc_hmac_set_key(channel->hmac, hash,
4229 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
4230 memset(hash, 0, sizeof(hash));
4234 if (mode_mask & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
4235 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
4236 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
4237 /* Set the founder authentication */
4238 tmp = silc_argument_get_arg_type(cmd->args, 7, &tmp_len);
4240 silc_server_command_send_status_reply(
4241 cmd, SILC_COMMAND_CMODE,
4242 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
4246 /* Verify the payload before setting the mode */
4247 if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY,
4248 idata->public_key, 0, server->sha1hash,
4249 client->id, SILC_ID_CLIENT)) {
4250 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4251 SILC_STATUS_ERR_AUTH_FAILED,
4256 /* Save the public key */
4257 channel->founder_key = silc_pkcs_public_key_copy(idata->public_key);
4258 if (!channel->founder_key) {
4259 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4260 SILC_STATUS_ERR_AUTH_FAILED,
4265 founder_key = channel->founder_key;
4266 fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len);
4268 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
4269 SILC_STATUS_ERR_AUTH_FAILED,
4276 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
4277 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
4278 if (channel->founder_key)
4279 silc_pkcs_public_key_free(channel->founder_key);
4280 channel->founder_key = NULL;
4285 /* Finally, set the mode */
4286 channel->mode = mode_mask;
4288 /* Send CMODE_CHANGE notify. */
4289 cidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4290 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
4291 SILC_NOTIFY_TYPE_CMODE_CHANGE, 6,
4292 cidp->data, cidp->len,
4294 cipher, cipher ? strlen(cipher) : 0,
4295 hmac, hmac ? strlen(hmac) : 0,
4296 passphrase, passphrase ?
4297 strlen(passphrase) : 0,
4300 /* Set CMODE notify type to network */
4301 if (!server->standalone)
4302 silc_server_send_notify_cmode(server, server->router->connection,
4303 server->server_type == SILC_ROUTER ?
4304 TRUE : FALSE, channel,
4305 mode_mask, client->id, SILC_ID_CLIENT,
4306 cipher, hmac, passphrase, founder_key);
4308 /* Send command reply to sender */
4309 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
4310 SILC_STATUS_OK, 0, ident, 2,
4311 2, tmp_id, tmp_len2,
4313 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4314 packet->data, packet->len, FALSE);
4316 silc_buffer_free(packet);
4317 silc_buffer_free(cidp);
4321 silc_free(channel_id);
4322 silc_server_command_free(cmd);
4325 /* Server side of CUMODE command. Changes client's mode on a channel. */
4327 SILC_SERVER_CMD_FUNC(cumode)
4329 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4330 SilcServer server = cmd->server;
4331 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4332 SilcIDListData idata = (SilcIDListData)client;
4333 SilcChannelID *channel_id;
4334 SilcClientID *client_id;
4335 SilcChannelEntry channel;
4336 SilcClientEntry target_client;
4337 SilcChannelClientEntry chl;
4338 SilcBuffer packet, idp;
4339 unsigned char *tmp_id, *tmp_ch_id, *tmp_mask;
4340 SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
4342 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
4343 SilcPublicKey founder_key = NULL;
4344 unsigned char *fkey = NULL;
4345 SilcUInt32 fkey_len = 0;
4347 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4);
4349 /* Get Channel ID */
4350 tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
4352 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4353 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4356 channel_id = silc_id_payload_parse_id(tmp_ch_id, tmp_ch_len, NULL);
4358 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4359 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4363 /* Get channel entry */
4364 channel = silc_idlist_find_channel_by_id(server->local_list,
4367 channel = silc_idlist_find_channel_by_id(server->global_list,
4370 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4371 SILC_STATUS_ERR_NO_SUCH_CHANNEL,
4377 /* Check whether sender is on the channel */
4378 if (!silc_server_client_on_channel(client, channel, &chl)) {
4379 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4380 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
4383 sender_mask = chl->mode;
4385 /* Get the target client's channel mode mask */
4386 tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
4388 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4389 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4393 SILC_GET32_MSB(target_mask, tmp_mask);
4395 /* Get target Client ID */
4396 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
4398 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4399 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
4402 client_id = silc_id_payload_parse_id(tmp_id, tmp_len, NULL);
4404 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4405 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
4409 /* Get target client's entry */
4410 target_client = silc_idlist_find_client_by_id(server->local_list,
4411 client_id, TRUE, NULL);
4412 if (!target_client) {
4413 target_client = silc_idlist_find_client_by_id(server->global_list,
4414 client_id, TRUE, NULL);
4417 if (target_client != client &&
4418 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO) &&
4419 !(sender_mask & SILC_CHANNEL_UMODE_CHANOP)) {
4420 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4421 SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0);
4425 /* Check whether target client is on the channel */
4426 if (target_client != client) {
4427 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
4428 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4429 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL, 0);
4438 /* If the target client is founder, no one else can change their mode
4440 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && client != target_client) {
4441 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4442 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
4447 if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
4448 if (target_client != client) {
4449 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4450 SILC_STATUS_ERR_NOT_YOU, 0);
4454 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
4455 /* The client tries to claim the founder rights. */
4456 unsigned char *tmp_auth;
4457 SilcUInt32 tmp_auth_len;
4458 SilcChannelClientEntry chl2;
4459 SilcHashTableList htl;
4461 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
4462 !channel->founder_key || !idata->public_key ||
4463 !silc_pkcs_public_key_compare(channel->founder_key,
4464 idata->public_key)) {
4465 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4466 SILC_STATUS_ERR_AUTH_FAILED, 0);
4470 tmp_auth = silc_argument_get_arg_type(cmd->args, 4, &tmp_auth_len);
4472 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4473 SILC_STATUS_ERR_AUTH_FAILED, 0);
4477 /* Verify the authentication payload */
4478 if (!silc_auth_verify_data(tmp_auth, tmp_auth_len, SILC_AUTH_PUBLIC_KEY,
4479 channel->founder_key, 0, server->sha1hash,
4480 client->id, SILC_ID_CLIENT)) {
4481 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4482 SILC_STATUS_ERR_AUTH_FAILED, 0);
4487 founder_key = channel->founder_key;
4488 fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len);
4490 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4491 SILC_STATUS_ERR_AUTH_FAILED, 0);
4495 /* There cannot be anyone else as founder on the channel now. This
4496 client is definitely the founder due to this authentication */
4497 silc_hash_table_list(channel->user_list, &htl);
4498 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
4499 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
4500 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
4501 silc_server_force_cumode_change(server, NULL, channel, chl2,
4505 silc_hash_table_list_reset(&htl);
4507 sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
4510 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
4511 if (target_client == client) {
4512 /* Remove channel founder rights from itself */
4513 chl->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
4516 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4517 SILC_STATUS_ERR_NOT_YOU, 0);
4523 if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
4524 /* Promote to operator */
4525 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
4526 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
4527 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
4528 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4529 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
4534 chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
4538 if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
4539 if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
4540 !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
4541 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4542 SILC_STATUS_ERR_NO_CHANNEL_PRIV,
4547 /* Demote to normal user */
4548 chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
4553 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
4554 if (target_client != client) {
4555 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4556 SILC_STATUS_ERR_NOT_YOU, 0);
4560 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)) {
4561 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
4565 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
4566 if (target_client != client) {
4567 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4568 SILC_STATUS_ERR_NOT_YOU, 0);
4572 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
4577 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
4578 if (target_client != client) {
4579 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4580 SILC_STATUS_ERR_NOT_YOU, 0);
4584 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)) {
4585 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
4589 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
4590 if (target_client != client) {
4591 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4592 SILC_STATUS_ERR_NOT_YOU, 0);
4596 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS;
4601 if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
4602 if (target_client != client) {
4603 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4604 SILC_STATUS_ERR_NOT_YOU, 0);
4608 if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)) {
4609 chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
4613 if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
4614 if (target_client != client) {
4615 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4616 SILC_STATUS_ERR_NOT_YOU, 0);
4620 chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS;
4625 if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
4626 if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
4627 if (client == target_client) {
4628 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4629 SILC_STATUS_ERR_PERM_DENIED, 0);
4632 chl->mode |= SILC_CHANNEL_UMODE_QUIET;
4636 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
4637 if (client == target_client) {
4638 silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
4639 SILC_STATUS_ERR_PERM_DENIED, 0);
4642 chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
4647 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4648 tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
4650 /* Send notify to channel, notify only if mode was actually changed. */
4652 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
4653 SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
4654 idp->data, idp->len,
4659 /* Set CUMODE notify type to network */
4660 if (!server->standalone)
4661 silc_server_send_notify_cumode(server, server->router->connection,
4662 server->server_type == SILC_ROUTER ?
4663 TRUE : FALSE, channel,
4664 target_mask, client->id,
4666 target_client->id, founder_key);
4669 /* Send command reply to sender */
4670 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CUMODE,
4671 SILC_STATUS_OK, 0, ident, 3,
4673 3, tmp_ch_id, tmp_ch_len,
4674 4, tmp_id, tmp_len);
4675 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
4676 packet->data, packet->len, FALSE);
4678 silc_buffer_free(packet);
4679 silc_free(channel_id);
4680 silc_free(client_id);
4681 silc_buffer_free(idp);
4685 silc_server_command_free(cmd);
4688 /* Server side of KICK command. Kicks client out of channel. */
4690 SILC_SERVER_CMD_FUNC(kick)
4692 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4693 SilcServer server = cmd->server;
4694 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4695 SilcClientEntry target_client;
4696 SilcChannelID *channel_id;
4697 SilcClientID *client_id;
4698 SilcChannelEntry channel;
4699 SilcChannelClientEntry chl;
4701 SilcUInt32 tmp_len, target_idp_len;
4702 unsigned char *tmp, *comment, *target_idp;
4704 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 3);
4706 /* Get Channel ID */
4707 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4709 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
4710 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4713 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
4715 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
4716 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
4720 /* Get channel entry */
4721 channel = silc_idlist_find_channel_by_id(server->local_list,
4724 channel = silc_idlist_find_channel_by_id(server->local_list,
4727 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
4728 SILC_STATUS_ERR_NO_SUCH_CHANNEL,
4734 /* Check whether sender is on the channel */
4735 if (!silc_server_client_on_channel(client, channel, &chl)) {
4736 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
4737 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
4741 /* Check that the kicker is channel operator or channel founder */
4742 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
4743 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
4744 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
4745 SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0);
4749 /* Get target Client ID */
4750 target_idp = silc_argument_get_arg_type(cmd->args, 2, &target_idp_len);
4752 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
4753 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
4756 client_id = silc_id_payload_parse_id(target_idp, target_idp_len, NULL);
4758 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
4759 SILC_STATUS_ERR_NO_CLIENT_ID, 0);
4763 /* Get target client's entry */
4764 target_client = silc_idlist_find_client_by_id(server->local_list,
4765 client_id, TRUE, NULL);
4766 if (!target_client) {
4767 target_client = silc_idlist_find_client_by_id(server->global_list,
4768 client_id, TRUE, NULL);
4771 /* Check whether target client is on the channel */
4772 if (!silc_server_client_on_channel(target_client, channel, &chl)) {
4773 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
4774 SILC_STATUS_ERR_USER_NOT_ON_CHANNEL,
4779 /* Check that the target client is not channel founder. Channel founder
4780 cannot be kicked from the channel. */
4781 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
4782 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
4783 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
4790 comment = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
4794 /* Send command reply to sender */
4795 silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
4798 /* Send KICKED notify to local clients on the channel */
4799 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
4800 silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
4801 SILC_NOTIFY_TYPE_KICKED, 3,
4802 target_idp, target_idp_len,
4803 comment, comment ? strlen(comment) : 0,
4804 idp->data, idp->len);
4805 silc_buffer_free(idp);
4807 /* Remove the client from the channel. If the channel does not exist
4808 after removing the client then the client kicked itself off the channel
4809 and we don't have to send anything after that. */
4810 if (!silc_server_remove_from_one_channel(server, NULL, channel,
4811 target_client, FALSE))
4814 /* Send KICKED notify to primary route */
4815 if (!server->standalone)
4816 silc_server_send_notify_kicked(server, server->router->connection,
4817 server->server_type == SILC_ROUTER ?
4818 TRUE : FALSE, channel,
4819 target_client->id, client->id, comment);
4821 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
4822 /* Re-generate channel key */
4823 if (!silc_server_create_channel_key(server, channel, 0))
4826 /* Send the channel key to the channel. The key of course is not sent
4827 to the client who was kicked off the channel. */
4828 silc_server_send_channel_key(server, target_client->connection, channel,
4829 server->server_type == SILC_ROUTER ?
4830 FALSE : !server->standalone);
4834 silc_server_command_free(cmd);
4837 /* Server side of OPER command. Client uses this comand to obtain server
4838 operator privileges to this server/router. */
4840 SILC_SERVER_CMD_FUNC(oper)
4842 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4843 SilcServer server = cmd->server;
4844 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4845 unsigned char *username, *auth;
4847 SilcServerConfigAdmin *admin;
4848 SilcIDListData idata = (SilcIDListData)client;
4849 bool result = FALSE;
4850 SilcPublicKey cached_key;
4852 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2);
4854 if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
4857 /* Get the username */
4858 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
4860 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4861 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4866 /* Get the admin configuration */
4867 admin = silc_server_config_find_admin(server, cmd->sock->ip,
4868 username, client->nickname);
4870 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
4871 username, client->nickname);
4873 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4874 SILC_STATUS_ERR_AUTH_FAILED,
4880 /* Get the authentication payload */
4881 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
4883 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4884 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
4889 /* Verify the authentication data. If both passphrase and public key
4890 is set then try both of them. */
4891 if (admin->passphrase)
4892 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
4893 admin->passphrase, admin->passphrase_len,
4894 idata->hash, client->id, SILC_ID_CLIENT);
4895 if (!result && admin->publickeys) {
4896 cached_key = silc_server_get_public_key(server, admin->publickeys);
4899 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
4900 cached_key, 0, idata->hash,
4901 client->id, SILC_ID_CLIENT);
4904 /* Authentication failed */
4905 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4906 SILC_STATUS_ERR_AUTH_FAILED,
4911 /* Client is now server operator */
4912 client->mode |= SILC_UMODE_SERVER_OPERATOR;
4914 /* Update statistics */
4915 if (client->connection)
4916 server->stat.my_server_ops++;
4917 if (server->server_type == SILC_ROUTER)
4918 server->stat.server_ops++;
4920 /* Send UMODE change to primary router */
4921 if (!server->standalone)
4922 silc_server_send_notify_umode(server, server->router->connection, TRUE,
4923 client->id, client->mode);
4925 /* Check if anyone is watching this nickname */
4926 if (server->server_type == SILC_ROUTER)
4927 silc_server_check_watcher_list(server, client, NULL,
4928 SILC_NOTIFY_TYPE_UMODE_CHANGE);
4930 /* Send reply to the sender */
4931 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
4935 silc_server_command_free(cmd);
4938 SILC_TASK_CALLBACK(silc_server_command_detach_cb)
4940 QuitInternal q = (QuitInternal)context;
4941 SilcClientEntry client = (SilcClientEntry)q->sock->user_data;
4943 /* If there is pending outgoing data for the client then purge it
4944 to the network before closing connection. */
4945 silc_server_packet_queue_purge(q->server, q->sock);
4947 /* Close the connection on our side */
4948 client->router = NULL;
4949 client->connection = NULL;
4950 q->sock->user_data = NULL;
4951 silc_server_close_connection(q->server, q->sock);
4956 SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
4958 QuitInternal q = (QuitInternal)context;
4959 SilcClientID *client_id = (SilcClientID *)q->sock;
4960 SilcClientEntry client;
4962 SILC_LOG_DEBUG(("Start"));
4964 client = silc_idlist_find_client_by_id(q->server->local_list, client_id,
4967 if (client && client->mode & SILC_UMODE_DETACHED)
4968 silc_server_free_client_data(q->server, NULL, client, TRUE,
4971 silc_free(client_id);
4975 /* Server side of DETACH command. Detached the client from the network
4976 by closing the connection but preserving the session. */
4978 SILC_SERVER_CMD_FUNC(detach)
4980 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
4981 SilcServer server = cmd->server;
4982 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
4985 if (server->config->detach_disabled) {
4986 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
4987 SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
4991 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
4994 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_DETACH, cmd, 0, 0);
4996 /* Send the user mode notify to notify that client is detached */
4997 client->mode |= SILC_UMODE_DETACHED;
4998 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
4999 client->last_command = 0;
5000 client->fast_command = 0;
5001 if (!server->standalone)
5002 silc_server_send_notify_umode(server, server->router->connection,
5003 server->server_type == SILC_SERVER ?
5004 FALSE : TRUE, client->id, client->mode);
5005 server->stat.my_detached++;
5007 /* Check if anyone is watching this nickname */
5008 if (server->server_type == SILC_ROUTER)
5009 silc_server_check_watcher_list(server, client, NULL,
5010 SILC_NOTIFY_TYPE_UMODE_CHANGE);
5012 q = silc_calloc(1, sizeof(*q));
5014 q->sock = cmd->sock;
5015 silc_schedule_task_add(server->schedule, 0, silc_server_command_detach_cb,
5016 q, 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
5018 if (server->config->detach_timeout) {
5019 q = silc_calloc(1, sizeof(*q));
5021 q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
5022 silc_schedule_task_add(server->schedule, 0,
5023 silc_server_command_detach_timeout,
5024 q, server->config->detach_timeout * 60,
5025 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
5028 /* Send reply to the sender */
5029 silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
5033 silc_server_command_free(cmd);
5036 /* Server side of WATCH command. */
5038 SILC_SERVER_CMD_FUNC(watch)
5040 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5041 SilcServer server = cmd->server;
5042 char *add_nick, *del_nick;
5043 SilcUInt32 add_nick_len, del_nick_len, tmp_len;
5045 unsigned char hash[16], *tmp;
5046 SilcClientEntry client;
5047 SilcClientID *client_id = NULL;
5049 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WATCH, cmd, 1, 3);
5051 if (server->server_type == SILC_SERVER && !server->standalone) {
5052 if (!cmd->pending) {
5053 /* Send the command to router */
5055 SilcUInt16 old_ident;
5057 old_ident = silc_command_get_ident(cmd->payload);
5058 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5059 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5061 silc_server_packet_send(server, server->router->connection,
5062 SILC_PACKET_COMMAND, cmd->packet->flags,
5063 tmpbuf->data, tmpbuf->len, TRUE);
5065 /* Reprocess this packet after received reply from router */
5066 silc_server_command_pending(server, SILC_COMMAND_WATCH,
5067 silc_command_get_ident(cmd->payload),
5068 silc_server_command_watch,
5069 silc_server_command_dup(cmd));
5070 cmd->pending = TRUE;
5071 silc_command_set_ident(cmd->payload, old_ident);
5072 silc_buffer_free(tmpbuf);
5073 } else if (context2) {
5074 /* Received reply from router, just send same data to the client. */
5075 SilcServerCommandReplyContext reply = context2;
5077 silc_command_get_status(reply->payload, &status, NULL);
5078 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH, status,
5085 /* We are router and keep the watch list for local cell */
5087 /* Get the client ID */
5088 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5090 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
5091 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5095 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
5097 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
5098 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
5103 /* Get the client entry which must be in local list */
5104 client = silc_idlist_find_client_by_id(server->local_list,
5105 client_id, TRUE, NULL);
5107 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
5108 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
5114 add_nick = silc_argument_get_arg_type(cmd->args, 2, &add_nick_len);
5115 del_nick = silc_argument_get_arg_type(cmd->args, 3, &del_nick_len);
5116 if (!add_nick && !del_nick) {
5117 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
5118 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5123 if (add_nick && add_nick_len > 128)
5124 add_nick[128] = '\0';
5125 if (del_nick && del_nick_len > 128)
5126 del_nick[128] = '\0';
5128 memset(nick, 0, sizeof(nick));
5130 /* Add new nickname to be watched in our cell */
5132 if (silc_server_name_bad_chars(add_nick, strlen(add_nick)) == TRUE) {
5133 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
5134 SILC_STATUS_ERR_BAD_NICKNAME, 0);
5138 /* Hash the nick, we have the hash saved, not nicks because we can
5139 do one to one mapping to the nick from Client ID hash this way. */
5140 silc_to_lower(add_nick, nick, sizeof(nick) - 1);
5141 silc_hash_make(server->md5hash, nick, strlen(nick), hash);
5143 /* Check whether this client is already watching this nickname */
5144 if (silc_hash_table_find_by_context(server->watcher_list, hash,
5146 /* Nickname is alredy being watched for this client */
5147 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
5148 SILC_STATUS_ERR_NICKNAME_IN_USE,
5153 /* Get the nickname from the watcher list and use the same key in
5154 new entries as well. If key doesn't exist then create it. */
5155 if (!silc_hash_table_find(server->watcher_list, hash, (void **)&tmp, NULL))
5156 tmp = silc_memdup(hash, CLIENTID_HASH_LEN);
5158 /* Add the client to the watcher list with the specified nickname hash. */
5159 silc_hash_table_add(server->watcher_list, tmp, client);
5162 /* Delete nickname from watch list */
5164 if (silc_server_name_bad_chars(del_nick, strlen(del_nick)) == TRUE) {
5165 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
5166 SILC_STATUS_ERR_BAD_NICKNAME, 0);
5170 /* Hash the nick, we have the hash saved, not nicks because we can
5171 do one to one mapping to the nick from Client ID hash this way. */
5172 silc_to_lower(del_nick, nick, sizeof(nick) - 1);
5173 silc_hash_make(server->md5hash, nick, strlen(nick), hash);
5175 /* Check that this client is watching for this nickname */
5176 if (!silc_hash_table_find_by_context(server->watcher_list, hash,
5177 client, (void **)&tmp)) {
5178 /* Nickname is alredy being watched for this client */
5179 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
5180 SILC_STATUS_ERR_NO_SUCH_NICK, 0);
5184 /* Delete the nickname from the watcher list. */
5185 silc_hash_table_del_by_context(server->watcher_list, hash, client);
5187 /* Now check whether there still exists entries with this key, if not
5188 then free the key to not leak memory. */
5189 if (!silc_hash_table_find(server->watcher_list, hash, NULL, NULL))
5193 /* Distribute the watch list to backup routers too */
5194 if (server->backup) {
5196 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5197 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5198 silc_server_backup_send(server, NULL, SILC_PACKET_COMMAND,
5199 cmd->packet->flags, tmpbuf->data, tmpbuf->len,
5201 silc_buffer_free(tmpbuf);
5204 silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
5208 silc_free(client_id);
5209 silc_server_command_free(cmd);
5212 /* Server side of SILCOPER command. Client uses this comand to obtain router
5213 operator privileges to this router. */
5215 SILC_SERVER_CMD_FUNC(silcoper)
5217 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5218 SilcServer server = cmd->server;
5219 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5220 unsigned char *username, *auth;
5222 SilcServerConfigAdmin *admin;
5223 SilcIDListData idata = (SilcIDListData)client;
5224 bool result = FALSE;
5225 SilcPublicKey cached_key;
5227 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
5229 if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
5232 if (server->server_type != SILC_ROUTER) {
5233 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
5234 SILC_STATUS_ERR_AUTH_FAILED, 0);
5238 /* Get the username */
5239 username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5241 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
5242 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5247 /* Get the admin configuration */
5248 admin = silc_server_config_find_admin(server, cmd->sock->ip,
5249 username, client->nickname);
5251 admin = silc_server_config_find_admin(server, cmd->sock->hostname,
5252 username, client->nickname);
5254 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
5255 SILC_STATUS_ERR_AUTH_FAILED, 0);
5260 /* Get the authentication payload */
5261 auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5263 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
5264 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5269 /* Verify the authentication data. If both passphrase and public key
5270 is set then try both of them. */
5271 if (admin->passphrase)
5272 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
5273 admin->passphrase, admin->passphrase_len,
5274 idata->hash, client->id, SILC_ID_CLIENT);
5275 if (!result && admin->publickeys) {
5276 cached_key = silc_server_get_public_key(server, admin->publickeys);
5279 result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
5280 cached_key, 0, idata->hash,
5281 client->id, SILC_ID_CLIENT);
5284 /* Authentication failed */
5285 silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
5286 SILC_STATUS_ERR_AUTH_FAILED, 0);
5290 /* Client is now router operator */
5291 client->mode |= SILC_UMODE_ROUTER_OPERATOR;
5293 /* Update statistics */
5294 if (client->connection)
5295 server->stat.my_router_ops++;
5296 if (server->server_type == SILC_ROUTER)
5297 server->stat.router_ops++;
5299 /* Send UMODE change to primary router */
5300 if (!server->standalone)
5301 silc_server_send_notify_umode(server, server->router->connection, TRUE,
5302 client->id, client->mode);
5304 /* Check if anyone is watching this nickname */
5305 if (server->server_type == SILC_ROUTER)
5306 silc_server_check_watcher_list(server, client, NULL,
5307 SILC_NOTIFY_TYPE_UMODE_CHANGE);
5309 /* Send reply to the sender */
5310 silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
5314 silc_server_command_free(cmd);
5317 /* Server side of command BAN. This is used to manage the ban list of the
5318 channel. To add clients and remove clients from the ban list. */
5320 SILC_SERVER_CMD_FUNC(ban)
5322 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5323 SilcServer server = cmd->server;
5324 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5326 SilcChannelEntry channel;
5327 SilcChannelClientEntry chl;
5328 SilcChannelID *channel_id = NULL;
5329 unsigned char *id, *add, *del;
5330 SilcUInt32 id_len, tmp_len;
5331 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
5333 if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
5336 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_BAN, cmd, 0, 3);
5338 /* Get Channel ID */
5339 id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
5341 channel_id = silc_id_payload_parse_id(id, id_len, NULL);
5343 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
5344 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
5349 /* Get channel entry. The server must know about the channel since the
5350 client is expected to be on the channel. */
5351 channel = silc_idlist_find_channel_by_id(server->local_list,
5354 channel = silc_idlist_find_channel_by_id(server->global_list,
5357 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
5358 SILC_STATUS_ERR_NO_SUCH_CHANNEL,
5364 /* Check whether this client is on the channel */
5365 if (!silc_server_client_on_channel(client, channel, &chl)) {
5366 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
5367 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
5371 /* The client must be at least channel operator. */
5372 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
5373 silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
5374 SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0);
5378 /* Get the new ban and add it to the ban list */
5379 add = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5381 if (!channel->ban_list)
5382 channel->ban_list = silc_calloc(tmp_len + 2, sizeof(*channel->ban_list));
5384 channel->ban_list = silc_realloc(channel->ban_list,
5385 sizeof(*channel->ban_list) *
5387 strlen(channel->ban_list) + 2));
5388 if (add[tmp_len - 1] == ',')
5389 add[tmp_len - 1] = '\0';
5391 strncat(channel->ban_list, add, tmp_len);
5392 strncat(channel->ban_list, ",", 1);
5395 /* Get the ban to be removed and remove it from the list */
5396 del = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
5397 if (del && channel->ban_list) {
5398 char *start, *end, *n;
5400 if (!strncmp(channel->ban_list, del, strlen(channel->ban_list) - 1)) {
5401 silc_free(channel->ban_list);
5402 channel->ban_list = NULL;
5404 start = strstr(channel->ban_list, del);
5405 if (start && strlen(start) >= tmp_len) {
5406 end = start + tmp_len;
5407 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
5408 strncat(n, channel->ban_list, start - channel->ban_list);
5409 strncat(n, end + 1, ((channel->ban_list + strlen(channel->ban_list)) -
5411 silc_free(channel->ban_list);
5412 channel->ban_list = n;
5417 /* Send the BAN notify type to our primary router. */
5418 if (!server->standalone && (add || del))
5419 silc_server_send_notify_ban(server, server->router->connection,
5420 server->server_type == SILC_ROUTER ?
5421 TRUE : FALSE, channel, add, del);
5423 /* Send the reply back to the client */
5425 silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
5426 SILC_STATUS_OK, 0, ident, 2,
5428 3, channel->ban_list,
5430 strlen(channel->ban_list) -1 : 0);
5431 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
5432 packet->data, packet->len, FALSE);
5434 silc_buffer_free(packet);
5437 silc_free(channel_id);
5438 silc_server_command_free(cmd);
5441 /* Server side command of LEAVE. Removes client from a channel. */
5443 SILC_SERVER_CMD_FUNC(leave)
5445 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5446 SilcServer server = cmd->server;
5447 SilcSocketConnection sock = cmd->sock;
5448 SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
5449 SilcChannelID *id = NULL;
5450 SilcChannelEntry channel;
5454 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 2);
5456 /* Get Channel ID */
5457 tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
5459 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
5460 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
5463 id = silc_id_payload_parse_id(tmp, len, NULL);
5465 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
5466 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
5470 /* Get channel entry */
5471 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
5473 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
5475 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
5476 SILC_STATUS_ERR_NO_SUCH_CHANNEL,
5482 /* Check whether this client is on the channel */
5483 if (!silc_server_client_on_channel(id_entry, channel, NULL)) {
5484 silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
5485 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
5489 /* Notify routers that they should remove this client from their list
5490 of clients on the channel. Send LEAVE notify type. */
5491 if (!server->standalone)
5492 silc_server_send_notify_leave(server, server->router->connection,
5493 server->server_type == SILC_ROUTER ?
5494 TRUE : FALSE, channel, id_entry->id);
5496 silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
5497 SILC_STATUS_OK, 0, 2, tmp, len);
5499 /* Remove client from channel */
5500 if (!silc_server_remove_from_one_channel(server, sock, channel, id_entry,
5502 /* If the channel does not exist anymore we won't send anything */
5505 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
5506 /* Re-generate channel key */
5507 if (!silc_server_create_channel_key(server, channel, 0))
5510 /* Send the channel key */
5511 silc_server_send_channel_key(server, NULL, channel,
5512 server->server_type == SILC_ROUTER ?
5513 FALSE : !server->standalone);
5518 silc_server_command_free(cmd);
5521 /* Server side of command USERS. Resolves clients and their USERS currently
5522 joined on the requested channel. The list of Client ID's and their modes
5523 on the channel is sent back. */
5525 SILC_SERVER_CMD_FUNC(users)
5527 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5528 SilcServer server = cmd->server;
5529 SilcChannelEntry channel;
5530 SilcChannelID *id = NULL;
5531 SilcBuffer packet, idp;
5532 unsigned char *channel_id;
5533 SilcUInt32 channel_id_len;
5534 SilcBuffer client_id_list;
5535 SilcBuffer client_mode_list;
5536 unsigned char lc[4];
5537 SilcUInt32 list_count = 0;
5538 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
5541 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2);
5543 /* Get Channel ID */
5544 channel_id = silc_argument_get_arg_type(cmd->args, 1, &channel_id_len);
5546 /* Get channel name */
5547 channel_name = silc_argument_get_arg_type(cmd->args, 2, NULL);
5549 if (!channel_id && !channel_name) {
5550 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
5551 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
5556 id = silc_id_payload_parse_id(channel_id, channel_id_len, NULL);
5558 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
5559 SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
5564 /* If we are server and we don't know about this channel we will send
5565 the command to our router. If we know about the channel then we also
5566 have the list of users already. */
5568 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
5570 channel = silc_idlist_find_channel_by_name(server->local_list,
5571 channel_name, NULL);
5573 if (!channel || (!server->standalone && (channel->disabled ||
5574 !channel->users_resolved))) {
5575 if (server->server_type != SILC_ROUTER && !server->standalone &&
5579 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5580 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5582 /* Send USERS command */
5583 silc_server_packet_send(server, server->router->connection,
5584 SILC_PACKET_COMMAND, cmd->packet->flags,
5585 tmpbuf->data, tmpbuf->len, TRUE);
5587 /* Reprocess this packet after received reply */
5588 silc_server_command_pending(server, SILC_COMMAND_USERS,
5589 silc_command_get_ident(cmd->payload),
5590 silc_server_command_users,
5591 silc_server_command_dup(cmd));
5592 cmd->pending = TRUE;
5593 silc_command_set_ident(cmd->payload, ident);
5594 silc_buffer_free(tmpbuf);
5599 /* Check the global list as well. */
5601 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
5603 channel = silc_idlist_find_channel_by_name(server->global_list,
5604 channel_name, NULL);
5606 /* Channel really does not exist */
5607 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
5608 SILC_STATUS_ERR_NO_SUCH_CHANNEL,
5614 /* If the channel is private or secret do not send anything, unless the
5615 user requesting this command is on the channel or is server */
5616 if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
5617 if (channel->mode & (SILC_CHANNEL_MODE_PRIVATE | SILC_CHANNEL_MODE_SECRET)
5618 && !silc_server_client_on_channel(cmd->sock->user_data, channel,
5620 silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
5621 SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
5626 /* Get the users list */
5627 if (!silc_server_get_users_on_channel(server, channel, &client_id_list,
5628 &client_mode_list, &list_count)) {
5630 client_id_list = NULL;
5631 client_mode_list = NULL;
5635 SILC_PUT32_MSB(list_count, lc);
5638 idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
5639 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_USERS,
5640 SILC_STATUS_OK, 0, ident, 4,
5641 2, idp->data, idp->len,
5644 client_id_list->data : NULL,
5646 client_id_list->len : 0,
5647 5, client_mode_list ?
5648 client_mode_list->data : NULL,
5650 client_mode_list->len : 0);
5651 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
5652 packet->data, packet->len, FALSE);
5654 silc_buffer_free(idp);
5655 silc_buffer_free(packet);
5657 silc_buffer_free(client_id_list);
5658 if (client_mode_list)
5659 silc_buffer_free(client_mode_list);
5663 silc_server_command_free(cmd);
5666 /* Server side of command GETKEY. This fetches the client's public key
5667 from the server where to the client is connected. */
5669 SILC_SERVER_CMD_FUNC(getkey)
5671 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5672 SilcServer server = cmd->server;
5674 SilcClientEntry client;
5675 SilcServerEntry server_entry;
5676 SilcClientID *client_id = NULL;
5677 SilcServerID *server_id = NULL;
5678 SilcIDPayload idp = NULL;
5679 SilcUInt16 ident = silc_command_get_ident(cmd->payload);
5680 unsigned char *tmp, *pkdata;
5681 SilcUInt32 tmp_len, pklen;
5682 SilcBuffer pk = NULL;
5684 SilcPublicKey public_key;
5686 SILC_LOG_DEBUG(("Start"));
5688 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5690 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
5691 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5695 idp = silc_id_payload_parse(tmp, tmp_len);
5697 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
5698 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5703 id_type = silc_id_payload_get_type(idp);
5704 if (id_type == SILC_ID_CLIENT) {
5705 client_id = silc_id_payload_get_id(idp);
5707 /* If the client is not found from local list there is no chance it
5708 would be locally connected client so send the command further. */
5709 client = silc_idlist_find_client_by_id(server->local_list,
5710 client_id, TRUE, NULL);
5712 client = silc_idlist_find_client_by_id(server->global_list,
5713 client_id, TRUE, NULL);
5715 if ((!client && !cmd->pending && !server->standalone) ||
5716 (client && !client->connection && !cmd->pending &&
5717 !(client->mode & SILC_UMODE_DETACHED)) ||
5718 (client && !client->data.public_key && !cmd->pending)) {
5720 SilcUInt16 old_ident;
5721 SilcSocketConnection dest_sock;
5723 dest_sock = silc_server_get_client_route(server, NULL, 0,
5724 client_id, NULL, NULL);
5728 old_ident = silc_command_get_ident(cmd->payload);
5729 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5730 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5732 silc_server_packet_send(server, dest_sock,
5733 SILC_PACKET_COMMAND, cmd->packet->flags,
5734 tmpbuf->data, tmpbuf->len, TRUE);
5736 /* Reprocess this packet after received reply from router */
5737 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
5738 silc_command_get_ident(cmd->payload),
5739 silc_server_command_getkey,
5740 silc_server_command_dup(cmd));
5741 cmd->pending = TRUE;
5742 silc_command_set_ident(cmd->payload, old_ident);
5743 silc_buffer_free(tmpbuf);
5748 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
5749 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
5754 /* The client is locally connected, just get the public key and
5755 send it back. If they key does not exist then do not send it,
5756 send just OK reply */
5757 public_key = client->data.public_key;
5762 tmp = silc_pkcs_public_key_encode(public_key, &tmp_len);
5763 pk = silc_buffer_alloc(4 + tmp_len);
5764 silc_buffer_pull_tail(pk, SILC_BUFFER_END(pk));
5765 silc_buffer_format(pk,
5766 SILC_STR_UI_SHORT(tmp_len),
5767 SILC_STR_UI_SHORT(SILC_SKE_PK_TYPE_SILC),
5768 SILC_STR_UI_XNSTRING(tmp, tmp_len),
5774 } else if (id_type == SILC_ID_SERVER) {
5775 server_id = silc_id_payload_get_id(idp);
5777 /* If the server is not found from local list there is no chance it
5778 would be locally connected server so send the command further. */
5779 server_entry = silc_idlist_find_server_by_id(server->local_list,
5780 server_id, TRUE, NULL);
5782 server_entry = silc_idlist_find_server_by_id(server->global_list,
5783 server_id, TRUE, NULL);
5785 if (server_entry != server->id_entry &&
5786 ((!server_entry && !cmd->pending && !server->standalone) ||
5787 (server_entry && !server_entry->connection && !cmd->pending &&
5788 !server->standalone) ||
5789 (server_entry && !server_entry->data.public_key && !cmd->pending &&
5790 !server->standalone))) {
5792 SilcUInt16 old_ident;
5794 old_ident = silc_command_get_ident(cmd->payload);
5795 silc_command_set_ident(cmd->payload, ++server->cmd_ident);
5796 tmpbuf = silc_command_payload_encode_payload(cmd->payload);
5798 silc_server_packet_send(server, server->router->connection,
5799 SILC_PACKET_COMMAND, cmd->packet->flags,
5800 tmpbuf->data, tmpbuf->len, TRUE);
5802 /* Reprocess this packet after received reply from router */
5803 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
5804 silc_command_get_ident(cmd->payload),
5805 silc_server_command_getkey,
5806 silc_server_command_dup(cmd));
5807 cmd->pending = TRUE;
5808 silc_command_set_ident(cmd->payload, old_ident);
5809 silc_buffer_free(tmpbuf);
5813 if (!server_entry) {
5814 silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
5815 SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
5820 /* If they key does not exist then do not send it, send just OK reply */
5821 public_key = (!server_entry->data.public_key ?
5822 (server_entry == server->id_entry ? server->public_key :
5823 NULL) : server_entry->data.public_key);
5828 tmp = silc_pkcs_public_key_encode(public_key, &tmp_len);
5829 pk = silc_buffer_alloc(4 + tmp_len);
5830 silc_buffer_pull_tail(pk, SILC_BUFFER_END(pk));
5831 silc_buffer_format(pk,
5832 SILC_STR_UI_SHORT(tmp_len),
5833 SILC_STR_UI_SHORT(SILC_SKE_PK_TYPE_SILC),
5834 SILC_STR_UI_XNSTRING(tmp, tmp_len),
5844 tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5845 packet = silc_command_reply_payload_encode_va(SILC_COMMAND_GETKEY,
5846 SILC_STATUS_OK, 0, ident,
5850 silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
5851 packet->data, packet->len, FALSE);
5852 silc_buffer_free(packet);
5855 silc_buffer_free(pk);
5859 silc_id_payload_free(idp);
5860 silc_free(client_id);
5861 silc_free(server_id);
5862 silc_server_command_free(cmd);
5866 /* Private range commands, specific to this implementation */
5868 /* Server side command of CONNECT. Connects us to the specified remote
5869 server or router. */
5871 SILC_SERVER_CMD_FUNC(connect)
5873 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5874 SilcServer server = cmd->server;
5875 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5876 unsigned char *tmp, *host;
5878 SilcUInt32 port = SILC_PORT;
5880 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CONNECT, cmd, 1, 2);
5882 if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
5885 /* Check whether client has the permissions. */
5886 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5887 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5888 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5889 SILC_STATUS_ERR_NO_SERVER_PRIV, 0);
5893 if (server->server_type == SILC_ROUTER &&
5894 client->mode & SILC_UMODE_SERVER_OPERATOR) {
5895 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5896 SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
5900 /* Get the remote server */
5901 host = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5903 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5904 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5910 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5912 SILC_GET32_MSB(port, tmp);
5914 /* Create the connection. It is done with timeout and is async. */
5915 silc_server_create_connection(server, host, port);
5917 /* Send reply to the sender */
5918 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
5922 silc_server_command_free(cmd);
5925 /* Server side command of CLOSE. Closes connection to a specified server. */
5927 SILC_SERVER_CMD_FUNC(close)
5929 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
5930 SilcServer server = cmd->server;
5931 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
5932 SilcServerEntry server_entry;
5933 SilcSocketConnection sock;
5936 unsigned char *name;
5937 SilcUInt32 port = SILC_PORT;
5939 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_CLOSE, cmd, 1, 2);
5941 if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
5944 /* Check whether client has the permissions. */
5945 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
5946 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
5947 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5948 SILC_STATUS_ERR_NO_SERVER_PRIV,
5953 /* Get the remote server */
5954 name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
5956 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5957 SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
5963 tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
5965 SILC_GET32_MSB(port, tmp);
5967 server_entry = silc_idlist_find_server_by_conn(server->local_list,
5968 name, port, FALSE, NULL);
5970 server_entry = silc_idlist_find_server_by_conn(server->global_list,
5971 name, port, FALSE, NULL);
5972 if (!server_entry) {
5973 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5974 SILC_STATUS_ERR_NO_SERVER_ID, 0);
5978 /* Send reply to the sender */
5979 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
5982 /* Close the connection to the server */
5983 sock = (SilcSocketConnection)server_entry->connection;
5985 /* If we shutdown primary router connection manually then don't trigger
5986 any reconnect or backup router connections, by setting the router
5988 if (server->router == server_entry) {
5989 server->id_entry->router = NULL;
5990 server->router = NULL;
5991 server->standalone = TRUE;
5993 silc_server_free_sock_user_data(server, sock, NULL);
5994 silc_server_close_connection(server, sock);
5997 silc_server_command_free(cmd);
6000 /* Server side command of SHUTDOWN. Shutdowns the server and closes all
6001 active connections. */
6003 SILC_SERVER_CMD_FUNC(shutdown)
6005 SilcServerCommandContext cmd = (SilcServerCommandContext)context;
6006 SilcServer server = cmd->server;
6007 SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
6009 SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PRIV_SHUTDOWN, cmd, 0, 0);
6011 if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
6014 /* Check whether client has the permission. */
6015 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
6016 !(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
6017 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
6018 SILC_STATUS_ERR_NO_SERVER_PRIV,
6023 /* Send reply to the sender */
6024 silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
6027 /* Then, gracefully, or not, bring the server down. */
6028 silc_server_stop(server);
6032 silc_server_command_free(cmd);