updates.
[silc.git] / lib / silcclient / protocol.c
index da7bc07fb352423627398550db7c670bd609cb86..6ab25d6806b4d7a7fbb8050961be574bb91abc34 100644 (file)
@@ -22,7 +22,8 @@
  */
 /* $Id$ */
 
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
 #include "client_internal.h"
 
 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
@@ -77,7 +78,7 @@ static void silc_client_verify_key_cb(bool success, void *context)
 
 void silc_client_protocol_ke_verify_key(SilcSKE ske,
                                        unsigned char *pk_data,
-                                       uint32 pk_len,
+                                       SilcUInt32 pk_len,
                                        SilcSKEPKType pk_type,
                                        void *context,
                                        SilcSKEVerifyCbCompletion completion,
@@ -166,61 +167,40 @@ void silc_client_protocol_ke_set_keys(SilcSKE ske,
 /* Checks the version string of the server. */
 
 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
-                                    uint32 len, void *context)
+                                    SilcUInt32 len, void *context)
 {
   SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
   SilcClient client = (SilcClient)ske->user_data;
-  SilcSKEStatus status = SILC_SKE_STATUS_OK;
-  char *cp;
-  int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
-
-  /* Check for initial version string */
-  if (!strstr(version, "SILC-1.0-"))
-    status = SILC_SKE_STATUS_BAD_VERSION;
-
-  /* Check software version */
+  SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
 
-  cp = version + 9;
-  if (!cp)
-    status = SILC_SKE_STATUS_BAD_VERSION;
-
-  maj = atoi(cp);
-  cp = strchr(cp, '.');
-  if (cp) {
-    min = atoi(cp + 1);
-    cp++;
-  }
-  cp = strchr(cp, '.');
-  if (cp)
-    build = atoi(cp + 1);
-
-  cp = client->internal->silc_client_version + 9;
-  if (!cp)
-    status = SILC_SKE_STATUS_BAD_VERSION;
-
-  maj2 = atoi(cp);
-  cp = strchr(cp, '.');
-  if (cp) {
-    min2 = atoi(cp + 1);
-    cp++;
+  if (!silc_parse_version_string(version, &r_protocol_version, NULL, NULL,
+                                NULL, NULL)) {
+    client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+                              "We don't support server version `%s'", 
+                              version);
+    return SILC_SKE_STATUS_BAD_VERSION;
   }
-  cp = strchr(cp, '.');
-  if (cp)
-    build2 = atoi(cp + 1);
-
-  if (maj != maj2)
-    status = SILC_SKE_STATUS_BAD_VERSION;
 
-  /* XXX backward support for 0.6.1 */
-  if (maj == 0 && min == 6 && build < 2)
-    ske->backward_version = 1;
+  if (!silc_parse_version_string(client->internal->silc_client_version, 
+                                &l_protocol_version, NULL, NULL,
+                                NULL, NULL)) {
+    client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+                              "We don't support server version `%s'", 
+                              version);
+    return SILC_SKE_STATUS_BAD_VERSION;
+  }
 
-  if (status != SILC_SKE_STATUS_OK)
+  /* If remote is too new, don't connect */
+  if (l_protocol_version < r_protocol_version) {
     client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
                               "We don't support server version `%s'", 
                               version);
+    return SILC_SKE_STATUS_BAD_VERSION;
+  }
+
+  ske->sock->version = r_protocol_version;
 
-  return status;
+  return SILC_SKE_STATUS_OK;
 }
 
 /* Callback that is called by the SKE to indicate that it is safe to
@@ -548,7 +528,7 @@ static int
 silc_client_get_public_key_auth(SilcClient client,
                                SilcClientConnection conn,
                                unsigned char *auth_data,
-                               uint32 *auth_data_len,
+                               SilcUInt32 *auth_data_len,
                                SilcSKE ske)
 {
   int len;
@@ -584,7 +564,7 @@ silc_client_get_public_key_auth(SilcClient client,
 
 static void 
 silc_client_conn_auth_continue(unsigned char *auth_data,
-                              uint32 auth_data_len, void *context)
+                              SilcUInt32 auth_data_len, void *context)
 {
   SilcProtocol protocol = (SilcProtocol)context;
   SilcClientConnAuthInternalContext *ctx = 
@@ -592,9 +572,21 @@ silc_client_conn_auth_continue(unsigned char *auth_data,
   SilcClient client = (SilcClient)ctx->client;
   SilcBuffer packet;
   int payload_len = 0;
+  unsigned char *autf8 = NULL;
 
   SILC_LOG_DEBUG(("Start"));
 
+  /* Passphrase must be UTF-8 encoded, if it isn't encode it */
+  if (ctx->auth_meth == SILC_AUTH_PASSWORD && 
+      !silc_utf8_valid(auth_data, auth_data_len)) {
+    payload_len = silc_utf8_encoded_len(auth_data, auth_data_len, 
+                                       SILC_STRING_ASCII);
+    autf8 = silc_calloc(payload_len, sizeof(*autf8));
+    auth_data_len = silc_utf8_encode(auth_data, auth_data_len, 
+                                    SILC_STRING_ASCII, autf8, payload_len);
+    auth_data = autf8;
+  }
+
   payload_len = 4 + auth_data_len;
   packet = silc_buffer_alloc(payload_len);
   silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
@@ -610,6 +602,7 @@ silc_client_conn_auth_continue(unsigned char *auth_data,
                          NULL, 0, NULL, NULL,
                          packet->data, packet->len, TRUE);
   silc_buffer_free(packet);
+  silc_free(autf8);
       
   /* Next state is end of protocol */
   protocol->state = SILC_PROTOCOL_STATE_END;
@@ -636,7 +629,7 @@ SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
        * to be authenticated.
        */
       unsigned char *auth_data = NULL;
-      uint32 auth_data_len = 0;
+      SilcUInt32 auth_data_len = 0;
       unsigned char sign[1024];
 
       switch(ctx->auth_meth) {
@@ -798,8 +791,8 @@ silc_client_protocol_rekey_generate(SilcClient client,
 {
   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
   SilcSKEKeyMaterial *keymat;
-  uint32 key_len = silc_cipher_get_key_len(conn->send_key);
-  uint32 hash_len = conn->hash->hash->hash_len;
+  SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
+  SilcUInt32 hash_len = conn->hash->hash->hash_len;
 
   SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
                  send ? "sending" : "receiving"));
@@ -827,10 +820,10 @@ silc_client_protocol_rekey_generate_pfs(SilcClient client,
 {
   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
   SilcSKEKeyMaterial *keymat;
-  uint32 key_len = silc_cipher_get_key_len(conn->send_key);
-  uint32 hash_len = conn->hash->hash->hash_len;
+  SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
+  SilcUInt32 hash_len = conn->hash->hash->hash_len;
   unsigned char *tmpbuf;
-  uint32 klen;
+  SilcUInt32 klen;
 
   SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
                  send ? "sending" : "receiving"));