From 6ce316e741339532a2d150b7a5e24f4e1686c9ff Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 11 Dec 2006 15:43:45 +0000 Subject: [PATCH] Added settings sign_channel_messages, sign_private_messages and key_exchange_rekey_pfs. And more Toolkit API porting. --- .../irssi/src/fe-common/silc/module-formats.c | 2 +- apps/irssi/src/silc/core/client_ops.c | 51 +++++++----- apps/irssi/src/silc/core/clientutil.c | 3 + apps/irssi/src/silc/core/silc-channels.c | 20 +++-- apps/irssi/src/silc/core/silc-core.c | 82 ++++++++++++++----- apps/irssi/src/silc/core/silc-core.h | 1 + apps/irssi/src/silc/core/silc-servers.c | 27 ++++-- 7 files changed, 127 insertions(+), 59 deletions(-) diff --git a/apps/irssi/src/fe-common/silc/module-formats.c b/apps/irssi/src/fe-common/silc/module-formats.c index 77c02762..ce7c5012 100644 --- a/apps/irssi/src/fe-common/silc/module-formats.c +++ b/apps/irssi/src/fe-common/silc/module-formats.c @@ -136,7 +136,7 @@ FORMAT_REC fecommon_silc_formats[] = { { "key_agreement_request", "{nick $0} wants to perform key agreement", 1, { 0 } }, { "key_agreement_request_host", "{nick $0} wants to perform key agreement on {nickhost $1} port {hilight $2} ($3)", 4, { 0, 0, 0, 0 } }, { "key_agreement_negotiate", "Starting key agreement with {nick $0}", 1, { 0 } }, - { "key_agreement_privmsg", "Pprivate messages with {nick $0} are now protected with private key", 1, { 0 } }, + { "key_agreement_privmsg", "Private messages with {nick $0} are now protected with private key", 1, { 0 } }, { "key_agreement_ok", "Key agreement completed successfully with {nick $0}", 1, { 0 } }, { "key_agreement_error", "Error occurred during key agreement with {nick $0}", 1, { 0 } }, { "key_agreement_failure", "Key agreement failed with {nick $0}", 1, { 0 } }, diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index fa4002aa..776fe69d 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -256,7 +256,7 @@ int verify_message_signature(SilcClientEntry sender, if (pk != NULL) { fingerprint = silc_hash_fingerprint(NULL, pk_data, pk_datalen); - if (sender->fingerprint) { + if (sender->fingerprint[0]) { fingerprint2 = silc_fingerprint(sender->fingerprint, sizeof(sender->fingerprint)); if (strcmp(fingerprint, fingerprint2)) { @@ -268,7 +268,7 @@ int verify_message_signature(SilcClientEntry sender, } silc_free(fingerprint2); } - } else if (sender->fingerprint) + } else if (sender->fingerprint[0]) fingerprint = silc_fingerprint(sender->fingerprint, sizeof(sender->fingerprint)); else @@ -310,7 +310,7 @@ int verify_message_signature(SilcClientEntry sender, /* the public key is now in pk, our "level of trust" in ret */ if ((pk) && silc_message_signed_verify(message, pk, - sha1hash)!= SILC_AUTH_OK) + sha1hash) != SILC_AUTH_OK) ret = SILC_MSG_SIGNED_FAILED; if (pk) @@ -1151,35 +1151,34 @@ void silc_notify(SilcClient client, SilcClientConnection conn, * Server has quit the network. */ int i; - SilcClientEntry *clients; - SilcUInt32 clients_count; + SilcDList clients; - SILC_LOG_DEBUG(("Notify: SIGNOFF")); + SILC_LOG_DEBUG(("Notify: SERVER_SIGNOFF")); (void)va_arg(va, void *); - clients = va_arg(va, SilcClientEntry *); - clients_count = va_arg(va, SilcUInt32); + clients = va_arg(va, SilcDList); - for (i = 0; i < clients_count; i++) { + silc_dlist_start(clients); + while ((client_entry = silc_dlist_get(clients))) { memset(buf, 0, sizeof(buf)); /* Print only if we have the nickname. If this client has just quit when we were only resolving it, it is possible we don't have the nickname. */ - if (clients[i]->nickname) { - if (clients[i]->username) + if (client_entry->nickname[0]) { + if (client_entry->username[0]) snprintf(buf, sizeof(buf) - 1, "%s@%s", - clients[i]->username, clients[i]->hostname); - signal_emit("message quit", 4, server, clients[i]->nickname, - clients[i]->username ? buf : "", + client_entry->username, client_entry->hostname); + signal_emit("message quit", 4, server, client_entry->nickname, + client_entry->username[0] ? buf : "", "server signoff"); } #if 0 - silc_server_free_ftp(server, clients[i]); + silc_server_free_ftp(server, client_entry); #endif - list1 = nicklist_get_same_unique(SERVER(server), clients[i]); + list1 = nicklist_get_same_unique(SERVER(server), client_entry); for (list_tmp = list1; list_tmp != NULL; list_tmp = list_tmp->next->next) { CHANNEL_REC *channel = list_tmp->data; @@ -1638,8 +1637,10 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn, SilcClientEntry founder = NULL; NICK_REC *ownnick; - if (SILC_STATUS_IS_ERROR(status)) + if (SILC_STATUS_IS_ERROR(status)) { + silc_say_error("JOIN: %s", silc_get_status_message(status)); return; + } channel = va_arg(vp, char *); channel_entry = va_arg(vp, SilcChannelEntry); @@ -1691,6 +1692,8 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn, } ownnick = NICK(silc_nicklist_find(chanrec, conn->local_entry)); + if (!ownnick) + break; nicklist_set_own(CHANNEL(chanrec), ownnick); signal_emit("channel joined", 1, chanrec); chanrec->entry = channel_entry; @@ -1724,8 +1727,10 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry = va_arg(vp, SilcClientEntry); GSList *nicks; - if (SILC_STATUS_IS_ERROR(status)) + if (SILC_STATUS_IS_ERROR(status)) { + silc_say_error("NICK: %s", silc_get_status_message(status)); return; + } nicks = nicklist_get_same(SERVER(server), client_entry->nickname); if ((nicks != NULL) && @@ -1878,8 +1883,10 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn, SilcChannelEntry channel; SilcChannelUser chu; - if (SILC_STATUS_IS_ERROR(status)) + if (SILC_STATUS_IS_ERROR(status)) { + silc_say_error("USERS: %s", silc_get_status_message(status)); return; + } channel = va_arg(vp, SilcChannelEntry); @@ -1954,8 +1961,10 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn, GetkeyContext getkey; char *name; - if (SILC_STATUS_IS_ERROR(status)) + if (SILC_STATUS_IS_ERROR(status)) { + silc_say_error("GETKEY: %s", silc_get_status_message(status)); return; + } id_type = va_arg(vp, SilcUInt32); entry = va_arg(vp, void *); @@ -2592,7 +2601,7 @@ void silc_key_agreement(SilcClient client, SilcClientConnection conn, if (hostname) { snprintf(portstr, sizeof(portstr) - 1, "%d", port); - snprintf(protostr, sizeof(protostr) - 1, "%s", protocol == 1 ? "UDP" : + snprintf(protostr, sizeof(protostr) - 1, "%s", protocol == 1 ? "UDP" : "TCP"); } diff --git a/apps/irssi/src/silc/core/clientutil.c b/apps/irssi/src/silc/core/clientutil.c index 4ebf2e9d..c3bcd328 100644 --- a/apps/irssi/src/silc/core/clientutil.c +++ b/apps/irssi/src/silc/core/clientutil.c @@ -318,5 +318,8 @@ int silc_client_load_keys(SilcClient client) if (!ret) ret = silc_load_key_pair(pub, prv, NULL, &irssi_pubkey, &irssi_privkey); + if (!ret) + SILC_LOG_ERROR(("Could not load key pair")); + return ret; } diff --git a/apps/irssi/src/silc/core/silc-channels.c b/apps/irssi/src/silc/core/silc-channels.c index a0e1dcd6..502bb61b 100644 --- a/apps/irssi/src/silc/core/silc-channels.c +++ b/apps/irssi/src/silc/core/silc-channels.c @@ -214,6 +214,7 @@ static void command_action(const char *data, SILC_SERVER_REC *server, char *message = NULL; int target_type; void *free_arg; + SilcBool sign = FALSE; CMD_SILC_SERVER(server); if (!IS_SILC_SERVER(server) || !server->connected) @@ -254,12 +255,14 @@ static void command_action(const char *data, SILC_SERVER_REC *server, message, len); } + sign = (g_hash_table_lookup(optlist, "sign") ? TRUE : + settings_get_bool("sign_channel_messages") ? TRUE : FALSE); + if (target != NULL) { if (target_type == SEND_TARGET_CHANNEL) { if (silc_send_channel(server, target, (message != NULL ? message : msg), SILC_MESSAGE_FLAG_ACTION | SILC_MESSAGE_FLAG_UTF8 | - (g_hash_table_lookup(optlist, "sign") != NULL ? - SILC_MESSAGE_FLAG_SIGNED : 0))) { + (sign ? SILC_MESSAGE_FLAG_SIGNED : 0))) { if (g_hash_table_lookup(optlist, "sign")) signal_emit("message silc signed_own_action", 3, server, msg, target); else @@ -269,8 +272,7 @@ static void command_action(const char *data, SILC_SERVER_REC *server, if (silc_send_msg(server, target, (message != NULL ? message : msg), (message != NULL ? strlen(message) : strlen(msg)), SILC_MESSAGE_FLAG_ACTION | SILC_MESSAGE_FLAG_UTF8 | - (g_hash_table_lookup(optlist, "sign") != NULL ? - SILC_MESSAGE_FLAG_SIGNED : 0))) { + (sign ? SILC_MESSAGE_FLAG_SIGNED : 0))) { if (g_hash_table_lookup(optlist, "sign")) signal_emit("message silc signed_own_private_action", 3, server, msg, target); @@ -318,6 +320,7 @@ static void command_notice(const char *data, SILC_SERVER_REC *server, char *message = NULL; int target_type; void *free_arg; + SilcBool sign; CMD_SILC_SERVER(server); if (!IS_SILC_SERVER(server) || !server->connected) @@ -358,12 +361,14 @@ static void command_notice(const char *data, SILC_SERVER_REC *server, message, len); } + sign = (g_hash_table_lookup(optlist, "sign") ? TRUE : + settings_get_bool("sign_channel_messages") ? TRUE : FALSE); + if (target != NULL) { if (target_type == SEND_TARGET_CHANNEL) { if (silc_send_channel(server, target, (message != NULL ? message : msg), SILC_MESSAGE_FLAG_NOTICE | SILC_MESSAGE_FLAG_UTF8 | - (g_hash_table_lookup(optlist, "sign") != NULL ? - SILC_MESSAGE_FLAG_SIGNED : 0))) { + (sign ? SILC_MESSAGE_FLAG_SIGNED : 0))) { if (g_hash_table_lookup(optlist, "sign")) signal_emit("message silc signed_own_notice", 3, server, msg, target); else @@ -373,8 +378,7 @@ static void command_notice(const char *data, SILC_SERVER_REC *server, if (silc_send_msg(server, target, (message != NULL ? message : msg), (message != NULL ? strlen(message) : strlen(msg)), SILC_MESSAGE_FLAG_NOTICE | SILC_MESSAGE_FLAG_UTF8 | - (g_hash_table_lookup(optlist, "sign") != NULL ? - SILC_MESSAGE_FLAG_SIGNED : 0))) { + (sign ? SILC_MESSAGE_FLAG_SIGNED : 0))) { if (g_hash_table_lookup(optlist, "sign")) signal_emit("message silc signed_own_private_notice", 3, server, msg, target); diff --git a/apps/irssi/src/silc/core/silc-core.c b/apps/irssi/src/silc/core/silc-core.c index db56d68c..430748b2 100644 --- a/apps/irssi/src/silc/core/silc-core.c +++ b/apps/irssi/src/silc/core/silc-core.c @@ -51,11 +51,14 @@ SilcClient silc_client = NULL; extern SilcClientOperations ops; /* Our keypair */ -SilcPublicKey irssi_pubkey; -SilcPrivateKey irssi_privkey; +SilcPublicKey irssi_pubkey = NULL; +SilcPrivateKey irssi_privkey = NULL; + +char *opt_nickname = NULL; +char *opt_hostname = NULL; /* Default hash function */ -SilcHash sha1hash; +SilcHash sha1hash = NULL; void silc_expandos_init(void); void silc_expandos_deinit(void); @@ -112,6 +115,18 @@ static void silc_init_userinfo(void) str != NULL ? str : silc_get_real_name()); } + /* Check that real name is UTF-8 encoded */ + set = settings_get_str("real_name"); + if (!silc_utf8_valid(set, strlen(set))) { + int len = silc_utf8_encoded_len(set, strlen(set), SILC_STRING_LOCALE); + tmp = silc_calloc(len, sizeof(*tmp)); + if (tmp) { + silc_utf8_encode(set, strlen(set), SILC_STRING_LOCALE, tmp, len); + settings_set_str("real_name", tmp); + silc_free(tmp); + } + } + /* username */ user_name = settings_get_str("user_name"); if (user_name == NULL || *user_name == '\0') { @@ -193,6 +208,14 @@ static bool silc_log_misc(SilcLogType type, char *message, void *context) return TRUE; } +static bool silc_log_stderr(SilcLogType type, char *message, void *context) +{ + fprintf(stderr, "%s: %s\n", + (type == SILC_LOG_INFO ? "[Info]" : + type == SILC_LOG_WARNING ? "[Warning]" : "[Error]"), message); + return TRUE; +} + static void silc_nickname_format_parse(const char *nickname, char **ret_nickname) { @@ -271,17 +294,15 @@ void silc_opt_callback(poptContext con, const struct poptOption *opt, const char *arg, void *data) { -#if 0 if (strcmp(opt->longName, "nick") == 0) { - g_free(silc_client->nickname); - silc_client->nickname = g_strdup(arg); + g_free(opt_nickname); + opt_nickname = g_strdup(arg); } if (strcmp(opt->longName, "hostname") == 0) { - silc_free(silc_client->hostname); - silc_client->hostname = g_strdup(arg); + g_free(opt_hostname); + opt_hostname = g_strdup(arg); } -#endif /* 0 */ if (strcmp(opt->longName, "list-ciphers") == 0) { silc_cipher_register_default(); @@ -354,17 +375,34 @@ void silc_opt_callback(poptContext con, static void sig_init_finished(void) { /* Check ~/.silc directory and public and private keys */ - if (!silc_client_check_silc_dir()) - exit(1); + if (!silc_client_check_silc_dir()) { + sleep(1); + signal_emit("gui exit", 0); + return; + } /* Load public and private key */ - if (!silc_client_load_keys(silc_client)) - exit(1); + if (!silc_client_load_keys(silc_client)) { + sleep(1); + signal_emit("gui exit", 0); + return; + } /* Initialize the SILC client */ if (!silc_client_init(silc_client, settings_get_str("user_name"), - silc_net_localhost(), settings_get_str("real_name"))) - exit(1); + opt_hostname ? opt_hostname : silc_net_localhost(), + settings_get_str("real_name"))) { + sleep(1); + signal_emit("gui exit", 0); + return; + } + + silc_log_set_callback(SILC_LOG_INFO, silc_log_misc, NULL); + silc_log_set_callback(SILC_LOG_WARNING, silc_log_misc, NULL); + silc_log_set_callback(SILC_LOG_ERROR, silc_log_misc, NULL); + silc_log_set_callback(SILC_LOG_FATAL, silc_log_misc, NULL); + + silc_hash_alloc("sha1", &sha1hash); /* register SILC scheduler */ idletag = g_timeout_add(5, (GSourceFunc) my_silc_scheduler, NULL); @@ -419,10 +457,13 @@ void silc_core_init(void) settings_add_str("server", "crypto_default_hmac", SILC_DEFAULT_HMAC); settings_add_int("server", "key_exchange_timeout_secs", 120); settings_add_int("server", "key_exchange_rekey_secs", 3600); + settings_add_bool("server", "key_exchange_rekey_pfs", FALSE); settings_add_int("server", "connauth_request_secs", 2); settings_add_int("server", "heartbeat", 300); settings_add_bool("server", "ignore_message_signatures", FALSE); settings_add_str("server", "session_filename", "session.$chatnet"); + settings_add_bool("server", "sign_channel_messages", FALSE); + settings_add_bool("server", "sign_private_messages", FALSE); /* Requested Attributes settings */ settings_add_bool("silc", "attr_allow", TRUE); @@ -448,11 +489,15 @@ void silc_core_init(void) silc_init_userinfo(); + silc_log_set_callback(SILC_LOG_INFO, silc_log_stderr, NULL); + silc_log_set_callback(SILC_LOG_WARNING, silc_log_stderr, NULL); + silc_log_set_callback(SILC_LOG_ERROR, silc_log_stderr, NULL); + silc_log_set_callback(SILC_LOG_FATAL, silc_log_stderr, NULL); + /* Initialize client parameters */ memset(¶ms, 0, sizeof(params)); strcat(params.nickname_format, "%n@%h%a"); params.nickname_parse = silc_nickname_format_parse; - params.rekey_secs = settings_get_int("key_exchange_rekey_secs"); params.connauth_request_secs = settings_get_int("connauth_request_secs"); /* Allocate SILC client */ @@ -467,11 +512,6 @@ void silc_core_init(void) silc_register_hmac(silc_client, def_hmac); silc_pkcs_register_default(); - silc_log_set_callback(SILC_LOG_INFO, silc_log_misc, NULL); - silc_log_set_callback(SILC_LOG_WARNING, silc_log_misc, NULL); - silc_log_set_callback(SILC_LOG_ERROR, silc_log_misc, NULL); - silc_log_set_callback(SILC_LOG_FATAL, silc_log_misc, NULL); - /* Register SILC to the irssi */ rec = g_new0(CHAT_PROTOCOL_REC, 1); rec->name = "SILC"; diff --git a/apps/irssi/src/silc/core/silc-core.h b/apps/irssi/src/silc/core/silc-core.h index 0f381157..1f6365a3 100644 --- a/apps/irssi/src/silc/core/silc-core.h +++ b/apps/irssi/src/silc/core/silc-core.h @@ -29,6 +29,7 @@ extern SilcClient silc_client; extern SilcHash sha1hash; extern SilcPublicKey irssi_pubkey; extern SilcPrivateKey irssi_privkey; +extern char *opt_nickname; #define IS_SILC_ITEM(rec) (IS_SILC_CHANNEL(rec) || IS_SILC_QUERY(rec)) diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index 09c6532d..6f57d782 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -162,8 +162,9 @@ int silc_send_msg(SILC_SERVER_REC *server, char *nick, char *msg, rec->len = msg_len; /* Could not find client with that nick, resolve it from server. */ - silc_client_get_clients(silc_client, server->conn, - nickname, NULL, silc_send_msg_clients, rec); + silc_client_get_clients_whois(silc_client, server->conn, + nickname, NULL, NULL, + silc_send_msg_clients, rec); return TRUE; } @@ -242,6 +243,7 @@ static void send_message(SILC_SERVER_REC *server, char *target, { char *message = NULL, *t = NULL; int len; + SilcBool sign; g_return_if_fail(server != NULL); g_return_if_fail(target != NULL); @@ -254,9 +256,12 @@ static void send_message(SILC_SERVER_REC *server, char *target, silc_utf8_encode(msg, strlen(msg), SILC_STRING_LOCALE, message, len); } + sign = settings_get_bool("sign_channel_messages"); + if (target_type == SEND_TARGET_CHANNEL) silc_send_channel(server, target, message ? message : msg, - SILC_MESSAGE_FLAG_UTF8); + SILC_MESSAGE_FLAG_UTF8 | + (sign ? SILC_MESSAGE_FLAG_SIGNED : 0)); else { if (!silc_term_utf8()) { len = silc_utf8_encoded_len(target, strlen(target), SILC_STRING_LOCALE); @@ -267,7 +272,8 @@ static void send_message(SILC_SERVER_REC *server, char *target, silc_send_msg(server, t ? t : target, message ? message : msg, message ? strlen(message) : strlen(msg), - SILC_MESSAGE_FLAG_UTF8); + SILC_MESSAGE_FLAG_UTF8 | + (sign ? SILC_MESSAGE_FLAG_SIGNED : 0)); } silc_free(message); @@ -296,11 +302,12 @@ static void silc_connect_cb(SilcClient client, /* We have successfully connected to server */ /* Enable queueing until we have our requested nick */ -#if 0 - if (settings_get_str("nick") && + if (((opt_nickname && + strcmp(opt_nickname, conn->local_entry->nickname)) || + (settings_get_str("nick") && + strcmp(settings_get_str("nick"), conn->local_entry->nickname))) && !strcmp(conn->local_entry->nickname, conn->local_entry->username)) silc_queue_enable(conn); -#endif /* Put default attributes */ silc_query_attributes_default(silc_client, conn); @@ -399,7 +406,11 @@ static void sig_connected_stream_created(SilcSocketStreamStatus status, /* Set connection parameters */ memset(¶ms, 0, sizeof(params)); - params.nickname = (char *)settings_get_str("nick"); + params.nickname = (opt_nickname ? (char *)opt_nickname : + (char *)settings_get_str("nick")); + params.timeout_secs = settings_get_int("key_exchange_timeout_secs"); + params.rekey_secs = settings_get_int("key_exchange_rekey_secs"); + params.pfs = settings_get_bool("key_exchange_rekey_pfs"); /* Try to read detached session data and use it if found. */ file = silc_get_session_filename(server); -- 2.24.0