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, 0, 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 SilcIDCacheEntry cache;
1278 SilcClientID *client_id;
1280 SilcIDListData idata;
1281 char *username = NULL, *realname = NULL, *id_string;
1285 SILC_LOG_DEBUG(("Creating new client"));
1287 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1290 /* Take client entry */
1291 client = (SilcClientEntry)sock->user_data;
1292 idata = (SilcIDListData)client;
1294 /* Fetch the old client cache entry so that we can update it. */
1295 if (!silc_idcache_find_by_context(server->local_list->clients,
1296 sock->user_data, &cache)) {
1297 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1298 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1303 /* Parse incoming packet */
1304 ret = silc_buffer_unformat(buffer,
1305 SILC_STR_UI16_STRING_ALLOC(&username),
1306 SILC_STR_UI16_STRING_ALLOC(&realname),
1310 silc_free(username);
1312 silc_free(realname);
1313 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1314 "Incomplete client information");
1319 silc_free(username);
1321 silc_free(realname);
1322 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1323 "Incomplete client information");
1327 /* Create Client ID */
1328 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1329 username, &client_id);
1331 if (strlen(username) > 128)
1332 username[127] = '\0';
1334 /* Update client entry */
1335 idata->registered = TRUE;
1336 client->nickname = strdup(username);
1337 client->username = username;
1338 client->userinfo = realname ? realname : strdup(" ");
1339 client->id = client_id;
1340 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1342 /* Update the cache entry */
1343 cache->id = (void *)client_id;
1344 cache->type = SILC_ID_CLIENT;
1345 cache->data = username;
1346 cache->data_len = strlen(username);
1347 silc_idcache_sort_by_data(server->local_list->clients);
1349 /* Notify our router about new client on the SILC network */
1350 if (!server->standalone)
1351 silc_server_send_new_id(server, (SilcSocketConnection)
1352 server->router->connection,
1353 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1354 client->id, SILC_ID_CLIENT, id_len);
1356 /* Send the new client ID to the client. */
1357 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1358 reply = silc_buffer_alloc(2 + 2 + id_len);
1359 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1360 silc_buffer_format(reply,
1361 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1362 SILC_STR_UI_SHORT(id_len),
1363 SILC_STR_UI_XNSTRING(id_string, id_len),
1365 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1366 reply->data, reply->len, FALSE);
1367 silc_free(id_string);
1368 silc_buffer_free(reply);
1370 /* Send some nice info to the client */
1371 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1372 ("Welcome to the SILC Network %s@%s",
1373 username, sock->hostname));
1374 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1375 ("Your host is %s, running version %s",
1376 server->config->server_info->server_name,
1378 if (server->server_type == SILC_ROUTER) {
1379 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1380 ("There are %d clients on %d servers in SILC "
1381 "Network", server->stat.clients,
1382 server->stat.servers + 1));
1383 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1384 ("There are %d clients on %d server in our cell",
1385 server->stat.cell_clients,
1386 server->stat.cell_servers + 1));
1387 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1388 ("I have %d clients, %d channels, %d servers and "
1390 server->stat.my_clients,
1391 server->stat.my_channels,
1392 server->stat.my_servers,
1393 server->stat.my_routers));
1394 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1395 ("%d server operators and %d router operators "
1397 server->stat.my_server_ops,
1398 server->stat.my_router_ops));
1400 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1401 ("I have %d clients and %d channels formed",
1402 server->stat.my_clients,
1403 server->stat.my_channels));
1404 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1405 ("%d operators online",
1406 server->stat.my_server_ops));
1408 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1409 ("Your connection is secured with %s cipher, "
1410 "key length %d bits",
1411 idata->send_key->cipher->name,
1412 idata->send_key->cipher->key_len));
1413 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1414 ("Your current nickname is %s",
1418 silc_server_send_motd(server, sock);
1423 /* Create new server. This processes received New Server packet and
1424 saves the received Server ID. The server is our locally connected
1425 server thus we save all the information and save it to local list.
1426 This funtion can be used by both normal server and router server.
1427 If normal server uses this it means that its router has connected
1428 to the server. If router uses this it means that one of the cell's
1429 servers is connected to the router. */
1431 SilcServerEntry silc_server_new_server(SilcServer server,
1432 SilcSocketConnection sock,
1433 SilcPacketContext *packet)
1435 SilcBuffer buffer = packet->buffer;
1436 SilcServerEntry new_server;
1437 SilcIDCacheEntry cache;
1438 SilcServerID *server_id;
1439 SilcIDListData idata;
1440 unsigned char *server_name, *id_string;
1441 uint16 id_len, name_len;
1444 SILC_LOG_DEBUG(("Creating new server"));
1446 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1447 sock->type != SILC_SOCKET_TYPE_ROUTER)
1450 /* Take server entry */
1451 new_server = (SilcServerEntry)sock->user_data;
1452 idata = (SilcIDListData)new_server;
1454 /* Fetch the old server cache entry so that we can update it. */
1455 if (!silc_idcache_find_by_context(server->local_list->servers,
1456 sock->user_data, &cache)) {
1457 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1461 /* Parse the incoming packet */
1462 ret = silc_buffer_unformat(buffer,
1463 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1464 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1469 silc_free(id_string);
1471 silc_free(server_name);
1475 if (id_len > buffer->len) {
1476 silc_free(id_string);
1477 silc_free(server_name);
1482 server_name[255] = '\0';
1485 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1487 silc_free(id_string);
1488 silc_free(server_name);
1491 silc_free(id_string);
1493 /* Update client entry */
1494 idata->registered = TRUE;
1495 new_server->server_name = server_name;
1496 new_server->id = server_id;
1498 /* Update the cache entry */
1499 cache->id = (void *)server_id;
1500 cache->type = SILC_ID_SERVER;
1501 cache->data = server_name;
1502 cache->data_len = strlen(server_name);
1503 silc_idcache_sort_by_data(server->local_list->servers);
1505 /* Distribute the information about new server in the SILC network
1506 to our router. If we are normal server we won't send anything
1507 since this connection must be our router connection. */
1508 if (server->server_type == SILC_ROUTER && !server->standalone &&
1509 server->router->connection != sock)
1510 silc_server_send_new_id(server, server->router->connection,
1511 TRUE, new_server->id, SILC_ID_SERVER,
1512 silc_id_get_len(server_id, SILC_ID_SERVER));
1514 if (server->server_type == SILC_ROUTER)
1515 server->stat.cell_servers++;
1520 /* Processes incoming New ID packet. New ID Payload is used to distribute
1521 information about newly registered clients and servers. */
1523 static void silc_server_new_id_real(SilcServer server,
1524 SilcSocketConnection sock,
1525 SilcPacketContext *packet,
1528 SilcBuffer buffer = packet->buffer;
1530 SilcServerEntry router;
1531 SilcSocketConnection router_sock;
1534 unsigned char *hash = NULL;
1537 SILC_LOG_DEBUG(("Processing new ID"));
1539 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1540 server->server_type == SILC_SERVER ||
1541 packet->src_id_type != SILC_ID_SERVER)
1544 idp = silc_id_payload_parse(buffer);
1548 id_type = silc_id_payload_get_type(idp);
1550 /* Normal server cannot have other normal server connections */
1551 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1554 id = silc_id_payload_get_id(idp);
1558 /* If the sender of this packet is server and we are router we need to
1559 broadcast this packet to other routers in the network. */
1560 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1561 sock->type == SILC_SOCKET_TYPE_SERVER &&
1562 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1563 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1564 silc_server_packet_send(server, server->router->connection,
1566 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1567 buffer->data, buffer->len, FALSE);
1570 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1571 id_list = server->local_list;
1573 id_list = server->global_list;
1575 /* If the packet is coming from server then use the sender as the
1576 origin of the the packet. If it came from router then check the real
1577 sender of the packet and use that as the origin. */
1578 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1580 router = sock->user_data;
1582 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1583 packet->src_id_type);
1584 router = silc_idlist_find_server_by_id(server->global_list,
1587 router = silc_idlist_find_server_by_id(server->local_list,
1589 silc_free(sender_id);
1596 case SILC_ID_CLIENT:
1598 SilcClientEntry entry;
1600 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1601 silc_id_render(id, SILC_ID_CLIENT),
1602 sock->type == SILC_SOCKET_TYPE_SERVER ?
1603 "Server" : "Router", sock->hostname));
1605 /* As a router we keep information of all global information in our
1606 global list. Cell wide information however is kept in the local
1607 list. The client is put to global list and we will take the hash
1608 value of the Client ID and save it to the ID Cache system for fast
1609 searching in the future. */
1610 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1611 sizeof(unsigned char));
1612 memcpy(hash, ((SilcClientID *)id)->hash,
1613 sizeof(((SilcClientID *)id)->hash));
1614 entry = silc_idlist_add_client(id_list, hash,
1615 sizeof(((SilcClientID *)id)->hash),
1616 NULL, NULL, id, router, NULL);
1617 entry->nickname = NULL;
1618 entry->data.registered = TRUE;
1620 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1621 server->stat.cell_clients++;
1622 server->stat.clients++;
1626 case SILC_ID_SERVER:
1627 /* If the ID is mine, ignore it. */
1628 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1629 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1633 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1634 silc_id_render(id, SILC_ID_SERVER),
1635 sock->type == SILC_SOCKET_TYPE_SERVER ?
1636 "Server" : "Router", sock->hostname));
1638 /* As a router we keep information of all global information in our global
1639 list. Cell wide information however is kept in the local list. */
1640 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1642 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1643 server->stat.cell_servers++;
1644 server->stat.servers++;
1647 case SILC_ID_CHANNEL:
1648 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1656 silc_id_payload_free(idp);
1660 /* Processes incoming New ID packet. New ID Payload is used to distribute
1661 information about newly registered clients and servers. */
1663 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1664 SilcPacketContext *packet)
1666 silc_server_new_id_real(server, sock, packet, TRUE);
1669 /* Receoved New Id List packet, list of New ID payloads inside one
1670 packet. Process the New ID payloads one by one. */
1672 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1673 SilcPacketContext *packet)
1675 SilcPacketContext *new_id;
1679 SILC_LOG_DEBUG(("Processing New ID List"));
1681 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1682 packet->src_id_type != SILC_ID_SERVER)
1685 /* If the sender of this packet is server and we are router we need to
1686 broadcast this packet to other routers in the network. Broadcast
1687 this list packet instead of multiple New ID packets. */
1688 if (!server->standalone && server->server_type == SILC_ROUTER &&
1689 sock->type == SILC_SOCKET_TYPE_SERVER &&
1690 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1691 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1692 silc_server_packet_send(server, server->router->connection,
1694 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1695 packet->buffer->data, packet->buffer->len, FALSE);
1698 /* Make copy of the original packet context, except for the actual
1699 data buffer, which we will here now fetch from the original buffer. */
1700 new_id = silc_packet_context_alloc();
1701 new_id->type = SILC_PACKET_NEW_ID;
1702 new_id->flags = packet->flags;
1703 new_id->src_id = packet->src_id;
1704 new_id->src_id_len = packet->src_id_len;
1705 new_id->src_id_type = packet->src_id_type;
1706 new_id->dst_id = packet->dst_id;
1707 new_id->dst_id_len = packet->dst_id_len;
1708 new_id->dst_id_type = packet->dst_id_type;
1710 idp = silc_buffer_alloc(256);
1711 new_id->buffer = idp;
1713 while (packet->buffer->len) {
1714 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1715 if ((id_len > packet->buffer->len) ||
1716 (id_len > idp->truelen))
1719 silc_buffer_pull_tail(idp, 4 + id_len);
1720 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1722 /* Process the New ID */
1723 silc_server_new_id_real(server, sock, new_id, FALSE);
1725 silc_buffer_push_tail(idp, 4 + id_len);
1726 silc_buffer_pull(packet->buffer, 4 + id_len);
1729 silc_buffer_free(idp);
1733 /* Received New Channel packet. Information about new channels in the
1734 network are distributed using this packet. Save the information about
1735 the new channel. This usually comes from router but also normal server
1736 can send this to notify channels it has when it connects to us. */
1738 void silc_server_new_channel(SilcServer server,
1739 SilcSocketConnection sock,
1740 SilcPacketContext *packet)
1742 SilcChannelPayload payload;
1743 SilcChannelID *channel_id;
1750 SILC_LOG_DEBUG(("Processing New Channel"));
1752 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1753 packet->src_id_type != SILC_ID_SERVER ||
1754 server->server_type == SILC_SERVER)
1757 /* Parse the channel payload */
1758 payload = silc_channel_payload_parse(packet->buffer);
1762 /* Get the channel ID */
1763 channel_id = silc_channel_get_id_parse(payload);
1765 silc_channel_payload_free(payload);
1769 channel_name = silc_channel_get_name(payload, &name_len);
1771 channel_name[255] = '\0';
1773 id = silc_channel_get_id(payload, &id_len);
1775 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1776 /* Add the server to global list as it is coming from router. It
1777 cannot be our own channel as it is coming from router. */
1779 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1780 silc_id_render(channel_id, SILC_ID_CHANNEL),
1783 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1784 0, channel_id, server->router->connection,
1787 server->stat.channels++;
1789 /* The channel is coming from our server, thus it is in our cell
1790 we will add it to our local list. */
1791 SilcChannelEntry channel;
1794 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1795 silc_id_render(channel_id, SILC_ID_CHANNEL),
1798 /* Check that we don't already have this channel */
1799 channel = silc_idlist_find_channel_by_name(server->local_list,
1800 channel_name, NULL);
1802 channel = silc_idlist_find_channel_by_name(server->global_list,
1803 channel_name, NULL);
1805 /* If the channel does not exist, then create it. We create the channel
1806 with the channel ID provided by the server. This creates a new
1807 key to the channel as well that we will send to the server. */
1809 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1813 silc_channel_payload_free(payload);
1814 silc_free(channel_id);
1818 /* Send the new channel key to the server */
1819 chk = silc_channel_key_payload_encode(id_len, id,
1820 strlen(channel->channel_key->
1822 channel->channel_key->cipher->name,
1823 channel->key_len / 8,
1825 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1826 chk->data, chk->len, FALSE);
1827 silc_buffer_free(chk);
1830 /* The channel exist by that name, check whether the ID's match.
1831 If they don't then we'll force the server to use the ID we have.
1832 We also create a new key for the channel. */
1833 SilcBuffer users = NULL, users_modes = NULL;
1836 channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1838 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1839 /* They don't match, send CHANNEL_CHANGE notify to the server to
1840 force the ID change. */
1841 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1842 silc_server_send_notify_channel_change(server, sock, FALSE,
1843 channel_id, channel->id);
1846 /* If the mode is different from what we have then enforce the
1848 mode = silc_channel_get_mode(payload);
1849 if (channel->mode != mode) {
1850 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1851 silc_server_send_notify_cmode(server, sock, FALSE, channel,
1852 channel->mode, server->id,
1854 channel->cipher, channel->hmac_name);
1857 /* Create new key for the channel and send it to the server and
1858 everybody else possibly on the channel. */
1860 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1861 silc_server_create_channel_key(server, channel, 0);
1863 /* Send to the channel */
1864 silc_server_send_channel_key(server, sock, channel, FALSE);
1865 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1866 id_len = SILC_ID_CHANNEL_LEN;
1868 /* Send to the server */
1869 chk = silc_channel_key_payload_encode(id_len, id,
1870 strlen(channel->channel_key->
1872 channel->channel_key->
1874 channel->key_len / 8,
1876 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1877 chk->data, chk->len, FALSE);
1878 silc_buffer_free(chk);
1882 silc_free(channel_id);
1884 /* Since the channel is coming from server and we also know about it
1885 then send the JOIN notify to the server so that it see's our
1886 users on the channel "joining" the channel. */
1887 silc_server_announce_get_channel_users(server, channel, &users,
1890 silc_buffer_push(users, users->data - users->head);
1891 silc_server_packet_send(server, sock,
1892 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1893 users->data, users->len, FALSE);
1894 silc_buffer_free(users);
1897 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1898 silc_server_packet_send(server, sock,
1899 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1900 users_modes->data, users_modes->len, FALSE);
1901 silc_buffer_free(users_modes);
1906 silc_channel_payload_free(payload);
1909 /* Received New Channel List packet, list of New Channel List payloads inside
1910 one packet. Process the New Channel payloads one by one. */
1912 void silc_server_new_channel_list(SilcServer server,
1913 SilcSocketConnection sock,
1914 SilcPacketContext *packet)
1916 SilcPacketContext *new;
1920 SILC_LOG_DEBUG(("Processing New Channel List"));
1922 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1923 packet->src_id_type != SILC_ID_SERVER ||
1924 server->server_type == SILC_SERVER)
1927 /* If the sender of this packet is server and we are router we need to
1928 broadcast this packet to other routers in the network. Broadcast
1929 this list packet instead of multiple New Channel packets. */
1930 if (!server->standalone && server->server_type == SILC_ROUTER &&
1931 sock->type == SILC_SOCKET_TYPE_SERVER &&
1932 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1933 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1934 silc_server_packet_send(server, server->router->connection,
1936 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1937 packet->buffer->data, packet->buffer->len, FALSE);
1940 /* Make copy of the original packet context, except for the actual
1941 data buffer, which we will here now fetch from the original buffer. */
1942 new = silc_packet_context_alloc();
1943 new->type = SILC_PACKET_NEW_CHANNEL;
1944 new->flags = packet->flags;
1945 new->src_id = packet->src_id;
1946 new->src_id_len = packet->src_id_len;
1947 new->src_id_type = packet->src_id_type;
1948 new->dst_id = packet->dst_id;
1949 new->dst_id_len = packet->dst_id_len;
1950 new->dst_id_type = packet->dst_id_type;
1952 buffer = silc_buffer_alloc(512);
1953 new->buffer = buffer;
1955 while (packet->buffer->len) {
1956 SILC_GET16_MSB(len1, packet->buffer->data);
1957 if ((len1 > packet->buffer->len) ||
1958 (len1 > buffer->truelen))
1961 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1962 if ((len2 > packet->buffer->len) ||
1963 (len2 > buffer->truelen))
1966 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1967 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1969 /* Process the New Channel */
1970 silc_server_new_channel(server, sock, new);
1972 silc_buffer_push_tail(buffer, 8 + len1 + len2);
1973 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1976 silc_buffer_free(buffer);
1980 /* Received key agreement packet. This packet is never for us. It is to
1981 the client in the packet's destination ID. Sending of this sort of packet
1982 equals sending private message, ie. it is sent point to point from
1983 one client to another. */
1985 void silc_server_key_agreement(SilcServer server,
1986 SilcSocketConnection sock,
1987 SilcPacketContext *packet)
1989 SilcSocketConnection dst_sock;
1990 SilcIDListData idata;
1992 SILC_LOG_DEBUG(("Start"));
1994 if (packet->src_id_type != SILC_ID_CLIENT ||
1995 packet->dst_id_type != SILC_ID_CLIENT)
1998 if (!packet->dst_id)
2001 /* Get the route to the client */
2002 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2003 packet->dst_id_len, NULL, &idata);
2007 /* Relay the packet */
2008 silc_server_relay_packet(server, dst_sock, idata->send_key,
2009 idata->hmac_send, packet, FALSE);
2012 /* Received connection auth request packet that is used during connection
2013 phase to resolve the mandatory authentication method. This packet can
2014 actually be received at anytime but usually it is used only during
2015 the connection authentication phase. Now, protocol says that this packet
2016 can come from client or server, however, we support only this coming
2017 from client and expect that server's always knows what authentication
2020 void silc_server_connection_auth_request(SilcServer server,
2021 SilcSocketConnection sock,
2022 SilcPacketContext *packet)
2024 SilcServerConfigSectionClientConnection *client = NULL;
2027 SilcAuthMethod auth_meth;
2029 SILC_LOG_DEBUG(("Start"));
2031 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2034 /* Parse the payload */
2035 ret = silc_buffer_unformat(packet->buffer,
2036 SILC_STR_UI_SHORT(&conn_type),
2037 SILC_STR_UI_SHORT(NULL),
2042 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2045 /* Get the authentication method for the client */
2046 auth_meth = SILC_AUTH_NONE;
2047 client = silc_server_config_find_client_conn(server->config,
2051 client = silc_server_config_find_client_conn(server->config,
2055 auth_meth = client->auth_meth;
2057 /* Send it back to the client */
2058 silc_server_send_connection_auth_request(server, sock,
2063 /* Received REKEY packet. The sender of the packet wants to regenerate
2064 its session keys. This starts the REKEY protocol. */
2066 void silc_server_rekey(SilcServer server,
2067 SilcSocketConnection sock,
2068 SilcPacketContext *packet)
2070 SilcProtocol protocol;
2071 SilcServerRekeyInternalContext *proto_ctx;
2072 SilcIDListData idata = (SilcIDListData)sock->user_data;
2074 SILC_LOG_DEBUG(("Start"));
2076 /* Allocate internal protocol context. This is sent as context
2078 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2079 proto_ctx->server = (void *)server;
2080 proto_ctx->sock = sock;
2081 proto_ctx->responder = TRUE;
2082 proto_ctx->pfs = idata->rekey->pfs;
2084 /* Perform rekey protocol. Will call the final callback after the
2085 protocol is over. */
2086 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2087 &protocol, proto_ctx, silc_server_rekey_final);
2088 sock->protocol = protocol;
2090 if (proto_ctx->pfs == FALSE)
2091 /* Run the protocol */
2092 protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0);