{
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);
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) {
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 *);
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);
client_id_list = va_arg(vp, SilcBuffer);
chanrec = silc_channel_find(server, channel);
- if (chanrec != NULL && !success)
- channel_destroy(CHANNEL(chanrec));
- else if (chanrec == NULL && success)
+ if (!chanrec)
chanrec = silc_channel_create(server, channel, TRUE);
-
+
if (topic) {
g_free_not_null(chanrec->topic);
chanrec->topic = *topic == '\0' ? NULL : g_strdup(topic);
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;
}
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;
"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
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) {