Added.
[silc.git] / lib / silcserver / server_util.c
1 /*
2
3   server_util.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2005 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19 /* $Id$ */
20
21 #include "silc.h"
22 #include "silcserver.h"
23 #include "server_internal.h"
24
25 SilcBool silc_server_check_watcher_list(SilcServer server,
26                                     SilcClientEntry client,
27                                     const char *new_nick,
28                                     SilcNotifyType notify)
29 {
30   return TRUE;
31 }
32
33 /* This function is used to send the notify packets and motd to the
34    incoming client connection. */
35
36 void silc_server_send_welcome(SilcServerAccept ac, SilcClientEntry client)
37 {
38   SilcServer server = ac->thread->server;
39   SilcPacketStream stream = client->stream;
40
41   SILC_LOG_DEBUG(("Send welcome notifys"));
42
43   /* Send some nice info to the client */
44   SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
45                           ("Welcome to the SILC Network %s",
46                            client->username));
47   SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
48                           ("Your host is %s, running version %s",
49                            server->server_name, SILC_DIST_VERSION_STRING));
50
51   if (server->server_type == SILC_ROUTER) {
52     SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
53                             ("There are %d clients, %d servers and %d "
54                              "routers in SILC Network",
55                              server->stat.clients, server->stat.servers,
56                              server->stat.routers));
57   } else {
58     if (server->stat.clients && server->stat.servers + 1)
59       SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
60                               ("There are %d clients, %d servers and %d "
61                                "routers in SILC Network",
62                                server->stat.clients, server->stat.servers,
63                                (server->standalone ? 0 :
64                                 !server->stat.routers ? 1 :
65                                 server->stat.routers)));
66   }
67
68   if (server->stat.cell_clients && server->stat.cell_servers + 1)
69     SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
70                             ("There are %d clients on %d servers in our cell",
71                              server->stat.cell_clients,
72                              server->stat.cell_servers));
73   if (server->server_type == SILC_ROUTER) {
74     SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
75                             ("I have %d clients, %d channels, %d servers and "
76                              "%d routers",
77                              server->stat.my_clients,
78                              server->stat.my_channels,
79                              server->stat.my_servers,
80                              server->stat.my_routers));
81   } else {
82     SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
83                             ("I have %d clients and %d channels formed",
84                              server->stat.my_clients,
85                              server->stat.my_channels));
86   }
87
88   if (server->stat.server_ops || server->stat.router_ops)
89     SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
90                             ("There are %d server operators and %d router "
91                              "operators online",
92                              server->stat.server_ops,
93                              server->stat.router_ops));
94   if (server->stat.my_router_ops + server->stat.my_server_ops)
95     SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
96                             ("I have %d operators online",
97                              server->stat.my_router_ops +
98                              server->stat.my_server_ops));
99
100   SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
101                           ("Your connection is secured with %s cipher, "
102                            "key length %d bits",
103                            silc_cipher_get_name(ac->prop->cipher),
104                            silc_cipher_get_key_len(ac->prop->cipher)));
105   SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
106                           ("Your current nickname is %s",
107                            client->nickname));
108
109   /* Send motd */
110   silc_server_send_motd(server, stream);
111 }
112
113 /* Creates new Client ID. */
114
115 SilcBool silc_server_create_client_id(SilcServer server, char *nickname,
116                                       SilcClientID *new_id)
117 {
118   unsigned char hash[16];
119   SilcBool finding = FALSE;
120
121   SILC_LOG_DEBUG(("Creating new Client ID"));
122
123   /* Create hash of the nickname (it's already checked as valid identifier
124      string). */
125   silc_hash_make(server->md5hash, nickname, strlen(nickname), hash);
126
127   /* Create the ID */
128   memcpy(new_id->ip.data, server->id.ip.data, server->id.ip.data_len);
129   new_id->ip.data_len = server->id.ip.data_len;
130   new_id->rnd = silc_rng_get_byte(server->rng);
131   memcpy(new_id->hash, hash, CLIENTID_HASH_LEN);
132
133   /* Assure that the ID does not exist already */
134   while (1) {
135     if (!silc_server_find_client_by_id(server, new_id, FALSE, NULL))
136       break;
137
138     /* The ID exists, start increasing the rnd from 0 until we find a
139        ID that does not exist. If we wrap and it still exists then we
140        will return FALSE and the caller must send some other nickname
141        since this cannot be used anymore. */
142     new_id->rnd++;
143
144     if (finding && new_id->rnd == 0)
145       return FALSE;
146
147     if (!finding) {
148       new_id->rnd = 0;
149       finding = TRUE;
150     }
151   }
152
153   SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(new_id, SILC_ID_CLIENT)));
154
155   return TRUE;
156 }
157
158 /* Creates a Server ID. */
159
160 SilcBool silc_server_create_server_id(SilcServer server,
161                                       const char *ip, SilcUInt16 port,
162                                       SilcServerID *new_id)
163 {
164   SILC_LOG_DEBUG(("Creating new Server ID"));
165
166   if (!new_id)
167     return FALSE;
168
169   /* Create the ID */
170
171   if (!silc_net_addr2bin(ip, new_id->ip.data, sizeof(new_id->ip.data)))
172     return FALSE;
173
174   new_id->ip.data_len = silc_net_is_ip4(ip) ? 4 : 16;
175   new_id->port = SILC_SWAB_16(port);
176   new_id->rnd = silc_rng_get_rn16(server->rng);
177
178   SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(new_id, SILC_ID_SERVER)));
179
180   return TRUE;
181 }
182
183 /* Checks whether the `server_id' is valid.  It must be based to the
184    IP address provided in the `remote' socket connection. */
185
186 SilcBool silc_server_check_server_id(const char *ip_address,
187                                      SilcServerID *server_id)
188 {
189   unsigned char ip[16];
190
191   if (!silc_net_addr2bin(ip_address, ip, sizeof(ip)))
192     return FALSE;
193
194   if (silc_net_is_ip4(ip_address)) {
195     if (!memcmp(server_id->ip.data, ip, 4))
196       return TRUE;
197   } else {
198     if (!memcmp(server_id->ip.data, ip, 16))
199       return TRUE;
200   }
201
202   return FALSE;
203 }