Changed the version string variables to #defines.
[silc.git] / lib / silcclient / client.c
index 45d81d04daa12f486a8d3b278c1b312bbb152db3..278fa3796644a2fee864081c10097356826552da 100644 (file)
@@ -47,7 +47,7 @@ void silc_client_resolve_auth_method(bool success,
 SilcClient silc_client_alloc(SilcClientOperations *ops, 
                             SilcClientParams *params,
                             void *application,
-                            const char *silc_version)
+                            const char *version_string)
 {
   SilcClient new_client;
 
@@ -58,7 +58,9 @@ SilcClient silc_client_alloc(SilcClientOperations *ops,
   new_client->internal->ops = ops;
   new_client->internal->params = 
     silc_calloc(1, sizeof(*new_client->internal->params));
-  new_client->internal->silc_client_version = strdup(silc_version);
+  if (!version_string)
+    version_string = silc_version_string;
+  new_client->internal->silc_client_version = strdup(version_string);
 
   if (params)
     memcpy(new_client->internal->params, params, sizeof(*params));
@@ -102,9 +104,17 @@ int silc_client_init(SilcClient client)
 {
   SILC_LOG_DEBUG(("Initializing client"));
 
+  /* Initialize the crypto library.  If application has done this already
+     this has no effect.  Also, we will not be overriding something
+     application might have registered earlier. */
+  silc_cipher_register_default();
+  silc_pkcs_register_default();
+  silc_hash_register_default();
+  silc_hmac_register_default();
+
   /* Initialize hash functions for client to use */
-  silc_hash_alloc("md5", &client->internal->md5hash);
-  silc_hash_alloc("sha1", &client->internal->sha1hash);
+  silc_hash_alloc("md5", &client->md5hash);
+  silc_hash_alloc("sha1", &client->sha1hash);
 
   /* Initialize none cipher */
   silc_cipher_alloc("none", &client->internal->none_cipher);
@@ -325,7 +335,8 @@ silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
                                     (void *)ctx, 0, 0, 
                                     SILC_TASK_FD,
                                     SILC_TASK_PRI_NORMAL);
-  silc_schedule_set_listen_fd(ctx->client->schedule, sock, SILC_TASK_WRITE);
+  silc_schedule_set_listen_fd(ctx->client->schedule, sock, SILC_TASK_WRITE,
+                             FALSE);
 
   ctx->sock = sock;
 
@@ -415,7 +426,7 @@ static void silc_client_start_key_exchange_cb(SilcSocketConnection sock,
     client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
                               "Error: Could not start key exchange protocol");
     silc_net_close_connection(conn->sock->sock);
-    client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_ERROR);
+    client->internal->ops->connected(client, conn, SILC_CLIENT_CONN_ERROR);
     return;
   }
   conn->sock->protocol = protocol;
@@ -461,8 +472,8 @@ void silc_client_start_key_exchange(SilcClient client,
                          conn, client->schedule);
 }
 
-/* Callback called when error has occurred during connecting to the server.
-   The `connect' client operation will be called. */
+/* Callback called when error has occurred during connecting (KE) to
+   the server.  The `connect' client operation will be called. */
 
 SILC_TASK_CALLBACK(silc_client_connect_failure)
 {
@@ -470,13 +481,27 @@ SILC_TASK_CALLBACK(silc_client_connect_failure)
     (SilcClientKEInternalContext *)context;
   SilcClient client = (SilcClient)ctx->client;
 
-  client->internal->ops->connect(client, ctx->sock->user_data, 
-                                SILC_CLIENT_CONN_ERROR);
+  client->internal->ops->connected(client, ctx->sock->user_data, 
+                                  SILC_CLIENT_CONN_ERROR);
   if (ctx->packet)
     silc_packet_context_free(ctx->packet);
   silc_free(ctx);
 }
 
+/* Callback called when error has occurred during connecting (auth) to
+   the server.  The `connect' client operation will be called. */
+
+SILC_TASK_CALLBACK(silc_client_connect_failure_auth)
+{
+  SilcClientConnAuthInternalContext *ctx =
+    (SilcClientConnAuthInternalContext *)context;
+  SilcClient client = (SilcClient)ctx->client;
+
+  client->internal->ops->connected(client, ctx->sock->user_data, 
+                                  SILC_CLIENT_CONN_ERROR);
+  silc_free(ctx);
+}
+
 /* Start of the connection to the remote server. This is called after
    succesful TCP/IP connection has been established to the remote host. */
 
@@ -521,7 +546,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
       silc_free(ctx);
 
       /* Notify application of failure */
-      client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_ERROR);
+      client->internal->ops->connected(client, conn, SILC_CLIENT_CONN_ERROR);
       silc_client_del_connection(client, conn);
     }
     return;
@@ -593,6 +618,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
   silc_protocol_free(protocol);
   if (ctx->packet)
     silc_packet_context_free(ctx->packet);
+  ctx->packet = NULL;
   silc_free(ctx);
   sock->protocol = NULL;
 
@@ -625,7 +651,21 @@ void silc_client_resolve_auth_method(bool success,
 
   proto_ctx->auth_meth = auth_meth;
 
-  if (auth_data && auth_data_len) {
+  if (success && auth_data && auth_data_len) {
+
+    /* Passphrase must be UTF-8 encoded, if it isn't encode it */
+    if (auth_meth == SILC_AUTH_PASSWORD && 
+       !silc_utf8_valid(auth_data, auth_data_len)) {
+      int payload_len = 0;
+      unsigned char *autf8 = NULL;
+      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;
+    }
+
     proto_ctx->auth_data = silc_memdup(auth_data, auth_data_len);
     proto_ctx->auth_data_len = auth_data_len;
   }
@@ -761,7 +801,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
 
   /* Notify application of failure */
   silc_schedule_task_add(client->schedule, ctx->sock->sock,
-                        silc_client_connect_failure, ctx,
+                        silc_client_connect_failure_auth, ctx,
                         0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
 }
 
@@ -864,14 +904,14 @@ SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
         close the connection */
       if (SILC_IS_DISCONNECTING(sock)) {
        if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
-         client->internal->ops->disconnect(client, conn, 0, NULL);
+         client->internal->ops->disconnected(client, conn, 0, NULL);
        silc_client_close_connection_real(client, sock, conn);
        return;
       }
       
       SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
       if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
-       client->internal->ops->disconnect(client, conn, 0, NULL);
+       client->internal->ops->disconnected(client, conn, 0, NULL);
       silc_client_close_connection_real(client, sock, conn);
       return;
     }
@@ -1252,7 +1292,7 @@ void silc_client_packet_send(SilcClient client,
                             SilcHmac hmac,
                             unsigned char *data, 
                             SilcUInt32 data_len, 
-                            int force_send)
+                            bool force_send)
 {
   SilcPacketContext packetdata;
   const SilcBufferStruct packet;
@@ -1386,7 +1426,7 @@ void silc_client_close_connection_real(SilcClient client,
       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
       silc_protocol_execute_final(sock->protocol, client->schedule);
       /* The application will recall this function with these protocols
-        (the ops->connect client operation). */
+        (the ops->connected client operation). */
       return;
     } else {
       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
@@ -1525,7 +1565,7 @@ void silc_client_disconnected_by_server(SilcClient client,
 
   conn = (SilcClientConnection)sock->user_data;
   if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
-    client->internal->ops->disconnect(client, conn, status, message);
+    client->internal->ops->disconnected(client, conn, status, message);
 
   silc_free(message);
 
@@ -1578,9 +1618,9 @@ static void silc_client_resume_session_cb(SilcClient client,
   SilcBuffer sidp;
 
   /* Notify application that connection is created to server */
-  client->internal->ops->connect(client, conn, success ?
-                                SILC_CLIENT_CONN_SUCCESS_RESUME :
-                                SILC_CLIENT_CONN_ERROR);
+  client->internal->ops->connected(client, conn, success ?
+                                  SILC_CLIENT_CONN_SUCCESS_RESUME :
+                                  SILC_CLIENT_CONN_ERROR);
 
   if (success) {
     /* Issue INFO command to fetch the real server name and server
@@ -1673,7 +1713,7 @@ void silc_client_receive_new_id(SilcClient client,
 
       /* Notify application of successful connection. We do it here now that
         we've received the Client ID and are allowed to send traffic. */
-      client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_SUCCESS);
+      client->internal->ops->connected(client, conn, SILC_CLIENT_CONN_SUCCESS);
 
       /* Issue INFO command to fetch the real server name and server
         information and other stuff. */