Porting to new Toolkit API.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 28 Nov 2006 20:27:14 +0000 (20:27 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 28 Nov 2006 20:27:14 +0000 (20:27 +0000)
14 files changed:
apps/irssi/src/fe-common/silc/module.h
apps/irssi/src/perl/silc/module.h
apps/irssi/src/silc/core/Makefile.am
apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/client_ops.h
apps/irssi/src/silc/core/clientutil.c
apps/irssi/src/silc/core/module.h
apps/irssi/src/silc/core/silc-channels.c
apps/irssi/src/silc/core/silc-cmdqueue.c
apps/irssi/src/silc/core/silc-core.c
apps/irssi/src/silc/core/silc-core.h
apps/irssi/src/silc/core/silc-lag.c
apps/irssi/src/silc/core/silc-queries.c
apps/irssi/src/silc/core/silc-servers.c

index 299d4d34aea031d139948822c6c451eb539a40ac..0a06d9c5bf1789d74f4cf57120e8967b5e1811f1 100644 (file)
@@ -4,6 +4,6 @@
 
 #undef PACKAGE
 #undef VERSION
-#include "silcincludes.h"
+#include "silc.h"
 #include "silcclient.h"
 #include "silc-core.h"
index 9061ea09a8d4859e03c82946101a700e3801e422..6a7617c47bb6dc40ea09757b55afef65b65fa63e 100644 (file)
@@ -1,6 +1,6 @@
 #include "../common/module.h"
 
-#include "silcincludes.h"
+#include "silc.h"
 #include "silcclient.h"
 #include "client_ops.h"
 #include "silc-core.h"
index fb35564c7d890d6dc1b00f3a498e8d62bc7a1f36..3e7d43a6739cb89fab346efc827e60ebb24456d7 100644 (file)
@@ -14,7 +14,6 @@ ADD_INCLUDES = \
 noinst_LIBRARIES=libsilc_core.a
 
 libsilc_core_a_SOURCES = \
-       client_ops.c \
        clientutil.c \
        silc-channels.c \
        silc-core.c \
@@ -25,7 +24,8 @@ libsilc_core_a_SOURCES = \
        silc-servers-reconnect.c \
        silc-lag.c \
        silc-chatnets.c \
-       silc-cmdqueue.c
+       silc-cmdqueue.c \
+       client_ops.c
 
 noinst_HEADERS = \
        module.h \
index 44c7b0a32b2c8e6cff34cbeb2c18ff35263f41cc..77b362f6d44a7b1c3a86a8129f5ebdb2c49b6cf7 100644 (file)
@@ -2,9 +2,9 @@
 
   client_ops.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,8 @@
 
 static void
 silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
-                               const char *name, SilcSocketType conn_type,
-                               unsigned char *pk, SilcUInt32 pk_len,
-                               SilcSKEPKType pk_type,
+                               const char *name, SilcConnectionType conn_type,
+                               SilcPublicKey public_key,
                                SilcVerifyPublicKey completion, void *context);
 
 char *silc_get_session_filename(SILC_SERVER_REC *server)
@@ -164,49 +163,48 @@ silc_print_nick_change(SILC_SERVER_REC *server, const char *newnick,
 
 static void silc_parse_channel_public_keys(SILC_SERVER_REC *server,
                                           SilcChannelEntry channel_entry,
-                                          SilcBuffer channel_pubkeys)
+                                          SilcDList channel_pubkeys)
 {
-  SilcUInt16 argc;
-  SilcArgumentPayload chpks;
-  unsigned char *pk;
+  SilcArgumentDecodedList e;
+  SilcPublicKey pubkey;
+  SilcSILCPublicKey silc_pubkey;
   SilcUInt32 pk_len, type;
-  int c = 1;
+  unsigned char *pk;
   char *fingerprint, *babbleprint;
-  SilcPublicKey pubkey;
-  SilcPublicKeyIdentifier ident;
+  int c = 1;
 
   printformat_module("fe-common/silc", server, NULL,
                     MSGLEVEL_CRAP, SILCTXT_CHANNEL_PK_LIST,
                     channel_entry->channel_name);
 
-  SILC_GET16_MSB(argc, channel_pubkeys->data);
-  chpks = silc_argument_payload_parse(channel_pubkeys->data + 2,
-                                     channel_pubkeys->len - 2, argc);
-  if (!chpks)
-    return;
+  silc_dlist_start(channel_pubkeys);
+  while ((e = silc_dlist_get(channel_pubkeys))) {
+    pubkey = e->argument;
+    type = e->arg_type;
 
-  pk = silc_argument_get_first_arg(chpks, &type, &pk_len);
-  while (pk) {
-    fingerprint = silc_hash_fingerprint(NULL, pk + 4, pk_len - 4);
-    babbleprint = silc_hash_babbleprint(NULL, pk + 4, pk_len - 4);
-    silc_pkcs_public_key_payload_decode(pk, pk_len, &pubkey);
-    ident = silc_pkcs_decode_identifier(pubkey->identifier);
+    if (silc_pkcs_get_type(pubkey) != SILC_PKCS_SILC)
+      continue;
+
+    pk = silc_pkcs_public_key_encode(pubkey, &pk_len);
+    if (!pk)
+      continue;
+
+    fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+    babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
+    silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, pubkey);
 
     printformat_module("fe-common/silc", server, NULL,
                       MSGLEVEL_CRAP, SILCTXT_CHANNEL_PK_LIST_ENTRY,
                       c++, channel_entry->channel_name,
                       type == 0x00 ? "Added" : "Removed",
-                      ident->realname ? ident->realname : "",
+                      silc_pubkey->identifier.realname ?
+                      silc_pubkey->identifier.realname : "",
                       fingerprint, babbleprint);
 
     silc_free(fingerprint);
     silc_free(babbleprint);
-    silc_pkcs_public_key_free(pubkey);
-    silc_pkcs_free_identifier(ident);
-    pk = silc_argument_get_next_arg(chpks, &type, &pk_len);
+    silc_free(pk);
   }
-
-  silc_argument_payload_free(chpks);
 }
 
 void silc_say(SilcClient client, SilcClientConnection conn,
@@ -238,32 +236,29 @@ void silc_say_error(char *msg, ...)
   va_end(va);
 }
 
-/* try to verify a message using locally stored public key data */
+/* Try to verify a message using locally stored public key data */
+
 int verify_message_signature(SilcClientEntry sender,
-                            SilcMessageSignedPayload sig,
                             SilcMessagePayload message)
 {
   SilcPublicKey pk;
   char file[256], filename[256];
   char *fingerprint, *fingerprint2;
-  unsigned char *pk_data;
+  const unsigned char *pk_data;
   SilcUInt32 pk_datalen;
   struct stat st;
   int ret = SILC_MSG_SIGNED_VERIFIED, i;
 
-  if (sig == NULL)
-    return SILC_MSG_SIGNED_UNKNOWN;
-
   /* get public key from the signature payload and compare it with the
      one stored in the client entry */
-  pk = silc_message_signed_get_public_key(sig, &pk_data, &pk_datalen);
+  pk = silc_message_signed_get_public_key(message, &pk_data, &pk_datalen);
 
   if (pk != NULL) {
     fingerprint = silc_hash_fingerprint(NULL, pk_data, pk_datalen);
 
     if (sender->fingerprint) {
       fingerprint2 = silc_fingerprint(sender->fingerprint,
-                                     sender->fingerprint_len);
+                                     sizeof(sender->fingerprint));
       if (strcmp(fingerprint, fingerprint2)) {
         /* since the public key differs from the senders public key, the
            verification _failed_ */
@@ -275,7 +270,7 @@ int verify_message_signature(SilcClientEntry sender,
     }
   } else if (sender->fingerprint)
     fingerprint = silc_fingerprint(sender->fingerprint,
-                                  sender->fingerprint_len);
+                                  sizeof(sender->fingerprint));
   else
     /* no idea, who or what signed that message ... */
     return SILC_MSG_SIGNED_UNKNOWN;
@@ -297,9 +292,7 @@ int verify_message_signature(SilcClientEntry sender,
     SilcPublicKey cached_pk=NULL;
 
     /* try to load the file */
-    if (!silc_pkcs_load_public_key(filename, &cached_pk, SILC_PKCS_FILE_PEM) &&
-       !silc_pkcs_load_public_key(filename, &cached_pk,
-                                  SILC_PKCS_FILE_BIN)) {
+    if (!silc_pkcs_load_public_key(filename, &cached_pk)) {
       printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
                         SILCTXT_PUBKEY_COULD_NOT_LOAD, "client");
       if (pk == NULL)
@@ -316,8 +309,8 @@ 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(sig, message, pk,
-                                        silc_client->sha1hash)!= SILC_AUTH_OK)
+  if ((pk) && silc_message_signed_verify(message, pk,
+                                        sha1hash)!= SILC_AUTH_OK)
     ret = SILC_MSG_SIGNED_FAILED;
 
   if (pk)
@@ -326,74 +319,74 @@ int verify_message_signature(SilcClientEntry sender,
   return ret;
 }
 
-char * silc_unescape_data(const char *escaped_data, SilcUInt32 *length)
+char *silc_unescape_data(const char *escaped_data, SilcUInt32 *length)
 {
-    char *data, *ptr;
-    int i = 0, j = 0, len = strlen(escaped_data);
-
-    data = silc_calloc(len, sizeof(char));
-
-    while (i < len) {
-        ptr = memchr(escaped_data + i, 1, len - i);
-        if (ptr) {
-            int inc = (ptr - escaped_data) - i;
-            memcpy(data + j, escaped_data + i, inc);
-            j += inc;
-            i += inc + 2;
-            data[j++] = *(ptr + 1) - 1;
-        } else {
-            memcpy(data + j, escaped_data + i, len - i);
-            j += (len - i);
-            break;
-        }
+  char *data, *ptr;
+  int i = 0, j = 0, len = strlen(escaped_data);
+
+  data = silc_calloc(len, sizeof(char));
+
+  while (i < len) {
+    ptr = memchr(escaped_data + i, 1, len - i);
+    if (ptr) {
+      int inc = (ptr - escaped_data) - i;
+      memcpy(data + j, escaped_data + i, inc);
+      j += inc;
+      i += inc + 2;
+      data[j++] = *(ptr + 1) - 1;
+    } else {
+      memcpy(data + j, escaped_data + i, len - i);
+      j += (len - i);
+      break;
     }
+  }
 
-    *length = j;
-    return data;
+  *length = j;
+  return data;
 }
 
-char * silc_escape_data(const char *data, SilcUInt32 len)
+char *silc_escape_data(const char *data, SilcUInt32 len)
 {
-    char *escaped_data, *ptr, *ptr0, *ptr1;
-    int i = 0, j = 0;
-
-    escaped_data = silc_calloc(2 * len, sizeof(char));
-
-    while (i < len) {
-        ptr0 = memchr(data + i, 0, len - i);
-        ptr1 = memchr(data + i, 1, len - i);
-
-        ptr = (ptr0 < ptr1 ? (ptr0 ? ptr0 : ptr1) : (ptr1 ? ptr1 : ptr0));
-
-        if (ptr) {
-            int inc = (ptr - data) - i;
-            if (inc)
-                memcpy(escaped_data + j, data + i, inc);
-            j += inc;
-            i += inc;
-            escaped_data[j++] = 1;
-            escaped_data[j++] = *(data + i++) + 1;
-        } else {
-            memcpy(escaped_data + j, data + i, len - i);
-            j += (len - i);
-            break;
-        }
+  char *escaped_data, *ptr, *ptr0, *ptr1;
+  int i = 0, j = 0;
+
+  escaped_data = silc_calloc(2 * len, sizeof(char));
+
+  while (i < len) {
+    ptr0 = memchr(data + i, 0, len - i);
+    ptr1 = memchr(data + i, 1, len - i);
+
+    ptr = (ptr0 < ptr1 ? (ptr0 ? ptr0 : ptr1) : (ptr1 ? ptr1 : ptr0));
+
+    if (ptr) {
+      int inc = (ptr - data) - i;
+      if (inc)
+       memcpy(escaped_data + j, data + i, inc);
+      j += inc;
+      i += inc;
+      escaped_data[j++] = 1;
+      escaped_data[j++] = *(data + i++) + 1;
+    } else {
+      memcpy(escaped_data + j, data + i, len - i);
+      j += (len - i);
+      break;
     }
+  }
 
-    return escaped_data;
+  return escaped_data;
 }
 
 void silc_emit_mime_sig(SILC_SERVER_REC *server, WI_ITEM_REC *item,
-               const char *data, SilcUInt32 data_len, const char *nick,
-              int verified)
+                       const char *data, SilcUInt32 data_len,
+                       const char *nick, int verified)
 {
-   char *escaped_data;
+  char *escaped_data;
 
-   escaped_data = silc_escape_data(data, data_len);
+  escaped_data = silc_escape_data(data, data_len);
 
-   signal_emit("mime", 5, server, item, escaped_data, nick, verified);
+  signal_emit("mime", 5, server, item, escaped_data, nick, verified);
 
-   silc_free(escaped_data);
+  silc_free(escaped_data);
 }
 
 
@@ -433,8 +426,7 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
   /* If the messages is digitally signed, verify it, if possible. */
   if (flags & SILC_MESSAGE_FLAG_SIGNED) {
     if (!settings_get_bool("ignore_message_signatures")) {
-      SilcMessageSignedPayload sig = silc_message_get_signature(payload);
-      verified = verify_message_signature(sender, sig, payload);
+      verified = verify_message_signature(sender, payload);
     } else {
       flags &= ~SILC_MESSAGE_FLAG_SIGNED;
     }
@@ -442,8 +434,8 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
 
   if (flags & SILC_MESSAGE_FLAG_DATA) {
     silc_emit_mime_sig(server, (WI_ITEM_REC *)chanrec, message, message_len,
-               nick == NULL ? NULL : nick->nick,
-               flags & SILC_MESSAGE_FLAG_SIGNED ? verified : -1);
+                      nick == NULL ? NULL : nick->nick,
+                      flags & SILC_MESSAGE_FLAG_SIGNED ? verified : -1);
     message = NULL;
   }
 
@@ -566,8 +558,7 @@ void silc_private_message(SilcClient client, SilcClientConnection conn,
   /* If the messages is digitally signed, verify it, if possible. */
   if (flags & SILC_MESSAGE_FLAG_SIGNED) {
     if (!settings_get_bool("ignore_message_signatures")) {
-      SilcMessageSignedPayload sig = silc_message_get_signature(payload);
-      verified = verify_message_signature(sender, sig, payload);
+      verified = verify_message_signature(sender, payload);
     } else {
       flags &= ~SILC_MESSAGE_FLAG_SIGNED;
     }
@@ -709,9 +700,9 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
   void *entry;
   SilcUInt32 mode;
   char buf[512];
-  char *name, *tmp;
+  char *name, *tmp, *cipher, *hmac;
   GSList *list1, *list_tmp;
-  SilcBuffer buffer;
+  SilcDList chpks;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -812,7 +803,9 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     client_entry = va_arg(va, SilcClientEntry);
     tmp = va_arg(va, char *);
 
+#if 0
     silc_server_free_ftp(server, client_entry);
+#endif
 
     /* Print only if we have the nickname.  If this cliente has just quit
        when we were only resolving it, it is possible we don't have the
@@ -925,18 +918,15 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     idtype = va_arg(va, int);
     entry = va_arg(va, void *);
     mode = va_arg(va, SilcUInt32);
-    (void)va_arg(va, char *);                 /* cipher */
-    (void)va_arg(va, char *);                 /* hmac */
+    cipher = va_arg(va, char *);               /* cipher */
+    hmac = va_arg(va, char *);                /* hmac */
     (void)va_arg(va, char *);                 /* passphrase */
     (void)va_arg(va, SilcPublicKey);          /* founder key */
-    buffer = va_arg(va, SilcBuffer);          /* channel public keys */
+    chpks = va_arg(va, SilcDList);            /* channel public keys */
     channel = va_arg(va, SilcChannelEntry);
 
-    tmp = silc_client_chmode(mode,
-                            channel->channel_key ?
-                            silc_cipher_get_name(channel->channel_key) : "",
-                            channel->hmac ?
-                            silc_hmac_get_name(channel->hmac) : "");
+    tmp = silc_client_chmode(mode, cipher ? cipher : "",
+                            hmac ? hmac : "");
 
     chanrec = silc_channel_find_entry(server, channel);
     if (chanrec != NULL) {
@@ -966,8 +956,8 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     }
 
     /* Print the channel public key list */
-    if (buffer)
-      silc_parse_channel_public_keys(server, channel, buffer);
+    if (chpks)
+      silc_parse_channel_public_keys(server, channel, chpks);
 
     silc_free(tmp);
     break;
@@ -1185,7 +1175,9 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
                      "server signoff");
        }
 
+#if 0
        silc_server_free_ftp(server, clients[i]);
+#endif
 
        list1 = nicklist_get_same_unique(SERVER(server), clients[i]);
        for (list_tmp = list1; list_tmp != NULL; list_tmp =
@@ -1275,114 +1267,6 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
   va_end(va);
 }
 
-/* Called to indicate that connection was either successfully established
-   or connecting failed.  This is also the first time application receives
-   the SilcClientConnection object which it should save somewhere. */
-
-void silc_connect(SilcClient client, SilcClientConnection conn,
-                 SilcClientConnectionStatus status)
-{
-  SILC_SERVER_REC *server = conn->context;
-
-  if (!server || server->disconnected) {
-    silc_client_close_connection(client, conn);
-    return;
-  }
-
-  switch (status) {
-  case SILC_CLIENT_CONN_SUCCESS:
-    /* We have successfully connected to server */
-    if ((client->nickname != NULL) &&
-        (strcmp(client->nickname, client->username)))
-      silc_queue_enable(conn); /* enable queueing until we have our nick */
-    server->connected = TRUE;
-    signal_emit("event connected", 1, server);
-    break;
-
-  case SILC_CLIENT_CONN_SUCCESS_RESUME:
-    /* We have successfully resumed old detached session */
-    server->connected = TRUE;
-    signal_emit("event connected", 1, server);
-
-    /* If we resumed old session check whether we need to update
-       our nickname */
-    if (strcmp(server->nick, conn->local_entry->nickname)) {
-      char *old;
-      old = g_strdup(server->nick);
-      server_change_nick(SERVER(server), conn->local_entry->nickname);
-      nicklist_rename_unique(SERVER(server),
-                            conn->local_entry, server->nick,
-                            conn->local_entry, conn->local_entry->nickname);
-      signal_emit("message own_nick", 4, server, server->nick, old, "");
-      g_free(old);
-    }
-
-    /* remove the detach data now */
-    {
-      char *file;
-
-      file = silc_get_session_filename(server);
-
-      unlink(file);
-      silc_free(file);
-    }
-    break;
-
-  default:
-    {
-      char * file;
-
-      file = silc_get_session_filename(server);
-
-      if (silc_file_size(file) > 0)
-        printformat_module("fe-common/silc", server, NULL,
-                          MSGLEVEL_CRAP, SILCTXT_REATTACH_FAILED, file);
-
-      silc_free(file);
-
-      server->connection_lost = TRUE;
-      if (server->conn)
-        server->conn->context = NULL;
-      server_disconnect(SERVER(server));
-
-      break;
-    }
-  }
-}
-
-/* Called to indicate that connection was disconnected to the server. */
-
-void silc_disconnect(SilcClient client, SilcClientConnection conn,
-                    SilcStatus status, const char *message)
-{
-  SILC_SERVER_REC *server = conn->context;
-
-  SILC_LOG_DEBUG(("Start"));
-
-  if (!server || server->connection_lost)
-    return;
-
-  if (server->conn && server->conn->local_entry) {
-    nicklist_rename_unique(SERVER(server),
-                          server->conn->local_entry, server->nick,
-                          server->conn->local_entry,
-                          silc_client->username);
-    silc_change_nick(server, silc_client->username);
-  }
-
-  if (message)
-    silc_say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
-            "Server closed connection: %s (%d) %s",
-            silc_get_status_message(status), status,
-            message ? message : "");
-
-  if (server->conn)
-    server->conn->context = NULL;
-  server->conn = NULL;
-  server->connection_lost = TRUE;
-  server_disconnect(SERVER(server));
-}
-
 /* Command handler. This function is called always in the command function.
    If error occurs it will be called as well. `conn' is the associated
    client connection. `cmd_context' is the command context that was
@@ -1395,8 +1279,8 @@ void silc_disconnect(SilcClient client, SilcClientConnection conn,
 static bool cmode_list_chpks = FALSE;
 
 void silc_command(SilcClient client, SilcClientConnection conn,
-                 SilcClientCommandContext cmd_context, bool success,
-                 SilcCommand command, SilcStatus status)
+                 SilcBool success, SilcCommand command, SilcStatus status,
+                 SilcUInt32 argc, unsigned char **argv)
 {
   SILC_SERVER_REC *server = conn->context;
 
@@ -1410,13 +1294,13 @@ void silc_command(SilcClient client, SilcClientConnection conn,
   switch (command) {
 
   case SILC_COMMAND_INVITE:
-    if (cmd_context->argc > 2)
+    if (argc > 2)
       printformat_module("fe-common/silc", server, NULL,
                         MSGLEVEL_CRAP, SILCTXT_CHANNEL_INVITING,
-                        cmd_context->argv[2],
-                        (cmd_context->argv[1][0] == '*' ?
+                        argv[2],
+                        (argv[1][0] == '*' ?
                          (char *)conn->current_channel->channel_name :
-                         (char *)cmd_context->argv[1]));
+                         (char *)argv[1]));
     break;
 
   case SILC_COMMAND_DETACH:
@@ -1424,8 +1308,7 @@ void silc_command(SilcClient client, SilcClientConnection conn,
     break;
 
   case SILC_COMMAND_CMODE:
-    if (cmd_context->argc == 3 &&
-       !strcmp(cmd_context->argv[2], "+C"))
+    if (argc == 3 && !strcmp(argv[2], "+C"))
       cmode_list_chpks = TRUE;
     else
       cmode_list_chpks = FALSE;
@@ -1436,85 +1319,11 @@ void silc_command(SilcClient client, SilcClientConnection conn,
   }
 }
 
-typedef struct {
-  SilcChannelEntry channel;
-  bool retry;
-} *SilcJoinResolve;
-
-/* Client info resolving callback when JOIN command reply is received.
-   This will cache all users on the channel. */
-
-static void silc_client_join_get_users(SilcClient client,
-                                      SilcClientConnection conn,
-                                      SilcClientEntry *clients,
-                                      SilcUInt32 clients_count,
-                                      void *context)
-{
-  SilcJoinResolve r = context;
-  SilcChannelEntry channel = r->channel;
-  SilcHashTableList htl;
-  SilcChannelUser chu;
-  SILC_SERVER_REC *server = conn->context;
-  SILC_CHANNEL_REC *chanrec;
-  SilcClientEntry founder = NULL;
-  NICK_REC *ownnick;
-
-  SILC_LOG_DEBUG(("Start, channel %s, %d users", channel->channel_name,
-                 silc_hash_table_count(channel->user_list)));
-
-  if (!clients && r->retry < 1) {
-    /* Retry to resolve */
-    r->retry++;
-    silc_client_get_clients_by_channel(client, conn, channel,
-                                      silc_client_join_get_users, context);
-    return;
-  }
-
-  chanrec = silc_channel_find(server, channel->channel_name);
-  if (chanrec == NULL)
-    return;
-
-  silc_hash_table_list(channel->user_list, &htl);
-  while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
-    if (!chu->client->nickname)
-      continue;
-    if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)
-      founder = chu->client;
-    silc_nicklist_insert(chanrec, chu, FALSE);
-  }
-  silc_hash_table_list_reset(&htl);
-
-  ownnick = NICK(silc_nicklist_find(chanrec, conn->local_entry));
-  nicklist_set_own(CHANNEL(chanrec), ownnick);
-  signal_emit("channel joined", 1, chanrec);
-  chanrec->entry = channel;
-
-  if (chanrec->topic)
-    printformat_module("fe-common/silc", server, channel->channel_name,
-                      MSGLEVEL_CRAP, SILCTXT_CHANNEL_TOPIC,
-                      channel->channel_name, chanrec->topic);
-
-  if (founder) {
-    if (founder == conn->local_entry) {
-      printformat_module("fe-common/silc",
-                        server, channel->channel_name, MSGLEVEL_CRAP,
-                        SILCTXT_CHANNEL_FOUNDER_YOU,
-                        channel->channel_name);
-      signal_emit("nick mode changed", 2, chanrec, ownnick);
-    } else
-      printformat_module("fe-common/silc",
-                        server, channel->channel_name, MSGLEVEL_CRAP,
-                        SILCTXT_CHANNEL_FOUNDER,
-                        channel->channel_name, founder->nickname);
-  }
-}
-
 typedef struct {
   SilcClient client;
   SilcClientConnection conn;
   void *entry;
   SilcIdType id_type;
-  char *fingerprint;
 } *GetkeyContext;
 
 void silc_getkey_cb(bool success, void *context)
@@ -1534,7 +1343,6 @@ void silc_getkey_cb(bool success, void *context)
                       entity, name);
   }
 
-  silc_free(getkey->fingerprint);
   silc_free(getkey);
 }
 
@@ -1564,13 +1372,13 @@ void silc_parse_inviteban_list(SilcClient client,
                     MSGLEVEL_CRAP, SILCTXT_CHANNEL_INVITEBAN_LIST,
                     channel->channel_name, list_type);
 
-  /* parse the list */
+  /* Parse the list */
   tmp = silc_argument_get_first_arg(list, &type, &len);
   while (tmp) {
     switch (type) {
       case 1:
        {
-         /* an invite string */
+         /* An invite string */
          char **list;
          int i=0;
 
@@ -1590,7 +1398,7 @@ void silc_parse_inviteban_list(SilcClient client,
 
       case 2:
        {
-         /* a public key */
+         /* A public key */
          char *fingerprint, *babbleprint;
 
          /* tmp is Public Key Payload, take public key from it. */
@@ -1607,32 +1415,29 @@ void silc_parse_inviteban_list(SilcClient client,
 
       case 3:
        {
-         /* a client ID */
-         SilcClientID *client_id;
+         /* A Client ID */
          SilcClientEntry client_entry;
+         SilcID id;
 
-         client_id = silc_id_payload_parse_id(tmp, len, NULL);
-
-         if (client_id == NULL) {
+         if (!silc_id_payload_parse_id(tmp, len, &id)) {
            silc_say_error("Invalid data in %s list encountered", list_type);
            break;
          }
 
-         client_entry = silc_client_get_client_by_id(client, conn, client_id);
-
+         client_entry = silc_client_get_client_by_id(client, conn,
+                                                     &id.u.client_id);
          if (client_entry) {
            printformat_module("fe-common/silc", server,
                               (chanrec ? chanrec->visible_name : NULL),
                               MSGLEVEL_CRAP, SILCTXT_CHANNEL_INVITEBAN_STRING,
                               ++counter, channel->channel_name, list_type,
                               client_entry->nickname);
+           silc_client_unref_client(client, conn, client_entry);
          } else {
            resolving = TRUE;
-           silc_client_get_client_by_id_resolve(client, conn, client_id,
+           silc_client_get_client_by_id_resolve(client, conn, &id.u.client_id,
                                                 NULL, NULL, NULL);
          }
-
-         silc_free(client_id);
        }
        break;
 
@@ -1640,6 +1445,7 @@ void silc_parse_inviteban_list(SilcClient client,
        /* "trash" */
        silc_say_error("Unkown type in %s list: %u (len %u)",
                       list_type, type, len);
+       break;
     }
     tmp = silc_argument_get_next_arg(list, &type, &len);
   }
@@ -1667,60 +1473,44 @@ void silc_parse_inviteban_list(SilcClient client,
    and each command defines the number and type of arguments it passes to the
    application (on error they are not sent). */
 
-void
-silc_command_reply(SilcClient client, SilcClientConnection conn,
-                  SilcCommandPayload cmd_payload, bool success,
-                  SilcCommand command, SilcStatus status, ...)
-
+void silc_command_reply(SilcClient client, SilcClientConnection conn,
+                       SilcCommand command, SilcStatus status,
+                       SilcStatus error, va_list vp)
 {
   SILC_SERVER_REC *server = conn->context;
   SILC_CHANNEL_REC *chanrec;
-  va_list vp;
-
-  va_start(vp, status);
 
   SILC_LOG_DEBUG(("Start"));
 
   switch(command) {
   case SILC_COMMAND_WHOIS:
     {
-      char buf[1024], *nickname, *username, *realname, *nick;
+      char buf[1024], *nickname, *username, *realname, nick[128 + 1];
       unsigned char *fingerprint;
-      SilcUInt32 idle, mode;
-      SilcBuffer channels, user_modes;
+      SilcUInt32 idle, mode, *user_modes;
+      SilcDList channels;
       SilcClientEntry client_entry;
       SilcDList attrs;
 
       if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
        /* Print the unknown nick for user */
-       unsigned char *tmp =
-         silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
-                                    2, NULL);
+       char *tmp = va_arg(vp, char *);
        if (tmp)
-         silc_say_error("%s: %s", tmp,
-                        silc_get_status_message(status));
+         silc_say_error("%s: %s", tmp, silc_get_status_message(status));
        break;
       } else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
        /* Try to find the entry for the unknown client ID, since we
           might have, and print the nickname of it for user. */
-       SilcUInt32 tmp_len;
-       unsigned char *tmp =
-         silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
-                                    2, &tmp_len);
-       if (tmp) {
-         SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len,
-                                                            NULL);
-         if (client_id) {
-           client_entry = silc_client_get_client_by_id(client, conn,
-                                                       client_id);
-           if (client_entry && client_entry->nickname)
-             silc_say_error("%s: %s", client_entry->nickname,
-                            silc_get_status_message(status));
-           silc_free(client_id);
-         }
+       SilcClientID *id = va_arg(vp, SilcClientID *);
+       if (id) {
+         client_entry = silc_client_get_client_by_id(client, conn, id);
+         if (client_entry && client_entry->nickname[0])
+           silc_say_error("%s: %s", client_entry->nickname,
+                          silc_get_status_message(status));
+         silc_client_unref_client(client, conn, client_entry);
        }
        break;
-      } else if (!success) {
+      } else if (status != SILC_STATUS_OK) {
        silc_say_error("WHOIS: %s", silc_get_status_message(status));
        return;
       }
@@ -1729,50 +1519,40 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       nickname = va_arg(vp, char *);
       username = va_arg(vp, char *);
       realname = va_arg(vp, char *);
-      channels = va_arg(vp, SilcBuffer);
+      channels = va_arg(vp, SilcDList);
       mode = va_arg(vp, SilcUInt32);
       idle = va_arg(vp, SilcUInt32);
       fingerprint = va_arg(vp, unsigned char *);
-      user_modes = va_arg(vp, SilcBuffer);
+      user_modes = va_arg(vp, SilcUInt32 *);
       attrs = va_arg(vp, SilcDList);
 
-      silc_parse_userfqdn(nickname, &nick, NULL);
+      silc_parse_userfqdn(nickname, nick, sizeof(nick), NULL, 0);
       printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
                         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 && user_modes) {
-       SilcUInt32 *umodes;
-       SilcDList list = silc_channel_payload_parse_list(channels->data,
-                                                        channels->len);
-       if (list && silc_get_mode_list(user_modes, silc_dlist_count(list),
-                                      &umodes)) {
-         SilcChannelPayload entry;
-         int i = 0;
-
-         memset(buf, 0, sizeof(buf));
-         silc_dlist_start(list);
-         while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
-           SilcUInt32 name_len;
-           char *m = silc_client_chumode_char(umodes[i++]);
-           char *name = silc_channel_get_name(entry, &name_len);
-
-           if (m)
-             silc_strncat(buf, sizeof(buf) - 1, m, strlen(m));
-           silc_strncat(buf, sizeof(buf) - 1, name, name_len);
-           silc_strncat(buf, sizeof(buf) - 1, " ", 1);
-           silc_free(m);
-         }
-
-         printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
-                            SILCTXT_WHOIS_CHANNELS, buf);
-         silc_channel_payload_list_free(list);
-         silc_free(umodes);
+       SilcChannelPayload entry;
+       int i = 0;
+
+       silc_dlist_start(channels);
+       while ((entry = silc_dlist_get(channels))) {
+         SilcUInt32 name_len;
+         char *m = silc_client_chumode_char(user_modes[i++]);
+         char *name = silc_channel_get_name(entry, &name_len);
+
+         if (m)
+           silc_strncat(buf, sizeof(buf) - 1, m, strlen(m));
+         silc_strncat(buf, sizeof(buf) - 1, name, name_len);
+         silc_strncat(buf, sizeof(buf) - 1, " ", 1);
+         silc_free(m);
        }
+
+       printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
+                          SILCTXT_WHOIS_CHANNELS, buf);
       }
 
       if (mode) {
@@ -1805,57 +1585,17 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
     }
     break;
 
-  case SILC_COMMAND_IDENTIFY:
-    {
-      SilcClientEntry client_entry;
-
-      if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
-       /* Print the unknown nick for user */
-       unsigned char *tmp =
-         silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
-                                    2, NULL);
-       if (tmp)
-         silc_say_error("%s: %s", tmp,
-                        silc_get_status_message(status));
-       break;
-      } else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
-       /* Try to find the entry for the unknown client ID, since we
-          might have, and print the nickname of it for user. */
-       SilcUInt32 tmp_len;
-       unsigned char *tmp =
-         silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
-                                    2, &tmp_len);
-       if (tmp) {
-         SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len,
-                                                            NULL);
-         if (client_id) {
-           client_entry = silc_client_get_client_by_id(client, conn,
-                                                       client_id);
-           if (client_entry && client_entry->nickname)
-             silc_say_error("%s: %s", client_entry->nickname,
-                            silc_get_status_message(status));
-           silc_free(client_id);
-         }
-       }
-       break;
-      }
-
-      break;
-    }
-
   case SILC_COMMAND_WHOWAS:
     {
       char *nickname, *username, *realname;
 
       if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
-       char *tmp =
-         silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
-                                    2, NULL);
+       char *tmp = va_arg(vp, char *);
        if (tmp)
          silc_say_error("%s: %s", tmp,
                         silc_get_status_message(status));
        break;
-      } else if (!success) {
+      } else if (status != SILC_STATUS_OK) {
        silc_say_error("WHOWAS: %s", silc_get_status_message(status));
        return;
       }
@@ -1874,51 +1614,40 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
   case SILC_COMMAND_INVITE:
     {
       SilcChannelEntry channel;
-      SilcBuffer payload;
       SilcArgumentPayload invite_list;
-      SilcUInt16 argc;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       channel = va_arg(vp, SilcChannelEntry);
-      payload = va_arg(vp, SilcBuffer);
-
-      if (payload) {
-       SILC_GET16_MSB(argc, payload->data);
-       invite_list = silc_argument_payload_parse(payload->data + 2,
-                                                 payload->len - 2, argc);
-       if (invite_list) {
-         silc_parse_inviteban_list(client, conn, server, channel,
-                                   "invite", invite_list);
-         silc_argument_payload_free(invite_list);
-       }
-      }
+      invite_list = va_arg(vp, SilcArgumentPayload);
+
+      if (invite_list)
+       silc_parse_inviteban_list(client, conn, server, channel,
+                                 "invite", invite_list);
     }
     break;
 
   case SILC_COMMAND_JOIN:
     {
-      char *channel, *mode, *topic;
+      char *channel, *mode, *topic, *cipher, *hmac;
       SilcUInt32 modei;
+      SilcHashTableList *user_list;
       SilcChannelEntry channel_entry;
-      SilcBuffer client_id_list;
-      SilcUInt32 list_count;
+      SilcChannelUser chu;
+      SilcClientEntry founder = NULL;
+      NICK_REC *ownnick;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       channel = va_arg(vp, char *);
       channel_entry = va_arg(vp, SilcChannelEntry);
       modei = va_arg(vp, SilcUInt32);
-      (void)va_arg(vp, SilcUInt32);
-      (void)va_arg(vp, unsigned char *);
-      (void)va_arg(vp, unsigned char *);
-      (void)va_arg(vp, unsigned char *);
+      user_list = va_arg(vp, SilcHashTableList *);
       topic = va_arg(vp, char *);
-      (void)va_arg(vp, unsigned char *);
-      list_count = va_arg(vp, SilcUInt32);
-      client_id_list = va_arg(vp, SilcBuffer);
+      cipher = va_arg(vp, char *);
+      hmac = va_arg(vp, char *);
 
       chanrec = silc_channel_find(server, channel);
       if (!chanrec)
@@ -1947,23 +1676,43 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        silc_free(dm);
       }
 
-      mode = silc_client_chmode(modei,
-                               channel_entry->channel_key ?
-                               silc_cipher_get_name(channel_entry->
-                                                    channel_key) : "",
-                               channel_entry->hmac ?
-                               silc_hmac_get_name(channel_entry->hmac) : "");
+      mode = silc_client_chmode(modei, cipher ? cipher : "", hmac ? hmac : "");
       g_free_not_null(chanrec->mode);
       chanrec->mode = g_strdup(mode == NULL ? "" : mode);
       signal_emit("channel mode changed", 1, chanrec);
 
-      /* Resolve the client information */
-      {
-       SilcJoinResolve r = silc_calloc(1, sizeof(*r));
-       r->channel = channel_entry;
-       silc_client_get_clients_by_list(client, conn, list_count,
-                                       client_id_list,
-                                       silc_client_join_get_users, r);
+      /* Get user list */
+      while (silc_hash_table_get(user_list, NULL, (void *)&chu)) {
+       if (!chu->client->nickname)
+         continue;
+       if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)
+         founder = chu->client;
+       silc_nicklist_insert(chanrec, chu, FALSE);
+      }
+
+      ownnick = NICK(silc_nicklist_find(chanrec, conn->local_entry));
+      nicklist_set_own(CHANNEL(chanrec), ownnick);
+      signal_emit("channel joined", 1, chanrec);
+      chanrec->entry = channel_entry;
+
+      if (chanrec->topic)
+       printformat_module("fe-common/silc", server,
+                          channel_entry->channel_name,
+                          MSGLEVEL_CRAP, SILCTXT_CHANNEL_TOPIC,
+                          channel_entry->channel_name, chanrec->topic);
+
+      if (founder) {
+       if (founder == conn->local_entry) {
+         printformat_module("fe-common/silc",
+                            server, channel_entry->channel_name,
+                            MSGLEVEL_CRAP, SILCTXT_CHANNEL_FOUNDER_YOU,
+                            channel_entry->channel_name);
+         signal_emit("nick mode changed", 2, chanrec, ownnick);
+       } else
+         printformat_module("fe-common/silc",
+                            server, channel_entry->channel_name,
+                            MSGLEVEL_CRAP, SILCTXT_CHANNEL_FOUNDER,
+                            channel_entry->channel_name, founder->nickname);
       }
 
       break;
@@ -1975,7 +1724,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       SilcClientEntry client_entry = va_arg(vp, SilcClientEntry);
       GSList *nicks;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       nicks = nicklist_get_same(SERVER(server), client_entry->nickname);
@@ -1985,11 +1734,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        SilcClientEntry collider, old;
 
        old = ((SILC_NICK_REC *)(nicks->next->data))->silc_user->client;
-       collider = silc_client_get_client_by_id(client, conn,
-                                               old->id);
-
+       collider = silc_client_get_client_by_id(client, conn, &old->id);
        if (collider != client_entry) {
-
           memset(buf, 0, sizeof(buf));
           snprintf(buf, sizeof(buf) - 1, "%s@%s",
                   collider->username, collider->hostname);
@@ -1999,6 +1745,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
          silc_print_nick_change(server, collider->nickname,
                                 client_entry->nickname, buf);
        }
+       silc_client_unref_client(client, conn, collider);
       }
 
       if (nicks != NULL)
@@ -2026,7 +1773,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       char users[20];
       char tmp[256], *cp, *dm = NULL;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       (void)va_arg(vp, SilcChannelEntry);
@@ -2071,7 +1818,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       SilcUInt32 mode;
       char *reason;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       mode = va_arg(vp, SilcUInt32);
@@ -2106,7 +1853,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
     break;
 
   case SILC_COMMAND_OPER:
-    if (!success)
+    if (status != SILC_STATUS_OK)
       return;
 
     server->umode |= SILC_UMODE_SERVER_OPERATOR;
@@ -2117,7 +1864,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
     break;
 
   case SILC_COMMAND_SILCOPER:
-    if (!success)
+    if (status != SILC_STATUS_OK)
       return;
 
     server->umode |= SILC_UMODE_ROUTER_OPERATOR;
@@ -2133,7 +1880,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       SilcChannelEntry channel;
       SilcChannelUser chu;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       channel = va_arg(vp, SilcChannelEntry);
@@ -2187,26 +1934,17 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
   case SILC_COMMAND_BAN:
     {
       SilcChannelEntry channel;
-      SilcBuffer payload;
-      SilcArgumentPayload ban_list;
-      SilcUInt16 argc;
+      SilcArgumentPayload invite_list;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       channel = va_arg(vp, SilcChannelEntry);
-      payload = va_arg(vp, SilcBuffer);
-
-      if (payload) {
-       SILC_GET16_MSB(argc, payload->data);
-       ban_list = silc_argument_payload_parse(payload->data + 2,
-                                              payload->len - 2, argc);
-       if (ban_list) {
-         silc_parse_inviteban_list(client, conn, server, channel,
-                                   "ban", ban_list);
-         silc_argument_payload_free(ban_list);
-       }
-      }
+      invite_list = va_arg(vp, SilcArgumentPayload);
+
+      if (invite_list)
+       silc_parse_inviteban_list(client, conn, server, channel,
+                                 "ban", invite_list);
     }
     break;
 
@@ -2215,12 +1953,10 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       SilcIdType id_type;
       void *entry;
       SilcPublicKey public_key;
-      unsigned char *pk;
-      SilcUInt32 pk_len;
       GetkeyContext getkey;
       char *name;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       id_type = va_arg(vp, SilcUInt32);
@@ -2228,14 +1964,11 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       public_key = va_arg(vp, SilcPublicKey);
 
       if (public_key) {
-       pk = silc_pkcs_public_key_encode(public_key, &pk_len);
-
        getkey = silc_calloc(1, sizeof(*getkey));
        getkey->entry = entry;
        getkey->id_type = id_type;
        getkey->client = client;
        getkey->conn = conn;
-       getkey->fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
 
        name = (id_type == SILC_ID_CLIENT ?
                ((SilcClientEntry)entry)->nickname :
@@ -2243,11 +1976,9 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
 
        silc_verify_public_key_internal(client, conn, name,
                                        (id_type == SILC_ID_CLIENT ?
-                                        SILC_SOCKET_TYPE_CLIENT :
-                                        SILC_SOCKET_TYPE_SERVER),
-                                       pk, pk_len, SILC_SKE_PK_TYPE_SILC,
-                                       silc_getkey_cb, getkey);
-       silc_free(pk);
+                                        SILC_CONN_CLIENT :
+                                        SILC_CONN_SERVER),
+                                       public_key, silc_getkey_cb, getkey);
       } else {
        printformat_module("fe-common/silc", server, NULL,
                           MSGLEVEL_CRAP, SILCTXT_PUBKEY_NOKEY);
@@ -2261,7 +1992,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       char *server_name;
       char *server_info;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       server_entry = va_arg(vp, SilcServerEntry);
@@ -2282,7 +2013,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       char *topic;
       char tmp[256], *cp, *dm = NULL;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       channel = va_arg(vp, SilcChannelEntry);
@@ -2336,7 +2067,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       const char *tmptime;
       int days, hours, mins, secs;
 
-      if (!success)
+      if (status != SILC_STATUS_OK)
        return;
 
       tmp_buf = va_arg(vp, unsigned char *);
@@ -2367,7 +2098,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
                           SILC_STR_UI_INT(&router_ops),
                           SILC_STR_END);
 
-      tmptime = silc_get_time(starttime);
+      tmptime = silc_time_string(starttime);
       printformat_module("fe-common/silc", server, NULL,
                         MSGLEVEL_CRAP, SILCTXT_STATS,
                         "Local server start time", tmptime);
@@ -2455,20 +2186,20 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
   case SILC_COMMAND_CMODE:
     {
       SilcChannelEntry channel_entry;
-      SilcBuffer channel_pubkeys;
+      SilcDList chpks;
 
       channel_entry = va_arg(vp, SilcChannelEntry);
       (void)va_arg(vp, SilcUInt32);
       (void)va_arg(vp, SilcPublicKey);
-      channel_pubkeys = va_arg(vp, SilcBuffer);
+      chpks = va_arg(vp, SilcDList);
 
-      if (!success || !cmode_list_chpks ||
+      if (status != SILC_STATUS_OK || !cmode_list_chpks ||
          !channel_entry || !channel_entry->channel_name)
        return;
 
       /* Print the channel public key list */
-      if (channel_pubkeys)
-        silc_parse_channel_public_keys(server, channel_entry, channel_pubkeys);
+      if (chpks)
+        silc_parse_channel_public_keys(server, channel_entry, chpks);
       else
         printformat_module("fe-common/silc", server, NULL,
                          MSGLEVEL_CRAP, SILCTXT_CHANNEL_PK_NO_LIST,
@@ -2485,8 +2216,6 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
     break;
 
   }
-
-  va_end(vp);
 }
 
 typedef struct {
@@ -2495,9 +2224,7 @@ typedef struct {
   char *filename;
   char *entity;
   char *entity_name;
-  unsigned char *pk;
-  SilcUInt32 pk_len;
-  SilcSKEPKType pk_type;
+  SilcPublicKey public_key;
   SilcVerifyPublicKey completion;
   void *context;
 } *PublicKeyVerify;
@@ -2512,8 +2239,8 @@ static void verify_public_key_completion(const char *line, void *context)
       verify->completion(TRUE, verify->context);
 
     /* Save the key for future checking */
-    silc_pkcs_save_public_key_data(verify->filename, verify->pk,
-                                  verify->pk_len, SILC_PKCS_FILE_PEM);
+    silc_pkcs_save_public_key(verify->filename, verify->public_key,
+                             SILC_PKCS_FILE_BASE64);
   } else {
     /* Call the completion */
     if (verify->completion)
@@ -2528,7 +2255,6 @@ static void verify_public_key_completion(const char *line, void *context)
   silc_free(verify->filename);
   silc_free(verify->entity);
   silc_free(verify->entity_name);
-  silc_free(verify->pk);
   silc_free(verify);
 }
 
@@ -2539,25 +2265,38 @@ static void verify_public_key_completion(const char *line, void *context)
 
 static void
 silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
-                               const char *name, SilcSocketType conn_type,
-                               unsigned char *pk, SilcUInt32 pk_len,
-                               SilcSKEPKType pk_type,
+                               const char *name,
+                               SilcConnectionType conn_type,
+                               SilcPublicKey public_key,
                                SilcVerifyPublicKey completion, void *context)
 {
-  int i;
+  PublicKeyVerify verify;
   char file[256], filename[256], filename2[256], *ipf, *hostf = NULL;
   char *fingerprint, *babbleprint, *format;
+  SilcPublicKey local_pubkey;
+  SilcUInt16 port;
+  const char *hostname, *ip;
+  unsigned char *pk;
+  SilcUInt32 pk_len;
   struct passwd *pw;
   struct stat st;
-  char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER ||
-                  conn_type == SILC_SOCKET_TYPE_ROUTER) ?
+  char *entity = ((conn_type == SILC_CONN_SERVER ||
+                  conn_type == SILC_CONN_ROUTER) ?
                  "server" : "client");
-  PublicKeyVerify verify;
+  int i;
 
-  if (pk_type != SILC_SKE_PK_TYPE_SILC) {
+  if (silc_pkcs_get_type(public_key) != SILC_PKCS_SILC) {
     printformat_module("fe-common/silc", NULL, NULL,
                       MSGLEVEL_CRAP, SILCTXT_PUBKEY_UNSUPPORTED,
-                      entity, pk_type);
+                      entity, silc_pkcs_get_type(public_key));
+    if (completion)
+      completion(FALSE, context);
+    return;
+  }
+
+  /* Encode public key */
+  pk = silc_pkcs_public_key_encode(public_key, &pk_len);
+  if (!pk) {
     if (completion)
       completion(FALSE, context);
     return;
@@ -2574,16 +2313,18 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
   memset(filename2, 0, sizeof(filename2));
   memset(file, 0, sizeof(file));
 
-  if (conn_type == SILC_SOCKET_TYPE_SERVER ||
-      conn_type == SILC_SOCKET_TYPE_ROUTER) {
+  /* Get remote host information */
+  silc_socket_stream_get_info(conn->stream, NULL, &hostname, &ip, &port);
+
+  if (conn_type == SILC_CONN_SERVER ||
+      conn_type == SILC_CONN_ROUTER) {
     if (!name) {
-      snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
-              conn->sock->ip, conn->sock->port);
+      snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, ip, port);
       snprintf(filename, sizeof(filename) - 1, "%s/%skeys/%s",
               get_irssi_dir(), entity, file);
 
       snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
-              conn->sock->hostname, conn->sock->port);
+              hostname, port);
       snprintf(filename2, sizeof(filename2) - 1, "%s/%skeys/%s",
               get_irssi_dir(), entity, file);
 
@@ -2591,7 +2332,7 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
       hostf = filename2;
     } else {
       snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
-              name, conn->sock->port);
+              name, port);
       snprintf(filename, sizeof(filename) - 1, "%s/%skeys/%s",
               get_irssi_dir(), entity, file);
 
@@ -2621,12 +2362,10 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
   verify->conn = conn;
   verify->filename = strdup(ipf);
   verify->entity = strdup(entity);
-  verify->entity_name = (conn_type != SILC_SOCKET_TYPE_CLIENT ?
-                        (name ? strdup(name) : strdup(conn->sock->hostname))
+  verify->entity_name = (conn_type != SILC_CONN_CLIENT ?
+                        (name ? strdup(name) : strdup(hostname))
                         : NULL);
-  verify->pk = silc_memdup(pk, pk_len);
-  verify->pk_len = pk_len;
-  verify->pk_type = pk_type;
+  verify->public_key = public_key;
   verify->completion = completion;
   verify->context = context;
 
@@ -2650,19 +2389,12 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
     return;
   } else {
     /* The key already exists, verify it. */
-    SilcPublicKey public_key;
     unsigned char *encpk;
     SilcUInt32 encpk_len;
 
     /* Load the key file, try for both IP filename and hostname filename */
-    if (!silc_pkcs_load_public_key(ipf, &public_key,
-                                  SILC_PKCS_FILE_PEM) &&
-       !silc_pkcs_load_public_key(ipf, &public_key,
-                                  SILC_PKCS_FILE_BIN) &&
-       (!hostf || (!silc_pkcs_load_public_key(hostf, &public_key,
-                                              SILC_PKCS_FILE_PEM) &&
-                   !silc_pkcs_load_public_key(hostf, &public_key,
-                                              SILC_PKCS_FILE_BIN)))) {
+    if (!silc_pkcs_load_public_key(ipf, &local_pubkey) &&
+       (!hostf || (!silc_pkcs_load_public_key(hostf, &local_pubkey)))) {
       printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
                         SILCTXT_PUBKEY_RECEIVED,verify->entity_name ?
                         verify->entity_name : entity);
@@ -2682,7 +2414,7 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
     }
 
     /* Encode the key data */
-    encpk = silc_pkcs_public_key_encode(public_key, &encpk_len);
+    encpk = silc_pkcs_public_key_encode(local_pubkey, &encpk_len);
     if (!encpk) {
       printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
                         SILCTXT_PUBKEY_RECEIVED,verify->entity_name ?
@@ -2725,17 +2457,18 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
                              format, 0, verify);
       g_free(format);
       silc_free(fingerprint);
+      silc_free(encpk);
       return;
     }
 
     /* Local copy matched */
     if (completion)
       completion(TRUE, context);
+    silc_free(encpk);
     silc_free(fingerprint);
     silc_free(verify->filename);
     silc_free(verify->entity);
     silc_free(verify->entity_name);
-    silc_free(verify->pk);
     silc_free(verify);
   }
 }
@@ -2747,12 +2480,11 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
 
 void
 silc_verify_public_key(SilcClient client, SilcClientConnection conn,
-                      SilcSocketType conn_type, unsigned char *pk,
-                      SilcUInt32 pk_len, SilcSKEPKType pk_type,
+                      SilcConnectionType conn_type,
+                      SilcPublicKey public_key,
                       SilcVerifyPublicKey completion, void *context)
 {
-  silc_verify_public_key_internal(client, conn, NULL, conn_type, pk,
-                                 pk_len, pk_type,
+  silc_verify_public_key_internal(client, conn, NULL, conn_type, public_key,
                                  completion, context);
 }
 
@@ -2856,62 +2588,11 @@ void silc_get_auth_method(SilcClient client, SilcClientConnection conn,
   internal->completion = completion;
   internal->context = context;
 
+#if 0
   silc_client_request_authentication_method(client, conn,
                                            silc_get_auth_method_callback,
                                            internal);
-}
-
-/* Notifies application that failure packet was received.  This is called
-   if there is some protocol active in the client.  The `protocol' is the
-   protocol context.  The `failure' is opaque pointer to the failure
-   indication.  Note, that the `failure' is protocol dependant and application
-   must explicitly cast it to correct type.  Usually `failure' is 32 bit
-   failure type (see protocol specs for all protocol failure types). */
-
-void silc_failure(SilcClient client, SilcClientConnection conn,
-                 SilcProtocol protocol, void *failure)
-{
-  SILC_LOG_DEBUG(("Start"));
-
-  if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
-    SilcSKEStatus status = (SilcSKEStatus)failure;
-
-    if (status == SILC_SKE_STATUS_BAD_VERSION)
-      printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
-                        SILCTXT_KE_BAD_VERSION);
-    if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY)
-      printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
-                        SILCTXT_KE_UNSUPPORTED_PUBLIC_KEY);
-    if (status == SILC_SKE_STATUS_UNKNOWN_GROUP)
-      printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
-                        SILCTXT_KE_UNKNOWN_GROUP);
-    if (status == SILC_SKE_STATUS_UNKNOWN_CIPHER)
-      printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
-                        SILCTXT_KE_UNKNOWN_CIPHER);
-    if (status == SILC_SKE_STATUS_UNKNOWN_PKCS)
-      printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
-                        SILCTXT_KE_UNKNOWN_PKCS);
-    if (status == SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION)
-      printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
-                        SILCTXT_KE_UNKNOWN_HASH_FUNCTION);
-    if (status == SILC_SKE_STATUS_UNKNOWN_HMAC)
-      printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
-                        SILCTXT_KE_UNKNOWN_HMAC);
-    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) {
-    SilcUInt32 err = (SilcUInt32)failure;
-
-    if (err == SILC_AUTH_FAILED)
-      printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
-                        SILCTXT_AUTH_FAILED);
-  }
+#endif
 }
 
 /* Asks whether the user would like to perform the key agreement protocol.
@@ -3030,6 +2711,13 @@ silc_detach(SilcClient client, SilcClientConnection conn,
   silc_free(file);
 }
 
+/* Called to indicate the client library is running. */
+
+static void
+silc_running(SilcClient client, void *application)
+{
+  SILC_LOG_DEBUG(("Client library is running"));
+}
 
 /* SILC client operations */
 SilcClientOperations ops = {
@@ -3039,13 +2727,11 @@ SilcClientOperations ops = {
   silc_notify,
   silc_command,
   silc_command_reply,
-  silc_connect,
-  silc_disconnect,
   silc_get_auth_method,
   silc_verify_public_key,
   silc_ask_passphrase,
-  silc_failure,
   silc_key_agreement,
   silc_ftp,
   silc_detach,
+  silc_running,
 };
index d9c181822a50034fa1731a333c3a4d07ff2ecaf0..0e9b9b10eeddaaaa8602f9e197e04b69862465f5 100644 (file)
@@ -2,9 +2,9 @@
 
   client_ops.h
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 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
@@ -43,26 +43,20 @@ void silc_private_message(SilcClient client, SilcClientConnection conn,
 void silc_notify(SilcClient client, SilcClientConnection conn,
                 SilcNotifyType type, ...);
 void silc_command(SilcClient client, SilcClientConnection conn,
-                 SilcClientCommandContext cmd_context, bool success,
-                 SilcCommand command, SilcStatus status);
+                 SilcBool success, SilcCommand command, SilcStatus status,
+                 SilcUInt32 argc, unsigned char **argv);
 void silc_command_reply(SilcClient client, SilcClientConnection conn,
-                       SilcCommandPayload cmd_payload, bool success,
-                       SilcCommand command, SilcStatus status, ...);
-void silc_connect(SilcClient client, SilcClientConnection conn,
-                 SilcClientConnectionStatus status);
-void silc_disconnect(SilcClient client, SilcClientConnection conn,
-                    SilcStatus status, const char *message);
+                       SilcCommand command, SilcStatus status,
+                       SilcStatus error, va_list ap);
 void silc_ask_passphrase(SilcClient client, SilcClientConnection conn,
                         SilcAskPassphrase completion, void *context);
 void silc_verify_public_key(SilcClient client, SilcClientConnection conn,
-                           SilcSocketType conn_type, unsigned char *pk,
-                           SilcUInt32 pk_len, SilcSKEPKType pk_type,
+                           SilcConnectionType conn_type,
+                           SilcPublicKey publi_key,
                            SilcVerifyPublicKey completion, void *context);
 void silc_get_auth_method(SilcClient client, SilcClientConnection conn,
                          char *hostname, SilcUInt16 port,
                          SilcGetAuthMeth completion, void *context);
-void silc_failure(SilcClient client, SilcClientConnection conn,
-                 SilcProtocol protocol, void *failure);
 bool silc_key_agreement(SilcClient client, SilcClientConnection conn,
                        SilcClientEntry client_entry, const char *hostname,
                        SilcUInt16 port, SilcKeyAgreementCallback *completion,
index 7118e5ccaf086509f2746eb3765abe064028dae4..4ebf2e9d2e61092af3db2882b3decddb39a054af 100644 (file)
@@ -4,12 +4,12 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2002 Pekka Riikonen
+  Copyright (C) 1997 - 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
   the Free Software Foundation; version 2 of the License.
-  
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -80,10 +80,10 @@ void silc_client_list_pkcs()
   silc_free(pkcs);
 }
 
-/* This checks stats for various SILC files and directories. First it 
-   checks if ~/.silc directory exist and is owned by the correct user. If 
+/* This checks stats for various SILC files and directories. First it
+   checks if ~/.silc directory exist and is owned by the correct user. If
    it doesn't exist, it will create the directory. After that it checks if
-   user's Public and Private key files exists. If they doesn't exist they 
+   user's Public and Private key files exists. If they doesn't exist they
    will be created after return. */
 
 int silc_client_check_silc_dir()
@@ -107,11 +107,11 @@ int silc_client_check_silc_dir()
 
   /* We'll take home path from /etc/passwd file to be sure. */
   snprintf(filename, sizeof(filename) - 1, "%s/", get_irssi_dir());
-  snprintf(servfilename, sizeof(servfilename) - 1, "%s/serverkeys", 
+  snprintf(servfilename, sizeof(servfilename) - 1, "%s/serverkeys",
           get_irssi_dir());
-  snprintf(clientfilename, sizeof(clientfilename) - 1, "%s/clientkeys", 
+  snprintf(clientfilename, sizeof(clientfilename) - 1, "%s/clientkeys",
           get_irssi_dir());
-  snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s/friends", 
+  snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s/friends",
           get_irssi_dir());
 
   /*
@@ -135,19 +135,19 @@ int silc_client_check_silc_dir()
       return FALSE;
     }
   } else {
-    
+
     /* Check the owner of the dir */
-    if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { 
+    if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
       fprintf(stderr, "You don't seem to own `%s' directory\n",
              filename);
       return FALSE;
     }
-    
+
 #if 0
     /* Check the permissions of the dir */
     if ((st.st_mode & 0777) != 0755) {
       if ((chmod(filename, 0755)) == -1) {
-       fprintf(stderr, "Permissions for `%s' directory must be 0755\n", 
+       fprintf(stderr, "Permissions for `%s' directory must be 0755\n",
                filename);
        return FALSE;
       }
@@ -176,7 +176,7 @@ int silc_client_check_silc_dir()
       return FALSE;
     }
   }
-  
+
   /*
    * Check ~./silc/clientkeys directory
    */
@@ -198,7 +198,7 @@ int silc_client_check_silc_dir()
       return FALSE;
     }
   }
-  
+
   /*
    * Check ~./silc/friends directory
    */
@@ -220,22 +220,22 @@ int silc_client_check_silc_dir()
       return FALSE;
     }
   }
-  
+
   /*
    * Check Public and Private keys
    */
-  snprintf(file_public_key, sizeof(file_public_key) - 1, "%s%s", 
+  snprintf(file_public_key, sizeof(file_public_key) - 1, "%s%s",
           filename, SILC_CLIENT_PUBLIC_KEY_NAME);
-  snprintf(file_private_key, sizeof(file_private_key) - 1, "%s%s", 
+  snprintf(file_private_key, sizeof(file_private_key) - 1, "%s%s",
           filename, SILC_CLIENT_PRIVATE_KEY_NAME);
-  
+
   if ((stat(file_public_key, &st)) == -1) {
     /* If file doesn't exist */
     if (errno == ENOENT) {
       fprintf(stdout, "Running SILC for the first time\n");
       silc_create_key_pair(SILC_CLIENT_DEF_PKCS,
                           SILC_CLIENT_DEF_PKCS_LEN,
-                          file_public_key, file_private_key, NULL,
+                          file_public_key, file_private_key,
                           NULL, NULL, NULL, NULL, FALSE);
       printf("Press <Enter> to continue...\n");
       getchar();
@@ -244,20 +244,20 @@ int silc_client_check_silc_dir()
       return FALSE;
     }
   }
-  
+
   /* Check the owner of the public key */
-  if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { 
+  if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
     fprintf(stderr, "You don't seem to own your public key!?\n");
     return FALSE;
   }
-  
+
   if ((stat(file_private_key, &st)) == -1) {
     /* If file doesn't exist */
     if (errno == ENOENT) {
       fprintf(stdout, "Your private key doesn't exist\n");
       silc_create_key_pair(SILC_CLIENT_DEF_PKCS,
                           SILC_CLIENT_DEF_PKCS_LEN,
-                          file_public_key, file_private_key, NULL,
+                          file_public_key, file_private_key,
                           NULL, NULL, NULL, NULL, FALSE);
       printf("Press <Enter> to continue...\n");
       getchar();
@@ -266,20 +266,20 @@ int silc_client_check_silc_dir()
       return FALSE;
     }
   }
-    
+
   /* Check the owner of the private key */
-  if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { 
+  if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
     fprintf(stderr, "You don't seem to own your private key!?\n");
     return FALSE;
   }
-    
+
   /* Check the permissions for the private key */
   if ((st.st_mode & 0777) != 0600) {
     fprintf(stderr, "Wrong permissions in your private key file `%s'!\n"
            "Trying to change them ... ", file_private_key);
     if ((chmod(file_private_key, 0600)) == -1) {
       fprintf(stderr,
-             "Failed to change permissions for private key file!\n" 
+             "Failed to change permissions for private key file!\n"
              "Permissions for your private key file must be 0600.\n");
       return FALSE;
     }
@@ -310,14 +310,13 @@ int silc_client_load_keys(SilcClient client)
   memset(pub, 0, sizeof(pub));
   snprintf(pub, sizeof(pub) - 1, "%s/%s",
           get_irssi_dir(), SILC_CLIENT_PUBLIC_KEY_NAME);
-  
+
   /* Try loading first with "" passphrase, for those that didn't set
      passphrase for private key, and only if that fails let it prompt
      for passphrase. */
-  ret = silc_load_key_pair(pub, prv, "", &client->pkcs, &client->public_key,
-                          &client->private_key);
+  ret = silc_load_key_pair(pub, prv, "", &irssi_pubkey, &irssi_privkey);
   if (!ret)
-    ret = silc_load_key_pair(pub, prv, NULL, &client->pkcs,
-                            &client->public_key, &client->private_key);
+    ret = silc_load_key_pair(pub, prv, NULL, &irssi_pubkey, &irssi_privkey);
+
   return ret;
 }
index 4cebee3001a4027fce5aa27c6bfc06ad9cbf1a3b..39db46a9691c914d6b4a55f156d461b68d8631bf 100644 (file)
@@ -4,7 +4,7 @@
 
 #undef PACKAGE
 #undef VERSION
-#include "silcincludes.h"
+#include "silc.h"
 #include "silcclient.h"
 #include "client_ops.h"
 #include "silc-core.h"
index 9c8028b56393a761eeb467bd84688cecc5b3c090..1bd719518c0851eec3fcadaf7f82688c04cf72a8 100644 (file)
@@ -1,8 +1,8 @@
 /*
   silc-channels.c : irssi
 
-  Copyright (C) 2000 - 2001, 2004 Timo Sirainen
-                            Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Copyright (C) 2000 - 2001, 2004, 2006 Timo Sirainen
+                Pekka Riikonen <priikone@silcnet.org>
 
   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-commands.h"
 
 void sig_mime(SILC_SERVER_REC *server, SILC_CHANNEL_REC *channel,
-               const char *blob, const char *nick, int verified)
+             const char *blob, const char *nick, int verified)
 {
-  char type[128], enc[128];
-  unsigned char *data, *message;
-  SilcUInt32 data_len, message_len;
+  unsigned char *message;
+  SilcUInt32 message_len;
+  SilcMime mime;
 
   if (!(IS_SILC_SERVER(server)))
     return;
 
   message = silc_unescape_data(blob, &message_len);
 
-  memset(type, 0, sizeof(type));
-  memset(enc, 0, sizeof(enc));
-
-  if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1,
-                enc, sizeof(enc) - 1, &data, &data_len)) {
+  mime = silc_mime_decode(NULL, message, message_len);
+  if (!mime) {
     silc_free(message);
     return;
   }
 
   printformat_module("fe-common/silc", server,
-                      channel == NULL ? NULL : channel->name,
-                      MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
-                      nick == NULL ? "[<unknown>]" : nick, type);
+                    channel == NULL ? NULL : channel->name,
+                    MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
+                    nick == NULL ? "[<unknown>]" : nick,
+                    silc_mime_get_field(mime, "Content-Type"));
 
   silc_free(message);
-
+  silc_mime_free(mime);
 }
 
 SILC_CHANNEL_REC *silc_channel_create(SILC_SERVER_REC *server,
@@ -138,7 +136,7 @@ static void sig_connected(SILC_SERVER_REC *server)
 
 static void sig_server_quit(SILC_SERVER_REC *server, const char *msg)
 {
-  if (IS_SILC_SERVER(server) && server->conn && server->conn->sock)
+  if (IS_SILC_SERVER(server) && server->conn)
     silc_command_exec(server, "QUIT", msg);
 }
 
@@ -523,6 +521,7 @@ static void keyagr_completion(SilcClient client,
     silc_free(i);
 }
 
+#if 0
 /* Local command KEY. This command is used to set and unset private
    keys for channels, set and unset private keys for private messages
    with remote clients and to send key agreement requests and
@@ -1112,7 +1111,6 @@ void silc_list_key(const char *pub_filename, int verbose)
 
 }
 
-
 void silc_list_keys_in_dir(const char *dirname, const char *where)
 {
   DIR *dir;
@@ -1173,6 +1171,7 @@ list_key:
   silc_list_key(path, TRUE);
 
 }
+#endif /* 0 */
 
 /* Lists locally saved client and server public keys. */
 static void command_listkeys(const char *data, SILC_SERVER_REC *server,
@@ -1227,8 +1226,8 @@ void silc_channels_init(void)
   command_bind_silc("action", MODULE_NAME, (SIGNAL_FUNC) command_action);
   command_bind_silc("notice", MODULE_NAME, (SIGNAL_FUNC) command_notice);
   command_bind_silc("away", MODULE_NAME, (SIGNAL_FUNC) command_away);
-  command_bind_silc("key", MODULE_NAME, (SIGNAL_FUNC) command_key);
-  command_bind("listkeys", MODULE_NAME, (SIGNAL_FUNC) command_listkeys);
+  //  command_bind_silc("key", MODULE_NAME, (SIGNAL_FUNC) command_key);
+  //  command_bind("listkeys", MODULE_NAME, (SIGNAL_FUNC) command_listkeys);
 
   command_set_options("listkeys", "clients servers");
   command_set_options("action", "sign channel");
@@ -1250,8 +1249,8 @@ void silc_channels_deinit(void)
   command_unbind("action", (SIGNAL_FUNC) command_action);
   command_unbind("notice", (SIGNAL_FUNC) command_notice);
   command_unbind("away", (SIGNAL_FUNC) command_away);
-  command_unbind("key", (SIGNAL_FUNC) command_key);
-  command_unbind("listkeys", (SIGNAL_FUNC) command_listkeys);
+  //  command_unbind("key", (SIGNAL_FUNC) command_key);
+  //  command_unbind("listkeys", (SIGNAL_FUNC) command_listkeys);
 
   silc_nicklist_deinit();
 }
index 2e9092d729f7a7fdc4dbcbfe69ee0311588c37f0..503b50816b909d7bd9b5d803409bde00ba4749b8 100644 (file)
@@ -67,8 +67,8 @@ void silc_queue_disable(SilcClientConnection conn)
 }
 
 bool silc_queue_command_call(SilcClient client,
-                       SilcClientConnection conn,
-                       const char *command_line, ...)
+                            SilcClientConnection conn,
+                            const char *command_line, ...)
 {
   va_list ap;
   char *cmd = (char *) command_line;
@@ -143,6 +143,7 @@ bool silc_queue_command_call(SilcClient client,
   return TRUE;
 }
 
-bool silc_queue_get_state(SilcClientConnection conn) {
+bool silc_queue_get_state(SilcClientConnection conn)
+{
   return g_hash_table_lookup(cmd_queues, conn) != NULL;
 }
index 47c927b4baffa668ba048daced079a36ab00742e..0aaef409d662635a2903ac583b540ab27ea60001 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,17 @@ static int opt_bits = 0;
 
 static int idletag = -1;
 
+/* SILC Client */
 SilcClient silc_client = NULL;
 extern SilcClientOperations ops;
 
+/* Our keypair */
+SilcPublicKey irssi_pubkey;
+SilcPrivateKey irssi_privkey;
+
+/* Default hash function */
+SilcHash sha1hash;
+
 void silc_expandos_init(void);
 void silc_expandos_deinit(void);
 
@@ -91,8 +99,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");
@@ -130,9 +138,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 */
@@ -188,7 +196,7 @@ static bool silc_log_misc(SilcLogType type, char *message, void *context)
 static void silc_nickname_format_parse(const char *nickname,
                                       char **ret_nickname)
 {
-  silc_parse_userfqdn(nickname, ret_nickname, NULL);
+  silc_parse_userfqdn(nickname, *ret_nickname, 128 + 1, NULL, 0);
 }
 
 static void silc_register_cipher(SilcClient client, const char *cipher)
@@ -261,6 +269,7 @@ 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);
@@ -270,6 +279,7 @@ void silc_opt_callback(poptContext con,
     silc_free(silc_client->hostname);
     silc_client->hostname = g_strdup(arg);
   }
+#endif /* 0 */
 
   if (strcmp(opt->longName, "list-ciphers") == 0) {
     silc_cipher_register_default();
@@ -313,7 +323,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,7 +344,7 @@ 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);
   }
 }
@@ -350,7 +360,8 @@ static void sig_init_finished(void)
     exit(1);
 
   /* Initialize the SILC client */
-  if (!silc_client_init(silc_client))
+  if (!silc_client_init(silc_client, settings_get_str("user_name"),
+                       silc_net_localhost(), settings_get_str("real_name")))
     exit(1);
 
   /* register SILC scheduler */
@@ -454,12 +465,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);
@@ -519,11 +524,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);
 }
index 594c3ffe91cdeef96e7aad034ac2b5715b9b2c0d..0f38115715ac59f90b844f2994d5da18873b4d4c 100644 (file)
@@ -26,6 +26,9 @@
 #define SILC_CLIENT_DEF_PKCS_LEN 2048
 
 extern SilcClient silc_client;
+extern SilcHash sha1hash;
+extern SilcPublicKey irssi_pubkey;
+extern SilcPrivateKey irssi_privkey;
 
 #define IS_SILC_ITEM(rec) (IS_SILC_CHANNEL(rec) || IS_SILC_QUERY(rec))
 
index ba2d9b30ebbed5b1690a607f51bb9101cb45dd06..d04015339786a858ad8e20430756cb81c33da9cf 100644 (file)
@@ -5,11 +5,14 @@
 
 #include "silc-servers.h"
 
-#define        SILC_CLIENT_LAG_PING_ID 0x1337
-
 static int timeout_tag;
-static void lag_event_pong(SILC_SERVER_REC *server, 
-               SilcClientCommandReplyContext cmd);
+static SilcBool lag_event_pong(SilcClient client,
+                              SilcClientConnection conn,
+                              SilcCommand command,
+                              SilcStatus status,
+                              SilcStatus error,
+                              void *context,
+                              va_list ap);
 
 static void lag_get(SILC_SERVER_REC *server)
 {
@@ -17,33 +20,36 @@ static void lag_get(SILC_SERVER_REC *server)
        g_get_current_time(&server->lag_sent);
        server->lag_last_check = time(NULL);
 
-       /* register pending callback & send ping */
-       silc_client_command_pending(server->conn, SILC_COMMAND_PING,
-                       SILC_CLIENT_LAG_PING_ID,
-                       (SilcCommandCb)lag_event_pong, (void *)server);
-       idp = silc_id_payload_encode(server->conn->remote_id, SILC_ID_SERVER);
+       /* Send PING */
+       idp = silc_id_payload_encode(&server->conn->remote_id.u.server_id,
+                                    SILC_ID_SERVER);
        silc_client_command_send(silc_client, server->conn,
-                       SILC_COMMAND_PING, SILC_CLIENT_LAG_PING_ID,
-                       1, 1, idp->data, idp->len);
+                                SILC_COMMAND_PING, lag_event_pong, server,
+                                1, 1, silc_buffer_data(idp),
+                                silc_buffer_len(idp));
        silc_buffer_free(idp);
 }
 
-static void lag_event_pong(SILC_SERVER_REC *server,
-                          SilcClientCommandReplyContext cmd)
+static SilcBool lag_event_pong(SilcClient client,
+                              SilcClientConnection conn,
+                              SilcCommand command,
+                              SilcStatus status,
+                              SilcStatus error,
+                              void *context,
+                              va_list ap)
 {
+       SILC_SERVER_REC *server = context;
        GTimeVal now;
 
-       if (cmd->error != SILC_STATUS_OK) {
-
+       if (status != SILC_STATUS_OK) {
                /* if the ping failed for some reason, try it again */
                lag_get(server);
-               return;
-
+               return TRUE;
        }
 
        if (server->lag_sent.tv_sec == 0) {
-               /* not expecting lag reply.. */
-               return;
+               /* not expecting lag reply. */
+               return TRUE;
        }
 
        g_get_current_time(&now);
@@ -51,6 +57,8 @@ static void lag_event_pong(SILC_SERVER_REC *server,
        memset(&server->lag_sent, 0, sizeof(server->lag_sent));
 
        signal_emit("server lag", 1, server);
+
+       return TRUE;
 }
 
 static int sig_check_lag(void)
@@ -95,7 +103,7 @@ void silc_lag_init(void)
 {
        /* silc-client will need those... silc-plugin uses irc defaults */
        settings_add_int("misc", "lag_check_time", 60);
-       settings_add_int("misc", "lag_max_before_disconnect", 300); 
+       settings_add_int("misc", "lag_max_before_disconnect", 300);
 
        timeout_tag = g_timeout_add(1000, (GSourceFunc) sig_check_lag, NULL);
 }
index 3da82845914b2b6947a61b4fd68561f34058483d..4a0516f74609b4b034774d21ce1004753f605762 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2002 Pekka Riikonen
+  Copyright (C) 2002 - 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
@@ -247,7 +247,7 @@ void silc_query_attributes_default(SilcClient client,
   const char *sv;
   SilcUInt32 tmp_len, mask;
   SilcAttributeObjService service;
-  SilcAttributeObjMime mime;
+  SilcMime mime;
   SilcAttributeObjGeo geo;
   SilcAttributeObjDevice dev;
   SilcAttributeObjPk pk;
@@ -255,7 +255,6 @@ void silc_query_attributes_default(SilcClient client,
   bool allowed;
 
   memset(&service, 0, sizeof(service));
-  memset(&mime, 0, sizeof(mime));
   memset(&geo, 0, sizeof(geo));
   memset(&dev, 0, sizeof(dev));
   memset(&pk, 0, sizeof(pk));
@@ -387,12 +386,11 @@ void silc_query_attributes_default(SilcClient client,
                              SILC_ATTRIBUTE_STATUS_MESSAGE, NULL);
     tmp = silc_file_readfile(sv, &tmp_len);
     if (tmp) {
-      tmp[tmp_len] = 0;
-      mime.mime = (const unsigned char *)tmp;
-      mime.mime_len = tmp_len;
-      silc_client_attribute_add(silc_client, conn,
-                               SILC_ATTRIBUTE_STATUS_MESSAGE, &mime,
-                               sizeof(mime));
+      mime = silc_mime_decode(NULL, tmp, tmp_len);
+      if (mime)
+       silc_client_attribute_add(silc_client, conn,
+                                 SILC_ATTRIBUTE_STATUS_MESSAGE, mime,
+                                 sizeof(*mime));
     }
     silc_free(tmp);
   }
@@ -555,9 +553,10 @@ typedef struct {
   SILC_SERVER_REC *server;
   char *name;
   SilcAttributeObjPk userpk;
+  SilcPublicKey public_key;
   SilcVCardStruct vcard;
-  SilcAttributeObjMime message;
-  SilcAttributeObjMime extension;
+  SilcMime message;
+  SilcMime extension;
   bool nopk;
 } *AttrVerify;
 
@@ -666,8 +665,11 @@ void silc_query_attributes_print(SILC_SERVER_REC *server,
 
     case SILC_ATTRIBUTE_STATUS_MESSAGE:
       {
-       if (!silc_attribute_get_object(attr, (void *)&verify->message,
-                                      sizeof(verify->message)))
+       verify->message = silc_mime_alloc();
+       if (!verify->message)
+         continue;
+       if (!silc_attribute_get_object(attr, (void *)verify->message,
+                                      sizeof(*verify->message)))
          continue;
        printformat_module("fe-common/silc", server, NULL,
                           MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MESSAGE,
@@ -722,8 +724,11 @@ void silc_query_attributes_print(SILC_SERVER_REC *server,
 
     case SILC_ATTRIBUTE_EXTENSION:
       {
-       if (!silc_attribute_get_object(attr, (void *)&verify->extension,
-                                      sizeof(verify->extension)))
+       verify->extension = silc_mime_alloc();
+       if (!verify->extension)
+         continue;
+       if (!silc_attribute_get_object(attr, (void *)verify->extension,
+                                      sizeof(*verify->extension)))
          continue;
        printformat_module("fe-common/silc", server, NULL,
                           MSGLEVEL_CRAP, SILCTXT_ATTR_EXTENSION,
@@ -816,72 +821,91 @@ void silc_query_attributes_print(SILC_SERVER_REC *server,
 
   /* Handle the signature verifications and public key verifying here */
 
-  if (usersign.data && !strcmp(verify->userpk.type, "silc-rsa")) {
+  if (usersign.data) {
     /* Verify the signature now */
     SilcPublicKey public_key;
-    SilcPKCS pkcs;
+    SilcPKCSType type = 0;
     unsigned char *verifyd;
     SilcUInt32 verify_len;
 
-    if (silc_pkcs_public_key_decode(verify->userpk.data,
-                                   verify->userpk.data_len,
-                                   &public_key)) {
-      silc_pkcs_alloc("rsa", &pkcs);
+    if (!strcmp(verify->userpk.type, "silc-rsa"))
+      type = SILC_PKCS_SILC;
+    else if (!strcmp(verify->userpk.type, "ssh-rsa"))
+      type = SILC_PKCS_SSH2;
+    else if (!strcmp(verify->userpk.type, "x509v3-sign-rsa"))
+      type = SILC_PKCS_X509V3;
+    else if (!strcmp(verify->userpk.type, "pgp-sign-rsa"))
+      type = SILC_PKCS_OPENPGP;
+
+    if (silc_pkcs_public_key_alloc(type, verify->userpk.data,
+                                  verify->userpk.data_len,
+                                  &verify->public_key)) {
       verifyd = silc_attribute_get_verify_data(attrs, FALSE, &verify_len);
-      if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)){
-       if (silc_pkcs_verify_with_hash(pkcs, client->sha1hash,
-                                      usersign.data,
-                                      usersign.data_len,
-                                      verifyd, verify_len)) {
-         printformat_module("fe-common/silc", server, NULL,
-                            MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_VERIFIED);
-       } else {
-         printformat_module("fe-common/silc", server, NULL,
-                            MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_FAILED);
-       }
+      if (verifyd && silc_pkcs_verify(verify->public_key,
+                                     usersign.data,
+                                     usersign.data_len,
+                                     verifyd, verify_len,
+                                     sha1hash)) {
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_VERIFIED);
+      } else {
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_FAILED);
       }
 
-      silc_pkcs_public_key_free(public_key);
       silc_free(verifyd);
+    } else {
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_FAILED);
     }
   } else {
     printformat_module("fe-common/silc", server, NULL,
                       MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_NOT_PRESENT);
   }
 
-  if (serversign.data && !strcmp(serverpk.type, "silc-rsa")) {
+  if (serversign.data) {
     /* Verify the signature now */
     SilcPublicKey public_key;
-    SilcPKCS pkcs;
+    SilcPKCSType type = 0;
     unsigned char *verifyd;
     SilcUInt32 verify_len;
 
-    if (silc_pkcs_public_key_decode(serverpk.data, serverpk.data_len,
-                                   &public_key)) {
-      silc_pkcs_alloc("rsa", &pkcs);
+    if (!strcmp(verify->userpk.type, "silc-rsa"))
+      type = SILC_PKCS_SILC;
+    else if (!strcmp(verify->userpk.type, "ssh-rsa"))
+      type = SILC_PKCS_SSH2;
+    else if (!strcmp(verify->userpk.type, "x509v3-sign-rsa"))
+      type = SILC_PKCS_X509V3;
+    else if (!strcmp(verify->userpk.type, "pgp-sign-rsa"))
+      type = SILC_PKCS_OPENPGP;
+
+    if (silc_pkcs_public_key_alloc(type, serverpk.data,
+                                  serverpk.data_len,
+                                  &public_key)) {
       verifyd = silc_attribute_get_verify_data(attrs, TRUE, &verify_len);
-      if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)) {
-       if (silc_pkcs_verify_with_hash(pkcs, client->sha1hash,
-                                      serversign.data,
-                                      serversign.data_len,
-                                      verifyd, verify_len)) {
-         printformat_module("fe-common/silc", server, NULL,
-                            MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_VERIFIED);
-       } else {
-         printformat_module("fe-common/silc", server, NULL,
-                            MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_FAILED);
-       }
+      if (verifyd && silc_pkcs_verify(public_key,
+                                     serversign.data,
+                                     serversign.data_len,
+                                     verifyd, verify_len,
+                                     sha1hash)) {
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_VERIFIED);
+      } else {
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_FAILED);
       }
 
       silc_pkcs_public_key_free(public_key);
       silc_free(verifyd);
+    } else {
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_FAILED);
     }
   }
 
   if (verify->userpk.data) {
-    silc_verify_public_key(client, conn, SILC_SOCKET_TYPE_CLIENT,
-                          verify->userpk.data, verify->userpk.data_len,
-                          SILC_SKE_PK_TYPE_SILC,
+    silc_verify_public_key(client, conn, SILC_CONN_CLIENT,
+                          verify->public_key,
                           silc_query_attributes_print_final, verify);
   } else {
     verify->nopk = TRUE;
@@ -915,7 +939,7 @@ static void silc_query_attributes_print_final(bool success, void *context)
                     MSGLEVEL_CRAP, SILCTXT_ATTR_FOOTER);
 
   /* Replace all whitespaces with `_'. */
-  fingerprint = silc_hash_fingerprint(client->sha1hash,
+  fingerprint = silc_hash_fingerprint(sha1hash,
                                      verify->userpk.data,
                                      verify->userpk.data_len);
   for (i = 0; i < strlen(fingerprint); i++)
@@ -963,7 +987,7 @@ static void silc_query_attributes_accept(const char *line, void *context)
       goto out;
 
     /* Replace all whitespaces with `_'. */
-    fingerprint = silc_hash_fingerprint(client->sha1hash,
+    fingerprint = silc_hash_fingerprint(sha1hash,
                                        verify->userpk.data,
                                        verify->userpk.data_len);
     for (i = 0; i < strlen(fingerprint); i++)
@@ -1010,26 +1034,27 @@ static void silc_query_attributes_accept(const char *line, void *context)
     memset(filename2, 0, sizeof(filename2));
     snprintf(filename2, sizeof(filename2) - 1, "%s/clientkey_%s.pub",
             filename, fingerprint);
-    silc_pkcs_save_public_key_data(filename2, verify->userpk.data,
-                                  verify->userpk.data_len,
-                                  SILC_PKCS_FILE_PEM);
+    silc_pkcs_save_public_key(filename2, verify->public_key,
+                             SILC_PKCS_FILE_BASE64);
 
     /* Save extension data */
-    if (verify->extension.mime) {
+    if (verify->extension) {
       memset(filename2, 0, sizeof(filename2));
       snprintf(filename2, sizeof(filename2) - 1, "%s/extension.mime",
               filename);
-      silc_file_writefile(filename2, verify->extension.mime,
-                         verify->extension.mime_len);
+      tmp = silc_mime_encode(verify->extension, &len);
+      if (tmp)
+       silc_file_writefile(filename2, tmp, len);
     }
 
     /* Save MIME message data */
-    if (verify->message.mime) {
+    if (verify->message) {
       memset(filename2, 0, sizeof(filename2));
       snprintf(filename2, sizeof(filename2) - 1, "%s/status_message.mime",
               filename);
-      silc_file_writefile(filename2, verify->message.mime,
-                         verify->message.mime_len);
+      tmp = silc_mime_encode(verify->message, &len);
+      if (tmp)
+       silc_file_writefile(filename2, tmp, len);
     }
 
     printformat_module("fe-common/silc", server, NULL,
index 476205d450e0cfcf3c00b81e9f4da307873bf1b2..359d5b2054df2b270830b007343cee4ef3ab6014 100644 (file)
@@ -1,7 +1,7 @@
 /*
   silc-server.c : irssi
 
-  Copyright (C) 2000 - 2005 Timo Sirainen
+  Copyright (C) 2000 - 2006 Timo Sirainen
                             Pekka Riikonen <priikone@silcnet.org>
 
   This program is free software; you can redistribute it and/or modify
@@ -63,9 +63,9 @@ int silc_send_channel(SILC_SERVER_REC *server,
     cmd_return_error_value(CMDERR_NOT_JOINED, FALSE);
   }
 
-  silc_client_send_channel_message(silc_client, server->conn, rec->entry,
-                                  NULL, flags, msg, strlen(msg), TRUE);
-  return TRUE;
+  return silc_client_send_channel_message(silc_client, server->conn,
+                                         rec->entry, NULL, flags, sha1hash,
+                                         msg, strlen(msg));
 }
 
 typedef struct {
@@ -81,43 +81,42 @@ typedef struct {
 
 static void silc_send_msg_clients(SilcClient client,
                                  SilcClientConnection conn,
-                                 SilcClientEntry *clients,
-                                 SilcUInt32 clients_count,
+                                 SilcStatus status,
+                                 SilcDList clients,
                                  void *context)
 {
   PRIVMSG_REC *rec = context;
   SILC_SERVER_REC *server = rec->server;
   SilcClientEntry target;
-  char *nickname = NULL;
+  char nickname[128 + 1];
+  SilcDList lclients = NULL;
 
-  if (!clients_count) {
+  if (!clients) {
     printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
              "%s: There is no such client", rec->nick);
   } else {
-    if (clients_count > 1) {
-      silc_parse_userfqdn(rec->nick, &nickname, NULL);
+    if (silc_dlist_count(clients) > 1) {
+      silc_parse_userfqdn(rec->nick, nickname, sizeof(nickname), NULL, 0);
 
       /* Find the correct one. The rec->nick might be a formatted nick
         so this will find the correct one. */
-      clients = silc_client_get_clients_local(silc_client, server->conn,
-                                             nickname, rec->nick,
-                                             &clients_count);
+      clients = lclients =
+       silc_client_get_clients_local(silc_client, server->conn,
+                                     nickname, rec->nick);
       if (!clients) {
        printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
                  "%s: There is no such client", rec->nick);
-       silc_free(nickname);
        goto out;
       }
-      silc_free(nickname);
     }
 
-    target = clients[0];
+    target = silc_dlist_get(clients);
 
     /* Still check for exact math for nickname, this compares the
        real (formatted) nickname and the nick (maybe formatted) that
-       use gave. This is to assure that `nick' does not match
+       user gave. This is to assure that `nick' does not match
        `nick@host'. */
-    if (!silc_utf8_strcasecmp(rec->nick, clients[0]->nickname)) {
+    if (!silc_utf8_strcasecmp(rec->nick, target->nickname)) {
       printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
                "%s: There is no such client", rec->nick);
       goto out;
@@ -125,12 +124,12 @@ static void silc_send_msg_clients(SilcClient client,
 
     /* Send the private message */
     silc_client_send_private_message(client, conn, target,
-                                    rec->flags,
-                                    rec->msg, rec->len,
-                                    TRUE);
+                                    rec->flags, sha1hash,
+                                    rec->msg, rec->len);
   }
 
  out:
+  silc_client_list_free(silc_client, server->conn, lclients);
   g_free(rec->nick);
   g_free(rec->msg);
   g_free(rec);
@@ -140,11 +139,12 @@ int silc_send_msg(SILC_SERVER_REC *server, char *nick, char *msg,
                  int msg_len, SilcMessageFlags flags)
 {
   PRIVMSG_REC *rec;
-  SilcClientEntry *clients;
-  SilcUInt32 clients_count;
-  char *nickname = NULL;
+  char nickname[128 + 1];
+  SilcDList clients;
+  SilcClientEntry target;
+  int ret;
 
-  if (!silc_parse_userfqdn(nick, &nickname, NULL)) {
+  if (!silc_parse_userfqdn(nick, nickname, sizeof(nickname), NULL, 0)) {
     printformat_module("fe-common/silc", server, NULL,
                       MSGLEVEL_CRAP, SILCTXT_BAD_NICK, nick);
     return FALSE;
@@ -152,7 +152,7 @@ int silc_send_msg(SILC_SERVER_REC *server, char *nick, char *msg,
 
   /* Find client entry */
   clients = silc_client_get_clients_local(silc_client, server->conn,
-                                         nickname, nick, &clients_count);
+                                         nickname, nick);
   if (!clients) {
     rec = g_new0(PRIVMSG_REC, 1);
     rec->nick = g_strdup(nick);
@@ -169,11 +169,15 @@ int silc_send_msg(SILC_SERVER_REC *server, char *nick, char *msg,
   }
 
   /* Send the private message directly */
+  target = silc_dlist_get(clients);
+  ret = silc_client_send_private_message(silc_client, server->conn,
+                                        target, flags, sha1hash,
+                                        msg, msg_len);
+
   silc_free(nickname);
-  silc_client_send_private_message(silc_client, server->conn,
-                                  clients[0], flags,
-                                  msg, msg_len, TRUE);
-  return TRUE;
+  silc_client_list_free(silc_client, server->conn, clients);
+
+  return ret;
 }
 
 void silc_send_mime(SILC_SERVER_REC *server, int channel, const char *to,
@@ -206,7 +210,8 @@ void silc_send_mime(SILC_SERVER_REC *server, int channel, const char *to,
     silc_client_send_channel_message(silc_client, server->conn, rec->entry,
                                     NULL, SILC_MESSAGE_FLAG_DATA |
                                     (sign ? SILC_MESSAGE_FLAG_SIGNED : 0),
-                                    unescaped_data, unescaped_data_len, TRUE);
+                                    sha1hash, unescaped_data,
+                                    unescaped_data_len);
   } else {
     silc_send_msg(server, (char *)to, unescaped_data, unescaped_data_len,
                  SILC_MESSAGE_FLAG_DATA |
@@ -271,62 +276,143 @@ static void send_message(SILC_SERVER_REC *server, char *target,
   silc_free(t);
 }
 
-void silc_send_heartbeat(SilcSocketConnection sock,
-                        void *hb_context)
+/* Connection callback */
+
+static void silc_connect_cb(SilcClient client,
+                           SilcClientConnection conn,
+                           SilcClientConnectionStatus status,
+                           SilcStatus error,
+                           const char *message,
+                           void *context)
 {
-  SILC_SERVER_REC *server = SILC_SERVER(hb_context);
+  SILC_SERVER_REC *server = context;
+  char *file;
 
-  if (server == NULL)
+  if (!server->disconnected) {
+    silc_client_close_connection(client, conn);
     return;
+  }
+
+  switch (status) {
+  case SILC_CLIENT_CONN_SUCCESS:
+    /* We have successfully connected to server */
+
+    /* Enable queueing until we have our requested nick */
+    if (settings_get_str("nick") &&
+       !strcmp(conn->local_entry->nickname, conn->local_entry->username))
+      silc_queue_enable(conn);
+
+    /* Put default attributes */
+    silc_query_attributes_default(silc_client, conn);
+
+    server->connected = TRUE;
+    server->conn = conn;
+    server->conn->context = server;
+    signal_emit("event connected", 1, server);
+    break;
+
+  case SILC_CLIENT_CONN_SUCCESS_RESUME:
+    /* We have successfully resumed old detached session */
+    server->connected = TRUE;
+    server->conn = conn;
+    server->conn->context = server;
+    signal_emit("event connected", 1, server);
+
+    /* Put default attributes */
+    silc_query_attributes_default(silc_client, conn);
+
+    /* If we resumed old session check whether we need to update
+       our nickname */
+    if (strcmp(server->nick, conn->local_entry->nickname)) {
+      char *old;
+      old = g_strdup(server->nick);
+      server_change_nick(SERVER(server), conn->local_entry->nickname);
+      nicklist_rename_unique(SERVER(server),
+                            conn->local_entry, server->nick,
+                            conn->local_entry, conn->local_entry->nickname);
+      signal_emit("message own_nick", 4, server, server->nick, old, "");
+      g_free(old);
+    }
+
+    /* Remove the detach data now */
+    file = silc_get_session_filename(server);
+    unlink(file);
+    silc_free(file);
+    break;
+
+  case SILC_CLIENT_CONN_DISCONNECTED:
+    /* Server disconnected */
+    if (server->conn && server->conn->local_entry) {
+      nicklist_rename_unique(SERVER(server),
+                            server->conn->local_entry, server->nick,
+                            server->conn->local_entry,
+                            silc_client->username);
+      silc_change_nick(server, silc_client->username);
+    }
+
+    if (message)
+      silc_say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+              "Server closed connection: %s (%d) %s",
+              silc_get_status_message(error), error,
+              message ? message : "");
+
+    if (server->conn)
+      server->conn->context = NULL;
+    server->conn = NULL;
+    server->connection_lost = TRUE;
+    server_disconnect(SERVER(server));
+    break;
 
-  silc_client_send_packet(silc_client, server->conn, SILC_PACKET_HEARTBEAT,
-                         NULL, 0);
+  default:
+    file = silc_get_session_filename(server);
+    if (silc_file_size(file) > 0)
+      printformat_module("fe-common/silc", server, NULL,
+                        MSGLEVEL_CRAP, SILCTXT_REATTACH_FAILED, file);
+
+    silc_free(file);
+
+    server->connection_lost = TRUE;
+    if (server->conn)
+      server->conn->context = NULL;
+    server_disconnect(SERVER(server));
+    break;
+  }
 }
 
-static void sig_connected(SILC_SERVER_REC *server)
+static void sig_connected_stream_created(SilcSocketStreamStatus status,
+                                        SilcStream stream, void *context)
 {
-  SilcClientConnection conn;
+  SILC_SERVER_REC *server = context;
   SilcClientConnectionParams params;
   char *file;
-  int fd;
 
-  if (!IS_SILC_SERVER(server))
+  if (!stream) {
+    server->connection_lost = TRUE;
+    server_disconnect(SERVER(server));
     return;
+  }
 
-  /* Try to read detached session data and use it if found. */
+  if (!server->disconnected) {
+    silc_stream_destroy(stream);
+    return;
+  }
+
+  /* Set connection parameters */
   memset(&params, 0, sizeof(params));
+  params.nickname = (char *)settings_get_str("nick");
+
+  /* Try to read detached session data and use it if found. */
   file = silc_get_session_filename(server);
   params.detach_data = silc_file_readfile(file, &params.detach_data_len);
   if (params.detach_data)
     params.detach_data[params.detach_data_len] = 0;
-
-  /* Add connection to the client library */
-  conn = silc_client_add_connection(silc_client, &params,
-                                   server->connrec->address,
-                                   server->connrec->port,
-                                   server);
-  server->conn = conn;
-
   if (params.detach_data)
     printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
                        SILCTXT_REATTACH, server->tag);
 
-  silc_free(params.detach_data);
-
-  fd = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle));
-
-  /* Start key exchange with the server */
-  silc_client_start_key_exchange(silc_client, conn, fd);
-
-  /* Put default attributes */
-  silc_query_attributes_default(silc_client, conn);
-
-  /* initialize heartbeat sending */
-  if (settings_get_int("heartbeat") > 0)
-    silc_socket_set_heartbeat(conn->sock, settings_get_int("heartbeat"),
-                               (void *)server,
-                               (SilcSocketConnectionHBCb)silc_send_heartbeat,
-                               silc_client->schedule);
+  /* Start key exchange */
+  silc_client_key_exchange(silc_client, &params, irssi_pubkey, irssi_privkey,
+                          stream, SILC_CONN_SERVER, silc_connect_cb, server);
 
   server->ftp_sessions = silc_dlist_init();
   server->isnickflag = isnickflag_func;
@@ -335,6 +421,22 @@ static void sig_connected(SILC_SERVER_REC *server)
   server->send_message = (void *) send_message;
 }
 
+static void sig_connected(SILC_SERVER_REC *server)
+{
+  int fd;
+
+  if (!IS_SILC_SERVER(server))
+    return;
+
+  //  server->connrec->address,
+  //  server->connrec->port,
+
+  /* Wrap the socket to TCP stream */
+  fd = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle));
+  silc_socket_tcp_stream_create(fd, TRUE, FALSE, silc_client->schedule,
+                               sig_connected_stream_created, server);
+}
+
 static void sig_disconnected(SILC_SERVER_REC *server)
 {
   if (!IS_SILC_SERVER(server))
@@ -342,7 +444,7 @@ static void sig_disconnected(SILC_SERVER_REC *server)
 
   silc_dlist_uninit(server->ftp_sessions);
 
-  if (server->conn && server->conn->sock != NULL) {
+  if (server->conn) {
     silc_client_close_connection(silc_client, server->conn);
 
     /* SILC closes the handle */
@@ -587,6 +689,7 @@ out:
   cmd_params_free(free_arg);
 }
 
+#if 0
 /* FILE command */
 
 SILC_TASK_CALLBACK(silc_client_file_close_later)
@@ -1083,6 +1186,7 @@ static void command_file(const char *data, SILC_SERVER_REC *server,
  out:
   silc_free(nickname);
 }
+#endif /* 0 */
 
 void silc_server_init(void)
 {
@@ -1113,7 +1217,7 @@ void silc_server_init(void)
   command_bind_silc("shutdown", MODULE_NAME, (SIGNAL_FUNC) command_self);
   command_bind_silc("getkey", MODULE_NAME, (SIGNAL_FUNC) command_self);
   command_bind_silc("sconnect", MODULE_NAME, (SIGNAL_FUNC) command_sconnect);
-  command_bind_silc("file", MODULE_NAME, (SIGNAL_FUNC) command_file);
+//  command_bind_silc("file", MODULE_NAME, (SIGNAL_FUNC) command_file);
   command_bind_silc("detach", MODULE_NAME, (SIGNAL_FUNC) command_self);
   command_bind_silc("watch", MODULE_NAME, (SIGNAL_FUNC) command_self);
   command_bind_silc("stats", MODULE_NAME, (SIGNAL_FUNC) command_self);
@@ -1152,7 +1256,7 @@ void silc_server_deinit(void)
   command_unbind("shutdown", (SIGNAL_FUNC) command_self);
   command_unbind("getkey", (SIGNAL_FUNC) command_self);
   command_unbind("sconnect", (SIGNAL_FUNC) command_sconnect);
-  command_unbind("file", (SIGNAL_FUNC) command_file);
+//  command_unbind("file", (SIGNAL_FUNC) command_file);
   command_unbind("detach", (SIGNAL_FUNC) command_self);
   command_unbind("watch", (SIGNAL_FUNC) command_self);
   command_unbind("stats", (SIGNAL_FUNC) command_self);
@@ -1160,6 +1264,7 @@ void silc_server_deinit(void)
   command_unbind("smsg", (SIGNAL_FUNC) command_smsg);
 }
 
+#if 0
 void silc_server_free_ftp(SILC_SERVER_REC *server,
                          SilcClientEntry client_entry)
 {
@@ -1174,6 +1279,7 @@ void silc_server_free_ftp(SILC_SERVER_REC *server,
     }
   }
 }
+#endif /* 0 */
 
 bool silc_term_utf8(void)
 {