5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 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.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 extern char *server_version;
30 /* Received notify packet. Server can receive notify packets from router.
31 Server then relays the notify messages to clients if needed. */
33 void silc_server_notify(SilcServer server,
34 SilcSocketConnection sock,
35 SilcPacketContext *packet)
37 SilcNotifyPayload payload;
39 SilcArgumentPayload args;
40 SilcChannelID *channel_id = NULL, *channel_id2;
41 SilcClientID *client_id, *client_id2;
42 SilcServerID *server_id;
43 SilcChannelEntry channel;
44 SilcClientEntry client;
45 SilcServerEntry server_entry;
46 SilcChannelClientEntry chl;
47 SilcIDCacheEntry cache;
48 SilcHashTableList htl;
54 SILC_LOG_DEBUG(("Start"));
56 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
57 packet->src_id_type != SILC_ID_SERVER)
63 /* If the packet is destined directly to a client then relay the packet
64 before processing it. */
65 if (packet->dst_id_type == SILC_ID_CLIENT) {
67 SilcSocketConnection dst_sock;
69 /* Get the route to the client */
70 dst_sock = silc_server_get_client_route(server, packet->dst_id,
71 packet->dst_id_len, NULL, &idata);
73 /* Relay the packet */
74 silc_server_relay_packet(server, dst_sock, idata->send_key,
75 idata->hmac_receive, idata->psn_send++,
79 /* Parse the Notify Payload */
80 payload = silc_notify_payload_parse(packet->buffer->data,
85 /* If we are router and this packet is not already broadcast packet
86 we will broadcast it. The sending socket really cannot be router or
87 the router is buggy. If this packet is coming from router then it must
88 have the broadcast flag set already and we won't do anything. */
89 if (!server->standalone && server->server_type == SILC_ROUTER &&
90 sock->type == SILC_SOCKET_TYPE_SERVER &&
91 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
92 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
93 if (packet->dst_id_type == SILC_ID_CHANNEL) {
94 /* Packet is destined to channel */
95 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
100 silc_server_packet_send_dest(server, server->router->connection,
102 packet->flags | SILC_PACKET_FLAG_BROADCAST,
103 channel_id, SILC_ID_CHANNEL,
104 packet->buffer->data, packet->buffer->len,
106 silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data,
107 packet->type, packet->flags,
108 channel_id, SILC_ID_CHANNEL,
109 packet->buffer->data, packet->buffer->len,
112 /* Packet is destined to client or server */
113 silc_server_packet_send(server, server->router->connection,
115 packet->flags | SILC_PACKET_FLAG_BROADCAST,
116 packet->buffer->data, packet->buffer->len,
118 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
119 packet->type, packet->flags,
120 packet->buffer->data, packet->buffer->len,
125 type = silc_notify_get_type(payload);
126 args = silc_notify_get_args(payload);
131 case SILC_NOTIFY_TYPE_JOIN:
133 * Distribute the notify to local clients on the channel
135 SILC_LOG_DEBUG(("JOIN notify"));
138 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
141 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
145 /* Get channel entry */
146 channel = silc_idlist_find_channel_by_id(server->global_list,
149 channel = silc_idlist_find_channel_by_id(server->local_list,
152 silc_free(channel_id);
156 silc_free(channel_id);
159 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
162 client_id = silc_id_payload_parse_id(tmp, tmp_len);
166 /* If the the client is not in local list we check global list (ie. the
167 channel will be global channel) and if it does not exist then create
168 entry for the client. */
169 client = silc_idlist_find_client_by_id(server->global_list,
170 client_id, server->server_type,
173 client = silc_idlist_find_client_by_id(server->local_list,
174 client_id, server->server_type,
177 /* If router did not find the client the it is bogus */
178 if (server->server_type != SILC_SERVER)
182 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
183 silc_id_dup(client_id, SILC_ID_CLIENT),
184 sock->user_data, NULL, 0);
186 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
187 silc_free(client_id);
191 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
195 /* Do not process the notify if the client is not registered */
196 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
199 /* Do not add client to channel if it is there already */
200 if (silc_server_client_on_channel(client, channel)) {
201 SILC_LOG_DEBUG(("Client already on channel"));
205 /* Send to channel */
206 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
207 FALSE, packet->buffer->data,
208 packet->buffer->len, FALSE);
210 if (server->server_type != SILC_ROUTER &&
211 sock->type == SILC_SOCKET_TYPE_ROUTER)
212 /* The channel is global now */
213 channel->global_users = TRUE;
215 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
217 /* JOIN the global client to the channel (local clients (if router
218 created the channel) is joined in the pending JOIN command). */
219 chl = silc_calloc(1, sizeof(*chl));
220 chl->client = client;
221 chl->channel = channel;
223 /* If this is the first one on the channel then it is the founder of
225 if (!silc_hash_table_count(channel->user_list))
226 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
228 silc_hash_table_add(channel->user_list, client, chl);
229 silc_hash_table_add(client->channels, channel, chl);
230 silc_free(client_id);
234 case SILC_NOTIFY_TYPE_LEAVE:
236 * Distribute the notify to local clients on the channel
238 SILC_LOG_DEBUG(("LEAVE notify"));
241 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
242 packet->dst_id_type);
247 /* Get channel entry */
248 channel = silc_idlist_find_channel_by_id(server->global_list,
251 channel = silc_idlist_find_channel_by_id(server->local_list,
254 silc_free(channel_id);
260 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
262 silc_free(channel_id);
265 client_id = silc_id_payload_parse_id(tmp, tmp_len);
267 silc_free(channel_id);
271 /* Get client entry */
272 client = silc_idlist_find_client_by_id(server->global_list,
273 client_id, TRUE, NULL);
275 client = silc_idlist_find_client_by_id(server->local_list,
276 client_id, TRUE, NULL);
278 silc_free(client_id);
279 silc_free(channel_id);
283 silc_free(client_id);
285 /* Check if on channel */
286 if (!silc_server_client_on_channel(client, channel))
289 /* Send the leave notify to channel */
290 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
291 FALSE, packet->buffer->data,
292 packet->buffer->len, FALSE);
294 /* Remove the user from channel */
295 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
298 case SILC_NOTIFY_TYPE_SIGNOFF:
300 * Distribute the notify to local clients on the channel
302 SILC_LOG_DEBUG(("SIGNOFF notify"));
305 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
308 client_id = silc_id_payload_parse_id(tmp, tmp_len);
312 /* Get client entry */
313 client = silc_idlist_find_client_by_id(server->global_list,
314 client_id, TRUE, &cache);
316 client = silc_idlist_find_client_by_id(server->local_list,
317 client_id, TRUE, &cache);
319 silc_free(client_id);
323 silc_free(client_id);
325 /* Get signoff message */
326 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
330 /* Update statistics */
331 server->stat.clients--;
332 if (server->server_type == SILC_ROUTER)
333 server->stat.cell_clients--;
334 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
335 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
337 /* Remove the client from all channels. */
338 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
340 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
341 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
344 case SILC_NOTIFY_TYPE_TOPIC_SET:
346 * Distribute the notify to local clients on the channel
349 SILC_LOG_DEBUG(("TOPIC SET notify"));
352 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
353 packet->dst_id_type);
358 /* Get channel entry */
359 channel = silc_idlist_find_channel_by_id(server->global_list,
362 channel = silc_idlist_find_channel_by_id(server->local_list,
365 silc_free(channel_id);
371 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
373 silc_free(channel_id);
377 silc_free(channel->topic);
378 channel->topic = strdup(tmp);
380 /* Send the same notify to the channel */
381 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
382 FALSE, packet->buffer->data,
383 packet->buffer->len, FALSE);
384 silc_free(channel_id);
387 case SILC_NOTIFY_TYPE_NICK_CHANGE:
390 * Distribute the notify to local clients on the channel
392 unsigned char *id, *id2;
394 SILC_LOG_DEBUG(("NICK CHANGE notify"));
396 /* Get old client ID */
397 id = silc_argument_get_arg_type(args, 1, &tmp_len);
400 client_id = silc_id_payload_parse_id(id, tmp_len);
404 /* Get new client ID */
405 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
408 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
412 SILC_LOG_DEBUG(("Old Client ID id(%s)",
413 silc_id_render(client_id, SILC_ID_CLIENT)));
414 SILC_LOG_DEBUG(("New Client ID id(%s)",
415 silc_id_render(client_id2, SILC_ID_CLIENT)));
417 /* Replace the Client ID */
418 client = silc_idlist_replace_client_id(server->global_list, client_id,
421 client = silc_idlist_replace_client_id(server->local_list, client_id,
425 /* The nickname is not valid anymore, set it NULL. This causes that
426 the nickname will be queried if someone wants to know it. */
427 if (client->nickname)
428 silc_free(client->nickname);
429 client->nickname = NULL;
431 /* Send the NICK_CHANGE notify type to local clients on the channels
432 this client is joined to. */
433 silc_server_send_notify_on_channels(server, NULL, client,
434 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
439 silc_free(client_id);
441 silc_free(client_id2);
445 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
447 * Distribute the notify to local clients on the channel
450 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
453 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
454 packet->dst_id_type);
459 /* Get channel entry */
460 channel = silc_idlist_find_channel_by_id(server->global_list,
463 channel = silc_idlist_find_channel_by_id(server->local_list,
466 silc_free(channel_id);
472 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
474 silc_free(channel_id);
478 SILC_GET32_MSB(mode, tmp);
480 /* Check if mode changed */
481 if (channel->mode == mode)
484 /* Send the same notify to the channel */
485 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
486 FALSE, packet->buffer->data,
487 packet->buffer->len, FALSE);
489 /* If the channel had private keys set and the mode was removed then
490 we must re-generate and re-distribute a new channel key */
491 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
492 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
493 /* Re-generate channel key */
494 if (!silc_server_create_channel_key(server, channel, 0))
497 /* Send the channel key. This sends it to our local clients and if
498 we are normal server to our router as well. */
499 silc_server_send_channel_key(server, NULL, channel,
500 server->server_type == SILC_ROUTER ?
501 FALSE : !server->standalone);
505 channel->mode = mode;
506 silc_free(channel_id);
509 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
511 unsigned char hash[32];
514 silc_hmac_free(channel->hmac);
515 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
518 /* Set the HMAC key out of current channel key. The client must do
520 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
521 channel->key_len / 8,
523 silc_hmac_set_key(channel->hmac, hash,
524 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
525 memset(hash, 0, sizeof(hash));
528 /* Get the passphrase */
529 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
531 silc_free(channel->passphrase);
532 channel->passphrase = strdup(tmp);
537 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
540 * Distribute the notify to local clients on the channel
542 SilcChannelClientEntry chl2 = NULL;
543 bool notify_sent = FALSE;
545 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
548 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
549 packet->dst_id_type);
554 /* Get channel entry */
555 channel = silc_idlist_find_channel_by_id(server->global_list,
558 channel = silc_idlist_find_channel_by_id(server->local_list,
561 silc_free(channel_id);
567 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
569 silc_free(channel_id);
573 SILC_GET32_MSB(mode, tmp);
575 /* Get target client */
576 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
579 client_id = silc_id_payload_parse_id(tmp, tmp_len);
583 /* Get client entry */
584 client = silc_idlist_find_client_by_id(server->global_list,
585 client_id, TRUE, NULL);
587 client = silc_idlist_find_client_by_id(server->local_list,
588 client_id, TRUE, NULL);
590 silc_free(client_id);
594 silc_free(client_id);
596 /* Get entry to the channel user list */
597 silc_hash_table_list(channel->user_list, &htl);
598 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
599 /* If the mode is channel founder and we already find a client
600 to have that mode on the channel we will enforce the sender
601 to change the channel founder mode away. There can be only one
602 channel founder on the channel. */
603 if (server->server_type == SILC_ROUTER &&
604 mode & SILC_CHANNEL_UMODE_CHANFO &&
605 chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
607 unsigned char cumode[4];
609 if (chl->client == client && chl->mode == mode) {
614 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
615 silc_server_send_notify_cumode(server, sock, FALSE, channel, mode,
616 client->id, SILC_ID_CLIENT,
619 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
620 SILC_PUT32_MSB(mode, cumode);
621 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
622 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
623 3, idp->data, idp->len,
625 idp->data, idp->len);
626 silc_buffer_free(idp);
629 /* Force the mode change if we alredy set the mode */
632 silc_free(channel_id);
633 silc_hash_table_list_reset(&htl);
638 if (chl->client == client) {
639 if (chl->mode == mode) {
644 SILC_LOG_DEBUG(("Changing the channel user mode"));
646 /* Change the mode */
648 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
654 silc_hash_table_list_reset(&htl);
656 /* Send the same notify to the channel */
658 silc_server_packet_send_to_channel(server, sock, channel,
660 FALSE, packet->buffer->data,
661 packet->buffer->len, FALSE);
663 silc_free(channel_id);
667 case SILC_NOTIFY_TYPE_INVITE:
669 if (packet->dst_id_type == SILC_ID_CLIENT)
672 SILC_LOG_DEBUG(("INVITE notify"));
675 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
678 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
682 /* Get channel entry */
683 channel = silc_idlist_find_channel_by_id(server->global_list,
686 channel = silc_idlist_find_channel_by_id(server->local_list,
689 silc_free(channel_id);
693 silc_free(channel_id);
695 /* Get the added invite */
696 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
698 if (!channel->invite_list)
699 channel->invite_list = silc_calloc(tmp_len + 2,
700 sizeof(*channel->invite_list));
702 channel->invite_list = silc_realloc(channel->invite_list,
703 sizeof(*channel->invite_list) *
705 strlen(channel->invite_list) +
707 if (tmp[tmp_len - 1] == ',')
708 tmp[tmp_len - 1] = '\0';
710 strncat(channel->invite_list, tmp, tmp_len);
711 strncat(channel->invite_list, ",", 1);
714 /* Get the deleted invite */
715 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
716 if (tmp && channel->invite_list) {
717 char *start, *end, *n;
719 if (!strncmp(channel->invite_list, tmp,
720 strlen(channel->invite_list) - 1)) {
721 silc_free(channel->invite_list);
722 channel->invite_list = NULL;
724 start = strstr(channel->invite_list, tmp);
725 if (start && strlen(start) >= tmp_len) {
726 end = start + tmp_len;
727 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
728 strncat(n, channel->invite_list, start - channel->invite_list);
729 strncat(n, end + 1, ((channel->invite_list +
730 strlen(channel->invite_list)) - end) - 1);
731 silc_free(channel->invite_list);
732 channel->invite_list = n;
739 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
741 * Distribute to the local clients on the channel and change the
745 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
747 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
750 /* Get the old Channel ID */
751 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
754 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
758 /* Get the channel entry */
759 channel = silc_idlist_find_channel_by_id(server->local_list,
762 channel = silc_idlist_find_channel_by_id(server->global_list,
765 silc_free(channel_id);
770 /* Send the notify to the channel */
771 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
772 FALSE, packet->buffer->data,
773 packet->buffer->len, FALSE);
775 /* Get the new Channel ID */
776 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
779 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
783 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
784 silc_id_render(channel_id, SILC_ID_CHANNEL)));
785 SILC_LOG_DEBUG(("New Channel ID id(%s)",
786 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
788 /* Replace the Channel ID */
789 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
791 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
793 silc_free(channel_id2);
798 SilcBuffer users = NULL, users_modes = NULL;
800 /* Re-announce this channel which ID was changed. */
801 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
803 silc_id_get_len(channel->id,
807 /* Re-announce our clients on the channel as the ID has changed now */
808 silc_server_announce_get_channel_users(server, channel, &users,
811 silc_buffer_push(users, users->data - users->head);
812 silc_server_packet_send(server, sock,
813 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
814 users->data, users->len, FALSE);
815 silc_buffer_free(users);
818 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
819 silc_server_packet_send_dest(server, sock,
820 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
821 channel->id, SILC_ID_CHANNEL,
823 users_modes->len, FALSE);
824 silc_buffer_free(users_modes);
827 /* Re-announce channel's topic */
828 if (channel->topic) {
829 silc_server_send_notify_topic_set(server, sock,
830 server->server_type == SILC_ROUTER ?
831 TRUE : FALSE, channel,
832 channel->id, SILC_ID_CHANNEL,
837 silc_free(channel_id);
841 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
843 * Remove the server entry and all clients that this server owns.
846 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
849 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
852 server_id = silc_id_payload_parse_id(tmp, tmp_len);
856 /* Get server entry */
857 server_entry = silc_idlist_find_server_by_id(server->global_list,
858 server_id, TRUE, NULL);
861 server_entry = silc_idlist_find_server_by_id(server->local_list,
862 server_id, TRUE, NULL);
865 /* If we are normal server then we might not have the server. Check
866 whether router was kind enough to send the list of all clients
867 that actually was to be removed. Remove them if the list is
869 if (server->server_type != SILC_ROUTER &&
870 silc_argument_get_arg_num(args) > 1) {
873 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
875 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
878 client_id = silc_id_payload_parse_id(tmp, tmp_len);
882 /* Get client entry */
883 client = silc_idlist_find_client_by_id(server->global_list,
884 client_id, TRUE, &cache);
887 client = silc_idlist_find_client_by_id(server->local_list,
888 client_id, TRUE, &cache);
891 silc_free(client_id);
895 silc_free(client_id);
897 /* Update statistics */
898 server->stat.clients--;
899 if (server->server_type == SILC_ROUTER)
900 server->stat.cell_clients--;
901 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
902 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
904 /* Remove the client from all channels. */
905 silc_server_remove_from_channels(server, NULL, client,
908 /* Remove the client */
909 silc_idlist_del_client(local ? server->local_list :
910 server->global_list, client);
914 silc_free(server_id);
918 silc_free(server_id);
920 /* Free all client entries that this server owns as they will
921 become invalid now as well. */
922 silc_server_remove_clients_by_server(server, server_entry, TRUE);
924 /* Remove the server entry */
925 silc_idlist_del_server(local ? server->local_list :
926 server->global_list, server_entry);
928 /* XXX update statistics */
932 case SILC_NOTIFY_TYPE_KICKED:
934 * Distribute the notify to local clients on the channel
937 SILC_LOG_DEBUG(("KICKED notify"));
940 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
941 packet->dst_id_type);
946 /* Get channel entry */
947 channel = silc_idlist_find_channel_by_id(server->global_list,
950 channel = silc_idlist_find_channel_by_id(server->local_list,
953 silc_free(channel_id);
957 silc_free(channel_id);
960 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
963 client_id = silc_id_payload_parse_id(tmp, tmp_len);
967 /* If the the client is not in local list we check global list */
968 client = silc_idlist_find_client_by_id(server->global_list,
969 client_id, TRUE, NULL);
971 client = silc_idlist_find_client_by_id(server->local_list,
972 client_id, TRUE, NULL);
974 silc_free(client_id);
979 /* Send to channel */
980 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
981 FALSE, packet->buffer->data,
982 packet->buffer->len, FALSE);
984 /* Remove the client from channel */
985 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
989 case SILC_NOTIFY_TYPE_KILLED:
992 * Distribute the notify to local clients on channels
997 SILC_LOG_DEBUG(("KILLED notify"));
1000 id = silc_argument_get_arg_type(args, 1, &id_len);
1003 client_id = silc_id_payload_parse_id(id, id_len);
1007 /* If the the client is not in local list we check global list */
1008 client = silc_idlist_find_client_by_id(server->global_list,
1009 client_id, TRUE, NULL);
1011 client = silc_idlist_find_client_by_id(server->local_list,
1012 client_id, TRUE, NULL);
1014 silc_free(client_id);
1018 silc_free(client_id);
1020 /* If the client is one of ours, then close the connection to the
1021 client now. This removes the client from all channels as well. */
1022 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1023 sock = client->connection;
1024 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1025 silc_server_close_connection(server, sock);
1030 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1034 /* Send the notify to local clients on the channels except to the
1035 client who is killed. */
1036 silc_server_send_notify_on_channels(server, client, client,
1037 SILC_NOTIFY_TYPE_KILLED,
1042 /* Remove the client from all channels */
1043 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1049 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1051 * Save the mode of the client.
1054 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1057 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1060 client_id = silc_id_payload_parse_id(tmp, tmp_len);
1064 /* Get client entry */
1065 client = silc_idlist_find_client_by_id(server->global_list,
1066 client_id, TRUE, NULL);
1068 client = silc_idlist_find_client_by_id(server->local_list,
1069 client_id, TRUE, NULL);
1071 silc_free(client_id);
1075 silc_free(client_id);
1078 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1081 SILC_GET32_MSB(mode, tmp);
1083 #define SILC_UMODE_STATS_UPDATE(oper, mod) \
1085 if (client->mode & (mod)) { \
1086 if (!(mode & (mod))) { \
1087 if (client->connection) \
1088 server->stat.my_ ## oper ## _ops--; \
1089 if (server->server_type == SILC_ROUTER) \
1090 server->stat. oper ## _ops--; \
1093 if (mode & (mod)) { \
1094 if (client->connection) \
1095 server->stat.my_ ## oper ## _ops++; \
1096 if (server->server_type == SILC_ROUTER) \
1097 server->stat. oper ## _ops++; \
1102 /* Update statistics */
1103 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1104 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1107 client->mode = mode;
1111 case SILC_NOTIFY_TYPE_BAN:
1116 SILC_LOG_DEBUG(("BAN notify"));
1118 /* Get Channel ID */
1119 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1122 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1126 /* Get channel entry */
1127 channel = silc_idlist_find_channel_by_id(server->global_list,
1130 channel = silc_idlist_find_channel_by_id(server->local_list,
1133 silc_free(channel_id);
1137 silc_free(channel_id);
1139 /* Get the new ban and add it to the ban list */
1140 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1142 if (!channel->ban_list)
1143 channel->ban_list = silc_calloc(tmp_len + 2,
1144 sizeof(*channel->ban_list));
1146 channel->ban_list = silc_realloc(channel->ban_list,
1147 sizeof(*channel->ban_list) *
1149 strlen(channel->ban_list) + 2));
1150 strncat(channel->ban_list, tmp, tmp_len);
1151 strncat(channel->ban_list, ",", 1);
1154 /* Get the ban to be removed and remove it from the list */
1155 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1156 if (tmp && channel->ban_list) {
1157 char *start, *end, *n;
1159 if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1160 silc_free(channel->ban_list);
1161 channel->ban_list = NULL;
1163 start = strstr(channel->ban_list, tmp);
1164 if (start && strlen(start) >= tmp_len) {
1165 end = start + tmp_len;
1166 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1167 strncat(n, channel->ban_list, start - channel->ban_list);
1168 strncat(n, end + 1, ((channel->ban_list +
1169 strlen(channel->ban_list)) - end) - 1);
1170 silc_free(channel->ban_list);
1171 channel->ban_list = n;
1177 /* Ignore rest of the notify types for now */
1178 case SILC_NOTIFY_TYPE_NONE:
1179 case SILC_NOTIFY_TYPE_MOTD:
1186 silc_notify_payload_free(payload);
1189 void silc_server_notify_list(SilcServer server,
1190 SilcSocketConnection sock,
1191 SilcPacketContext *packet)
1193 SilcPacketContext *new;
1197 SILC_LOG_DEBUG(("Processing Notify List"));
1199 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1200 packet->src_id_type != SILC_ID_SERVER)
1203 /* Make copy of the original packet context, except for the actual
1204 data buffer, which we will here now fetch from the original buffer. */
1205 new = silc_packet_context_alloc();
1206 new->type = SILC_PACKET_NOTIFY;
1207 new->flags = packet->flags;
1208 new->src_id = packet->src_id;
1209 new->src_id_len = packet->src_id_len;
1210 new->src_id_type = packet->src_id_type;
1211 new->dst_id = packet->dst_id;
1212 new->dst_id_len = packet->dst_id_len;
1213 new->dst_id_type = packet->dst_id_type;
1215 buffer = silc_buffer_alloc(1024);
1216 new->buffer = buffer;
1218 while (packet->buffer->len) {
1219 SILC_GET16_MSB(len, packet->buffer->data + 2);
1220 if (len > packet->buffer->len)
1223 if (len > buffer->truelen) {
1224 silc_buffer_free(buffer);
1225 buffer = silc_buffer_alloc(1024 + len);
1228 silc_buffer_pull_tail(buffer, len);
1229 silc_buffer_put(buffer, packet->buffer->data, len);
1231 /* Process the Notify */
1232 silc_server_notify(server, sock, new);
1234 silc_buffer_push_tail(buffer, len);
1235 silc_buffer_pull(packet->buffer, len);
1238 silc_buffer_free(buffer);
1242 /* Received private message. This resolves the destination of the message
1243 and sends the packet. This is used by both server and router. If the
1244 destination is our locally connected client this sends the packet to
1245 the client. This may also send the message for further routing if
1246 the destination is not in our server (or router). */
1248 void silc_server_private_message(SilcServer server,
1249 SilcSocketConnection sock,
1250 SilcPacketContext *packet)
1252 SilcSocketConnection dst_sock;
1253 SilcIDListData idata;
1255 SILC_LOG_DEBUG(("Start"));
1257 if (packet->src_id_type != SILC_ID_CLIENT ||
1258 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1261 /* Get the route to the client */
1262 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1263 packet->dst_id_len, NULL, &idata);
1265 /* Send IDENTIFY command reply with error status to indicate that
1266 such destination ID does not exist or is invalid */
1267 SilcBuffer idp = silc_id_payload_encode_data(packet->dst_id,
1269 packet->dst_id_type);
1273 if (packet->src_id_type == SILC_ID_CLIENT) {
1274 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1276 packet->src_id_type);
1277 silc_server_send_dest_command_reply(server, sock,
1278 client_id, SILC_ID_CLIENT,
1279 SILC_COMMAND_IDENTIFY,
1280 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1281 0, 1, 2, idp->data, idp->len);
1282 silc_free(client_id);
1284 silc_server_send_command_reply(server, sock, SILC_COMMAND_IDENTIFY,
1285 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1286 0, 1, 2, idp->data, idp->len);
1289 silc_buffer_free(idp);
1293 /* Send the private message */
1294 silc_server_send_private_message(server, dst_sock, idata->send_key,
1295 idata->hmac_send, idata->psn_send++,
1299 /* Received private message key packet.. This packet is never for us. It is to
1300 the client in the packet's destination ID. Sending of this sort of packet
1301 equals sending private message, ie. it is sent point to point from
1302 one client to another. */
1304 void silc_server_private_message_key(SilcServer server,
1305 SilcSocketConnection sock,
1306 SilcPacketContext *packet)
1308 SilcSocketConnection dst_sock;
1309 SilcIDListData idata;
1311 SILC_LOG_DEBUG(("Start"));
1313 if (packet->src_id_type != SILC_ID_CLIENT ||
1314 packet->dst_id_type != SILC_ID_CLIENT)
1317 if (!packet->dst_id)
1320 /* Get the route to the client */
1321 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1322 packet->dst_id_len, NULL, &idata);
1326 /* Relay the packet */
1327 silc_server_relay_packet(server, dst_sock, idata->send_key,
1328 idata->hmac_send, idata->psn_send++, packet, FALSE);
1331 /* Processes incoming command reply packet. The command reply packet may
1332 be destined to one of our clients or it may directly for us. We will
1333 call the command reply routine after processing the packet. */
1335 void silc_server_command_reply(SilcServer server,
1336 SilcSocketConnection sock,
1337 SilcPacketContext *packet)
1339 SilcBuffer buffer = packet->buffer;
1340 SilcClientEntry client = NULL;
1341 SilcSocketConnection dst_sock;
1342 SilcIDListData idata;
1343 SilcClientID *id = NULL;
1345 SILC_LOG_DEBUG(("Start"));
1347 /* Source must be server or router */
1348 if (packet->src_id_type != SILC_ID_SERVER &&
1349 sock->type != SILC_SOCKET_TYPE_ROUTER)
1352 if (packet->dst_id_type == SILC_ID_CHANNEL)
1355 if (packet->dst_id_type == SILC_ID_CLIENT) {
1356 /* Destination must be one of ours */
1357 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1360 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1362 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1368 if (packet->dst_id_type == SILC_ID_SERVER) {
1369 /* For now this must be for us */
1370 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1371 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1376 /* Execute command reply locally for the command */
1377 silc_server_command_reply_process(server, sock, buffer);
1379 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1380 /* Relay the packet to the client */
1382 dst_sock = (SilcSocketConnection)client->connection;
1383 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1384 + packet->dst_id_len + packet->padlen);
1386 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1387 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1389 idata = (SilcIDListData)client;
1391 /* Encrypt packet */
1392 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1393 dst_sock->outbuf, buffer->len);
1395 /* Send the packet */
1396 silc_server_packet_send_real(server, dst_sock, TRUE);
1402 /* Process received channel message. The message can be originated from
1403 client or server. */
1405 void silc_server_channel_message(SilcServer server,
1406 SilcSocketConnection sock,
1407 SilcPacketContext *packet)
1409 SilcChannelEntry channel = NULL;
1410 SilcChannelID *id = NULL;
1411 void *sender = NULL;
1412 void *sender_entry = NULL;
1415 SILC_LOG_DEBUG(("Processing channel message"));
1418 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1419 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1423 /* Find channel entry */
1424 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1427 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1429 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1431 SILC_LOG_DEBUG(("Could not find channel"));
1436 /* See that this client is on the channel. If the original sender is
1437 not client (as it can be server as well) we don't do the check. */
1438 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1439 packet->src_id_type);
1442 if (packet->src_id_type == SILC_ID_CLIENT) {
1443 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1444 sender, TRUE, NULL);
1445 if (!sender_entry) {
1447 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1448 sender, TRUE, NULL);
1450 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1452 SILC_LOG_DEBUG(("Client not on channel"));
1456 /* If the packet is coming from router, but the client entry is
1457 local entry to us then some router is rerouting this to us and it is
1459 if (server->server_type == SILC_ROUTER &&
1460 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1461 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1466 /* Distribute the packet to our local clients. This will send the
1467 packet for further routing as well, if needed. */
1468 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1469 packet->src_id_type, sender_entry,
1470 packet->buffer->data,
1471 packet->buffer->len, FALSE);
1480 /* Received channel key packet. We distribute the key to all of our locally
1481 connected clients on the channel. */
1483 void silc_server_channel_key(SilcServer server,
1484 SilcSocketConnection sock,
1485 SilcPacketContext *packet)
1487 SilcBuffer buffer = packet->buffer;
1488 SilcChannelEntry channel;
1490 if (packet->src_id_type != SILC_ID_SERVER ||
1491 (server->server_type == SILC_ROUTER &&
1492 sock->type == SILC_SOCKET_TYPE_ROUTER))
1495 /* Save the channel key */
1496 channel = silc_server_save_channel_key(server, buffer, NULL);
1500 /* Distribute the key to everybody who is on the channel. If we are router
1501 we will also send it to locally connected servers. */
1502 silc_server_send_channel_key(server, sock, channel, FALSE);
1504 if (server->server_type != SILC_BACKUP_ROUTER) {
1505 /* Distribute to local cell backup routers. */
1506 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1507 SILC_PACKET_CHANNEL_KEY, 0,
1508 buffer->data, buffer->len, FALSE, TRUE);
1512 /* Received New Client packet and processes it. Creates Client ID for the
1513 client. Client becomes registered after calling this functions. */
1515 SilcClientEntry silc_server_new_client(SilcServer server,
1516 SilcSocketConnection sock,
1517 SilcPacketContext *packet)
1519 SilcBuffer buffer = packet->buffer;
1520 SilcClientEntry client;
1521 SilcClientID *client_id;
1523 SilcIDListData idata;
1524 char *username = NULL, *realname = NULL, *id_string;
1525 uint16 username_len;
1528 char *hostname, *nickname;
1531 SILC_LOG_DEBUG(("Creating new client"));
1533 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1536 /* Take client entry */
1537 client = (SilcClientEntry)sock->user_data;
1538 idata = (SilcIDListData)client;
1540 /* Remove the old cache entry. */
1541 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1542 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1543 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1548 /* Parse incoming packet */
1549 ret = silc_buffer_unformat(buffer,
1550 SILC_STR_UI16_NSTRING_ALLOC(&username,
1552 SILC_STR_UI16_STRING_ALLOC(&realname),
1555 silc_free(username);
1556 silc_free(realname);
1557 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1558 "Incomplete client information");
1563 silc_free(username);
1564 silc_free(realname);
1565 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1566 "Incomplete client information");
1570 if (username_len > 128)
1571 username[128] = '\0';
1573 /* Check for bad characters for nickname, and modify the nickname if
1574 it includes those. */
1575 if (silc_server_name_bad_chars(username, username_len)) {
1576 nickname = silc_server_name_modify_bad(username, username_len);
1578 nickname = strdup(username);
1581 /* Make sanity checks for the hostname of the client. If the hostname
1582 is provided in the `username' check that it is the same than the
1583 resolved hostname, or if not resolved the hostname that appears in
1584 the client's public key. If the hostname is not present then put
1585 it from the resolved name or from the public key. */
1586 if (strchr(username, '@')) {
1587 SilcPublicKeyIdentifier pident;
1588 int tlen = strcspn(username, "@");
1589 char *phostname = NULL;
1591 hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
1592 memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
1594 if (strcmp(sock->hostname, sock->ip) &&
1595 strcmp(sock->hostname, hostname)) {
1596 silc_free(username);
1597 silc_free(hostname);
1598 silc_free(realname);
1599 silc_server_disconnect_remote(server, sock,
1600 "Server closed connection: "
1601 "Incomplete client information");
1605 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1607 phostname = strdup(pident->host);
1608 silc_pkcs_free_identifier(pident);
1611 if (!strcmp(sock->hostname, sock->ip) &&
1612 phostname && strcmp(phostname, hostname)) {
1613 silc_free(username);
1614 silc_free(hostname);
1615 silc_free(phostname);
1616 silc_free(realname);
1617 silc_server_disconnect_remote(server, sock,
1618 "Server closed connection: "
1619 "Incomplete client information");
1623 silc_free(phostname);
1625 /* The hostname is not present, add it. */
1627 /* XXX For now we cannot take the host name from the public key since
1628 they are not trusted or we cannot verify them as trusted. Just take
1629 what the resolved name or address is. */
1631 if (strcmp(sock->hostname, sock->ip)) {
1633 newusername = silc_calloc(strlen(username) +
1634 strlen(sock->hostname) + 2,
1635 sizeof(*newusername));
1636 strncat(newusername, username, strlen(username));
1637 strncat(newusername, "@", 1);
1638 strncat(newusername, sock->hostname, strlen(sock->hostname));
1639 silc_free(username);
1640 username = newusername;
1643 SilcPublicKeyIdentifier pident =
1644 silc_pkcs_decode_identifier(client->data.public_key->identifier);
1647 newusername = silc_calloc(strlen(username) +
1648 strlen(pident->host) + 2,
1649 sizeof(*newusername));
1650 strncat(newusername, username, strlen(username));
1651 strncat(newusername, "@", 1);
1652 strncat(newusername, pident->host, strlen(pident->host));
1653 silc_free(username);
1654 username = newusername;
1655 silc_pkcs_free_identifier(pident);
1661 /* Create Client ID */
1662 while (!silc_id_create_client_id(server, server->id, server->rng,
1663 server->md5hash, nickname, &client_id)) {
1665 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1668 /* Update client entry */
1669 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1670 client->nickname = nickname;
1671 client->username = username;
1672 client->userinfo = realname ? realname : strdup(" ");
1673 client->id = client_id;
1674 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1676 /* Add the client again to the ID cache */
1677 silc_idcache_add(server->local_list->clients, client->nickname,
1678 client_id, client, 0, NULL);
1680 /* Notify our router about new client on the SILC network */
1681 if (!server->standalone)
1682 silc_server_send_new_id(server, (SilcSocketConnection)
1683 server->router->connection,
1684 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1685 client->id, SILC_ID_CLIENT, id_len);
1687 /* Send the new client ID to the client. */
1688 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1689 reply = silc_buffer_alloc(2 + 2 + id_len);
1690 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1691 silc_buffer_format(reply,
1692 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1693 SILC_STR_UI_SHORT(id_len),
1694 SILC_STR_UI_XNSTRING(id_string, id_len),
1696 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1697 reply->data, reply->len, FALSE);
1698 silc_free(id_string);
1699 silc_buffer_free(reply);
1701 /* Send some nice info to the client */
1702 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1703 ("Welcome to the SILC Network %s",
1705 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1706 ("Your host is %s, running version %s",
1707 server->config->server_info->server_name,
1709 if (server->server_type == SILC_ROUTER) {
1710 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1711 ("There are %d clients on %d servers in SILC "
1712 "Network", server->stat.clients,
1713 server->stat.servers + 1));
1714 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1715 ("There are %d clients on %d server in our cell",
1716 server->stat.cell_clients,
1717 server->stat.cell_servers + 1));
1718 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1719 ("I have %d clients, %d channels, %d servers and "
1721 server->stat.my_clients,
1722 server->stat.my_channels,
1723 server->stat.my_servers,
1724 server->stat.my_routers));
1725 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1726 ("There are %d server operators and %d router "
1728 server->stat.server_ops,
1729 server->stat.router_ops));
1730 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1731 ("I have %d operators online",
1732 server->stat.my_router_ops +
1733 server->stat.my_server_ops));
1735 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1736 ("I have %d clients and %d channels formed",
1737 server->stat.my_clients,
1738 server->stat.my_channels));
1739 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1740 ("%d operators online",
1741 server->stat.my_server_ops));
1743 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1744 ("Your connection is secured with %s cipher, "
1745 "key length %d bits",
1746 idata->send_key->cipher->name,
1747 idata->send_key->cipher->key_len));
1748 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1749 ("Your current nickname is %s",
1753 silc_server_send_motd(server, sock);
1758 /* Create new server. This processes received New Server packet and
1759 saves the received Server ID. The server is our locally connected
1760 server thus we save all the information and save it to local list.
1761 This funtion can be used by both normal server and router server.
1762 If normal server uses this it means that its router has connected
1763 to the server. If router uses this it means that one of the cell's
1764 servers is connected to the router. */
1766 SilcServerEntry silc_server_new_server(SilcServer server,
1767 SilcSocketConnection sock,
1768 SilcPacketContext *packet)
1770 SilcBuffer buffer = packet->buffer;
1771 SilcServerEntry new_server, server_entry;
1772 SilcServerID *server_id;
1773 SilcIDListData idata;
1774 unsigned char *server_name, *id_string;
1775 uint16 id_len, name_len;
1779 SILC_LOG_DEBUG(("Creating new server"));
1781 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1782 sock->type != SILC_SOCKET_TYPE_ROUTER)
1785 /* Take server entry */
1786 new_server = (SilcServerEntry)sock->user_data;
1787 idata = (SilcIDListData)new_server;
1789 /* Remove the old cache entry */
1790 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
1791 silc_idcache_del_by_context(server->global_list->servers, new_server);
1795 /* Parse the incoming packet */
1796 ret = silc_buffer_unformat(buffer,
1797 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1798 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1803 silc_free(id_string);
1805 silc_free(server_name);
1809 if (id_len > buffer->len) {
1810 silc_free(id_string);
1811 silc_free(server_name);
1816 server_name[255] = '\0';
1819 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1821 silc_free(id_string);
1822 silc_free(server_name);
1825 silc_free(id_string);
1827 /* Check that we do not have this ID already */
1828 server_entry = silc_idlist_find_server_by_id(server->local_list,
1829 server_id, TRUE, NULL);
1831 silc_idcache_del_by_context(server->local_list->servers, server_entry);
1833 server_entry = silc_idlist_find_server_by_id(server->global_list,
1834 server_id, TRUE, NULL);
1836 silc_idcache_del_by_context(server->global_list->servers, server_entry);
1839 /* Update server entry */
1840 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1841 new_server->server_name = server_name;
1842 new_server->id = server_id;
1844 SILC_LOG_DEBUG(("New server id(%s)",
1845 silc_id_render(server_id, SILC_ID_SERVER)));
1847 /* Add again the entry to the ID cache. */
1848 silc_idcache_add(local ? server->local_list->servers :
1849 server->global_list->servers, server_name, server_id,
1850 new_server, 0, NULL);
1852 /* Distribute the information about new server in the SILC network
1853 to our router. If we are normal server we won't send anything
1854 since this connection must be our router connection. */
1855 if (server->server_type == SILC_ROUTER && !server->standalone &&
1856 server->router->connection != sock)
1857 silc_server_send_new_id(server, server->router->connection,
1858 TRUE, new_server->id, SILC_ID_SERVER,
1859 silc_id_get_len(server_id, SILC_ID_SERVER));
1861 if (server->server_type == SILC_ROUTER)
1862 server->stat.cell_servers++;
1864 /* Check whether this router connection has been replaced by an
1865 backup router. If it has been then we'll disable the server and will
1866 ignore everything it will send until the backup router resuming
1867 protocol has been completed. */
1868 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1869 silc_server_backup_replaced_get(server, server_id, NULL)) {
1870 /* Send packet to the server indicating that it cannot use this
1871 connection as it has been replaced by backup router. */
1872 SilcBuffer packet = silc_buffer_alloc(2);
1873 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1874 silc_buffer_format(packet,
1875 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
1876 SILC_STR_UI_CHAR(0),
1878 silc_server_packet_send(server, sock,
1879 SILC_PACKET_RESUME_ROUTER, 0,
1880 packet->data, packet->len, TRUE);
1881 silc_buffer_free(packet);
1883 /* Mark the router disabled. The data sent earlier will go but nothing
1884 after this does not go to this connection. */
1885 idata->status |= SILC_IDLIST_STATUS_DISABLED;
1887 /* If it is router announce our stuff to it. */
1888 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1889 server->server_type == SILC_ROUTER) {
1890 silc_server_announce_servers(server, FALSE, 0, sock);
1891 silc_server_announce_clients(server, 0, sock);
1892 silc_server_announce_channels(server, 0, sock);
1899 /* Processes incoming New ID packet. New ID Payload is used to distribute
1900 information about newly registered clients and servers. */
1902 static void silc_server_new_id_real(SilcServer server,
1903 SilcSocketConnection sock,
1904 SilcPacketContext *packet,
1907 SilcBuffer buffer = packet->buffer;
1909 SilcServerEntry router, server_entry;
1910 SilcSocketConnection router_sock;
1915 SILC_LOG_DEBUG(("Processing new ID"));
1917 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1918 server->server_type == SILC_SERVER ||
1919 packet->src_id_type != SILC_ID_SERVER)
1922 idp = silc_id_payload_parse(buffer->data, buffer->len);
1926 id_type = silc_id_payload_get_type(idp);
1928 /* Normal server cannot have other normal server connections */
1929 server_entry = (SilcServerEntry)sock->user_data;
1930 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
1931 server_entry->server_type == SILC_SERVER)
1934 id = silc_id_payload_get_id(idp);
1938 /* If the packet is coming from server then use the sender as the
1939 origin of the the packet. If it came from router then check the real
1940 sender of the packet and use that as the origin. */
1941 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1942 id_list = server->local_list;
1944 router = sock->user_data;
1946 /* If the sender is backup router and ID is server (and we are not
1947 backup router) then switch the entry to global list. */
1948 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
1949 id_type == SILC_ID_SERVER &&
1950 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
1951 id_list = server->global_list;
1952 router_sock = server->router ? server->router->connection : sock;
1955 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1956 packet->src_id_type);
1957 router = silc_idlist_find_server_by_id(server->global_list,
1958 sender_id, TRUE, NULL);
1960 router = silc_idlist_find_server_by_id(server->local_list,
1961 sender_id, TRUE, NULL);
1962 silc_free(sender_id);
1964 id_list = server->global_list;
1971 case SILC_ID_CLIENT:
1973 SilcClientEntry entry;
1975 /* Check that we do not have this client already */
1976 entry = silc_idlist_find_client_by_id(server->global_list,
1977 id, server->server_type,
1980 entry = silc_idlist_find_client_by_id(server->local_list,
1981 id, server->server_type,
1984 SILC_LOG_DEBUG(("Ignoring client that we already have"));
1988 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1989 silc_id_render(id, SILC_ID_CLIENT),
1990 sock->type == SILC_SOCKET_TYPE_SERVER ?
1991 "Server" : "Router", sock->hostname));
1993 /* As a router we keep information of all global information in our
1994 global list. Cell wide information however is kept in the local
1996 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1997 id, router, NULL, 0);
1999 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2001 /* Inform the sender that the ID is not usable */
2002 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2005 entry->nickname = NULL;
2006 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2008 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2009 server->stat.cell_clients++;
2010 server->stat.clients++;
2014 case SILC_ID_SERVER:
2016 SilcServerEntry entry;
2018 /* If the ID is mine, ignore it. */
2019 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2020 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2024 /* If the ID is the sender's ID, ignore it (we have it already) */
2025 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2026 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2030 /* Check that we do not have this server already */
2031 entry = silc_idlist_find_server_by_id(server->global_list,
2032 id, server->server_type,
2035 entry = silc_idlist_find_server_by_id(server->local_list,
2036 id, server->server_type,
2039 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2043 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2044 silc_id_render(id, SILC_ID_SERVER),
2045 sock->type == SILC_SOCKET_TYPE_SERVER ?
2046 "Server" : "Router", sock->hostname));
2048 /* As a router we keep information of all global information in our
2049 global list. Cell wide information however is kept in the local
2051 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2054 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2057 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2059 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2060 server->stat.cell_servers++;
2061 server->stat.servers++;
2065 case SILC_ID_CHANNEL:
2066 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2075 /* If the sender of this packet is server and we are router we need to
2076 broadcast this packet to other routers in the network. */
2077 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
2078 sock->type == SILC_SOCKET_TYPE_SERVER &&
2079 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2080 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2081 silc_server_packet_send(server, server->router->connection,
2083 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2084 buffer->data, buffer->len, FALSE);
2085 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2086 packet->type, packet->flags,
2087 packet->buffer->data, packet->buffer->len,
2092 silc_id_payload_free(idp);
2096 /* Processes incoming New ID packet. New ID Payload is used to distribute
2097 information about newly registered clients and servers. */
2099 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2100 SilcPacketContext *packet)
2102 silc_server_new_id_real(server, sock, packet, TRUE);
2105 /* Receoved New Id List packet, list of New ID payloads inside one
2106 packet. Process the New ID payloads one by one. */
2108 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2109 SilcPacketContext *packet)
2111 SilcPacketContext *new_id;
2115 SILC_LOG_DEBUG(("Processing New ID List"));
2117 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2118 packet->src_id_type != SILC_ID_SERVER)
2121 /* If the sender of this packet is server and we are router we need to
2122 broadcast this packet to other routers in the network. Broadcast
2123 this list packet instead of multiple New ID packets. */
2124 if (!server->standalone && server->server_type == SILC_ROUTER &&
2125 sock->type == SILC_SOCKET_TYPE_SERVER &&
2126 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2127 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2128 silc_server_packet_send(server, server->router->connection,
2130 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2131 packet->buffer->data, packet->buffer->len, FALSE);
2132 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2133 packet->type, packet->flags,
2134 packet->buffer->data, packet->buffer->len,
2138 /* Make copy of the original packet context, except for the actual
2139 data buffer, which we will here now fetch from the original buffer. */
2140 new_id = silc_packet_context_alloc();
2141 new_id->type = SILC_PACKET_NEW_ID;
2142 new_id->flags = packet->flags;
2143 new_id->src_id = packet->src_id;
2144 new_id->src_id_len = packet->src_id_len;
2145 new_id->src_id_type = packet->src_id_type;
2146 new_id->dst_id = packet->dst_id;
2147 new_id->dst_id_len = packet->dst_id_len;
2148 new_id->dst_id_type = packet->dst_id_type;
2150 idp = silc_buffer_alloc(256);
2151 new_id->buffer = idp;
2153 while (packet->buffer->len) {
2154 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2155 if ((id_len > packet->buffer->len) ||
2156 (id_len > idp->truelen))
2159 silc_buffer_pull_tail(idp, 4 + id_len);
2160 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2162 /* Process the New ID */
2163 silc_server_new_id_real(server, sock, new_id, FALSE);
2165 silc_buffer_push_tail(idp, 4 + id_len);
2166 silc_buffer_pull(packet->buffer, 4 + id_len);
2169 silc_buffer_free(idp);
2173 /* Received New Channel packet. Information about new channels in the
2174 network are distributed using this packet. Save the information about
2175 the new channel. This usually comes from router but also normal server
2176 can send this to notify channels it has when it connects to us. */
2178 void silc_server_new_channel(SilcServer server,
2179 SilcSocketConnection sock,
2180 SilcPacketContext *packet)
2182 SilcChannelPayload payload;
2183 SilcChannelID *channel_id;
2189 SilcServerEntry server_entry;
2190 SilcChannelEntry channel;
2192 SILC_LOG_DEBUG(("Processing New Channel"));
2194 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2195 packet->src_id_type != SILC_ID_SERVER ||
2196 server->server_type == SILC_SERVER)
2199 /* Parse the channel payload */
2200 payload = silc_channel_payload_parse(packet->buffer->data,
2201 packet->buffer->len);
2205 /* Get the channel ID */
2206 channel_id = silc_channel_get_id_parse(payload);
2208 silc_channel_payload_free(payload);
2212 channel_name = silc_channel_get_name(payload, &name_len);
2214 channel_name[255] = '\0';
2216 id = silc_channel_get_id(payload, &id_len);
2218 server_entry = (SilcServerEntry)sock->user_data;
2220 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2221 /* Add the channel to global list as it is coming from router. It
2222 cannot be our own channel as it is coming from router. */
2224 /* Check that we don't already have this channel */
2225 channel = silc_idlist_find_channel_by_name(server->local_list,
2226 channel_name, NULL);
2228 channel = silc_idlist_find_channel_by_name(server->global_list,
2229 channel_name, NULL);
2231 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2232 silc_id_render(channel_id, SILC_ID_CHANNEL),
2235 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2236 0, channel_id, sock->user_data, NULL, NULL, 0);
2237 server->stat.channels++;
2240 /* The channel is coming from our server, thus it is in our cell
2241 we will add it to our local list. */
2244 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2245 silc_id_render(channel_id, SILC_ID_CHANNEL),
2248 /* Check that we don't already have this channel */
2249 channel = silc_idlist_find_channel_by_name(server->local_list,
2250 channel_name, NULL);
2252 channel = silc_idlist_find_channel_by_name(server->global_list,
2253 channel_name, NULL);
2255 /* If the channel does not exist, then create it. This creates a new
2256 key to the channel as well that we will send to the server. */
2258 /* The protocol says that the Channel ID's IP address must be based
2259 on the router's IP address. Check whether the ID is based in our
2260 IP and if it is not then create a new ID and enforce the server
2261 to switch the ID. */
2262 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2263 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2265 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2267 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2268 silc_server_send_notify_channel_change(server, sock, FALSE,
2270 silc_free(channel_id);
2275 /* Create the channel with the provided Channel ID */
2276 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2280 silc_channel_payload_free(payload);
2281 silc_free(channel_id);
2285 /* Get the mode and set it to the channel */
2286 channel->mode = silc_channel_get_mode(payload);
2288 /* Send the new channel key to the server */
2289 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2290 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2291 chk = silc_channel_key_payload_encode(id_len, id,
2292 strlen(channel->channel_key->
2294 channel->channel_key->cipher->name,
2295 channel->key_len / 8,
2297 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2298 chk->data, chk->len, FALSE);
2299 silc_buffer_free(chk);
2302 /* The channel exist by that name, check whether the ID's match.
2303 If they don't then we'll force the server to use the ID we have.
2304 We also create a new key for the channel. */
2305 SilcBuffer users = NULL, users_modes = NULL;
2307 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2308 /* They don't match, send CHANNEL_CHANGE notify to the server to
2309 force the ID change. */
2310 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2311 silc_server_send_notify_channel_change(server, sock, FALSE,
2312 channel_id, channel->id);
2315 /* If the mode is different from what we have then enforce the
2317 mode = silc_channel_get_mode(payload);
2318 if (channel->mode != mode) {
2319 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2320 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2321 channel->mode, server->id,
2323 channel->cipher, channel->hmac_name,
2324 channel->passphrase);
2327 /* Create new key for the channel and send it to the server and
2328 everybody else possibly on the channel. */
2330 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2331 if (!silc_server_create_channel_key(server, channel, 0))
2334 /* Send to the channel */
2335 silc_server_send_channel_key(server, sock, channel, FALSE);
2336 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2337 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2339 /* Send to the server */
2340 chk = silc_channel_key_payload_encode(id_len, id,
2341 strlen(channel->channel_key->
2343 channel->channel_key->
2345 channel->key_len / 8,
2347 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2348 chk->data, chk->len, FALSE);
2349 silc_buffer_free(chk);
2353 silc_free(channel_id);
2355 /* Since the channel is coming from server and we also know about it
2356 then send the JOIN notify to the server so that it see's our
2357 users on the channel "joining" the channel. */
2358 silc_server_announce_get_channel_users(server, channel, &users,
2361 silc_buffer_push(users, users->data - users->head);
2362 silc_server_packet_send(server, sock,
2363 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2364 users->data, users->len, FALSE);
2365 silc_buffer_free(users);
2368 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2369 silc_server_packet_send_dest(server, sock,
2370 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2371 channel->id, SILC_ID_CHANNEL,
2373 users_modes->len, FALSE);
2374 silc_buffer_free(users_modes);
2379 silc_channel_payload_free(payload);
2382 /* Received New Channel List packet, list of New Channel List payloads inside
2383 one packet. Process the New Channel payloads one by one. */
2385 void silc_server_new_channel_list(SilcServer server,
2386 SilcSocketConnection sock,
2387 SilcPacketContext *packet)
2389 SilcPacketContext *new;
2393 SILC_LOG_DEBUG(("Processing New Channel List"));
2395 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2396 packet->src_id_type != SILC_ID_SERVER ||
2397 server->server_type == SILC_SERVER)
2400 /* If the sender of this packet is server and we are router we need to
2401 broadcast this packet to other routers in the network. Broadcast
2402 this list packet instead of multiple New Channel packets. */
2403 if (!server->standalone && server->server_type == SILC_ROUTER &&
2404 sock->type == SILC_SOCKET_TYPE_SERVER &&
2405 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2406 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2407 silc_server_packet_send(server, server->router->connection,
2409 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2410 packet->buffer->data, packet->buffer->len, FALSE);
2411 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2412 packet->type, packet->flags,
2413 packet->buffer->data, packet->buffer->len,
2417 /* Make copy of the original packet context, except for the actual
2418 data buffer, which we will here now fetch from the original buffer. */
2419 new = silc_packet_context_alloc();
2420 new->type = SILC_PACKET_NEW_CHANNEL;
2421 new->flags = packet->flags;
2422 new->src_id = packet->src_id;
2423 new->src_id_len = packet->src_id_len;
2424 new->src_id_type = packet->src_id_type;
2425 new->dst_id = packet->dst_id;
2426 new->dst_id_len = packet->dst_id_len;
2427 new->dst_id_type = packet->dst_id_type;
2429 buffer = silc_buffer_alloc(512);
2430 new->buffer = buffer;
2432 while (packet->buffer->len) {
2433 SILC_GET16_MSB(len1, packet->buffer->data);
2434 if ((len1 > packet->buffer->len) ||
2435 (len1 > buffer->truelen))
2438 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2439 if ((len2 > packet->buffer->len) ||
2440 (len2 > buffer->truelen))
2443 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2444 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2446 /* Process the New Channel */
2447 silc_server_new_channel(server, sock, new);
2449 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2450 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2453 silc_buffer_free(buffer);
2457 /* Received key agreement packet. This packet is never for us. It is to
2458 the client in the packet's destination ID. Sending of this sort of packet
2459 equals sending private message, ie. it is sent point to point from
2460 one client to another. */
2462 void silc_server_key_agreement(SilcServer server,
2463 SilcSocketConnection sock,
2464 SilcPacketContext *packet)
2466 SilcSocketConnection dst_sock;
2467 SilcIDListData idata;
2469 SILC_LOG_DEBUG(("Start"));
2471 if (packet->src_id_type != SILC_ID_CLIENT ||
2472 packet->dst_id_type != SILC_ID_CLIENT)
2475 if (!packet->dst_id)
2478 /* Get the route to the client */
2479 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2480 packet->dst_id_len, NULL, &idata);
2484 /* Relay the packet */
2485 silc_server_relay_packet(server, dst_sock, idata->send_key,
2486 idata->hmac_send, idata->psn_send++,
2490 /* Received connection auth request packet that is used during connection
2491 phase to resolve the mandatory authentication method. This packet can
2492 actually be received at anytime but usually it is used only during
2493 the connection authentication phase. Now, protocol says that this packet
2494 can come from client or server, however, we support only this coming
2495 from client and expect that server always knows what authentication
2498 void silc_server_connection_auth_request(SilcServer server,
2499 SilcSocketConnection sock,
2500 SilcPacketContext *packet)
2502 SilcServerConfigSectionClient *client = NULL;
2505 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
2507 SILC_LOG_DEBUG(("Start"));
2509 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2512 /* Parse the payload */
2513 ret = silc_buffer_unformat(packet->buffer,
2514 SILC_STR_UI_SHORT(&conn_type),
2515 SILC_STR_UI_SHORT(NULL),
2520 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2523 /* Get the authentication method for the client */
2524 auth_meth = SILC_AUTH_NONE;
2525 port = server->sockets[server->sock]->port; /* Listenning port */
2526 client = silc_server_config_find_client(server, sock->ip, port);
2528 client = silc_server_config_find_client(server, sock->hostname, port);
2530 if (client->passphrase) {
2531 if (client->publickey && !server->config->prefer_passphrase_auth)
2532 auth_meth = SILC_AUTH_PUBLIC_KEY;
2534 auth_meth = SILC_AUTH_PASSWORD;
2535 } else if (client->publickey)
2536 auth_meth = SILC_AUTH_PUBLIC_KEY;
2539 /* Send it back to the client */
2540 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
2543 /* Received REKEY packet. The sender of the packet wants to regenerate
2544 its session keys. This starts the REKEY protocol. */
2546 void silc_server_rekey(SilcServer server,
2547 SilcSocketConnection sock,
2548 SilcPacketContext *packet)
2550 SilcProtocol protocol;
2551 SilcServerRekeyInternalContext *proto_ctx;
2552 SilcIDListData idata = (SilcIDListData)sock->user_data;
2554 SILC_LOG_DEBUG(("Start"));
2556 /* Allocate internal protocol context. This is sent as context
2558 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2559 proto_ctx->server = (void *)server;
2560 proto_ctx->sock = sock;
2561 proto_ctx->responder = TRUE;
2562 proto_ctx->pfs = idata->rekey->pfs;
2564 /* Perform rekey protocol. Will call the final callback after the
2565 protocol is over. */
2566 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2567 &protocol, proto_ctx, silc_server_rekey_final);
2568 sock->protocol = protocol;
2570 if (proto_ctx->pfs == FALSE)
2571 /* Run the protocol */
2572 silc_protocol_execute(protocol, server->schedule, 0, 0);
2575 /* Received file transger packet. This packet is never for us. It is to
2576 the client in the packet's destination ID. Sending of this sort of packet
2577 equals sending private message, ie. it is sent point to point from
2578 one client to another. */
2580 void silc_server_ftp(SilcServer server,
2581 SilcSocketConnection sock,
2582 SilcPacketContext *packet)
2584 SilcSocketConnection dst_sock;
2585 SilcIDListData idata;
2587 SILC_LOG_DEBUG(("Start"));
2589 if (packet->src_id_type != SILC_ID_CLIENT ||
2590 packet->dst_id_type != SILC_ID_CLIENT)
2593 if (!packet->dst_id)
2596 /* Get the route to the client */
2597 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2598 packet->dst_id_len, NULL, &idata);
2602 /* Relay the packet */
2603 silc_server_relay_packet(server, dst_sock, idata->send_key,
2604 idata->hmac_send, idata->psn_send++,