silcclient: Fix error path memory freeing
[silc.git] / lib / silcclient / client.c
index 3ab7ba17b4aa96fc872496dce38c17ae078227d7..1d64e02fd502848d099880b396bec665e42160b7 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2007 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
@@ -391,6 +391,9 @@ SILC_FSM_STATE(silc_client_connection_st_close)
 {
   SilcClientConnection conn = fsm_context;
   SilcClientCommandContext cmd;
+  SilcList list;
+  SilcIDCacheEntry entry;
+  SilcClientEntry client_entry;
 
   /* Finish running command threads.  This will also finish waiting packet
      thread, as they are always waiting for some command.  If any thread is
@@ -416,6 +419,20 @@ SILC_FSM_STATE(silc_client_connection_st_close)
     conn->internal->op = NULL;
   }
 
+  /* Abort ongoing client entry operations */
+  if (conn->internal->client_cache) {
+    if (silc_idcache_get_all(conn->internal->client_cache, &list)) {
+      silc_list_start(list);
+      while ((entry = silc_list_get(list))) {
+       client_entry = entry->context;
+       if (client_entry->internal.op) {
+         silc_async_abort(client_entry->internal.op, NULL, NULL);
+         client_entry->internal.op = NULL;
+       }
+      }
+    }
+  }
+
   /* If event thread is running, finish it. */
   if (silc_fsm_is_started(&conn->internal->event_thread)) {
     SILC_LOG_DEBUG(("Finish event thread"));
@@ -452,7 +469,7 @@ SILC_FSM_STATE(silc_client_error)
   msg = silc_memdup(silc_buffer_data(&packet->buffer),
                    silc_buffer_len(&packet->buffer));
   if (msg)
-    client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, msg);
+    client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, msg);
 
   silc_free(msg);
   silc_packet_free(packet);
@@ -587,7 +604,7 @@ silc_client_add_connection(SilcClient client,
   SilcClientConnection conn;
   SilcFSMThread thread;
 
-  if (!callback)
+  if (!client || !callback || !remote_host)
     return NULL;
 
   SILC_LOG_DEBUG(("Adding new connection to %s:%d", remote_host, port));
@@ -607,6 +624,7 @@ silc_client_add_connection(SilcClient client,
 
   conn->internal = silc_calloc(1, sizeof(*conn->internal));
   if (!conn->internal) {
+    silc_free(conn->remote_host);
     silc_free(conn);
     return NULL;
   }
@@ -615,14 +633,17 @@ silc_client_add_connection(SilcClient client,
   silc_atomic_init16(&conn->internal->cmd_ident, 0);
 
   if (!silc_hash_alloc("sha1", &conn->internal->sha1hash)) {
-    silc_free(conn);
+    silc_free(conn->remote_host);
     silc_free(conn->internal);
+    silc_free(conn);
     return NULL;
   }
 
   /* Set parameters */
-  if (params)
+  if (params) {
     conn->internal->params = *params;
+    conn->context = params->context;
+  }
   if (!conn->internal->params.rekey_secs)
     conn->internal->params.rekey_secs = 3600;
 #ifndef SILC_DIST_INPLACE
@@ -769,7 +790,7 @@ silc_client_connect_to_server(SilcClient client,
 
   SILC_LOG_DEBUG(("Connecting to server"));
 
-  if (!client || !remote_host)
+  if (!client || !remote_host || !callback)
     return NULL;
 
   if (client->internal->run_callback) {
@@ -812,7 +833,7 @@ silc_client_connect_to_client(SilcClient client,
 
   SILC_LOG_DEBUG(("Connecting to client"));
 
-  if (!client || !remote_host)
+  if (!client || !remote_host || !callback)
     return NULL;
 
   if (client->internal->run_callback) {
@@ -857,7 +878,7 @@ silc_client_key_exchange(SilcClient client,
 
   SILC_LOG_DEBUG(("Performing key exchange"));
 
-  if (!client || !stream)
+  if (!client || !stream || !callback)
     return NULL;
 
   if (client->internal->run_callback) {
@@ -1001,18 +1022,18 @@ SilcBool silc_client_init(SilcClient client, const char *username,
   if (!silc_identifier_verify(username, strlen(username),
                              SILC_STRING_UTF8, 128)) {
     SILC_LOG_ERROR(("Malformed username '%s'. Username must be UTF-8 string",
-                   client->username));
+                   username));
     return FALSE;
   }
   if (!silc_identifier_verify(hostname, strlen(hostname),
                              SILC_STRING_UTF8, 256)) {
     SILC_LOG_ERROR(("Malformed hostname '%s'. Hostname must be UTF-8 string",
-                   client->hostname));
+                   hostname));
     return FALSE;
   }
   if (!silc_utf8_valid(realname, strlen(realname))) {
     SILC_LOG_ERROR(("Malformed realname '%s'. Realname must be UTF-8 string",
-                   client->realname));
+                   realname));
     return FALSE;
   }