The SILC Project

source navigation ]
identifier search ]
freetext search ]
file search ]

silc/silcd/serverid.c

  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