silc-client: handle prompt abort better silc.client.1.1.19 silc.client.1.1.9 silc.toolkit.1.1.11
authorPekka Riikonen <priikone@silcnet.org>
Tue, 6 May 2014 09:24:10 +0000 (12:24 +0300)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 6 May 2014 09:24:10 +0000 (12:24 +0300)
When verfying public key abort any previously ungoing prompt so that we
can get the public key verification prompt up.  It's important to not
loose the public key verification prompts so we now allow new prompt to
come up after previous one has aborted.  It leaks Irssi memory, but
handles things correctly towards silcclient library.  Irssi's prompt
handling is broken because it stores the data in a global variable
allowing only one prompt at a time.

apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/clientutil.c
lib/silcclient/client_prvmsg.c

index 25db9eae17f7fcce96171ca588cd9594e9a15ac7..b3b6cdbc59b2112d4eab5898dae76dd594cd28d0 100644 (file)
@@ -2487,8 +2487,8 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
                  "server" : "client");
   int i;
 
+  server = (SILC_SERVER_REC*)conn->context;
   if (conn_type != SILC_CONN_CLIENT) {
-    server = (SILC_SERVER_REC*)conn->context;
     SILC_VERIFY(server);
     if (!server) {
       if (completion)
@@ -2497,6 +2497,12 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
     }
   }
 
+  /* If we have pending public key prompt already up */
+  if (server && server->prompt_op) {
+    silc_async_abort(server->prompt_op, NULL, NULL);
+    server->prompt_op = NULL;
+  }
+
   if (silc_pkcs_get_type(public_key) != SILC_PKCS_SILC) {
     printformat_module("fe-common/silc", NULL, NULL,
                       MSGLEVEL_CRAP, SILCTXT_PUBKEY_UNSUPPORTED,
index a8a1b5b7328e318b547ac8f36e3a2b9d86049c51..0daceefff530e2952e227223e0271abc90067985 100644 (file)
@@ -411,6 +411,14 @@ static void silc_keyboard_entry_redirect_abort(SilcAsyncOperation op,
    * the operation has been aborted.
    */
   ctx->user_prompt_proc(NULL, ctx->user_context, KeyboardCompletionAborted);
+
+  /*
+   * Allow new prompt after we've abored despite us leaking Irssi prompt
+   * data.  It's more important to get new prompt up and this abort
+   * guarantees we handle things correctly towards silcclient library by
+   * calling the callback above.
+   */
+  silc_keyboard_prompt_pending = FALSE;
 }
 
 static void silc_keyboard_entry_redirect_completion(const char *line,
index 4abccb491e615bf2254bce96a41cbbfac73f8d8c..8116a9ff525636c237f4e0908e208aefbd843e2a 100644 (file)
@@ -808,25 +808,22 @@ silc_client_autoneg_key_recv_ske(SilcPacketEngine engine,
 
   /* Responder is started here if correct packet comes in */
   if (!ake->ske_op) {
-    if (packet->type == SILC_PACKET_KEY_EXCHANGE)
-      {
-       /* Ignore pre-set proposal */
-       if (ake->params.prop) {
-         silc_ske_group_free(ake->params.prop->group);
-         silc_cipher_free(ake->params.prop->cipher);
-         silc_hash_free(ake->params.prop->hash);
-         silc_hmac_free(ake->params.prop->hmac);
-         silc_pkcs_public_key_free(ake->params.prop->public_key);
-         silc_free(ake->params.prop);
-         ake->params.prop = NULL;
-       }
-      }
-    else if (packet->type != SILC_PACKET_KEY_EXCHANGE_1)
-      {
-       SILC_LOG_DEBUG(("Invalid SKE packet for responder"));
-       silc_async_abort(client_entry->internal.op, NULL, NULL);
-       goto drop;
+    if (packet->type == SILC_PACKET_KEY_EXCHANGE) {
+      /* Ignore pre-set proposal */
+      if (ake->params.prop) {
+       silc_ske_group_free(ake->params.prop->group);
+       silc_cipher_free(ake->params.prop->cipher);
+       silc_hash_free(ake->params.prop->hash);
+       silc_hmac_free(ake->params.prop->hmac);
+       silc_pkcs_public_key_free(ake->params.prop->public_key);
+       silc_free(ake->params.prop);
+       ake->params.prop = NULL;
       }
+    } else if (packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
+      SILC_LOG_DEBUG(("Invalid SKE packet for responder"));
+      silc_async_abort(client_entry->internal.op, NULL, NULL);
+      goto drop;
+    }
 
     ake->ske_op = silc_ske_responder(ake->ske, ake->ske_stream, &ake->params);
     if (!ake->ske_op) {
@@ -940,7 +937,7 @@ silc_client_autoneg_key_verify_pubkey_cb(SilcBool success, void *context)
   SilcVerifyKeyContext verify = context;
   SilcClientAutonegMessageKey ake = verify->context;
 
-  SILC_LOG_DEBUG(("Start"));
+  SILC_LOG_DEBUG(("Start, verify %p, ake %p", context, ake));
 
   /* Call the completion callback back to the SKE */
   if (!verify->aborted) {