Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2007 Pekka Riikonen
+ Copyright (C) 2001 - 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
#include "silc-queries.h"
#include "silc-nicklist.h"
#include "silc-cmdqueue.h"
+#include "clientutil.h"
#include "signals.h"
#include "levels.h"
SilcClientMessageType type, char *msg, ...)
{
SILC_SERVER_REC *server;
+ char *target = NULL;
va_list va;
char *str;
server = conn == NULL ? NULL : conn->context;
+ switch (conn->context_type) {
+ case SILC_ID_CLIENT:
+ target = (conn->client_entry->nickname[0] ?
+ conn->client_entry->nickname : NULL);
+ break;
+
+ case SILC_ID_CHANNEL:
+ target = conn->channel_entry->channel_name;
+ break;
+ }
+
va_start(va, msg);
str = g_strdup_vprintf(msg, va);
- printtext(server, NULL, MSGLEVEL_CRAP, "%s", str);
+ printtext(server, target, MSGLEVEL_CRAP, "%s", str);
g_free(str);
va_end(va);
}
sizeof(sender->fingerprint));
if (strcmp(fingerprint, fingerprint2)) {
/* since the public key differs from the senders public key, the
- verification _failed_ */
+ verification won't be done */
silc_pkcs_public_key_free(pk);
silc_free(fingerprint);
- ret = SILC_MSG_SIGNED_UNKNOWN;
+ silc_free(fingerprint2);
+ return SILC_MSG_SIGNED_UNKNOWN;
}
silc_free(fingerprint2);
}
tmp = cp;
}
- chanrec->topic = *tmp == '\0' ? NULL : g_strdup(tmp);
+ chanrec->topic = (tmp && *tmp == '\0' ? NULL : g_strdup(tmp));
signal_emit("channel topic changed", 1, chanrec);
silc_free(dm);
SilcIdType id_type;
} *GetkeyContext;
-void silc_getkey_cb(bool success, void *context)
+void silc_getkey_cb(SilcBool success, void *context)
{
GetkeyContext getkey = (GetkeyContext)context;
char *entity = (getkey->id_type == SILC_ID_CLIENT ? "user" : "server");
}
/*
- * XXX: What if the connection or client went away? They're not even
- * refcounted and we don't have a way to cancel the input callback. Bad!
- */
- switch (getkey->id_type)
- {
- case SILC_ID_CLIENT:
- silc_client_unref_client(getkey->client, getkey->conn, (SilcClientEntry)getkey->entry);
- break;
+ * Drop our references as need be.
+ */
+ switch (getkey->id_type) {
+ case SILC_ID_CLIENT:
+ silc_client_unref_client(getkey->client, getkey->conn,
+ (SilcClientEntry)getkey->entry);
+ break;
- case SILC_ID_SERVER:
- silc_client_unref_server(getkey->client, getkey->conn, (SilcServerEntry)getkey->entry);
- break;
+ case SILC_ID_SERVER:
+ silc_client_unref_server(getkey->client, getkey->conn,
+ (SilcServerEntry)getkey->entry);
+ break;
}
silc_free(getkey);
if (idle && nickname) {
memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf) - 1, "%lu %s",
+ snprintf(buf, sizeof(buf) - 1, "%u %s",
idle > 60 ? (idle / 60) : idle,
idle > 60 ? "minutes" : "seconds");
((SilcClientEntry)entry)->nickname :
((SilcServerEntry)entry)->server_name);
- switch (id_type)
- {
- case SILC_ID_CLIENT:
- name = ((SilcClientEntry)entry)->nickname;
- silc_client_ref_client(client, conn, (SilcClientEntry)entry);
- break;
-
- case SILC_ID_SERVER:
- name = ((SilcServerEntry)entry)->server_name;
- silc_client_ref_server(client, conn, (SilcServerEntry)entry);
- break;
+ switch (id_type) {
+ case SILC_ID_CLIENT:
+ name = ((SilcClientEntry)entry)->nickname;
+ silc_client_ref_client(client, conn, (SilcClientEntry)entry);
+ break;
+
+ case SILC_ID_SERVER:
+ name = ((SilcServerEntry)entry)->server_name;
+ silc_client_ref_server(client, conn, (SilcServerEntry)entry);
+ break;
}
silc_verify_public_key_internal(client, conn, name,
void *context;
} *PublicKeyVerify;
-static void verify_public_key_completion(const char *line, void *context)
+static void verify_public_key_completion(const char *line, void *context,
+ SilcKeyboardPromptStatus reason)
{
PublicKeyVerify verify = (PublicKeyVerify)context;
+ SilcBool success = (reason == KeyboardCompletionSuccess);
- if (line[0] == 'Y' || line[0] == 'y') {
- /* Call the completion */
- if (verify->completion)
- verify->completion(TRUE, verify->context);
-
+ if (success && (line[0] == 'Y' || line[0] == 'y')) {
/* Save the key for future checking */
silc_pkcs_save_public_key(verify->filename, verify->public_key,
SILC_PKCS_FILE_BASE64);
+
+ /* Call the completion */
+ if (verify->completion)
+ verify->completion(TRUE, verify->context);
} else {
/* Call the completion */
if (verify->completion)
verify->entity);
}
+ /*
+ * If we were not called due to a failure to begin the callback, then we
+ * shall zero the async context block in the server record. If we were
+ * called due to a failure to begin the callback, then it is possible that
+ * we failed due to an overlapping callback, in which case we shouldn't
+ * overwrite the async context block pointer.
+ */
+ if (reason != KeyboardCompletionFailed) {
+ /*
+ * Null out the completion context in the server record as this operation
+ * is done as far as we are concerned. The underlying keyboard library
+ * routine will take care of freeing the async context memory when the
+ * actual callback is called by irssi in the abort case. In the success
+ * case, it will free the async context memory after we return from this
+ * routine.
+ */
+ SILC_SERVER_REC *server = (SILC_SERVER_REC*)(verify->conn->context);
+ server->prompt_op = NULL;
+ }
+
silc_free(verify->filename);
silc_free(verify->entity);
silc_free(verify->entity_name);
SilcPublicKey local_pubkey;
SilcSILCPublicKey silc_pubkey;
SilcUInt16 port;
+ SILC_SERVER_REC *server = NULL;
const char *hostname, *ip;
unsigned char *pk;
SilcUInt32 pk_len;
"server" : "client");
int i;
+ server = (SILC_SERVER_REC*)conn->context;
+ if (conn_type != SILC_CONN_CLIENT) {
+ SILC_VERIFY(server);
+ if (!server) {
+ if (completion)
+ completion(FALSE, context);
+ return;
+ }
+ }
+
+ /* 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,
silc_pubkey->identifier.realname,
silc_pubkey->identifier.email ?
silc_pubkey->identifier.email : "");
+ else if (conn_type == SILC_CONN_CLIENT &&
+ (silc_pubkey->identifier.realname ||
+ silc_pubkey->identifier.email))
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_RECEIVED_CLIENT, "",
+ silc_pubkey->identifier.realname,
+ silc_pubkey->identifier.email ?
+ silc_pubkey->identifier.email : "");
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_BABBLEPRINT, babbleprint);
format = format_get_text("fe-common/silc", NULL, NULL, NULL,
SILCTXT_PUBKEY_ACCEPT);
- keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
- format, 0, verify);
+ silc_keyboard_entry_redirect(verify_public_key_completion,
+ format, 0, verify,
+ server ? &server->prompt_op : NULL);
g_free(format);
silc_free(fingerprint);
silc_free(babbleprint);
silc_pubkey->identifier.realname,
silc_pubkey->identifier.email ?
silc_pubkey->identifier.email : "");
+ else if (conn_type == SILC_CONN_CLIENT &&
+ (silc_pubkey->identifier.realname ||
+ silc_pubkey->identifier.email))
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_RECEIVED_CLIENT, "",
+ silc_pubkey->identifier.realname,
+ silc_pubkey->identifier.email ?
+ silc_pubkey->identifier.email : "");
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_COULD_NOT_LOAD, entity);
format = format_get_text("fe-common/silc", NULL, NULL, NULL,
SILCTXT_PUBKEY_ACCEPT_ANYWAY);
- keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
- format, 0, verify);
+ silc_keyboard_entry_redirect(verify_public_key_completion,
+ format, 0, verify,
+ server ? &server->prompt_op : NULL);
+
g_free(format);
silc_free(fingerprint);
silc_free(babbleprint);
silc_pubkey->identifier.realname,
silc_pubkey->identifier.email ?
silc_pubkey->identifier.email : "");
+ else if (conn_type == SILC_CONN_CLIENT &&
+ (silc_pubkey->identifier.realname ||
+ silc_pubkey->identifier.email))
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_RECEIVED_CLIENT, "",
+ silc_pubkey->identifier.realname,
+ silc_pubkey->identifier.email ?
+ silc_pubkey->identifier.email : "");
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_MALFORMED, entity);
format = format_get_text("fe-common/silc", NULL, NULL, NULL,
SILCTXT_PUBKEY_ACCEPT_ANYWAY);
- keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
- format, 0, verify);
+ silc_keyboard_entry_redirect(verify_public_key_completion,
+ format, 0, verify,
+ server ? &server->prompt_op : NULL);
g_free(format);
silc_free(fingerprint);
silc_free(babbleprint);
silc_pubkey->identifier.realname,
silc_pubkey->identifier.email ?
silc_pubkey->identifier.email : "");
+ else if (conn_type == SILC_CONN_CLIENT &&
+ (silc_pubkey->identifier.realname ||
+ silc_pubkey->identifier.email))
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_RECEIVED_CLIENT, "",
+ silc_pubkey->identifier.realname,
+ silc_pubkey->identifier.email ?
+ silc_pubkey->identifier.email : "");
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
/* Ask user to verify the key and save it */
format = format_get_text("fe-common/silc", NULL, NULL, NULL,
SILCTXT_PUBKEY_ACCEPT_ANYWAY);
- keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
- format, 0, verify);
+ silc_keyboard_entry_redirect(verify_public_key_completion,
+ format, 0, verify,
+ server ? &server->prompt_op : NULL);
g_free(format);
silc_free(fingerprint);
silc_free(babbleprint);
typedef struct {
SilcAskPassphrase completion;
+ SilcClientConnection conn;
void *context;
} *AskPassphrase;
-void ask_passphrase_completion(const char *passphrase, void *context)
+void ask_passphrase_completion(const char *passphrase, void *context,
+ SilcKeyboardPromptStatus reason)
{
AskPassphrase p = (AskPassphrase)context;
if (passphrase && passphrase[0] == '\0')
passphrase = NULL;
p->completion((unsigned char *)passphrase,
passphrase ? strlen(passphrase) : 0, p->context);
+
+ if (reason != KeyboardCompletionFailed) {
+ SILC_SERVER_REC *server = (SILC_SERVER_REC *)(p->conn->context);
+ server->prompt_op = NULL;
+ }
+
silc_free(p);
}
void silc_ask_passphrase(SilcClient client, SilcClientConnection conn,
SilcAskPassphrase completion, void *context)
{
- AskPassphrase p = silc_calloc(1, sizeof(*p));
+ SILC_SERVER_REC *server = (SILC_SERVER_REC*)(conn->context);
+ AskPassphrase p;
+
+ p = silc_calloc(1, sizeof(*p));
+ if (!p) {
+ if (completion)
+ completion(NULL, 0, context);
+ return;
+ }
+
p->completion = completion;
- p->context = context;
+ p->conn = conn;
+ p->context = context;
- keyboard_entry_redirect((SIGNAL_FUNC)ask_passphrase_completion,
- "Passphrase: ", ENTRY_REDIRECT_FLAG_HIDDEN, p);
+ silc_keyboard_entry_redirect(ask_passphrase_completion,
+ "Passphrase: ", ENTRY_REDIRECT_FLAG_HIDDEN,
+ p, &server->prompt_op);
}
typedef struct {