1 /*
2
3 serverid.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; either version 2 of the License, or
12 (at your option) any later version.
13
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.
18
19 */
20 /* $Id: serverid.c,v 1.17 2005/04/23 13:32:25 priikone Exp $ */
21
22 #include "serverincludes.h"
23 #include "server_internal.h"
24
25 /* Creates a Server ID. Newly created Server ID is returned to the
26 new_id argument. */
27
28 void silc_id_create_server_id(const char *ip, SilcUInt16 port, SilcRng rng,
29 SilcServerID **new_id)
30 {
31 SILC_LOG_DEBUG(("Creating new Server ID"));
32
33 *new_id = silc_calloc(1, sizeof(**new_id));
34
35 /* Create the ID */
36
37 if (!silc_net_addr2bin(ip, (*new_id)->ip.data,
38 sizeof((*new_id)->ip.data))) {
39 silc_free(*new_id);
40 *new_id = NULL;
41 return;
42 }
43
44 (*new_id)->ip.data_len = silc_net_is_ip4(ip) ? 4 : 16;
45 (*new_id)->port = SILC_SWAB_16(port);
46 (*new_id)->rnd = silc_rng_get_rn16(rng);
47
48 SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(*new_id, SILC_ID_SERVER)));
49 }
50
51 /* Creates Client ID. This assures that there are no collisions in the
52 created Client IDs. If the collision would occur (meaning that there
53 are 2^8 occurences of the `nickname' this will return FALSE, and the
54 caller must recall the function with different nickname. If this returns
55 TRUE the new ID was created successfully. */
56
57 bool silc_id_create_client_id(SilcServer server,
58 SilcServerID *server_id, SilcRng rng,
59 SilcHash md5hash,
60 unsigned char *nickname, SilcUInt32 nick_len,
61 SilcClientID **new_id)
62 {
63 unsigned char hash[16];
64 bool finding = FALSE;
65
66 SILC_LOG_DEBUG(("Creating new Client ID"));
67
68 *new_id = silc_calloc(1, sizeof(**new_id));
69
70 /* Create hash of the nickname (it's already checked as valid identifier
71 string). */
72 silc_hash_make(md5hash, nickname, nick_len, hash);
73
74 /* Create the ID */
75 memcpy((*new_id)->ip.data, server_id->ip.data, server_id->ip.data_len);
76 (*new_id)->ip.data_len = server_id->ip.data_len;
77 (*new_id)->rnd = silc_rng_get_byte(rng);
78 memcpy((*new_id)->hash, hash, CLIENTID_HASH_LEN);
79
80 /* Assure that the ID does not exist already */
81 while (1) {
82 if (!silc_idlist_find_client_by_id(server->local_list,
83 *new_id, FALSE, NULL))
84 if (!silc_idlist_find_client_by_id(server->global_list,
85 *new_id, FALSE, NULL))
86 break;
87
88 /* The ID exists, start increasing the rnd from 0 until we find a
89 ID that does not exist. If we wrap and it still exists then we
90 will return FALSE and the caller must send some other nickname
91 since this cannot be used anymore. */
92 (*new_id)->rnd++;
93
94 if (finding && (*new_id)->rnd == 0)
95 return FALSE;
96
97 if (!finding) {
98 (*new_id)->rnd = 0;
99 finding = TRUE;
100 }
101 }
102
103 SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(*new_id, SILC_ID_CLIENT)));
104
105 return TRUE;
106 }
107
108 /* Creates Channel ID */
109
110 bool silc_id_create_channel_id(SilcServer server,
111 SilcServerID *router_id, SilcRng rng,
112 SilcChannelID **new_id)
113 {
114 bool finding = TRUE;
115
116 SILC_LOG_DEBUG(("Creating new Channel ID"));
117
118 *new_id = silc_calloc(1, sizeof(**new_id));
119
120 /* Create the ID */
121 memcpy((*new_id)->ip.data, router_id->ip.data, router_id->ip.data_len);
122 (*new_id)->ip.data_len = router_id->ip.data_len;
123 (*new_id)->port = router_id->port;
124 (*new_id)->rnd = silc_rng_get_rn16(rng);
125
126 /* Assure that the ID does not exist already */
127 while (1) {
128 if (!silc_idlist_find_channel_by_id(server->local_list,
129 *new_id, NULL))
130 break;
131
132 (*new_id)->rnd++;
133
134 if (finding && (*new_id)->rnd == 0)
135 return FALSE;
136
137 if (!finding) {
138 (*new_id)->rnd = 0;
139 finding = TRUE;
140 }
141 }
142
143 SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(*new_id, SILC_ID_CHANNEL)));
144
145 return TRUE;
146 }
147
148 /* Checks whether the `server_id' is valid. It must be based to the
149 IP address provided in the `remote' socket connection. */
150
151 bool silc_id_is_valid_server_id(SilcServer server,
152 SilcServerID *server_id,
153 SilcSocketConnection remote)
154 {
155 unsigned char ip[16];
156
157 if (!silc_net_addr2bin(remote->ip, ip, sizeof(ip)))
158 return FALSE;
159
160 if (silc_net_is_ip4(remote->ip)) {
161 if (!memcmp(server_id->ip.data, ip, 4))
162 return TRUE;
163 } else {
164 if (!memcmp(server_id->ip.data, ip, 16))
165 return TRUE;
166 }
167
168 return FALSE;
169 }
170
This page was automatically generated by the LXR engine.
Free-text search provided by Glimpse