From: Pekka Riikonen Date: Tue, 6 May 2014 09:24:10 +0000 (+0300) Subject: silc-client: handle prompt abort better X-Git-Tag: silc.client.1.1.19 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=refs%2Ftags%2Fsilc.client.1.1.19 silc-client: handle prompt abort better 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. --- diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index 25db9eae..b3b6cdbc 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -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, diff --git a/apps/irssi/src/silc/core/clientutil.c b/apps/irssi/src/silc/core/clientutil.c index a8a1b5b7..0daceeff 100644 --- a/apps/irssi/src/silc/core/clientutil.c +++ b/apps/irssi/src/silc/core/clientutil.c @@ -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, diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index 4abccb49..8116a9ff 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -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) {