Bunch of small bugs fixed here and there found during static analysis.
ltmain.sh
stamp-h
stamp-h.in
+silcdefs.h
+silcdefs.h.in
+*.o
+*.a
+*.la
+*.Plo
+*.Po
+.exists
+*.so
+*.pm
+*.lo
+*.lai
+*.bs
+*.pc
+apps/irssi/docs/help
+*draft*.txt
+configure.ac
+stamp-h1
tmp = cp;
}
- chanrec->topic = *tmp == '\0' ? NULL : g_strdup(tmp);
+ chanrec->topic = (tmp && *tmp == '\0' ? NULL : g_strdup(tmp));
signal_emit("channel topic changed", 1, chanrec);
silc_free(dm);
return;
if (channel->server && channel->server->disconnected)
return;
+ if (!channel->server)
+ return;
if (channel->session_rejoin)
return;
mask |= SILC_ATTRIBUTE_MOOD_ANXIOUS;
}
silc_client_attribute_add(silc_client, conn,
- SILC_ATTRIBUTE_STATUS_MOOD, (void *)mask,
+ SILC_ATTRIBUTE_STATUS_MOOD,
+ SILC_32_TO_PTR(mask),
sizeof(SilcUInt32));
g_strfreev(list);
}
mask |= SILC_ATTRIBUTE_CONTACT_VIDEO;
}
silc_client_attribute_add(silc_client, conn,
- SILC_ATTRIBUTE_PREFERRED_CONTACT, (void *)mask,
+ SILC_ATTRIBUTE_PREFERRED_CONTACT,
+ SILC_32_TO_PTR(mask),
sizeof(SilcUInt32));
g_strfreev(list);
}
{
GHashTable *optlist;
char *target, *origtarget, *msg;
- void *free_arg;
+ void *free_arg = NULL;
int free_ret, target_type;
g_return_if_fail(data != NULL);
"message signed_own_public" : "message signed_own_private", 4,
server, msg, target, origtarget);
out:
- if (free_ret && target != NULL) g_free(target);
- cmd_params_free(free_arg);
+ if (free_ret && target != NULL)
+ g_free(target);
+ if (free_arg)
+ cmd_params_free(free_arg);
}
/* FILE command */
if (status == SILC_CLIENT_FILE_MONITOR_CLOSED)
return;
- snprintf(fsize, sizeof(fsize) - 1, "%llu", ((filesize + 1023) / 1024));
+ snprintf(fsize, sizeof(fsize) - 1, "%llu",
+ (unsigned long long)((filesize + 1023) / 1024));
silc_dlist_start(server->ftp_sessions);
while ((ftp = silc_dlist_get(server->ftp_sessions)) != SILC_LIST_END) {
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2009 Pekka Riikonen
+ Copyright (C) 1997 - 2014 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/* Allocate command context. This must be free'd by the
command routine receiving it. */
ctx = silc_server_command_alloc();
+ if (!ctx)
+ return;
ctx->server = server;
ctx->sock = sock;
ctx->packet = packet; /* Save original packet */
int fast;
timeout = silc_calloc(1, sizeof(*timeout));
+ if (!timeout) {
+ silc_server_command_send_status_reply(
+ ctx, command,
+ SILC_STATUS_ERR_OPERATION_ALLOWED, 0);
+ silc_packet_free(packet);
+ silc_packet_stream_unref(ctx->sock);
+ silc_free(ctx);
+ return;
+ }
timeout->ctx = ctx;
timeout->cmd = cmd;
SilcServerCommandContext silc_server_command_alloc()
{
SilcServerCommandContext ctx = silc_calloc(1, sizeof(*ctx));
- ctx->users++;
+ if (ctx)
+ ctx->users++;
return ctx;
}
/* Allocate temporary and bogus command reply context */
cmdr = silc_calloc(1, sizeof(*cmdr));
+ if (!cmdr)
+ return;
cmdr->server = server;
cmdr->ident = reply->ident;
cmdr->callbacks =
silc_server_command_pending_check(server, reply->reply_cmd,
reply->ident, &cmdr->callbacks_count);
+ if (!cmdr->callbacks) {
+ silc_free(cmdr);
+ return;
+ }
/* Create bogus command reply with an error inside */
tmpreply =
commands. If the `timeout' is zero default timeout is used. */
SilcBool silc_server_command_pending_timed(SilcServer server,
- SilcCommand reply_cmd,
- SilcUInt16 ident,
- SilcCommandCb callback,
- void *context,
- SilcUInt16 timeout)
+ SilcCommand reply_cmd,
+ SilcUInt16 ident,
+ SilcCommandCb callback,
+ void *context,
+ SilcUInt16 timeout)
{
SilcServerCommandPending *reply;
}
reply = silc_calloc(1, sizeof(*reply));
+ if (!reply)
+ return FALSE;
reply->reply_cmd = reply_cmd;
reply->ident = ident;
reply->context = context;
}
/* Checks for pending commands and marks callbacks to be called from
- the command reply function. Returns TRUE if there were pending command. */
+ the command reply function. Returns the pending callbacks if there were
+ any or NULL if there weren't. */
SilcServerCommandPendingCallbacks
silc_server_command_pending_check(SilcServer server,
if ((r->reply_cmd == command || r->reply_cmd == SILC_COMMAND_NONE)
&& r->ident == ident) {
callbacks = silc_realloc(callbacks, sizeof(*callbacks) * (i + 1));
+ if (!callbacks)
+ return NULL;
callbacks[i].context = r->context;
callbacks[i].callback = r->callback;
r->reply_check = TRUE;
tmp = NULL;
q = silc_calloc(1, sizeof(*q));
+ if (!q)
+ goto out;
q->sock = sock;
q->signoff = tmp ? strdup(tmp) : NULL;
silc_packet_stream_ref(q->sock);
Add also the channel to client entry's channels list for fast cross-
referencing. */
chl = silc_calloc(1, sizeof(*chl));
+ if (!chl)
+ goto out;
chl->mode = umode;
chl->client = client;
chl->channel = channel;
0);
goto out;
}
- tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
/* Get cipher, hmac name and auth payload */
cipher = silc_argument_get_arg_type(cmd->args, 4, NULL);
silc_server_command_send_status_data(
cmd, SILC_COMMAND_CMODE,
SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0,
- 2, hmac, strlen(hmac));
+ 2, hmac ? hmac : SILC_DEFAULT_HMAC,
+ strlen(hmac ? hmac : SILC_DEFAULT_HMAC));
goto out;
}
QuitInternal q = (QuitInternal)context;
SilcPacketStream sock = q->sock;
SilcClientEntry client = silc_packet_get_context(sock);
- SilcIDListData idata = (SilcIDListData)client;
+ SilcIDListData idata;
if (!client) {
silc_packet_stream_unref(sock);
SILC_NOTIFY_TYPE_UMODE_CHANGE);
q = silc_calloc(1, sizeof(*q));
+ if (!q)
+ goto out;
q->sock = cmd->sock;
silc_packet_stream_ref(q->sock);
silc_schedule_task_add_timeout(server->schedule,
if (server->config->detach_timeout) {
q = silc_calloc(1, sizeof(*q));
+ if (!q)
+ goto out;
q->sock = (void *)silc_id_dup(client->id, SILC_ID_CLIENT);
silc_schedule_task_add_timeout(server->schedule,
silc_server_command_detach_timeout,
SilcServer server = cmd->server;
SilcUInt32 tmp_len, auth_len;
unsigned char *service_name, *auth;
- SilcBool send_list = FALSE;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SERVICE, cmd, 0, 256);
}
- send_list = TRUE;
-
/* Send our service list back */
silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_SERVICE,
SILC_STATUS_OK, 0, ident, 0);
SilcUInt32 len;
SilcClientEntry client = silc_packet_get_context(cmd->sock);
+ if (!client)
+ return FALSE;
+
/* Take Requested Attributes if set. */
tmp = silc_argument_get_arg_type(cmd->args, 11, &len);
- if (tmp && client) {
+ if (tmp) {
silc_free(client->attrs);
client->attrs = silc_memdup(tmp, len);
client->attrs_len = len;
if (!idp)
return FALSE;
+ memset(nick, 0, sizeof(nick));
+
name = silc_argument_get_arg_type(cmd->args, 3, &len);
info = silc_argument_get_arg_type(cmd->args, 4, &len);
SilcIDCacheEntry cache;
unsigned char *tmp, *name, *namec = NULL, *topic;
SilcUInt32 usercount = 0;
- SilcBool global_list = FALSE;
COMMAND_CHECK_STATUS;
/* Add the channel entry if we do not have it already */
channel = silc_idlist_find_channel_by_name(server->local_list,
namec, &cache);
- if (!channel) {
+ if (!channel)
channel = silc_idlist_find_channel_by_name(server->global_list,
namec, &cache);
- global_list = TRUE;
- }
if (!channel) {
/* If router did not find such channel in its lists then this must
be bogus channel or some router in the net is buggy. */
}
server = silc_calloc(1, sizeof(*server));
+ if (!server) {
+ silc_free(server_namec);
+ return NULL;
+ }
server->server_name = server_name;
server->server_type = server_type;
server->id = id;
}
channel = silc_calloc(1, sizeof(*channel));
+ if (!channel) {
+ silc_free(channel_namec);
+ return NULL;
+ }
channel->channel_name = channel_name;
channel->mode = mode;
channel->id = id;
return NULL;
channels = silc_calloc(silc_list_count(list), sizeof(*channels));
+ if (!channels)
+ return NULL;
i = 0;
silc_list_start(list);
i = 1;
channels = silc_calloc(1, sizeof(*channels));
+ if (!channels)
+ return NULL;
channels[0] = (SilcChannelEntry)id_cache->context;
}
SilcStatus error;
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
- if (!tmp && tmp_len != 1)
+ if (!tmp || tmp_len != 1)
goto out;
error = (SilcStatus)tmp[0];
char *newusername;
newusername = silc_calloc(strlen(username) + strlen(hostname) + 2,
sizeof(*newusername));
+ if (!newusername) {
+ silc_free(username);
+ silc_free(realname);
+ silc_free(nickname);
+ silc_server_disconnect_remote(server, sock,
+ SILC_STATUS_ERR_OPERATION_ALLOWED, NULL);
+ silc_server_free_sock_user_data(server, sock, NULL);
+ silc_packet_free(packet);
+ return NULL;
+ }
strncat(newusername, username, strlen(username));
strncat(newusername, "@", 1);
strncat(newusername, hostname, strlen(hostname));
if (!silc_id_create_client_id(server, server->id, server->rng,
server->md5hash, nicknamec,
strlen(nicknamec), &client_id)) {
+ silc_free(username);
+ silc_free(realname);
+ silc_free(nickname);
silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_BAD_NICKNAME, NULL);
silc_server_free_sock_user_data(server, sock, NULL);
SilcChannelID channel_id;
char *channel_name, *channel_namec = NULL;
SilcUInt32 name_len;
- unsigned char *id, cid[32];
+ unsigned char cid[32];
SilcUInt32 id_len, cipher_len;
SilcServerEntry server_entry;
SilcChannelEntry channel;
if (!channel_namec)
return;
- id = silc_channel_get_id(payload, &id_len);
-
server_entry = (SilcServerEntry)idata;
if (idata->conn_type == SILC_CONN_ROUTER) {
routed = silc_calloc(silc_hash_table_count(channel->user_list),
sizeof(*routed));
+ if (!routed)
+ goto out;
/* Send the message to clients on the channel's client list. */
silc_hash_table_list(channel->user_list, &htl);
}
}
+ if (!silc_hash_table_count(channel->user_list)) {
+ SILC_LOG_DEBUG(("Channel %s is empty", channel->channel_name));
+ return;
+ }
+
routed = silc_calloc(silc_hash_table_count(channel->user_list),
sizeof(*routed));
+ if (!routed)
+ return;
/* Assure we won't route the message back to the sender's way. */
if (sender_entry->router)
SILC_LOG_DEBUG(("Verifying public key"));
- if (silc_pkcs_get_type(public_key) != SILC_SKE_PK_TYPE_SILC) {
+ if (silc_pkcs_get_type(public_key) != SILC_PKCS_SILC) {
SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
entry->hostname, entry->ip, entry->port,
silc_pkcs_get_type(public_key)));
SilcBool initiator = FALSE;
SilcBool backup_local = FALSE;
SilcBool backup_router = FALSE;
- char *backup_replace_ip = NULL;
- SilcUInt16 backup_replace_port = 0;
SilcServerConfigServer *srvconn = entry->sconfig.ref_ptr;
SilcServerConfigRouter *rconn = entry->rconfig.ref_ptr;
initiator = rconn->initiator;
backup_local = rconn->backup_local;
backup_router = rconn->backup_router;
- backup_replace_ip = rconn->backup_replace_ip;
- backup_replace_port = rconn->backup_replace_port;
}
}
if (server->server_type == SILC_ROUTER) {
if (!channel->rekey)
channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
+ if (!channel->rekey) {
+ memset(channel->key, 0, channel->key_len / 8);
+ silc_free(channel->key);
+ silc_cipher_free(channel->send_key);
+ silc_cipher_free(channel->receive_key);
+ channel->send_key = channel->receive_key = NULL;
+ return FALSE;
+ }
channel->rekey->channel = channel;
channel->rekey->key_len = key_len;
if (channel->rekey->task)
silc_cipher_free(channel->send_key);
silc_cipher_free(channel->receive_key);
channel->send_key = channel->receive_key = NULL;
- return FALSE;
+ return NULL;
}
silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash);
silc_hmac_set_key(channel->hmac, hash,
if (server->server_type == SILC_ROUTER) {
if (!channel->rekey)
channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
+ if (!channel->rekey) {
+ memset(channel->key, 0, channel->key_len / 8);
+ silc_free(channel->key);
+ silc_cipher_free(channel->send_key);
+ silc_cipher_free(channel->receive_key);
+ channel->send_key = channel->receive_key = NULL;
+ return NULL;
+ }
channel->rekey->channel = channel;
if (channel->rekey->task)
silc_schedule_task_del(server->schedule, channel->rekey->task);
if (!silc_server_client_on_channel(client, channel, &chl)) {
/* Client was not on the channel, add it. */
chl = silc_calloc(1, sizeof(*chl));
+ if (!chl)
+ continue;
chl->client = client;
chl->mode = mode;
chl->channel = channel;
/* Add the client on the channel */
if (!silc_server_client_on_channel(client, channel, &chl)) {
chl = silc_calloc(1, sizeof(*chl));
+ if (!chl)
+ continue;
chl->client = client;
chl->mode = chumodes[i++];
chl->channel = channel;
buffer = silc_buffer_realloc(buffer,
(buffer ?
silc_buffer_truelen(buffer) + len : len));
+ if (!buffer)
+ return NULL;
silc_buffer_pull_tail(buffer, (buffer->end - buffer->data));
silc_buffer_format(buffer,
SILC_STR_UI_SHORT(name_len),
silc_buffer_realloc(*user_mode_list,
(*user_mode_list ?
silc_buffer_truelen((*user_mode_list)) + 4 : 4));
+ if (!(*user_mode_list))
+ return NULL;
silc_buffer_pull_tail(*user_mode_list, ((*user_mode_list)->end -
(*user_mode_list)->data));
SILC_PUT32_MSB(chl->mode, (*user_mode_list)->data);
SilcClientEntry client,
SilcBool notify,
const char *signoff_message,
- SilcBool keygen, bool killed);
+ SilcBool keygen, SilcBool killed);
SilcBool silc_server_remove_from_one_channel(SilcServer server,
SilcPacketStream sock,
SilcChannelEntry channel,
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2007 Pekka Riikonen
+ Copyright (C) 2001 - 2014 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
int i;
SilcServerBackupReplaced *r = silc_calloc(1, sizeof(*r));;
+ if (!r)
+ return;
if (!server->backup)
server->backup = silc_calloc(1, sizeof(*server->backup));
+ if (!server->backup)
+ return;
if (!server->backup->replaced) {
server->backup->replaced =
silc_calloc(1, sizeof(*server->backup->replaced));
server->backup->replaced_count = 1;
}
+ if (!server->backup->replaced)
+ return;
SILC_LOG_DEBUG(("Replacing router %s with %s",
silc_id_render(server_id, SILC_ID_SERVER),
SilcBool local)
{
SilcServerEntry backup;
- SilcPacketStream sock;
int i;
if (!server->backup || server->server_type != SILC_ROUTER)
if (server->backup->servers[i].server == server->id_entry)
continue;
- sock = backup->connection;
-
silc_server_packet_send(server, backup->connection, type, flags,
data, data_len);
}
SilcBool local)
{
SilcServerEntry backup;
- SilcPacketStream sock;
int i;
if (!server->backup || server->server_type != SILC_ROUTER)
if (server->backup->servers[i].server == server->id_entry)
continue;
- sock = backup->connection;
-
silc_server_packet_send_dest(server, backup->connection, type, flags,
dst_id, dst_id_type, data, data_len);
}
/* Reprocess this packet after received reply from router */
pc = silc_calloc(1, sizeof(*pc));
+ if (!pc) {
+ silc_server_backup_send_start_use(server, sock, FALSE);
+ silc_packet_free(packet);
+ return;
+ }
pc->server = server;
pc->sock = sock;
pc->packet = packet;
/* We have received a start for resuming protocol. We are either
primary router that came back online or normal server. */
SilcServerBackupProtocolContext proto_ctx;
+ unsigned char data[4];
/* If backup had closed the connection earlier we won't allow resuming
since we (primary router) have never gone away. */
if (server->server_type == SILC_ROUTER && !server->backup_router &&
server->backup_closed) {
- unsigned char data[4];
SILC_LOG_DEBUG(("Backup resuming not allowed since we are still "
"primary router"));
SILC_LOG_INFO(("Backup resuming not allowed since we are still "
}
proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
+ if (!proto_ctx) {
+ SILC_PUT32_MSB(SILC_SERVER_BACKUP_START, data);
+ silc_server_packet_send(server, sock, SILC_PACKET_FAILURE, 0,
+ data, 4);
+ server->backup_closed = FALSE;
+ silc_packet_free(packet);
+ return;
+ }
proto_ctx->server = server;
proto_ctx->sock = sock;
proto_ctx->responder = TRUE;
sock = server_entry->connection;
proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
+ if (!proto_ctx)
+ return;
proto_ctx->server = server;
proto_ctx->sock = sock;
proto_ctx->responder = FALSE;
/* Restart the protocol. */
proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
+ if (!proto_ctx)
+ continue;
proto_ctx->server = server;
proto_ctx->sock = sock;
proto_ctx->responder = FALSE;
if (!old_query) {
query = silc_calloc(1, sizeof(*query));
+ if (!query)
+ return FALSE;
query->querycmd = querycmd;
query->cmd = silc_server_command_dup(cmd);
query->router = SILC_PRIMARY_ROUTE(server);
} else {
/* Parse the IDs included in the query */
query->ids = silc_calloc(argc, sizeof(*query->ids));
+ if (!query->ids)
+ return FALSE;
for (i = 0; i < argc; i++) {
tmp = silc_argument_get_arg_type(cmd->args, i + 4, &tmp_len);
} else {
/* Parse the IDs included in the query */
query->ids = silc_calloc(argc, sizeof(*query->ids));
+ if (!query->ids)
+ return FALSE;
for (i = 0; i < argc; i++) {
tmp = silc_argument_get_arg_type(cmd->args, i + 5, &tmp_len);
SILC_LOG_DEBUG(("Creating new Client ID"));
*new_id = silc_calloc(1, sizeof(**new_id));
+ if (!(*new_id))
+ return FALSE;
/* Create hash of the nickname (it's already checked as valid identifier
string). */
SILC_LOG_DEBUG(("Creating new Channel ID"));
*new_id = silc_calloc(1, sizeof(**new_id));
+ if (!(*new_id))
+ return FALSE;
/* Create the ID */
memcpy((*new_id)->ip.data, router_id->ip.data, router_id->ip.data_len);
gboolean do_compat = (mode == G_NORMALIZE_NFKC || mode == G_NORMALIZE_NFKD);
gboolean do_compose = (mode == G_NORMALIZE_NFC || mode == G_NORMALIZE_NFKC);
+ if (!str)
+ return NULL;
+
n_wc = 0;
p = str;
while ((max_len < 0 || p < str + max_len) && *p)
const char *silc_asn1_tag_name(SilcAsn1Tag tag)
{
- switch (tag) {
+ switch ((long)tag) {
case SILC_ASN1_END:
return "END";
case SILC_ASN1_TAG_OPTS:
}
/* Decode by the type user expects the data to be. */
- switch (type) {
+ switch ((long)type) {
case SILC_ASN1_TAG_ANY:
{
}
/* Encode by the type */
- switch (type) {
+ switch ((long)type) {
case SILC_ASN1_TAG_ANY:
{
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2008 Pekka Riikonen
+ Copyright (C) 1997 - 2014 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
SILC_LOG_DEBUG(("Connecting to server"));
- if (!client || !remote_host)
+ if (!client || !remote_host || !callback)
return NULL;
if (client->internal->run_callback) {
SILC_LOG_DEBUG(("Connecting to client"));
- if (!client || !remote_host)
+ if (!client || !remote_host || !callback)
return NULL;
if (client->internal->run_callback) {
SILC_LOG_DEBUG(("Performing key exchange"));
- if (!client || !stream)
+ if (!client || !stream || !callback)
return NULL;
if (client->internal->run_callback) {
/* Take all without any further checking */
while ((id_cache = silc_list_get(list))) {
entry = id_cache->context;
+ if (!entry)
+ continue;
if (!get_valid || entry->internal.valid) {
silc_client_ref_client(client, conn, id_cache->context);
silc_dlist_add(clients, id_cache->context);
/* Check multiple cache entries for exact match */
while ((id_cache = silc_list_get(list))) {
entry = id_cache->context;
+ if (!entry)
+ continue;
/* If server was provided, find entries that either have no server
set or have the same server. Ignore those that have different
void silc_client_unref_server(SilcClient client, SilcClientConnection conn,
SilcServerEntry server_entry)
{
- SilcBool ret;
SilcIDCacheEntry id_cache;
char *namec;
if (silc_idcache_find_by_context(conn->internal->server_cache, server_entry,
&id_cache)) {
namec = id_cache->name;
- ret = silc_idcache_del_by_context(conn->internal->server_cache,
- server_entry, NULL);
+ silc_idcache_del_by_context(conn->internal->server_cache,
+ server_entry, NULL);
silc_free(namec);
}
silc_mutex_unlock(conn->internal->lock);
/* Get error */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
- if (!tmp && tmp_len != 1)
+ if (!tmp || tmp_len != 1)
goto out;
error = (SilcStatus)tmp[0];
/* Mark that we are responder */
client_entry = silc_dlist_get(clients);
- client_entry->internal.prv_resp = TRUE;
+ if (client_entry)
+ client_entry->internal.prv_resp = TRUE;
/* XXX we should notify application that remote wants to set up the
static key. And we should tell if we already have key with remote.
res_argc, res_argv, res_argv_lens,
res_argv_types);
- for (i = 0; i < resume->channel_count; i++)
+ for (i = 0; res_argv && i < resume->channel_count; i++)
silc_free(res_argv[i]);
silc_free(res_argv);
silc_free(res_argv_lens);
SilcServerEntry server_entry;
unsigned char *tmp;
SilcUInt32 len;
- SilcPublicKey public_key;
+ SilcPublicKey public_key = NULL;
SilcID id;
/* Sanity checks */
SilcBufferStruct buffer;
SilcArgumentPayload newp;
SilcUInt16 p_len = 0;
- unsigned char arg_num = 0;
unsigned char arg_type = 0;
SilcUInt32 pull_len = 0;
int i = 0, ret;
goto err;
/* Get arguments */
- arg_num = 1;
for (i = 0; i < argc; i++) {
ret = silc_buffer_unformat(&buffer,
SILC_STR_UI_SHORT(&p_len),
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2002 - 2007 Pekka Riikonen
+ Copyright (C) 2002 - 2014 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
unsigned char tmp[4], *str = NULL, *ret;
SilcUInt32 len;
+ if (ret_len)
+ *ret_len = 0;
+
/* Encode according to attribute type */
if (flags & SILC_ATTRIBUTE_FLAG_VALID) {
- if (!object && !object_size)
+ if (!object || !object_size)
return NULL;
switch (attribute) {
attr->data =
silc_attribute_payload_encode_int(attribute, flags, object,
object_size, &tmp_len);
- attr->data_len = (SilcUInt16)tmp_len;
if (!attr->data) {
silc_free(attr);
return NULL;
}
+ attr->data_len = (SilcUInt16)tmp_len;
return attr;
}
silc_buffer_purge(&buf);
va_end(va);
- return TRUE;
+ return ret;
}
/***************************** Packet Receiving *****************************/
cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
- cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
- cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
+ ss[4] = word_in(key, 4);
+ cx->ks[v(48,(4))] = ff(ss[4]);
+ ss[5] = word_in(key, 5);
+ cx->ks[v(48,(5))] = ff(ss[5]);
kdf6(cx->ks, 0); kd6(cx->ks, 1);
kd6(cx->ks, 2); kd6(cx->ks, 3);
kd6(cx->ks, 4); kd6(cx->ks, 5);
cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
- cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
- cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
- cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
- cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
+ ss[4] = word_in(key, 4);
+ cx->ks[v(56,(4))] = ff(ss[4]);
+ ss[5] = word_in(key, 5);
+ cx->ks[v(56,(5))] = ff(ss[5]);
+ ss[6] = word_in(key, 6);
+ cx->ks[v(56,(6))] = ff(ss[6]);
+ ss[7] = word_in(key, 7);
+ cx->ks[v(56,(7))] = ff(ss[7]);
kdf8(cx->ks, 0); kd8(cx->ks, 1);
kd8(cx->ks, 2); kd8(cx->ks, 3);
kd8(cx->ks, 4); kd8(cx->ks, 5);
}
#endif /* SILC_SYMBIAN */
- list[len - 1] = 0;
+ if (list)
+ list[len - 1] = 0;
return list;
}
}
#endif /* SILC_SYMBIAN */
- list[len - 1] = 0;
+ if (list)
+ list[len - 1] = 0;
return list;
}
}
#endif /* SILC_SYMBIAN */
- list[len - 1] = 0;
+ if (list)
+ list[len - 1] = 0;
return list;
}
}
#endif /* SILC_SYMBIAN */
- list[len - 1] = 0;
+ if (list)
+ list[len - 1] = 0;
return list;
}
/* MP to data */
padded = silc_mp_mp2bin(&mp_dst, (key->bits + 7) / 8, &padded_len);
+ if (!padded) {
+ silc_mp_uninit(&mp_tmp);
+ silc_mp_uninit(&mp_dst);
+ return FALSE;
+ }
/* Unpad data */
if (!silc_pkcs1_decode(SILC_PKCS1_BT_PUB, padded, padded_len,
SilcBool ret = FALSE;
SilcMPInt mp_tmp2;
SilcMPInt mp_dst;
- unsigned char *verify, unpadded[2048 + 1], hashr[SILC_HASH_MAXLEN];
+ unsigned char *verify = NULL, unpadded[65536 + 1], hashr[SILC_HASH_MAXLEN];
SilcUInt32 verify_len, len = (key->bits + 7) / 8;
SilcBufferStruct di, ldi;
SilcHash ihash = NULL;
/* MP to data */
verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
+ if (!verify)
+ goto err;
/* Unpad data */
if (!silc_pkcs1_decode(SILC_PKCS1_BT_PRV1, verify, verify_len,
return ret;
err:
- memset(verify, 0, verify_len);
- silc_free(verify);
+ if (verify) {
+ memset(verify, 0, verify_len);
+ silc_free(verify);
+ }
silc_mp_uninit(&mp_tmp2);
silc_mp_uninit(&mp_dst);
if (ihash)
/* MP to data */
verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
+ if (!verify) {
+ silc_mp_uninit(&mp_tmp2);
+ silc_mp_uninit(&mp_dst);
+ return FALSE;
+ }
/* Unpad data */
if (!silc_pkcs1_decode(SILC_PKCS1_BT_PRV1, verify, verify_len,
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2003 Pekka Riikonen
+ Copyright (C) 1997 - 2014 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
}
new->devrandom = strdup("/dev/random");
+ if (!new->devrandom) {
+ silc_rng_free(new);
+ return NULL;
+ }
return new;
}
/* Initialize the states for the RNG. */
rng->state = silc_calloc(1, sizeof(*rng->state));
+ if (!rng->state) {
+ SILC_LOG_ERROR(("Error allocating memory for RNG"));
+ return;
+ }
rng->state->low = 0;
rng->state->pos = 8;
rng->state->next = NULL;
first = rng->state;
for (i = SILC_RNG_STATE_NUM - 1; i >= 1; i--) {
next = silc_calloc(1, sizeof(*rng->state));
+ if (!next) {
+ SILC_LOG_ERROR(("Error allocating memory for RNG"));
+ return;
+ }
next->low =
(i * (sizeof(rng->pool) / SILC_RNG_STATE_NUM));
next->pos =
unsigned char *string;
string = silc_calloc((len * 2 + 1), sizeof(unsigned char));
+ if (!string)
+ return NULL;
for (i = 0; i < len; i++)
sprintf(string + 2 * i, "%02x", silc_rng_get_byte(rng));
unsigned char *data;
data = silc_calloc(len + 1, sizeof(*data));
+ if (!data)
+ return NULL;
for (i = 0; i < len; i++)
data[i] = silc_rng_get_byte(rng);
}
#endif
- ctx->k_len = ctx->k_len = key_len / 64; /* 2, 3 or 4 */
+ ctx->k_len = key_len / 64; /* 2, 3 or 4 */
for(i = 0; i < ctx->k_len; ++i)
{
if (value && !strcasecmp(value, "close"))
conn->keepalive = FALSE;
+ if (!conn->method)
+ return FALSE;
+
/* Deliver request to caller */
if (!strcasecmp(conn->method, "GET") || !strcasecmp(conn->method, "HEAD")) {
httpd->callback(httpd, conn, conn->uri, conn->method,
void silc_mp_uninit(SilcMPInt *mp)
{
- mpz_clear(mp);
+ if (mp)
+ mpz_clear(mp);
}
size_t silc_mp_size(SilcMPInt *mp)
void silc_mp_uninit(SilcMPInt *mp)
{
- fp_zero(mp);
+ if (mp)
+ fp_zero(mp);
}
size_t silc_mp_size(SilcMPInt *mp)
void silc_mp_uninit(SilcMPInt *mp)
{
- tma_mp_clear(mp);
+ if (mp)
+ tma_mp_clear(mp);
}
size_t silc_mp_size(SilcMPInt *mp)
*
* DESCRIPTION
*
- * Uninitializes the MP Integer.
+ * Uninitializes the MP Integer. The pointer may be NULL.
*
***/
void silc_mp_uninit(SilcMPInt *mp);
/* number of output digits to produce */
pa = MIN(digs, a->used + b->used);
+ if (!pa)
+ return MP_VAL;
/* clear the carry */
_W = 0;
/* number of output digits to produce */
pa = a->used + b->used;
+ if (!pa)
+ return MP_VAL;
+
_W = 0;
for (ix = digs; ix < pa; ix++) {
int tx, ty, iy;
char *path, *cp;
cp = path = memfs_expand_path(dir, p);
+ if (!cp)
+ return NULL;
if (strlen(cp) == 1 && cp[0] == '/')
return dir;
len++;
}
- list[len - 1] = 0;
+ if (list)
+ list[len - 1] = 0;
return list;
}
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2000 - 2008 Pekka Riikonen
+ Copyright (C) 2000 - 2014 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
SILC_LOG_DEBUG(("Parsing KE Start Payload"));
rp = remote_payload;
+ if (!rp)
+ return SILC_SKE_STATUS_BAD_VERSION;
/* Check for mandatory fields */
if (!rp->ke_grp_len) {
s_len = (ske->start_payload_copy ?
silc_buffer_len(ske->start_payload_copy) : 0);
e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
+ if (!e)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
+ if (!f)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
+ if (!KEY)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
/* Format the buffer used to compute the hash value */
buf = silc_buffer_alloc_size(s_len +
s_len = (ske->start_payload_copy ?
silc_buffer_len(ske->start_payload_copy) : 0);
e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
+ if (!e)
+ return SILC_SKE_STATUS_OUT_OF_MEMORY;
buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
if (!buf)
SilcSKERekeyMaterial rekey;
const char *hash;
+ if (!keymat)
+ return NULL;
+
/* Create rekey material */
rekey = silc_calloc(1, sizeof(*rekey));
if (!rekey)
SILC_LOG_DEBUG(("Assembling KE Start Payload"));
rp = silc_calloc(1, sizeof(*rp));
+ if (!rp)
+ return NULL;
/* Set flags */
rp->flags = (unsigned char)flags;
/* Set random cookie */
rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
+ if (!rp->cookie) {
+ silc_free(rp);
+ return NULL;
+ }
for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
rp->cookie_len = SILC_SKE_COOKIE_LEN;
/* Put version */
rp->version = strdup(version);
- rp->version_len = strlen(version);
+ if (rp->version)
+ rp->version_len = strlen(version);
/* Get supported Key Exhange groups */
rp->ke_grp_list = silc_ske_get_supported_groups();
- rp->ke_grp_len = strlen(rp->ke_grp_list);
+ if (rp->ke_grp_list)
+ rp->ke_grp_len = strlen(rp->ke_grp_list);
/* Get supported PKCS algorithms */
rp->pkcs_alg_list = silc_pkcs_get_supported();
- rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
+ if (rp->pkcs_alg_list)
+ rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
/* Get supported encryption algorithms */
rp->enc_alg_list = silc_cipher_get_supported();
- rp->enc_alg_len = strlen(rp->enc_alg_list);
+ if (rp->enc_alg_list)
+ rp->enc_alg_len = strlen(rp->enc_alg_list);
/* Get supported hash algorithms */
rp->hash_alg_list = silc_hash_get_supported();
- rp->hash_alg_len = strlen(rp->hash_alg_list);
+ if (rp->hash_alg_list)
+ rp->hash_alg_len = strlen(rp->hash_alg_list);
/* Get supported HMACs */
rp->hmac_alg_list = silc_hmac_get_supported();
- rp->hmac_alg_len = strlen(rp->hmac_alg_list);
+ if (rp->hmac_alg_list)
+ rp->hmac_alg_len = strlen(rp->hmac_alg_list);
/* XXX */
/* Get supported compression algorithms */
ske->retrans.type = type;
ske->retrans.flags = flags;
ske->retrans.data = silc_memdup(data, data_len);
- ske->retrans.data_len = data_len;
- silc_ske_install_retransmission(ske);
+ if (ske->retrans.data) {
+ ske->retrans.data_len = data_len;
+ silc_ske_install_retransmission(ske);
+ }
}
return ret;
* FSM finish routine is called. We have to be prepared to handle
* that case.
*/
- ske->packet = NULL;
- ske->status = SILC_SKE_STATUS_ERROR;
+ ske->packet = NULL;
+ ske->status = SILC_SKE_STATUS_ERROR;
silc_ske_notify_failure(ske);
silc_ske_payload_start_free(payload);
if (group)
silc_ske_group_free(group);
- if (prop->cipher)
- silc_cipher_free(prop->cipher);
- if (prop->hash)
- silc_hash_free(prop->hash);
- if (prop->hmac)
- silc_hmac_free(prop->hmac);
- silc_free(prop);
+ if (prop) {
+ if (prop->cipher)
+ silc_cipher_free(prop->cipher);
+ if (prop->hash)
+ silc_hash_free(prop->hash);
+ if (prop->hmac)
+ silc_hmac_free(prop->hmac);
+ silc_free(prop);
+ }
ske->prop = NULL;
if (status == SILC_SKE_STATUS_OK)
/* Create the random number x, 1 < x < q. */
x = silc_calloc(1, sizeof(*x));
- if (!x){
+ if (!x) {
/** Out of memory */
ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
silc_fsm_next(fsm, silc_ske_st_initiator_error);
/* Compute the hash value */
memset(hash, 0, sizeof(hash));
- silc_ske_make_hash(ske, hash, &hash_len, TRUE);
+ if (silc_ske_make_hash(ske, hash, &hash_len, TRUE) != SILC_SKE_STATUS_OK)
+ {
+ /** Error computing hash */
+ silc_mp_uninit(x);
+ silc_free(x);
+ silc_mp_uninit(&payload->x);
+ silc_free(payload->pk_data);
+ silc_free(payload);
+ ske->ke1_payload = NULL;
+ ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
+ silc_fsm_next(fsm, silc_ske_st_initiator_error);
+ return SILC_FSM_CONTINUE;
+ }
SILC_LOG_DEBUG(("Signing HASH_i value"));
/* Compute the shared secret key */
KEY = silc_calloc(1, sizeof(*KEY));
+ if (!KEY) {
+ ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+ goto err;
+ }
silc_mp_init(KEY);
silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
ske->KEY = KEY;
if (status != SILC_SKE_STATUS_OK)
goto err;
ske->hash = silc_memdup(hash, hash_len);
+ if (!ske->hash) {
+ status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+ goto err;
+ }
ske->hash_len = hash_len;
if (ske->prop->public_key) {
ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
ske->start_payload = start_payload;
ske->version = params->version;
- ++ ske->refcnt;
+ ++ske->refcnt;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
/* Take a copy of the payload buffer for future use. It is used to
compute the HASH value. */
ske->start_payload_copy = silc_buffer_copy(packet_buf);
+ if (!ske->start_payload_copy) {
+ silc_packet_free(ske->packet);
+ ske->packet = NULL;
+ ske->status = status;
+ silc_fsm_next(fsm, silc_ske_st_responder_error);
+ return SILC_FSM_CONTINUE;
+ }
silc_packet_free(ske->packet);
ske->packet = NULL;
{
SilcSKE ske = fsm_context;
SilcSKEStatus status;
- SilcSKEKEPayload recv_payload, send_payload;
- SilcMPInt *x, *KEY;
+ SilcSKEKEPayload recv_payload, send_payload = NULL;
+ SilcMPInt *x = NULL, *KEY;
if (ske->aborted) {
/** Aborted */
if (ske->status != SILC_SKE_STATUS_OK) {
/** Public key not verified */
SILC_LOG_DEBUG(("Public key verification failed"));
- silc_fsm_next(fsm, silc_ske_st_initiator_error);
- return SILC_FSM_CONTINUE;
+ goto err;
}
recv_payload = ske->ke1_payload;
status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
if (status != SILC_SKE_STATUS_OK) {
/** Error computing hash */
+ SILC_LOG_DEBUG(("Error computing hash"));
ske->status = status;
- silc_fsm_next(fsm, silc_ske_st_responder_error);
- return SILC_FSM_CONTINUE;
+ goto err;
}
SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
/** Incorrect signature */
SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
- silc_fsm_next(fsm, silc_ske_st_responder_error);
- return SILC_FSM_CONTINUE;
+ goto err;
}
SILC_LOG_DEBUG(("Signature is Ok"));
/* Create the random number x, 1 < x < q. */
x = silc_calloc(1, sizeof(*x));
+ if (!x) {
+ ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+ goto err;
+ }
silc_mp_init(x);
status =
silc_ske_create_rnd(ske, &ske->prop->group->group_order,
x);
if (status != SILC_SKE_STATUS_OK) {
/** Error generating random number */
- silc_mp_uninit(x);
- silc_free(x);
ske->status = status;
- silc_fsm_next(fsm, silc_ske_st_responder_error);
- return SILC_FSM_CONTINUE;
+ goto err;
}
/* Save the results for later processing */
send_payload = silc_calloc(1, sizeof(*send_payload));
+ if (!send_payload) {
+ ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+ goto err;
+ }
ske->x = x;
ske->ke2_payload = send_payload;
/* Compute the shared secret key */
KEY = silc_calloc(1, sizeof(*KEY));
+ if (!KEY) {
+ ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+ goto err;
+ }
silc_mp_init(KEY);
silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
&ske->prop->group->group);
/** Send KE2 payload */
silc_fsm_next(fsm, silc_ske_st_responder_phase5);
return SILC_FSM_CONTINUE;
+
+ err:
+ silc_mp_uninit(x);
+ silc_free(x);
+ ske->x = NULL;
+ silc_free(send_payload);
+ ske->ke2_payload = NULL;
+
+ silc_fsm_next(fsm, silc_ske_st_responder_error);
+ return SILC_FSM_CONTINUE;
}
/* Phase-5. Send KE2 payload */
pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
if (!pk) {
/** Error encoding public key */
- status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+ ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
silc_fsm_next(fsm, silc_ske_st_responder_error);
return SILC_FSM_CONTINUE;
}
return SILC_FSM_CONTINUE;
}
ske->hash = silc_memdup(hash, hash_len);
+ if (!ske->hash) {
+ /** Error computing hash */
+ ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+ silc_fsm_next(fsm, silc_ske_st_responder_error);
+ return SILC_FSM_CONTINUE;
+ }
ske->hash_len = hash_len;
if (ske->public_key && ske->private_key) {
if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
/** Error computing signature */
- status = SILC_SKE_STATUS_SIGNATURE_ERROR;
+ ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
silc_fsm_next(fsm, silc_ske_st_responder_error);
return SILC_FSM_CONTINUE;
}
ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
+ if (!ske->ke2_payload->sign_data) {
+ /** Error computing hash */
+ ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
+ silc_fsm_next(fsm, silc_ske_st_responder_error);
+ return SILC_FSM_CONTINUE;
+ }
ske->ke2_payload->sign_len = sign_len;
memset(sign, 0, sizeof(sign));
}
ske->status, silc_ske_map_status(ske->status)));
/* Send FAILURE packet */
- if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
+ if (ske->status == SILC_SKE_STATUS_OUT_OF_MEMORY)
+ ske->status = SILC_SKE_STATUS_ERROR;
+ else if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
SILC_PUT32_MSB(ske->status, tmp);
silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
ske->version = params->version;
if (!ske->version)
return NULL;
- ++ ske->refcnt;
+ ++ske->refcnt;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
if (ske->rekey->pfs) {
/* PFS */
pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
- if (pfsbuf) {
- ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
- block_len, key_len,
- hash_len, hash);
- memset(pfsbuf, 0, x_len);
- silc_free(pfsbuf);
+ if (!pfsbuf) {
+ SILC_LOG_ERROR(("Error processing key material"));
+ silc_fsm_next(fsm, silc_ske_st_initiator_error);
+ return SILC_FSM_CONTINUE;
}
+ ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
+ block_len, key_len,
+ hash_len, hash);
+ memset(pfsbuf, 0, x_len);
+ silc_free(pfsbuf);
} else {
/* No PFS */
ske->keymat =
ske->rekey = rekey;
ske->responder = FALSE;
ske->rekeying = TRUE;
- ++ ske->refcnt;
+ ++ske->refcnt;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
if (ske->rekey->pfs) {
/* PFS */
pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
- if (pfsbuf) {
- ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
- block_len, key_len,
- hash_len, hash);
- memset(pfsbuf, 0, x_len);
- silc_free(pfsbuf);
+ if (!pfsbuf) {
+ SILC_LOG_ERROR(("Error processing key material"));
+ silc_fsm_next(fsm, silc_ske_st_responder_error);
+ return SILC_FSM_CONTINUE;
}
+ ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
+ block_len, key_len,
+ hash_len, hash);
+ memset(pfsbuf, 0, x_len);
+ silc_free(pfsbuf);
} else {
/* No PFS */
ske->keymat =
ske->responder = TRUE;
ske->rekeying = TRUE;
ske->packet = packet;
- ++ ske->refcnt;
+ ++ske->refcnt;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
buf->data[0] = 0;
silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
+ if (!key->send_iv) {
+ silc_buffer_clear(buf);
+ silc_buffer_free(buf);
+ silc_free(key);
+ return NULL;
+ }
memcpy(key->send_iv, hashd, req_iv_len);
memset(hashd, 0, sizeof(hashd));
buf->data[0] = 1;
silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
+ if (!key->receive_iv) {
+ silc_buffer_clear(buf);
+ silc_buffer_free(buf);
+ silc_free(key);
+ return NULL;
+ }
memcpy(key->receive_iv, hashd, req_iv_len);
key->iv_len = req_iv_len;
/* Then, save the keys */
dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
+ if (!dtmp) {
+ silc_buffer_clear(buf);
+ silc_buffer_free(buf);
+ silc_free(key);
+ return NULL;
+ }
memcpy(dtmp, k1, hash_len);
memcpy(dtmp + hash_len, k2, hash_len);
memcpy(dtmp + hash_len + hash_len, k3, hash_len);
key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
+ if (!key->send_enc_key) {
+ silc_buffer_clear(buf);
+ silc_buffer_free(buf);
+ silc_free(key);
+ silc_free(dtmp);
+ return NULL;
+ }
memcpy(key->send_enc_key, dtmp, enc_key_len);
key->enc_key_len = req_enc_key_len;
memset(hashd, 0, sizeof(hashd));
silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
+ if (!key->send_enc_key) {
+ silc_buffer_clear(buf);
+ silc_buffer_free(buf);
+ silc_free(key);
+ return NULL;
+ }
memcpy(key->send_enc_key, hashd, enc_key_len);
key->enc_key_len = req_enc_key_len;
}
/* Then, save the keys */
dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
+ if (!dtmp) {
+ silc_buffer_clear(buf);
+ silc_buffer_free(buf);
+ silc_free(key);
+ return NULL;
+ }
memcpy(dtmp, k1, hash_len);
memcpy(dtmp + hash_len, k2, hash_len);
memcpy(dtmp + hash_len + hash_len, k3, hash_len);
key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
+ if (!key->receive_enc_key) {
+ silc_buffer_clear(buf);
+ silc_buffer_free(buf);
+ silc_free(key);
+ silc_free(dtmp);
+ return NULL;
+ }
memcpy(key->receive_enc_key, dtmp, enc_key_len);
key->enc_key_len = req_enc_key_len;
memset(hashd, 0, sizeof(hashd));
silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
+ if (!key->receive_enc_key) {
+ silc_buffer_clear(buf);
+ silc_buffer_free(buf);
+ silc_free(key);
+ return NULL;
+ }
memcpy(key->receive_enc_key, hashd, enc_key_len);
key->enc_key_len = req_enc_key_len;
}
buf->data[0] = 4;
silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
+ if (!key->send_hmac_key) {
+ silc_buffer_clear(buf);
+ silc_buffer_free(buf);
+ silc_free(key);
+ return NULL;
+ }
memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
memset(hashd, 0, sizeof(hashd));
buf->data[0] = 5;
silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
+ if (!key->receive_hmac_key) {
+ silc_buffer_clear(buf);
+ silc_buffer_free(buf);
+ silc_free(key);
+ return NULL;
+ }
memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
key->hmac_key_len = req_hmac_key_len;
memset(hashd, 0, sizeof(hashd));
}
}
+ if (!compbuf)
+ goto err;
+
/* Now parse the complete MIME message and deliver it */
complete = silc_mime_decode(NULL, (const unsigned char *)compbuf->head,
silc_buffer_truelen(compbuf));
if (hostname)
*hostname = NULL;
- *ip = NULL;
+ if (ip)
+ *ip = NULL;
SILC_LOG_DEBUG(("Resolving remote hostname and IP address"));
NI_NUMERICHOST))
return FALSE;
- *ip = silc_memdup(s, strlen(s));
- if (*ip == NULL)
- return FALSE;
+ if (ip) {
+ *ip = silc_memdup(s, strlen(s));
+ if (*ip == NULL)
+ return FALSE;
+ }
#else
struct sockaddr_in remote;
char *host_ip;
if (hostname)
*hostname = NULL;
- *ip = NULL;
+ if (ip)
+ *ip = NULL;
SILC_LOG_DEBUG(("Resolving remote hostname and IP address"));
if (!host_ip)
return FALSE;
- *ip = silc_memdup(host_ip, strlen(host_ip));
- if (*ip == NULL)
- return FALSE;
+ if (ip) {
+ *ip = silc_memdup(host_ip, strlen(host_ip));
+ if (*ip == NULL)
+ return FALSE;
+ }
#endif
/* Do reverse lookup if we want hostname too. */
if (hostname) {
/* Get host by address */
- if (!silc_net_gethostbyaddr(*ip, host, sizeof(host)))
+ if (!ip || !silc_net_gethostbyaddr(*ip, host, sizeof(host)))
return FALSE;
*hostname = silc_memdup(host, strlen(host));
return FALSE;
}
- SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
+ if (ip)
+ SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
return TRUE;
}
if (hostname)
*hostname = NULL;
- *ip = NULL;
+ if (ip)
+ *ip = NULL;
SILC_LOG_DEBUG(("Resolving local hostname and IP address"));
NI_NUMERICHOST))
return FALSE;
- *ip = silc_memdup(s, strlen(s));
- if (*ip == NULL)
- return FALSE;
+ if (ip) {
+ *ip = silc_memdup(s, strlen(s));
+ if (*ip == NULL)
+ return FALSE;
+ }
#else
struct sockaddr_in local;
char *host_ip;
if (hostname)
*hostname = NULL;
- *ip = NULL;
+ if (ip)
+ *ip = NULL;
SILC_LOG_DEBUG(("Resolving local hostname and IP address"));
if (!host_ip)
return FALSE;
- *ip = silc_memdup(host_ip, strlen(host_ip));
- if (*ip == NULL)
- return FALSE;
+ if (ip) {
+ *ip = silc_memdup(host_ip, strlen(host_ip));
+ if (*ip == NULL)
+ return FALSE;
+ }
#endif
/* Do reverse lookup if we want hostname too. */
if (hostname) {
/* Get host by address */
- if (!silc_net_gethostbyaddr(*ip, host, sizeof(host)))
+ if (!ip || !silc_net_gethostbyaddr(*ip, host, sizeof(host)))
return FALSE;
*hostname = silc_memdup(host, strlen(host));
return FALSE;
}
- SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
+ if (ip)
+ SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
return TRUE;
}
fprintf(stdout, "Schedule %p statistics:\n\n", schedule);
fprintf(stdout, "Num FD tasks : %u (%u bytes allocated)\n",
silc_hash_table_count(schedule->fd_queue),
- sizeof(*ftask) * silc_hash_table_count(schedule->fd_queue));
+ (unsigned int)sizeof(*ftask) *
+ silc_hash_table_count(schedule->fd_queue));
fprintf(stdout, "Num Timeout tasks : %d (%d bytes allocated)\n",
silc_list_count(schedule->timeout_queue),
- sizeof(struct SilcTaskTimeoutStruct) *
+ (unsigned int)sizeof(struct SilcTaskTimeoutStruct) *
silc_list_count(schedule->timeout_queue));
fprintf(stdout, "Num Timeout freelist : %d (%d bytes allocated)\n",
silc_list_count(schedule->free_tasks),
- sizeof(struct SilcTaskTimeoutStruct) *
+ (unsigned int)sizeof(struct SilcTaskTimeoutStruct) *
silc_list_count(schedule->free_tasks));
}
#endif /* SILC_DIST_INPLACE */
SILC_SCHEDULE_UNLOCK(schedule);
- return TRUE;
+ return ret;
}
/* Sets a file descriptor to be listened by scheduler. One can call this