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, *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;
52 SILC_LOG_DEBUG(("Start"));
54 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
55 packet->src_id_type != SILC_ID_SERVER)
61 /* If the packet is destined directly to a client then relay the packet
62 before processing it. */
63 if (packet->dst_id_type == SILC_ID_CLIENT) {
65 SilcSocketConnection dst_sock;
67 /* Get the route to the client */
68 dst_sock = silc_server_get_client_route(server, packet->dst_id,
69 packet->dst_id_len, NULL, &idata);
71 /* Relay the packet */
72 silc_server_relay_packet(server, dst_sock, idata->send_key,
73 idata->hmac_receive, packet, TRUE);
76 /* If we are router and this packet is not already broadcast packet
77 we will broadcast it. The sending socket really cannot be router or
78 the router is buggy. If this packet is coming from router then it must
79 have the broadcast flag set already and we won't do anything. */
80 if (!server->standalone && server->server_type == SILC_ROUTER &&
81 sock->type == SILC_SOCKET_TYPE_SERVER &&
82 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
83 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
84 silc_server_packet_send(server, server->router->connection, packet->type,
85 packet->flags | SILC_PACKET_FLAG_BROADCAST,
86 packet->buffer->data, packet->buffer->len, FALSE);
89 payload = silc_notify_payload_parse(packet->buffer);
93 type = silc_notify_get_type(payload);
94 args = silc_notify_get_args(payload);
99 case SILC_NOTIFY_TYPE_JOIN:
101 * Distribute the notify to local clients on the channel
103 SILC_LOG_DEBUG(("JOIN notify"));
106 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
109 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
113 /* Get channel entry */
114 channel = silc_idlist_find_channel_by_id(server->global_list,
117 channel = silc_idlist_find_channel_by_id(server->local_list,
120 silc_free(channel_id);
124 silc_free(channel_id);
127 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
130 client_id = silc_id_payload_parse_id(tmp, tmp_len);
134 /* Send to channel */
135 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
136 FALSE, packet->buffer->data,
137 packet->buffer->len, FALSE);
139 /* If the the client is not in local list we check global list (ie. the
140 channel will be global channel) and if it does not exist then create
141 entry for the client. */
142 client = silc_idlist_find_client_by_id(server->global_list,
145 client = silc_idlist_find_client_by_id(server->local_list,
148 /* If router did not find the client the it is bogus */
149 if (server->server_type == SILC_ROUTER)
153 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
154 silc_id_dup(client_id, SILC_ID_CLIENT),
155 sock->user_data, NULL);
157 silc_free(client_id);
161 client->data.registered = TRUE;
165 /* Do not add client to channel if it is there already */
166 if (silc_server_client_on_channel(client, channel))
169 if (server->server_type == SILC_SERVER &&
170 sock->type == SILC_SOCKET_TYPE_ROUTER)
171 /* The channel is global now */
172 channel->global_users = TRUE;
174 /* JOIN the global client to the channel (local clients (if router
175 created the channel) is joined in the pending JOIN command). */
176 chl = silc_calloc(1, sizeof(*chl));
177 chl->client = client;
178 chl->channel = channel;
179 silc_list_add(channel->user_list, chl);
180 silc_list_add(client->channels, chl);
181 silc_free(client_id);
185 case SILC_NOTIFY_TYPE_LEAVE:
187 * Distribute the notify to local clients on the channel
189 SILC_LOG_DEBUG(("LEAVE notify"));
191 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
192 packet->dst_id_type);
196 /* Get channel entry */
197 channel = silc_idlist_find_channel_by_id(server->global_list,
200 channel = silc_idlist_find_channel_by_id(server->local_list,
203 silc_free(channel_id);
209 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
211 silc_free(channel_id);
214 client_id = silc_id_payload_parse_id(tmp, tmp_len);
216 silc_free(channel_id);
220 /* Send to channel */
221 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
222 FALSE, packet->buffer->data,
223 packet->buffer->len, FALSE);
225 /* Get client entry */
226 client = silc_idlist_find_client_by_id(server->global_list,
229 client = silc_idlist_find_client_by_id(server->local_list,
232 silc_free(client_id);
233 silc_free(channel_id);
237 silc_free(client_id);
239 /* Remove the user from channel */
240 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
243 case SILC_NOTIFY_TYPE_SIGNOFF:
245 * Distribute the notify to local clients on the channel
247 SILC_LOG_DEBUG(("SIGNOFF notify"));
250 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
253 client_id = silc_id_payload_parse_id(tmp, tmp_len);
257 /* Get client entry */
258 client = silc_idlist_find_client_by_id(server->global_list,
261 client = silc_idlist_find_client_by_id(server->local_list,
264 silc_free(client_id);
268 silc_free(client_id);
270 /* Get signoff message */
271 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
275 /* Remove the client from all channels. */
276 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
278 client->data.registered = FALSE;
279 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
282 case SILC_NOTIFY_TYPE_TOPIC_SET:
284 * Distribute the notify to local clients on the channel
287 SILC_LOG_DEBUG(("TOPIC SET notify"));
289 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
290 packet->dst_id_type);
294 /* Get channel entry */
295 channel = silc_idlist_find_channel_by_id(server->global_list,
298 channel = silc_idlist_find_channel_by_id(server->local_list,
301 silc_free(channel_id);
307 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
309 silc_free(channel_id);
314 silc_free(channel->topic);
315 channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
316 memcpy(channel->topic, tmp, tmp_len);
318 /* Send the same notify to the channel */
319 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
320 FALSE, packet->buffer->data,
321 packet->buffer->len, FALSE);
322 silc_free(channel_id);
325 case SILC_NOTIFY_TYPE_NICK_CHANGE:
328 * Distribute the notify to local clients on the channel
330 unsigned char *id, *id2;
332 SILC_LOG_DEBUG(("NICK CHANGE notify"));
334 /* Get old client ID */
335 id = silc_argument_get_arg_type(args, 1, &tmp_len);
338 client_id = silc_id_payload_parse_id(id, tmp_len);
342 /* Get new client ID */
343 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
346 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
350 SILC_LOG_DEBUG(("Old Client ID id(%s)",
351 silc_id_render(client_id, SILC_ID_CLIENT)));
352 SILC_LOG_DEBUG(("New Client ID id(%s)",
353 silc_id_render(client_id2, SILC_ID_CLIENT)));
355 /* Replace the Client ID */
356 client = silc_idlist_replace_client_id(server->global_list, client_id,
359 client = silc_idlist_replace_client_id(server->local_list, client_id,
363 /* The nickname is not valid anymore, set it NULL. This causes that
364 the nickname will be queried if someone wants to know it. */
365 if (client->nickname)
366 silc_free(client->nickname);
367 client->nickname = NULL;
369 /* Send the NICK_CHANGE notify type to local clients on the channels
370 this client is joined to. */
371 silc_server_send_notify_on_channels(server, NULL, client,
372 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
377 silc_free(client_id);
379 silc_free(client_id2);
383 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
385 * Distribute the notify to local clients on the channel
388 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
390 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
391 packet->dst_id_type);
395 /* Get channel entry */
396 channel = silc_idlist_find_channel_by_id(server->global_list,
399 channel = silc_idlist_find_channel_by_id(server->local_list,
402 silc_free(channel_id);
407 /* Send the same notify to the channel */
408 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
409 FALSE, packet->buffer->data,
410 packet->buffer->len, FALSE);
413 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
415 silc_free(channel_id);
419 SILC_GET32_MSB(mode, tmp);
421 /* If the channel had private keys set and the mode was removed then
422 we must re-generate and re-distribute a new channel key */
423 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
424 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
425 /* Re-generate channel key */
426 silc_server_create_channel_key(server, channel, 0);
428 /* Send the channel key. This sends it to our local clients and if
429 we are normal server to our router as well. */
430 silc_server_send_channel_key(server, NULL, channel,
431 server->server_type == SILC_ROUTER ?
432 FALSE : !server->standalone);
436 channel->mode = mode;
437 silc_free(channel_id);
440 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
442 unsigned char hash[32];
445 silc_hmac_free(channel->hmac);
446 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
449 /* Set the HMAC key out of current channel key. The client must do
451 silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8,
453 silc_hmac_set_key(channel->hmac, hash,
454 silc_hash_len(channel->hmac->hash));
455 memset(hash, 0, sizeof(hash));
460 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
462 * Distribute the notify to local clients on the channel
465 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
467 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
468 packet->dst_id_type);
472 /* Get channel entry */
473 channel = silc_idlist_find_channel_by_id(server->global_list,
476 channel = silc_idlist_find_channel_by_id(server->local_list,
479 silc_free(channel_id);
485 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
487 silc_free(channel_id);
491 SILC_GET32_MSB(mode, tmp);
493 /* Get target client */
494 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
497 client_id = silc_id_payload_parse_id(tmp, tmp_len);
501 /* Get client entry */
502 client = silc_idlist_find_client_by_id(server->global_list,
505 client = silc_idlist_find_client_by_id(server->local_list,
508 silc_free(client_id);
512 silc_free(client_id);
514 /* Get entry to the channel user list */
515 silc_list_start(channel->user_list);
516 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
517 SilcChannelClientEntry chl2 = NULL;
519 /* If the mode is channel founder and we already find a client
520 to have that mode on the channel we will enforce the sender
521 to change the channel founder mode away. There can be only one
522 channel founder on the channel. */
523 if (server->server_type == SILC_ROUTER &&
524 mode & SILC_CHANNEL_UMODE_CHANFO &&
525 chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
526 silc_server_send_notify_cumode(server, sock, FALSE, channel,
527 (mode & (~SILC_CHANNEL_UMODE_CHANFO)),
528 server->id, SILC_ID_SERVER,
530 silc_free(channel_id);
532 /* Change the mode back if we changed it */
534 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
538 if (chl->client == client) {
539 /* Change the mode */
541 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
548 /* Send the same notify to the channel */
549 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
550 FALSE, packet->buffer->data,
551 packet->buffer->len, FALSE);
552 silc_free(channel_id);
555 case SILC_NOTIFY_TYPE_INVITE:
557 if (packet->dst_id_type == SILC_ID_CLIENT)
560 SILC_LOG_DEBUG(("INVITE notify"));
563 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
566 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
570 /* Get channel entry */
571 channel = silc_idlist_find_channel_by_id(server->global_list,
574 channel = silc_idlist_find_channel_by_id(server->local_list,
577 silc_free(channel_id);
581 silc_free(channel_id);
583 /* Get the added invite */
584 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
586 if (!channel->invite_list)
587 channel->invite_list = silc_calloc(tmp_len + 2,
588 sizeof(*channel->invite_list));
590 channel->invite_list = silc_realloc(channel->invite_list,
591 sizeof(*channel->invite_list) *
593 strlen(channel->invite_list) +
595 if (tmp[tmp_len - 1] == ',')
596 tmp[tmp_len - 1] = '\0';
598 strncat(channel->invite_list, tmp, tmp_len);
599 strncat(channel->invite_list, ",", 1);
602 /* Get the deleted invite */
603 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
604 if (tmp && channel->invite_list) {
605 char *start, *end, *n;
607 if (!strncmp(channel->invite_list, tmp,
608 strlen(channel->invite_list) - 1)) {
609 silc_free(channel->invite_list);
610 channel->invite_list = NULL;
612 start = strstr(channel->invite_list, tmp);
613 if (start && strlen(start) >= tmp_len) {
614 end = start + tmp_len;
615 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
616 strncat(n, channel->invite_list, start - channel->invite_list);
617 strncat(n, end + 1, ((channel->invite_list +
618 strlen(channel->invite_list)) - end) - 1);
619 silc_free(channel->invite_list);
620 channel->invite_list = n;
627 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
629 * Distribute to the local clients on the channel and change the
633 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
635 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
638 /* Get the old Channel ID */
639 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
642 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
646 /* Get the channel entry */
647 channel = silc_idlist_find_channel_by_id(server->global_list,
650 channel = silc_idlist_find_channel_by_id(server->local_list,
653 silc_free(channel_id);
658 /* Send the notify to the channel */
659 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
660 FALSE, packet->buffer->data,
661 packet->buffer->len, FALSE);
663 /* Get the new Channel ID */
664 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
667 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
671 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
672 silc_id_render(channel_id, SILC_ID_CHANNEL)));
673 SILC_LOG_DEBUG(("New Channel ID id(%s)",
674 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
676 /* Replace the Channel ID */
677 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
679 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
681 silc_free(channel_id2);
686 SilcBuffer users = NULL, users_modes = NULL;
688 /* Re-announce our clients on the channel as the ID has changed now */
689 silc_server_announce_get_channel_users(server, channel, &users,
692 silc_buffer_push(users, users->data - users->head);
693 silc_server_packet_send(server, sock,
694 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
695 users->data, users->len, FALSE);
696 silc_buffer_free(users);
699 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
700 silc_server_packet_send(server, sock,
701 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
702 users_modes->data, users_modes->len, FALSE);
703 silc_buffer_free(users_modes);
707 silc_free(channel_id);
711 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
713 * Remove the server entry and all clients that this server owns.
716 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
719 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
722 server_id = silc_id_payload_parse_id(tmp, tmp_len);
726 /* Get server entry */
727 server_entry = silc_idlist_find_server_by_id(server->global_list,
730 server_entry = silc_idlist_find_server_by_id(server->local_list,
733 silc_free(server_id);
737 silc_free(server_id);
739 /* Free all client entries that this server owns as they will
740 become invalid now as well. */
741 silc_server_remove_clients_by_server(server, server_entry, TRUE);
743 /* Remove the server entry */
744 if (!silc_idlist_del_server(server->global_list, server_entry))
745 silc_idlist_del_server(server->local_list, server_entry);
747 /* XXX update statistics */
751 case SILC_NOTIFY_TYPE_KICKED:
753 * Distribute the notify to local clients on the channel
756 SILC_LOG_DEBUG(("KICKED notify"));
758 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
759 packet->dst_id_type);
763 /* Get channel entry */
764 channel = silc_idlist_find_channel_by_id(server->global_list,
767 channel = silc_idlist_find_channel_by_id(server->local_list,
770 silc_free(channel_id);
774 silc_free(channel_id);
777 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
780 client_id = silc_id_payload_parse_id(tmp, tmp_len);
784 /* Send to channel */
785 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
786 FALSE, packet->buffer->data,
787 packet->buffer->len, FALSE);
789 /* If the the client is not in local list we check global list */
790 client = silc_idlist_find_client_by_id(server->global_list,
793 client = silc_idlist_find_client_by_id(server->local_list,
796 silc_free(client_id);
801 /* Remove the client from channel */
802 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
806 case SILC_NOTIFY_TYPE_KILLED:
809 * Distribute the notify to local clients on channels
814 SILC_LOG_DEBUG(("KILLED notify"));
817 id = silc_argument_get_arg_type(args, 1, &id_len);
820 client_id = silc_id_payload_parse_id(id, id_len);
824 /* If the the client is not in local list we check global list */
825 client = silc_idlist_find_client_by_id(server->global_list,
828 client = silc_idlist_find_client_by_id(server->local_list,
831 silc_free(client_id);
835 silc_free(client_id);
837 /* If the client is one of ours, then close the connection to the
838 client now. This removes the client from all channels as well. */
839 if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
840 client->connection) {
841 sock = client->connection;
842 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
843 silc_server_close_connection(server, sock);
848 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
852 /* Send the notify to local clients on the channels except to the
853 client who is killed. */
854 silc_server_send_notify_on_channels(server, client, client,
855 SILC_NOTIFY_TYPE_KILLED,
860 /* Remove the client from all channels */
861 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
867 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
869 * Save the mode of the client.
872 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
875 tmp = silc_argument_get_arg_type(args, 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,
886 client = silc_idlist_find_client_by_id(server->local_list,
889 silc_free(client_id);
893 silc_free(client_id);
896 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
901 SILC_GET32_MSB(client->mode, tmp);
905 case SILC_NOTIFY_TYPE_BAN:
910 SILC_LOG_DEBUG(("BAN notify"));
913 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
916 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
920 /* Get channel entry */
921 channel = silc_idlist_find_channel_by_id(server->global_list,
924 channel = silc_idlist_find_channel_by_id(server->local_list,
927 silc_free(channel_id);
931 silc_free(channel_id);
933 /* Get the new ban and add it to the ban list */
934 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
936 if (!channel->ban_list)
937 channel->ban_list = silc_calloc(tmp_len + 2,
938 sizeof(*channel->ban_list));
940 channel->ban_list = silc_realloc(channel->ban_list,
941 sizeof(*channel->ban_list) *
943 strlen(channel->ban_list) + 2));
944 strncat(channel->ban_list, tmp, tmp_len);
945 strncat(channel->ban_list, ",", 1);
948 /* Get the ban to be removed and remove it from the list */
949 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
950 if (tmp && channel->ban_list) {
951 char *start, *end, *n;
953 if (!strcmp(channel->ban_list, tmp)) {
954 silc_free(channel->ban_list);
955 channel->ban_list = NULL;
957 start = strstr(channel->ban_list, tmp);
958 if (start && strlen(start) >= tmp_len) {
959 end = start + tmp_len;
960 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
961 strncat(n, channel->ban_list, start - channel->ban_list);
962 strncat(n, end + 1, ((channel->ban_list +
963 strlen(channel->ban_list)) - end) - 1);
964 silc_free(channel->ban_list);
965 channel->ban_list = n;
972 /* Ignore rest of the notify types for now */
973 case SILC_NOTIFY_TYPE_NONE:
974 case SILC_NOTIFY_TYPE_MOTD:
981 silc_notify_payload_free(payload);
984 void silc_server_notify_list(SilcServer server,
985 SilcSocketConnection sock,
986 SilcPacketContext *packet)
988 SilcPacketContext *new;
992 SILC_LOG_DEBUG(("Processing Notify List"));
994 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
995 packet->src_id_type != SILC_ID_SERVER)
998 /* Make copy of the original packet context, except for the actual
999 data buffer, which we will here now fetch from the original buffer. */
1000 new = silc_packet_context_alloc();
1001 new->type = SILC_PACKET_NOTIFY;
1002 new->flags = packet->flags;
1003 new->src_id = packet->src_id;
1004 new->src_id_len = packet->src_id_len;
1005 new->src_id_type = packet->src_id_type;
1006 new->dst_id = packet->dst_id;
1007 new->dst_id_len = packet->dst_id_len;
1008 new->dst_id_type = packet->dst_id_type;
1010 buffer = silc_buffer_alloc(1024);
1011 new->buffer = buffer;
1013 while (packet->buffer->len) {
1014 SILC_GET16_MSB(len, packet->buffer->data + 2);
1015 if (len > packet->buffer->len)
1018 if (len > buffer->truelen) {
1019 silc_buffer_free(buffer);
1020 buffer = silc_buffer_alloc(1024 + len);
1023 silc_buffer_pull_tail(buffer, len);
1024 silc_buffer_put(buffer, packet->buffer->data, len);
1026 /* Process the Notify */
1027 silc_server_notify(server, sock, new);
1029 silc_buffer_push_tail(buffer, len);
1030 silc_buffer_pull(packet->buffer, len);
1033 silc_buffer_free(buffer);
1037 /* Received private message. This resolves the destination of the message
1038 and sends the packet. This is used by both server and router. If the
1039 destination is our locally connected client this sends the packet to
1040 the client. This may also send the message for further routing if
1041 the destination is not in our server (or router). */
1043 void silc_server_private_message(SilcServer server,
1044 SilcSocketConnection sock,
1045 SilcPacketContext *packet)
1047 SilcSocketConnection dst_sock;
1048 SilcIDListData idata;
1050 SILC_LOG_DEBUG(("Start"));
1052 if (packet->src_id_type != SILC_ID_CLIENT ||
1053 packet->dst_id_type != SILC_ID_CLIENT)
1056 if (!packet->dst_id)
1059 /* Get the route to the client */
1060 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1061 packet->dst_id_len, NULL, &idata);
1065 /* Send the private message */
1066 silc_server_send_private_message(server, dst_sock, idata->send_key,
1067 idata->hmac_send, packet);
1070 /* Received private message key packet.. This packet is never for us. It is to
1071 the client in the packet's destination ID. Sending of this sort of packet
1072 equals sending private message, ie. it is sent point to point from
1073 one client to another. */
1075 void silc_server_private_message_key(SilcServer server,
1076 SilcSocketConnection sock,
1077 SilcPacketContext *packet)
1079 SilcSocketConnection dst_sock;
1080 SilcIDListData idata;
1082 SILC_LOG_DEBUG(("Start"));
1084 if (packet->src_id_type != SILC_ID_CLIENT ||
1085 packet->dst_id_type != SILC_ID_CLIENT)
1088 if (!packet->dst_id)
1091 /* Get the route to the client */
1092 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1093 packet->dst_id_len, NULL, &idata);
1097 /* Relay the packet */
1098 silc_server_relay_packet(server, dst_sock, idata->send_key,
1099 idata->hmac_send, packet, FALSE);
1102 /* Processes incoming command reply packet. The command reply packet may
1103 be destined to one of our clients or it may directly for us. We will
1104 call the command reply routine after processing the packet. */
1106 void silc_server_command_reply(SilcServer server,
1107 SilcSocketConnection sock,
1108 SilcPacketContext *packet)
1110 SilcBuffer buffer = packet->buffer;
1111 SilcClientEntry client = NULL;
1112 SilcSocketConnection dst_sock;
1113 SilcIDListData idata;
1114 SilcClientID *id = NULL;
1116 SILC_LOG_DEBUG(("Start"));
1118 /* Source must be server or router */
1119 if (packet->src_id_type != SILC_ID_SERVER &&
1120 sock->type != SILC_SOCKET_TYPE_ROUTER)
1123 if (packet->dst_id_type == SILC_ID_CHANNEL)
1126 if (packet->dst_id_type == SILC_ID_CLIENT) {
1127 /* Destination must be one of ours */
1128 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1131 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1133 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1139 if (packet->dst_id_type == SILC_ID_SERVER) {
1140 /* For now this must be for us */
1141 if (memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
1142 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1147 /* Execute command reply locally for the command */
1148 silc_server_command_reply_process(server, sock, buffer);
1150 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1151 /* Relay the packet to the client */
1153 dst_sock = (SilcSocketConnection)client->connection;
1154 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1155 + packet->dst_id_len + packet->padlen);
1157 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1158 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1160 idata = (SilcIDListData)client;
1162 /* Encrypt packet */
1163 silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf,
1166 /* Send the packet */
1167 silc_server_packet_send_real(server, dst_sock, TRUE);
1173 /* Process received channel message. The message can be originated from
1174 client or server. */
1176 void silc_server_channel_message(SilcServer server,
1177 SilcSocketConnection sock,
1178 SilcPacketContext *packet)
1180 SilcChannelEntry channel = NULL;
1181 SilcChannelClientEntry chl;
1182 SilcChannelID *id = NULL;
1183 void *sender = NULL;
1184 void *sender_entry = NULL;
1186 SILC_LOG_DEBUG(("Processing channel message"));
1189 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1190 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1194 /* Find channel entry */
1195 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1198 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1200 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1202 SILC_LOG_DEBUG(("Could not find channel"));
1207 /* See that this client is on the channel. If the message is coming
1208 from router we won't do the check as the message is from client that
1209 we don't know about. Also, if the original sender is not client
1210 (as it can be server as well) we don't do the check. */
1211 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1212 packet->src_id_type);
1215 if (packet->src_id_type == SILC_ID_CLIENT) {
1216 silc_list_start(channel->user_list);
1217 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1218 if (chl->client && SILC_ID_CLIENT_COMPARE(chl->client->id, sender)) {
1219 sender_entry = chl->client;
1223 if (chl == SILC_LIST_END) {
1224 SILC_LOG_DEBUG(("Client not on channel"));
1229 /* Distribute the packet to our local clients. This will send the
1230 packet for further routing as well, if needed. */
1231 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1232 packet->src_id_type, sender_entry,
1233 packet->buffer->data,
1234 packet->buffer->len, FALSE);
1243 /* Received channel key packet. We distribute the key to all of our locally
1244 connected clients on the channel. */
1246 void silc_server_channel_key(SilcServer server,
1247 SilcSocketConnection sock,
1248 SilcPacketContext *packet)
1250 SilcBuffer buffer = packet->buffer;
1251 SilcChannelEntry channel;
1253 if (packet->src_id_type != SILC_ID_SERVER ||
1254 (server->server_type == SILC_ROUTER &&
1255 sock->type == SILC_SOCKET_TYPE_ROUTER))
1258 /* Save the channel key */
1259 channel = silc_server_save_channel_key(server, buffer, NULL);
1263 /* Distribute the key to everybody who is on the channel. If we are router
1264 we will also send it to locally connected servers. */
1265 silc_server_send_channel_key(server, sock, channel, FALSE);
1268 /* Received New Client packet and processes it. Creates Client ID for the
1269 client. Client becomes registered after calling this functions. */
1271 SilcClientEntry silc_server_new_client(SilcServer server,
1272 SilcSocketConnection sock,
1273 SilcPacketContext *packet)
1275 SilcBuffer buffer = packet->buffer;
1276 SilcClientEntry client;
1277 SilcClientID *client_id;
1279 SilcIDListData idata;
1280 char *username = NULL, *realname = NULL, *id_string;
1284 SILC_LOG_DEBUG(("Creating new client"));
1286 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1289 /* Take client entry */
1290 client = (SilcClientEntry)sock->user_data;
1291 idata = (SilcIDListData)client;
1293 /* Remove the old cache entry */
1294 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1295 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1296 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1301 /* Parse incoming packet */
1302 ret = silc_buffer_unformat(buffer,
1303 SILC_STR_UI16_STRING_ALLOC(&username),
1304 SILC_STR_UI16_STRING_ALLOC(&realname),
1308 silc_free(username);
1310 silc_free(realname);
1311 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1312 "Incomplete client information");
1317 silc_free(username);
1319 silc_free(realname);
1320 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1321 "Incomplete client information");
1325 /* Create Client ID */
1326 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1327 username, &client_id);
1329 if (strlen(username) > 128)
1330 username[127] = '\0';
1332 /* Update client entry */
1333 idata->registered = TRUE;
1334 client->nickname = strdup(username);
1335 client->username = username;
1336 client->userinfo = realname ? realname : strdup(" ");
1337 client->id = client_id;
1338 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1340 /* Add the client again to the ID cache */
1341 silc_idcache_add(server->local_list->clients, client->nickname,
1342 client_id, client, FALSE);
1344 /* Notify our router about new client on the SILC network */
1345 if (!server->standalone)
1346 silc_server_send_new_id(server, (SilcSocketConnection)
1347 server->router->connection,
1348 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1349 client->id, SILC_ID_CLIENT, id_len);
1351 /* Send the new client ID to the client. */
1352 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1353 reply = silc_buffer_alloc(2 + 2 + id_len);
1354 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1355 silc_buffer_format(reply,
1356 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1357 SILC_STR_UI_SHORT(id_len),
1358 SILC_STR_UI_XNSTRING(id_string, id_len),
1360 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1361 reply->data, reply->len, FALSE);
1362 silc_free(id_string);
1363 silc_buffer_free(reply);
1365 /* Send some nice info to the client */
1366 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1367 ("Welcome to the SILC Network %s@%s",
1368 username, sock->hostname));
1369 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1370 ("Your host is %s, running version %s",
1371 server->config->server_info->server_name,
1373 if (server->server_type == SILC_ROUTER) {
1374 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1375 ("There are %d clients on %d servers in SILC "
1376 "Network", server->stat.clients,
1377 server->stat.servers + 1));
1378 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1379 ("There are %d clients on %d server in our cell",
1380 server->stat.cell_clients,
1381 server->stat.cell_servers + 1));
1382 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1383 ("I have %d clients, %d channels, %d servers and "
1385 server->stat.my_clients,
1386 server->stat.my_channels,
1387 server->stat.my_servers,
1388 server->stat.my_routers));
1389 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1390 ("%d server operators and %d router operators "
1392 server->stat.my_server_ops,
1393 server->stat.my_router_ops));
1395 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1396 ("I have %d clients and %d channels formed",
1397 server->stat.my_clients,
1398 server->stat.my_channels));
1399 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1400 ("%d operators online",
1401 server->stat.my_server_ops));
1403 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1404 ("Your connection is secured with %s cipher, "
1405 "key length %d bits",
1406 idata->send_key->cipher->name,
1407 idata->send_key->cipher->key_len));
1408 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1409 ("Your current nickname is %s",
1413 silc_server_send_motd(server, sock);
1418 /* Create new server. This processes received New Server packet and
1419 saves the received Server ID. The server is our locally connected
1420 server thus we save all the information and save it to local list.
1421 This funtion can be used by both normal server and router server.
1422 If normal server uses this it means that its router has connected
1423 to the server. If router uses this it means that one of the cell's
1424 servers is connected to the router. */
1426 SilcServerEntry silc_server_new_server(SilcServer server,
1427 SilcSocketConnection sock,
1428 SilcPacketContext *packet)
1430 SilcBuffer buffer = packet->buffer;
1431 SilcServerEntry new_server;
1432 SilcServerID *server_id;
1433 SilcIDListData idata;
1434 unsigned char *server_name, *id_string;
1435 uint16 id_len, name_len;
1438 SILC_LOG_DEBUG(("Creating new server"));
1440 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1441 sock->type != SILC_SOCKET_TYPE_ROUTER)
1444 /* Take server entry */
1445 new_server = (SilcServerEntry)sock->user_data;
1446 idata = (SilcIDListData)new_server;
1448 /* Remove the old cache entry */
1449 silc_idcache_del_by_context(server->local_list->servers, new_server);
1451 /* Parse the incoming packet */
1452 ret = silc_buffer_unformat(buffer,
1453 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1454 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1459 silc_free(id_string);
1461 silc_free(server_name);
1465 if (id_len > buffer->len) {
1466 silc_free(id_string);
1467 silc_free(server_name);
1472 server_name[255] = '\0';
1475 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1477 silc_free(id_string);
1478 silc_free(server_name);
1481 silc_free(id_string);
1483 /* Update server entry */
1484 idata->registered = TRUE;
1485 new_server->server_name = server_name;
1486 new_server->id = server_id;
1488 /* Add again the entry to the ID cache. */
1489 silc_idcache_add(server->local_list->servers, server_name, server_id,
1492 /* Distribute the information about new server in the SILC network
1493 to our router. If we are normal server we won't send anything
1494 since this connection must be our router connection. */
1495 if (server->server_type == SILC_ROUTER && !server->standalone &&
1496 server->router->connection != sock)
1497 silc_server_send_new_id(server, server->router->connection,
1498 TRUE, new_server->id, SILC_ID_SERVER,
1499 silc_id_get_len(server_id, SILC_ID_SERVER));
1501 if (server->server_type == SILC_ROUTER)
1502 server->stat.cell_servers++;
1507 /* Processes incoming New ID packet. New ID Payload is used to distribute
1508 information about newly registered clients and servers. */
1510 static void silc_server_new_id_real(SilcServer server,
1511 SilcSocketConnection sock,
1512 SilcPacketContext *packet,
1515 SilcBuffer buffer = packet->buffer;
1517 SilcServerEntry router;
1518 SilcSocketConnection router_sock;
1523 SILC_LOG_DEBUG(("Processing new ID"));
1525 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1526 server->server_type == SILC_SERVER ||
1527 packet->src_id_type != SILC_ID_SERVER)
1530 idp = silc_id_payload_parse(buffer);
1534 id_type = silc_id_payload_get_type(idp);
1536 /* Normal server cannot have other normal server connections */
1537 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1540 id = silc_id_payload_get_id(idp);
1544 /* If the sender of this packet is server and we are router we need to
1545 broadcast this packet to other routers in the network. */
1546 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1547 sock->type == SILC_SOCKET_TYPE_SERVER &&
1548 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1549 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1550 silc_server_packet_send(server, server->router->connection,
1552 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1553 buffer->data, buffer->len, FALSE);
1556 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1557 id_list = server->local_list;
1559 id_list = server->global_list;
1561 /* If the packet is coming from server then use the sender as the
1562 origin of the the packet. If it came from router then check the real
1563 sender of the packet and use that as the origin. */
1564 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1566 router = sock->user_data;
1568 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1569 packet->src_id_type);
1570 router = silc_idlist_find_server_by_id(server->global_list,
1573 router = silc_idlist_find_server_by_id(server->local_list,
1575 silc_free(sender_id);
1582 case SILC_ID_CLIENT:
1584 SilcClientEntry entry;
1586 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1587 silc_id_render(id, SILC_ID_CLIENT),
1588 sock->type == SILC_SOCKET_TYPE_SERVER ?
1589 "Server" : "Router", sock->hostname));
1591 /* As a router we keep information of all global information in our
1592 global list. Cell wide information however is kept in the local
1594 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1596 entry->nickname = NULL;
1597 entry->data.registered = TRUE;
1599 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1600 server->stat.cell_clients++;
1601 server->stat.clients++;
1605 case SILC_ID_SERVER:
1606 /* If the ID is mine, ignore it. */
1607 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1608 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1612 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1613 silc_id_render(id, SILC_ID_SERVER),
1614 sock->type == SILC_SOCKET_TYPE_SERVER ?
1615 "Server" : "Router", sock->hostname));
1617 /* As a router we keep information of all global information in our global
1618 list. Cell wide information however is kept in the local list. */
1619 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1621 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1622 server->stat.cell_servers++;
1623 server->stat.servers++;
1626 case SILC_ID_CHANNEL:
1627 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1635 silc_id_payload_free(idp);
1639 /* Processes incoming New ID packet. New ID Payload is used to distribute
1640 information about newly registered clients and servers. */
1642 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1643 SilcPacketContext *packet)
1645 silc_server_new_id_real(server, sock, packet, TRUE);
1648 /* Receoved New Id List packet, list of New ID payloads inside one
1649 packet. Process the New ID payloads one by one. */
1651 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1652 SilcPacketContext *packet)
1654 SilcPacketContext *new_id;
1658 SILC_LOG_DEBUG(("Processing New ID List"));
1660 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1661 packet->src_id_type != SILC_ID_SERVER)
1664 /* If the sender of this packet is server and we are router we need to
1665 broadcast this packet to other routers in the network. Broadcast
1666 this list packet instead of multiple New ID packets. */
1667 if (!server->standalone && server->server_type == SILC_ROUTER &&
1668 sock->type == SILC_SOCKET_TYPE_SERVER &&
1669 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1670 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1671 silc_server_packet_send(server, server->router->connection,
1673 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1674 packet->buffer->data, packet->buffer->len, FALSE);
1677 /* Make copy of the original packet context, except for the actual
1678 data buffer, which we will here now fetch from the original buffer. */
1679 new_id = silc_packet_context_alloc();
1680 new_id->type = SILC_PACKET_NEW_ID;
1681 new_id->flags = packet->flags;
1682 new_id->src_id = packet->src_id;
1683 new_id->src_id_len = packet->src_id_len;
1684 new_id->src_id_type = packet->src_id_type;
1685 new_id->dst_id = packet->dst_id;
1686 new_id->dst_id_len = packet->dst_id_len;
1687 new_id->dst_id_type = packet->dst_id_type;
1689 idp = silc_buffer_alloc(256);
1690 new_id->buffer = idp;
1692 while (packet->buffer->len) {
1693 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1694 if ((id_len > packet->buffer->len) ||
1695 (id_len > idp->truelen))
1698 silc_buffer_pull_tail(idp, 4 + id_len);
1699 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1701 /* Process the New ID */
1702 silc_server_new_id_real(server, sock, new_id, FALSE);
1704 silc_buffer_push_tail(idp, 4 + id_len);
1705 silc_buffer_pull(packet->buffer, 4 + id_len);
1708 silc_buffer_free(idp);
1712 /* Received New Channel packet. Information about new channels in the
1713 network are distributed using this packet. Save the information about
1714 the new channel. This usually comes from router but also normal server
1715 can send this to notify channels it has when it connects to us. */
1717 void silc_server_new_channel(SilcServer server,
1718 SilcSocketConnection sock,
1719 SilcPacketContext *packet)
1721 SilcChannelPayload payload;
1722 SilcChannelID *channel_id;
1729 SILC_LOG_DEBUG(("Processing New Channel"));
1731 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1732 packet->src_id_type != SILC_ID_SERVER ||
1733 server->server_type == SILC_SERVER)
1736 /* Parse the channel payload */
1737 payload = silc_channel_payload_parse(packet->buffer);
1741 /* Get the channel ID */
1742 channel_id = silc_channel_get_id_parse(payload);
1744 silc_channel_payload_free(payload);
1748 channel_name = silc_channel_get_name(payload, &name_len);
1750 channel_name[255] = '\0';
1752 id = silc_channel_get_id(payload, &id_len);
1754 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1755 /* Add the server to global list as it is coming from router. It
1756 cannot be our own channel as it is coming from router. */
1758 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1759 silc_id_render(channel_id, SILC_ID_CHANNEL),
1762 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1763 0, channel_id, server->router->connection,
1766 server->stat.channels++;
1768 /* The channel is coming from our server, thus it is in our cell
1769 we will add it to our local list. */
1770 SilcChannelEntry channel;
1773 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1774 silc_id_render(channel_id, SILC_ID_CHANNEL),
1777 /* Check that we don't already have this channel */
1778 channel = silc_idlist_find_channel_by_name(server->local_list,
1779 channel_name, NULL);
1781 channel = silc_idlist_find_channel_by_name(server->global_list,
1782 channel_name, NULL);
1784 /* If the channel does not exist, then create it. We create the channel
1785 with the channel ID provided by the server. This creates a new
1786 key to the channel as well that we will send to the server. */
1788 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1792 silc_channel_payload_free(payload);
1793 silc_free(channel_id);
1797 /* Send the new channel key to the server */
1798 chk = silc_channel_key_payload_encode(id_len, id,
1799 strlen(channel->channel_key->
1801 channel->channel_key->cipher->name,
1802 channel->key_len / 8,
1804 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1805 chk->data, chk->len, FALSE);
1806 silc_buffer_free(chk);
1809 /* The channel exist by that name, check whether the ID's match.
1810 If they don't then we'll force the server to use the ID we have.
1811 We also create a new key for the channel. */
1812 SilcBuffer users = NULL, users_modes = NULL;
1815 channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1817 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1818 /* They don't match, send CHANNEL_CHANGE notify to the server to
1819 force the ID change. */
1820 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1821 silc_server_send_notify_channel_change(server, sock, FALSE,
1822 channel_id, channel->id);
1825 /* If the mode is different from what we have then enforce the
1827 mode = silc_channel_get_mode(payload);
1828 if (channel->mode != mode) {
1829 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1830 silc_server_send_notify_cmode(server, sock, FALSE, channel,
1831 channel->mode, server->id,
1833 channel->cipher, channel->hmac_name);
1836 /* Create new key for the channel and send it to the server and
1837 everybody else possibly on the channel. */
1839 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1840 silc_server_create_channel_key(server, channel, 0);
1842 /* Send to the channel */
1843 silc_server_send_channel_key(server, sock, channel, FALSE);
1844 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1845 id_len = SILC_ID_CHANNEL_LEN;
1847 /* Send to the server */
1848 chk = silc_channel_key_payload_encode(id_len, id,
1849 strlen(channel->channel_key->
1851 channel->channel_key->
1853 channel->key_len / 8,
1855 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1856 chk->data, chk->len, FALSE);
1857 silc_buffer_free(chk);
1861 silc_free(channel_id);
1863 /* Since the channel is coming from server and we also know about it
1864 then send the JOIN notify to the server so that it see's our
1865 users on the channel "joining" the channel. */
1866 silc_server_announce_get_channel_users(server, channel, &users,
1869 silc_buffer_push(users, users->data - users->head);
1870 silc_server_packet_send(server, sock,
1871 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1872 users->data, users->len, FALSE);
1873 silc_buffer_free(users);
1876 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1877 silc_server_packet_send(server, sock,
1878 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1879 users_modes->data, users_modes->len, FALSE);
1880 silc_buffer_free(users_modes);
1885 silc_channel_payload_free(payload);
1888 /* Received New Channel List packet, list of New Channel List payloads inside
1889 one packet. Process the New Channel payloads one by one. */
1891 void silc_server_new_channel_list(SilcServer server,
1892 SilcSocketConnection sock,
1893 SilcPacketContext *packet)
1895 SilcPacketContext *new;
1899 SILC_LOG_DEBUG(("Processing New Channel List"));
1901 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1902 packet->src_id_type != SILC_ID_SERVER ||
1903 server->server_type == SILC_SERVER)
1906 /* If the sender of this packet is server and we are router we need to
1907 broadcast this packet to other routers in the network. Broadcast
1908 this list packet instead of multiple New Channel packets. */
1909 if (!server->standalone && server->server_type == SILC_ROUTER &&
1910 sock->type == SILC_SOCKET_TYPE_SERVER &&
1911 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1912 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1913 silc_server_packet_send(server, server->router->connection,
1915 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1916 packet->buffer->data, packet->buffer->len, FALSE);
1919 /* Make copy of the original packet context, except for the actual
1920 data buffer, which we will here now fetch from the original buffer. */
1921 new = silc_packet_context_alloc();
1922 new->type = SILC_PACKET_NEW_CHANNEL;
1923 new->flags = packet->flags;
1924 new->src_id = packet->src_id;
1925 new->src_id_len = packet->src_id_len;
1926 new->src_id_type = packet->src_id_type;
1927 new->dst_id = packet->dst_id;
1928 new->dst_id_len = packet->dst_id_len;
1929 new->dst_id_type = packet->dst_id_type;
1931 buffer = silc_buffer_alloc(512);
1932 new->buffer = buffer;
1934 while (packet->buffer->len) {
1935 SILC_GET16_MSB(len1, packet->buffer->data);
1936 if ((len1 > packet->buffer->len) ||
1937 (len1 > buffer->truelen))
1940 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1941 if ((len2 > packet->buffer->len) ||
1942 (len2 > buffer->truelen))
1945 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1946 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1948 /* Process the New Channel */
1949 silc_server_new_channel(server, sock, new);
1951 silc_buffer_push_tail(buffer, 8 + len1 + len2);
1952 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1955 silc_buffer_free(buffer);
1959 /* Received key agreement packet. This packet is never for us. It is to
1960 the client in the packet's destination ID. Sending of this sort of packet
1961 equals sending private message, ie. it is sent point to point from
1962 one client to another. */
1964 void silc_server_key_agreement(SilcServer server,
1965 SilcSocketConnection sock,
1966 SilcPacketContext *packet)
1968 SilcSocketConnection dst_sock;
1969 SilcIDListData idata;
1971 SILC_LOG_DEBUG(("Start"));
1973 if (packet->src_id_type != SILC_ID_CLIENT ||
1974 packet->dst_id_type != SILC_ID_CLIENT)
1977 if (!packet->dst_id)
1980 /* Get the route to the client */
1981 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1982 packet->dst_id_len, NULL, &idata);
1986 /* Relay the packet */
1987 silc_server_relay_packet(server, dst_sock, idata->send_key,
1988 idata->hmac_send, packet, FALSE);
1991 /* Received connection auth request packet that is used during connection
1992 phase to resolve the mandatory authentication method. This packet can
1993 actually be received at anytime but usually it is used only during
1994 the connection authentication phase. Now, protocol says that this packet
1995 can come from client or server, however, we support only this coming
1996 from client and expect that server's always knows what authentication
1999 void silc_server_connection_auth_request(SilcServer server,
2000 SilcSocketConnection sock,
2001 SilcPacketContext *packet)
2003 SilcServerConfigSectionClientConnection *client = NULL;
2006 SilcAuthMethod auth_meth;
2008 SILC_LOG_DEBUG(("Start"));
2010 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2013 /* Parse the payload */
2014 ret = silc_buffer_unformat(packet->buffer,
2015 SILC_STR_UI_SHORT(&conn_type),
2016 SILC_STR_UI_SHORT(NULL),
2021 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2024 /* Get the authentication method for the client */
2025 auth_meth = SILC_AUTH_NONE;
2026 client = silc_server_config_find_client_conn(server->config,
2030 client = silc_server_config_find_client_conn(server->config,
2034 auth_meth = client->auth_meth;
2036 /* Send it back to the client */
2037 silc_server_send_connection_auth_request(server, sock,
2042 /* Received REKEY packet. The sender of the packet wants to regenerate
2043 its session keys. This starts the REKEY protocol. */
2045 void silc_server_rekey(SilcServer server,
2046 SilcSocketConnection sock,
2047 SilcPacketContext *packet)
2049 SilcProtocol protocol;
2050 SilcServerRekeyInternalContext *proto_ctx;
2051 SilcIDListData idata = (SilcIDListData)sock->user_data;
2053 SILC_LOG_DEBUG(("Start"));
2055 /* Allocate internal protocol context. This is sent as context
2057 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2058 proto_ctx->server = (void *)server;
2059 proto_ctx->sock = sock;
2060 proto_ctx->responder = TRUE;
2061 proto_ctx->pfs = idata->rekey->pfs;
2063 /* Perform rekey protocol. Will call the final callback after the
2064 protocol is over. */
2065 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2066 &protocol, proto_ctx, silc_server_rekey_final);
2067 sock->protocol = protocol;
2069 if (proto_ctx->pfs == FALSE)
2070 /* Run the protocol */
2071 protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0);