+Sat Dec 1 12:52:39 EET 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * Memory leak fixes in:
+
+ lib/silcutil/silcsockconn.c
+ lib/silcske/silcske.c
+ lib/silcske/groups.c
+ lib/silccrypt/rsa.c
+ lib/silccrypt/silcpkcs.c
+ lib/silccore/silccommand.c
+ lib/silccore/silcidcache.c
+ silcd/idlist.c
+ silcd/packet_send.c
+ silcd/command.c
+
+ * ROBOdoc documented the lib/silcske/groups.h file and a
+ bit changed the interface for better.
+
Thu Nov 29 22:12:50 EET 2001 Pekka Riikonen <priikone@silcnet.org>'
* Update the client entry context in the ID cache after
silc_server_command_list_send_reply(cmd, lchannels, lch_count,
gchannels, gch_count);
+ silc_free(lchannels);
+ silc_free(gchannels);
+
out:
silc_server_command_free(cmd);
}
silc_buffer_free(packet);
silc_free(channel_id);
- silc_free(cidp);
+ silc_buffer_free(cidp);
out:
silc_server_command_free(cmd);
silc_hmac_free(idata->hmac_send);
if (idata->hmac_receive)
silc_hmac_free(idata->hmac_receive);
+ if (idata->hash)
+ silc_hash_free(idata->hash);
if (idata->public_key)
silc_pkcs_public_key_free(idata->public_key);
}
silc_free(entry->username);
silc_free(entry->userinfo);
silc_free(entry->id);
+ silc_hash_table_free(entry->channels);
memset(entry, 'F', sizeof(*entry));
silc_free(entry);
{
SilcClientEntry client;
- SILC_LOG_DEBUG(("Start"));
-
client = (SilcClientEntry)entry->context;
if (client) {
- if (client->nickname)
- silc_free(client->nickname);
- if (client->username)
- silc_free(client->username);
- if (client->userinfo)
- silc_free(client->userinfo);
- if (client->id)
- silc_free(client->id);
+ silc_free(client->nickname);
+ silc_free(client->username);
+ silc_free(client->userinfo);
+ silc_free(client->id);
+ silc_hash_table_free(client->channels);
memset(client, 'F', sizeof(*client));
silc_free(client);
silc_free(entry->key);
}
silc_free(entry->cipher);
+ if (entry->hmac)
+ silc_hmac_free(entry->hmac);
silc_free(entry->hmac_name);
silc_free(entry->rekey);
SilcClientID *client_id;
SilcBuffer reply;
SilcIDListData idata;
+ SilcIDCacheEntry id_cache = NULL;
char *username = NULL, *realname = NULL, *id_string;
uint32 id_len;
int ret;
client = (SilcClientEntry)sock->user_data;
idata = (SilcIDListData)client;
- /* Remove the old cache entry */
+ /* Remove the old cache entry. */
if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
silc_server_disconnect_remote(server, sock, "Server closed connection: "
idata->hmac_send, idata->psn_send++,
packet, FALSE);
}
-
silc_free(routed);
silc_free(sent_clients);
silc_free(packetdata.src_id);
+ silc_buffer_free(packet);
va_end(ap);
}
ctx->ske = silc_ske_alloc();
ctx->ske->rng = server->rng;
ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
- silc_ske_get_group_by_number(idata->rekey->ske_group,
+ silc_ske_group_get_by_number(idata->rekey->ske_group,
&ctx->ske->prop->group);
silc_ske_set_callbacks(ctx->ske,
ctx->ske = silc_ske_alloc();
ctx->ske->rng = server->rng;
ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
- silc_ske_get_group_by_number(idata->rekey->ske_group,
+ silc_ske_group_get_by_number(idata->rekey->ske_group,
&ctx->ske->prop->group);
silc_ske_set_callbacks(ctx->ske,
int silc_server_init(SilcServer server)
{
- int *sock = NULL, sock_count = 0, i;
+ int *sock = NULL, sock_count, i;
SilcServerID *id;
SilcServerEntry id_entry;
SilcIDListPurge purge;
tmp = silc_net_create_server(server->config->listen_port->port,
server->config->listen_port->listener_ip);
+
if (tmp < 0) {
SILC_LOG_ERROR(("Could not create server listener: %s on %d",
server->config->listen_port->listener_ip,
goto err0;
}
- sock = silc_realloc(sock, (sizeof(int *) * (sock_count + 1)));
+ sock = silc_realloc(sock, sizeof(*sock) * (sock_count + 1));
sock[sock_count] = tmp;
sock_count++;
listen = listen->next;
ctx->ske = silc_ske_alloc();
ctx->ske->rng = client->rng;
ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
- silc_ske_get_group_by_number(conn->rekey->ske_group,
+ silc_ske_group_get_by_number(conn->rekey->ske_group,
&ctx->ske->prop->group);
silc_ske_set_callbacks(ctx->ske,
ctx->ske = silc_ske_alloc();
ctx->ske->rng = client->rng;
ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
- silc_ske_get_group_by_number(conn->rekey->ske_group,
+ silc_ske_group_get_by_number(conn->rekey->ske_group,
&ctx->ske->prop->group);
silc_ske_set_callbacks(ctx->ske,
SILC_STR_UI_XNSTRING(args->data, args->len),
SILC_STR_END);
silc_buffer_push(buffer, SILC_COMMAND_PAYLOAD_LEN);
- silc_free(args);
+ silc_buffer_free(args);
}
return buffer;
SILC_STR_UI_XNSTRING(args->data, args->len),
SILC_STR_END);
silc_buffer_push(buffer, SILC_COMMAND_PAYLOAD_LEN);
- silc_free(args);
+ silc_buffer_free(args);
}
return buffer;
ret = silc_hash_table_del(cache->context_table, old->context);
if (old->id)
ret = silc_hash_table_del(cache->id_table, old->id);
+ else
+ silc_free(old);
return ret;
}
ret = silc_hash_table_del(cache->context_table, c->context);
if (c->id)
ret = silc_hash_table_del_by_context(cache->id_table, c->id, c);
+ else
+ silc_free(c);
return ret;
}
unsigned char tmp[4];
uint32 e_len, n_len;
+ if (key->pub_set) {
+ silc_mp_uninit(&key->e);
+ silc_mp_uninit(&key->e);
+ key->pub_set = FALSE;
+ }
+
silc_mp_init(&key->e);
silc_mp_init(&key->n);
silc_mp_bin2mp(key_data + 4 + e_len + 4, n_len, &key->n);
key->bits = n_len * 8;
+ key->pub_set = TRUE;
return key->bits;
}
unsigned char tmp[4];
uint32 e_len, n_len, d_len;
+ if (key->prv_set) {
+ silc_mp_uninit(&key->d);
+ key->prv_set = FALSE;
+ }
+
+ if (key->pub_set) {
+ silc_mp_uninit(&key->e);
+ silc_mp_uninit(&key->n);
+ key->pub_set = FALSE;
+ }
+
silc_mp_init(&key->e);
silc_mp_init(&key->n);
silc_mp_init(&key->d);
if (e_len > key_len) {
silc_mp_uninit(&key->e);
silc_mp_uninit(&key->n);
+ silc_mp_uninit(&key->d);
return FALSE;
}
if (e_len + n_len > key_len) {
silc_mp_uninit(&key->e);
silc_mp_uninit(&key->n);
+ silc_mp_uninit(&key->d);
return FALSE;
}
if (e_len + n_len + d_len > key_len) {
silc_mp_uninit(&key->e);
silc_mp_uninit(&key->n);
+ silc_mp_uninit(&key->d);
return FALSE;
}
silc_mp_bin2mp(key_data + 4 + e_len + 4 + n_len + 4, d_len, &key->d);
key->bits = n_len * 8;
+ key->prv_set = TRUE;
+ key->pub_set = TRUE;
return TRUE;
}
SilcMPInt pm1, qm1;
/* Initialize variables */
- silc_mp_init(&key->p);
- silc_mp_init(&key->q);
silc_mp_init(&key->n);
silc_mp_init(&key->e);
silc_mp_init(&key->d);
/* Set modulus length */
key->bits = bits;
- /* Set the primes */
- silc_mp_set(&key->p, p);
- silc_mp_set(&key->q, q);
-
/* Compute modulus, n = p * q */
- silc_mp_mul(&key->n, &key->p, &key->q);
+ silc_mp_mul(&key->n, p, q);
/* phi = (p - 1) * (q - 1) */
- silc_mp_sub_ui(&pm1, &key->p, 1);
- silc_mp_sub_ui(&qm1, &key->q, 1);
+ silc_mp_sub_ui(&pm1, p, 1);
+ silc_mp_sub_ui(&qm1, q, 1);
silc_mp_mul(&phi, &pm1, &qm1);
/* Set e, the public exponent. We try to use same public exponent
void rsa_clear_keys(RsaKey *key)
{
key->bits = 0;
- silc_mp_uninit(&key->p);
- silc_mp_uninit(&key->q);
- silc_mp_uninit(&key->n);
- silc_mp_uninit(&key->e);
- silc_mp_uninit(&key->d);
+ if (key->pub_set) {
+ silc_mp_uninit(&key->n);
+ silc_mp_uninit(&key->e);
+ }
+ if (key->prv_set)
+ silc_mp_uninit(&key->d);
}
/* RSA encrypt/decrypt function. cm = ciphertext or plaintext,
/* RSA Keys, includes both Private and Public key */
typedef struct {
int bits; /* bits in key */
- SilcMPInt p; /* prime p */
- SilcMPInt q; /* prime q */
+ char pub_set; /* TRUE is n and e is set */
+ char prv_set; /* TRUE if d is set */
SilcMPInt n; /* modulus */
SilcMPInt e; /* public exponent */
SilcMPInt d; /* private exponent */
void silc_pkcs_free(SilcPKCS pkcs)
{
- if (pkcs)
+ if (pkcs) {
+ pkcs->pkcs->clear_keys(pkcs->context);
silc_free(pkcs->context);
+ }
silc_free(pkcs);
}
$(SIM_CIPHER_OBJS): ../silccrypt/libsilccrypt.a
$(LTCOMPILE) -c $(srcdir)/../silccrypt/$*.c
$(LIBTOOL) --mode=link $(LINK) -rpath $(silc_modulesdir) -o lib$*.la $*.lo
- cd $(srcdir)/$(SIM_MODULES_DIR) && $(LN_S) $(srcdir)/../.libs/lib$*.so $(srcdir)/$*.sim.so
+ cd $(srcdir)/$(SIM_MODULES_DIR) && $(LN_S) -f $(srcdir)/../.libs/lib$*.so $(srcdir)/$*.sim.so
$(SIM_HASH_OBJS): ../silccrypt/libsilccrypt.a
$(LTCOMPILE) -c $(srcdir)/../silccrypt/$*.c
$(LIBTOOL) --mode=link $(LINK) -rpath $(silc_modulesdir) -o lib$*.la $*.lo
- cd $(srcdir)/$(SIM_MODULES_DIR) && $(LN_S) $(srcdir)/../.libs/lib$*.so $(srcdir)/$*.sim.so
+ cd $(srcdir)/$(SIM_MODULES_DIR) && $(LN_S) -f $(srcdir)/../.libs/lib$*.so $(srcdir)/$*.sim.so
CLEANFILES = $(SIM_MODULES_DIR)/*.sim.so *.la
/* Returns Diffie Hellman group by group number */
-SilcSKEStatus silc_ske_get_group_by_number(int number,
+SilcSKEStatus silc_ske_group_get_by_number(int number,
SilcSKEDiffieHellmanGroup *ret)
{
int i;
/* Returns Diffie Hellman group by name */
-SilcSKEStatus silc_ske_get_group_by_name(const char *name,
+SilcSKEStatus silc_ske_group_get_by_name(const char *name,
SilcSKEDiffieHellmanGroup *ret)
{
int i;
return SILC_SKE_STATUS_OK;
}
+/* Free group */
+
+void silc_ske_group_free(SilcSKEDiffieHellmanGroup group)
+{
+ silc_mp_uninit(&group->group);
+ silc_mp_uninit(&group->group_order);
+ silc_mp_uninit(&group->generator);
+ silc_free(group);
+}
+
/* Returns comma separated list of supported groups */
char *silc_ske_get_supported_groups()
{
return group->number;
}
+
+/* Returns the name of the `group'. */
+
+const char *silc_ske_group_get_name(SilcSKEDiffieHellmanGroup group)
+{
+ return group->name;
+}
*/
+/****h* silcske/SilcSKEGroups
+ *
+ * DESCRIPTION
+ *
+ * This interface defines the Diffie Hellman group management and utility
+ * functions for the SKE. They can be used find DH groups by group number,
+ * and group name. These routines are used during the SKE session.
+ *
+ ***/
+
#ifndef GROUPS_H
#define GROUPS_H
#include "silcske_status.h"
-/* Forward declaration */
+/****s* silcske/SilcSKEGroups/SilcSKEDiffieHellmanGroup
+ *
+ * NAME
+ *
+ * typedef struct SilcSKEDiffieHellmanGroupStruct
+ * *SilcSKEDiffieHellmanGroup;
+ *
+ * DESCRIPTION
+ *
+ * This context represents one Diffie Hellman group, and is returned
+ * by the utility functions for finding correct groups. The context
+ * is freed by calling the silc_ske_group_free function.
+ *
+ ***/
typedef struct SilcSKEDiffieHellmanGroupStruct *SilcSKEDiffieHellmanGroup;
-/* List of defined groups. */
-extern const struct SilcSKEDiffieHellmanGroupDefStruct silc_ske_groups[];
-
/* Prototypes */
-SilcSKEStatus silc_ske_get_group_by_number(int number,
+
+/****f* silcske/SilcSKEGroups/silc_ske_group_get_by_number
+ *
+ * SYNOPSIS
+ *
+ * SilcSKEStatus
+ * silc_ske_group_get_by_number(int number,
+ * SilcSKEDiffieHellmanGroup *ret);
+ *
+ * DESCRIPTION
+ *
+ * Returns the Diffie Hellman group into the `ret' pointer by
+ * group number indicated by the `number'. Returns error status
+ * if the group was not found.
+ *
+ ***/
+SilcSKEStatus silc_ske_group_get_by_number(int number,
SilcSKEDiffieHellmanGroup *ret);
-SilcSKEStatus silc_ske_get_group_by_name(const char *name,
+
+/****f* silcske/SilcSKEGroups/silc_ske_group_get_by_name
+ *
+ * SYNOPSIS
+ *
+ * SilcSKEStatus
+ * silc_ske_get_group_by_name(const char *name,
+ * SilcSKEDiffieHellmanGroup *ret);
+ *
+ * DESCRIPTION
+ *
+ * Returns the Diffie Hellman group into the `ret' pointer by
+ * group name indicated by the `name'. Returns error status
+ * if the group was not found.
+ *
+ ***/
+SilcSKEStatus silc_ske_group_get_by_name(const char *name,
SilcSKEDiffieHellmanGroup *ret);
+
+/****f* silcske/SilcSKEGroups/silc_ske_group_free
+ *
+ * SYNOPSIS
+ *
+ * void silc_ske_group_free(SilcSKEDiffieHellmanGroup group);
+ *
+ * DESCRIPTION
+ *
+ * Free the Diffie Hellman group indicated by the `group'.
+ *
+ ***/
+void silc_ske_group_free(SilcSKEDiffieHellmanGroup group);
+
+/****f* silcske/SilcSKEGroups/silc_ske_get_supported_groups
+ *
+ * SYNOPSIS
+ *
+ * char *silc_ske_get_supported_groups();
+ *
+ * DESCRIPTION
+ *
+ * Returns a comma separated list of support Diffie Hellman groups.
+ * This can be used to get the list of supported groups for SKE
+ * packets.
+ *
+ ***/
char *silc_ske_get_supported_groups();
+
+/****f* silcske/SilcSKEGroups/silc_ske_group_get_number
+ *
+ * SYNOPSIS
+ *
+ * int silc_ske_group_get_number(SilcSKEDiffieHellmanGroup group);
+ *
+ * DESCRIPTION
+ *
+ * Return the group number of the group indicated by the `group'.
+ *
+ ***/
int silc_ske_group_get_number(SilcSKEDiffieHellmanGroup group);
+/****f* silcske/SilcSKEGroups/silc_ske_group_get_name
+ *
+ * SYNOPSIS
+ *
+ * const char *silc_ske_group_get_name(SilcSKEDiffieHellmanGroup group);
+ *
+ * DESCRIPTION
+ *
+ * Return the group name of the group indicated by the `group'.
+ *
+ ***/
+const char *silc_ske_group_get_name(SilcSKEDiffieHellmanGroup group);
+
#endif
SilcMPInt generator;
};
+/* List of defined groups. */
+extern const struct SilcSKEDiffieHellmanGroupDefStruct silc_ske_groups[];
+
#endif
/* Free rest */
if (ske->prop) {
- silc_free(ske->prop->group);
+ if (ske->prop->group)
+ silc_ske_group_free(ske->prop->group);
if (ske->prop->pkcs)
silc_pkcs_free(ske->prop->pkcs);
if (ske->prop->cipher)
the callback function. */
ske->prop = prop = silc_calloc(1, sizeof(*prop));
prop->flags = payload->flags;
- status = silc_ske_get_group_by_name(payload->ke_grp_list, &group);
+ status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
if (status != SILC_SKE_STATUS_OK)
goto err;
if (payload)
silc_ske_payload_start_free(payload);
- silc_free(group);
+ silc_ske_group_free(group);
if (prop->pkcs)
silc_pkcs_free(prop->pkcs);
only for this negotiation and will be free'd after KE is over. */
ske->prop = prop = silc_calloc(1, sizeof(*prop));
prop->flags = start_payload->flags;
- status = silc_ske_get_group_by_name(start_payload->ke_grp_list, &group);
+ status = silc_ske_group_get_by_name(start_payload->ke_grp_list, &group);
if (status != SILC_SKE_STATUS_OK)
goto err;
err:
if (group)
- silc_free(group);
+ silc_ske_group_free(group);
if (prop->pkcs)
silc_pkcs_free(prop->pkcs);
SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
- if (silc_ske_get_group_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
+ if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
SILC_LOG_DEBUG(("Found KE group `%s'", item));
payload->ke_grp_len = len;