X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Firssi%2Fsrc%2Fsilc%2Fcore%2Fclient_ops.c;h=79be2e8c7b4eef61cc9c1e9d7bbbcd1e63e4c332;hb=017dec75a98209fbef49eb496c2269b0c49e736d;hp=b873e2cb9ed15ba194820b057a7866d042be3c02;hpb=6617b351fc8655b8772cae80117faf5b35cc0378;p=silc.git diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index b873e2cb..79be2e8c 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -188,6 +188,11 @@ void silc_connect(SilcClient client, SilcClientConnection conn, int success) { SILC_SERVER_REC *server = conn->context; + if (!server && !success) { + silc_client_close_connection(client, NULL, conn); + return; + } + if (success) { server->connected = TRUE; signal_emit("event connected", 1, server); @@ -328,9 +333,10 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, switch(command) { case SILC_COMMAND_WHOIS: { - char buf[1024], *nickname, *username, *realname; + char buf[1024], *nickname, *username, *realname, *nick; uint32 idle, mode; SilcBuffer channels; + SilcClientEntry client_entry; if (status == SILC_STATUS_ERR_NO_SUCH_NICK || status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { @@ -348,7 +354,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, if (!success) return; - (void)va_arg(vp, SilcClientEntry); + client_entry = va_arg(vp, SilcClientEntry); nickname = va_arg(vp, char *); username = va_arg(vp, char *); realname = va_arg(vp, char *); @@ -356,9 +362,14 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, mode = va_arg(vp, uint32); idle = va_arg(vp, uint32); + silc_parse_userfqdn(nickname, &nick, NULL); printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP, - SILCTXT_WHOIS_USERINFO, nickname, username, - realname); + SILCTXT_WHOIS_USERINFO, nickname, + client_entry->username, client_entry->hostname, + nick, client_entry->nickname); + printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP, + SILCTXT_WHOIS_REALNAME, realname); + silc_free(nick); if (channels) { SilcDList list = silc_channel_payload_parse_list(channels); @@ -673,14 +684,21 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, id_type = va_arg(vp, uint32); entry = va_arg(vp, void *); public_key = va_arg(vp, SilcPublicKey); - - pk = silc_pkcs_public_key_encode(public_key, &pk_len); - - if (id_type == SILC_ID_CLIENT) - silc_verify_public_key_internal(client, conn, SILC_SOCKET_TYPE_CLIENT, + + if (public_key) { + pk = silc_pkcs_public_key_encode(public_key, &pk_len); + + silc_verify_public_key_internal(client, conn, + (id_type == SILC_ID_CLIENT ? + SILC_SOCKET_TYPE_CLIENT : + SILC_SOCKET_TYPE_SERVER), pk, pk_len, SILC_SKE_PK_TYPE_SILC, NULL, NULL); - silc_free(pk); + silc_free(pk); + } else { + printformat_module("fe-common/silc", server, NULL, + MSGLEVEL_CRAP, SILCTXT_GETKEY_NOKEY); + } } break; @@ -949,7 +967,7 @@ void ask_passphrase_completion(const char *passphrase, void *context) } void silc_ask_passphrase(SilcClient client, SilcClientConnection conn, - SilcAskPassphrase completion, void *context) + SilcAskPassphrase completion, void *context) { AskPassphrase p = silc_calloc(1, sizeof(*p)); p->completion = completion; @@ -959,34 +977,69 @@ void silc_ask_passphrase(SilcClient client, SilcClientConnection conn, "Passphrase: ", ENTRY_REDIRECT_FLAG_HIDDEN, p); } +typedef struct { + SilcGetAuthMeth completion; + void *context; +} *InternalGetAuthMethod; + +/* Callback called when we've received the authentication method information + from the server after we've requested it. This will get the authentication + data from the user if needed. */ + +static void silc_get_auth_method_callback(SilcClient client, + SilcClientConnection conn, + SilcAuthMethod auth_meth, + void *context) +{ + InternalGetAuthMethod internal = (InternalGetAuthMethod)context; + + switch (auth_meth) { + case SILC_AUTH_NONE: + /* No authentication required. */ + (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context); + break; + case SILC_AUTH_PASSWORD: + /* Do not ask the passphrase from user, the library will ask it if + we do not provide it here. */ + (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context); + break; + case SILC_AUTH_PUBLIC_KEY: + /* Do not get the authentication data now, the library will generate + it using our default key, if we do not provide it here. */ + /* XXX In the future when we support multiple local keys and multiple + local certificates we will need to ask from user which one to use. */ + (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context); + break; + } + + silc_free(internal); +} + /* Find authentication method and authentication data by hostname and port. The hostname may be IP address as well. The found authentication method and authentication data is returned to `auth_meth', `auth_data' and `auth_data_len'. The function returns TRUE if authentication method is found and FALSE if not. `conn' may be NULL. */ -int silc_get_auth_method(SilcClient client, SilcClientConnection conn, - char *hostname, uint16 port, - SilcProtocolAuthMeth *auth_meth, - unsigned char **auth_data, - uint32 *auth_data_len) +void silc_get_auth_method(SilcClient client, SilcClientConnection conn, + char *hostname, uint16 port, + SilcGetAuthMeth completion, void *context) { - bool ret = TRUE; - SILC_SERVER_REC *server = conn ? conn->context : NULL; + InternalGetAuthMethod internal; /* XXX must resolve from configuration whether this connection has any specific authentication data */ - *auth_meth = SILC_AUTH_NONE; - *auth_data = NULL; - *auth_data_len = 0; + /* If we do not have this connection configured by the user in a + configuration file then resolve the authentication method from the + server for this session. */ + internal = silc_calloc(1, sizeof(*internal)); + internal->completion = completion; + internal->context = context; - if (ret == FALSE) { - printformat_module("fe-common/silc", server, NULL, - MSGLEVEL_MODES, SILCTXT_AUTH_METH_UNRESOLVED); - } - - return ret; + silc_client_request_authentication_method(client, conn, + silc_get_auth_method_callback, + internal); } /* Notifies application that failure packet was received. This is called @@ -1026,6 +1079,9 @@ void silc_failure(SilcClient client, SilcClientConnection conn, if (status == SILC_SKE_STATUS_INCORRECT_SIGNATURE) printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, SILCTXT_KE_INCORRECT_SIGNATURE); + if (status == SILC_SKE_STATUS_INVALID_COOKIE) + printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, + SILCTXT_KE_INVALID_COOKIE); } if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {