updates.
[silc.git] / apps / irssi / src / silc / core / silc-core.c
index 47c927b4baffa668ba048daced079a36ab00742e..5566ace2212d936df6f1872e65dfcb651a2ad31a 100644 (file)
@@ -2,9 +2,9 @@
 
   silc-core.c
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001, 2005 Pekka Riikonen
+  Copyright (C) 2001 - 2006 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
@@ -46,9 +46,20 @@ static int opt_bits = 0;
 
 static int idletag = -1;
 
+/* SILC Client */
 SilcClient silc_client = NULL;
 extern SilcClientOperations ops;
 
+/* Our keypair */
+SilcPublicKey irssi_pubkey = NULL;
+SilcPrivateKey irssi_privkey = NULL;
+
+char *opt_nickname = NULL;
+char *opt_hostname = NULL;
+
+/* Default hash function */
+SilcHash sha1hash = NULL;
+
 void silc_expandos_init(void);
 void silc_expandos_deinit(void);
 
@@ -91,8 +102,8 @@ static void destroy_server_connect(SERVER_CONNECT_REC *conn)
 
 static void silc_init_userinfo(void)
 {
-  const char *set, *nick, *user_name;
-  char *str;
+  const char *set, *nick, *user_name, *str;
+  char *tmp;
 
   /* check if nick/username/realname wasn't read from setup.. */
   set = settings_get_str("real_name");
@@ -104,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') {
@@ -130,9 +153,9 @@ static void silc_init_userinfo(void)
   /* alternate nick */
   set = settings_get_str("alternate_nick");
   if (set == NULL || *set == '\0') {
-    str = g_strconcat(nick, "_", NULL);
-    settings_set_str("alternate_nick", str);
-    g_free(str);
+    tmp = g_strconcat(nick, "_", NULL);
+    settings_set_str("alternate_nick", tmp);
+    g_free(tmp);
   }
 
   /* host name */
@@ -185,10 +208,12 @@ static bool silc_log_misc(SilcLogType type, char *message, void *context)
   return TRUE;
 }
 
-static void silc_nickname_format_parse(const char *nickname,
-                                      char **ret_nickname)
+static bool silc_log_stderr(SilcLogType type, char *message, void *context)
 {
-  silc_parse_userfqdn(nickname, ret_nickname, NULL);
+  fprintf(stderr, "%s: %s\n",
+         (type == SILC_LOG_INFO ? "[Info]" :
+          type == SILC_LOG_WARNING ? "[Warning]" : "[Error]"), message);
+  return TRUE;
 }
 
 static void silc_register_cipher(SilcClient client, const char *cipher)
@@ -262,13 +287,13 @@ void silc_opt_callback(poptContext con,
                       const char *arg, void *data)
 {
   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);
   }
 
   if (strcmp(opt->longName, "list-ciphers") == 0) {
@@ -313,7 +338,7 @@ void silc_opt_callback(poptContext con,
     silc_pkcs_register_default();
     silc_hash_register_default();
     silc_hmac_register_default();
-    silc_create_key_pair(opt_pkcs, opt_bits, NULL, NULL, NULL,
+    silc_create_key_pair(opt_pkcs, opt_bits, NULL, NULL,
                         NULL, NULL, NULL, NULL, TRUE);
     exit(0);
   }
@@ -334,24 +359,65 @@ void silc_opt_callback(poptContext con,
     silc_pkcs_register_default();
     silc_hash_register_default();
     silc_hmac_register_default();
-    silc_show_public_key((char *)arg);
+    silc_show_public_key_file((char *)arg);
     exit(0);
   }
 }
 
+/* Called to indicate the client library has stopped. */
+
+static void
+silc_stopped(SilcClient client, void *context)
+{
+  SILC_LOG_DEBUG(("Client library has stopped"));
+  if (idletag != -1)
+    g_source_remove(idletag);
+}
+
+static void sig_gui_quit(SILC_SERVER_REC *server, const char *msg)
+{
+  silc_client_stop(silc_client, silc_stopped, NULL);
+}
+
+/* Called to indicate the client library is running. */
+
+static void
+silc_running(SilcClient client, void *context)
+{
+  SILC_LOG_DEBUG(("Client library is running"));
+}
+
 static void sig_init_finished(void)
 {
   /* Check ~/.silc directory and public and private keys */
-  if (!silc_client_check_silc_dir())
+  if (!silc_client_check_silc_dir()) {
+    sleep(1);
     exit(1);
+    return;
+  }
 
   /* Load public and private key */
-  if (!silc_client_load_keys(silc_client))
+  if (!silc_client_load_keys(silc_client)) {
+    sleep(1);
     exit(1);
+    return;
+  }
 
   /* Initialize the SILC client */
-  if (!silc_client_init(silc_client))
+  if (!silc_client_init(silc_client, settings_get_str("user_name"),
+                       opt_hostname ? opt_hostname : silc_net_localhost(),
+                       settings_get_str("real_name"), silc_running, NULL)) {
+    sleep(1);
     exit(1);
+    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);
@@ -406,10 +472,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);
@@ -432,14 +501,18 @@ void silc_core_init(void)
 
   signal_add("setup changed", (SIGNAL_FUNC) sig_setup_changed);
   signal_add("irssi init finished", (SIGNAL_FUNC) sig_init_finished);
+  signal_add("gui exit", (SIGNAL_FUNC) sig_gui_quit);
 
   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(&params, 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 */
@@ -454,17 +527,6 @@ void silc_core_init(void)
   silc_register_hmac(silc_client, def_hmac);
   silc_pkcs_register_default();
 
-  /* Get user information */
-  silc_client->username = g_strdup(settings_get_str("user_name"));
-  silc_client->nickname = g_strdup(settings_get_str("nick"));
-  silc_client->hostname = silc_net_localhost();
-  silc_client->realname = g_strdup(settings_get_str("real_name"));
-
-  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";
@@ -508,6 +570,7 @@ void silc_core_deinit(void)
        chat_protocol_find("SILC"));
   signal_remove("setup changed", (SIGNAL_FUNC) sig_setup_changed);
   signal_remove("irssi init finished", (SIGNAL_FUNC) sig_init_finished);
+  signal_remove("gui exit", (SIGNAL_FUNC) sig_gui_quit);
 
   silc_queue_deinit();
   silc_server_deinit();
@@ -519,11 +582,7 @@ void silc_core_deinit(void)
 
   chat_protocol_unregister("SILC");
 
-  g_free(silc_client->username);
-  g_free(silc_client->realname);
-  silc_free(silc_client->hostname);
-  silc_pkcs_free(silc_client->pkcs);
-  silc_pkcs_private_key_free(silc_client->private_key);
-  silc_pkcs_public_key_free(silc_client->public_key);
+  silc_pkcs_private_key_free(irssi_privkey);
+  silc_pkcs_public_key_free(irssi_pubkey);
   silc_client_free(silc_client);
 }