-
- if (conn->internal->params.detach_data) {
- /* Send RESUME_CLIENT packet to the server, which is used to resume
- old detached session back. */
- SilcBuffer auth;
- SilcClientID *old_client_id;
- unsigned char *old_id;
- SilcUInt16 old_id_len;
-
- if (!silc_client_process_detach_data(client, conn, &old_id, &old_id_len)) {
- ctx->status = SILC_CLIENT_CONN_ERROR_RESUME;
- goto err;
- }
-
- old_client_id = silc_id_str2id(old_id, old_id_len, SILC_ID_CLIENT);
- if (!old_client_id) {
- silc_free(old_id);
- ctx->status = SILC_CLIENT_CONN_ERROR_RESUME;
- goto err;
- }
-
- /* Generate authentication data that server will verify */
- auth = silc_auth_public_key_auth_generate(client->public_key,
- client->private_key,
- client->rng,
- conn->internal->hash,
- old_client_id, SILC_ID_CLIENT);
- if (!auth) {
- silc_free(old_client_id);
- silc_free(old_id);
- ctx->status = SILC_CLIENT_CONN_ERROR_RESUME;
- goto err;
- }
-
- packet = silc_buffer_alloc_size(2 + old_id_len + auth->len);
- silc_buffer_format(packet,
- SILC_STR_UI_SHORT(old_id_len),
- SILC_STR_UI_XNSTRING(old_id, old_id_len),
- SILC_STR_UI_XNSTRING(auth->data, auth->len),
- SILC_STR_END);
-
- /* Send the packet */
- silc_client_packet_send(client, ctx->sock, SILC_PACKET_RESUME_CLIENT,
- NULL, 0, NULL, NULL,
- packet->data, packet->len, TRUE);
- silc_buffer_free(packet);
- silc_buffer_free(auth);
- silc_free(old_client_id);
- silc_free(old_id);
- } else {
- /* Send NEW_CLIENT packet to the server. We will become registered
- to the SILC network after sending this packet and we will receive
- client ID from the server. */
- packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
- strlen(client->realname));
- silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
- silc_buffer_format(packet,
- SILC_STR_UI_SHORT(strlen(client->username)),
- SILC_STR_UI_XNSTRING(client->username,
- strlen(client->username)),
- SILC_STR_UI_SHORT(strlen(client->realname)),
- SILC_STR_UI_XNSTRING(client->realname,
- strlen(client->realname)),
- SILC_STR_END);
-
- /* Send the packet */
- silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
- NULL, 0, NULL, NULL,
- packet->data, packet->len, TRUE);
- silc_buffer_free(packet);
- }
-
- /* Save remote ID. */
- conn->remote_id = ctx->dest_id;
- conn->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_SERVER);
- conn->remote_id_data_len = silc_id_get_len(ctx->dest_id, SILC_ID_SERVER);
-
- /* Register re-key timeout */
- conn->internal->rekey->timeout = client->internal->params->rekey_secs;
- conn->internal->rekey->context = (void *)client;
- silc_schedule_task_add(client->schedule, conn->sock->sock,
- silc_client_rekey_callback,
- (void *)conn->sock, conn->internal->rekey->timeout, 0,
- SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-
- silc_protocol_free(protocol);
- silc_free(ctx->auth_data);
- if (ctx->ske)
- silc_ske_free(ctx->ske);
- silc_socket_free(ctx->sock);
- silc_free(ctx);
- conn->sock->protocol = NULL;
- return;
-
- err:
- silc_protocol_free(protocol);
- silc_free(ctx->auth_data);
- silc_free(ctx->dest_id);
- if (ctx->ske)
- silc_ske_free(ctx->ske);
- conn->sock->protocol = NULL;
- silc_socket_free(ctx->sock);
-
- /* Notify application of failure */
- silc_schedule_task_add(client->schedule, ctx->sock->sock,
- silc_client_connect_failure_auth, ctx,
- 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-}
-
-/* Client session resuming callback. If the session was resumed
- this callback is called after the resuming is completed. This
- will call the `connect' client operation to the application
- since it has not been called yet. */
-
-static void silc_client_resume_session_cb(SilcClient client,
- SilcClientConnection conn,
- SilcBool success,
- void *context)
-{
- SilcBuffer sidp;
-
- /* Notify application that connection is created to server */
- client->internal->ops->connected(client, conn, success ?
- SILC_CLIENT_CONN_SUCCESS_RESUME :
- SILC_CLIENT_CONN_ERROR_RESUME);
-
- if (success) {
- /* Issue INFO command to fetch the real server name and server
- information and other stuff. */
- silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL,
- silc_client_command_reply_info_i, 0,
- ++conn->cmd_ident);
- sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
- silc_client_command_send(client, conn, SILC_COMMAND_INFO,
- conn->cmd_ident, 1, 2, sidp->data, sidp->len);
- silc_buffer_free(sidp);
- }
-}
-
-/* Processes incoming connection authentication method request packet.
- It is a reply to our previously sent request. The packet can be used
- to resolve the authentication method for the current session if the
- client does not know it beforehand. */
-
-void silc_client_connection_auth_request(SilcClient client,
- SilcClientConnection conn,
- SilcPacketContext *packet)
-{
- SilcClientConnection conn = (SilcClientConnection)sock->user_data;
- SilcUInt16 conn_type, auth_meth;
- int ret;
-
- /* If we haven't send our request then ignore this one. */
- if (!conn->internal->connauth)
- return;
-
- /* Parse the payload */
- ret = silc_buffer_unformat(packet->buffer,
- SILC_STR_UI_SHORT(&conn_type),
- SILC_STR_UI_SHORT(&auth_meth),
- SILC_STR_END);
- if (ret == -1)
- auth_meth = SILC_AUTH_NONE;
-
- /* Call the request callback to notify application for received
- authentication method information. */
- if (conn->internal->connauth->callback)
- (*conn->internal->connauth->callback)(client, conn, auth_meth,
- conn->internal->connauth->context);
-
- silc_schedule_task_del(client->schedule, conn->internal->connauth->timeout);
-
- silc_free(conn->internal->connauth);
- conn->internal->connauth = NULL;
-}
-
-/* Timeout task callback called if the server does not reply to our
- connection authentication method request in the specified time interval. */
-
-SILC_TASK_CALLBACK(silc_client_request_authentication_method_timeout)
-{
- SilcClientConnection conn = (SilcClientConnection)context;
- SilcClient client = conn->client;
-
- if (!conn->internal->connauth)
- return;
-
- /* Call the request callback to notify application */
- if (conn->internal->connauth->callback)
- (*conn->internal->connauth->callback)(client, conn, SILC_AUTH_NONE,
- conn->internal->connauth->context);
-
- silc_free(conn->internal->connauth);
- conn->internal->connauth = NULL;