updates.
[silc.git] / lib / silcclient / client.c
1 /*
2
3   client.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2001 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /* $Id$ */
21
22 #include "clientlibincludes.h"
23 #include "client_internal.h"
24
25 /* Static task callback prototypes */
26 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
27 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
28 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
29 SILC_TASK_CALLBACK(silc_client_rekey_callback);
30 SILC_TASK_CALLBACK(silc_client_rekey_final);
31
32 static bool silc_client_packet_parse(SilcPacketParserContext *parser_context,
33                                      void *context);
34 static void silc_client_packet_parse_type(SilcClient client, 
35                                           SilcSocketConnection sock,
36                                           SilcPacketContext *packet);
37 void silc_client_resolve_auth_method(bool success,
38                                      SilcProtocolAuthMeth auth_meth,
39                                      const unsigned char *auth_data,
40                                      uint32 auth_data_len, void *context);
41
42 /* Allocates new client object. This has to be done before client may
43    work. After calling this one must call silc_client_init to initialize
44    the client. The `application' is application specific user data pointer
45    and caller must free it. */
46
47 SilcClient silc_client_alloc(SilcClientOperations *ops, 
48                              SilcClientParams *params,
49                              void *application,
50                              const char *silc_version)
51 {
52   SilcClient new_client;
53
54   new_client = silc_calloc(1, sizeof(*new_client));
55   new_client->application = application;
56   new_client->ops = ops;
57   new_client->silc_client_version = strdup(silc_version);
58   new_client->params = silc_calloc(1, sizeof(*new_client->params));
59
60   if (params)
61     memcpy(new_client->params, params, sizeof(*params));
62
63   if (!new_client->params->task_max)
64     new_client->params->task_max = 200;
65
66   if (!new_client->params->rekey_secs)
67     new_client->params->rekey_secs = 3600;
68
69   if (!new_client->params->connauth_request_secs)
70     new_client->params->connauth_request_secs = 2;
71
72   new_client->params->
73     nickname_format[sizeof(new_client->params->nickname_format) - 1] = 0;
74
75   return new_client;
76 }
77
78 /* Frees client object and its internals. */
79
80 void silc_client_free(SilcClient client)
81 {
82   if (client) {
83     if (client->rng)
84       silc_rng_free(client->rng);
85
86     silc_free(client->silc_client_version);
87     silc_free(client->params);
88     silc_free(client);
89   }
90 }
91
92 /* Initializes the client. This makes all the necessary steps to make
93    the client ready to be run. One must call silc_client_run to run the
94    client. Returns FALSE if error occured, TRUE otherwise. */
95
96 int silc_client_init(SilcClient client)
97 {
98   SILC_LOG_DEBUG(("Initializing client"));
99
100   /* Initialize hash functions for client to use */
101   silc_hash_alloc("md5", &client->md5hash);
102   silc_hash_alloc("sha1", &client->sha1hash);
103
104   /* Initialize none cipher */
105   silc_cipher_alloc("none", &client->none_cipher);
106
107   /* Initialize random number generator */
108   client->rng = silc_rng_alloc();
109   silc_rng_init(client->rng);
110   silc_rng_global_init(client->rng);
111
112   /* Register protocols */
113   silc_client_protocols_register();
114
115   /* Initialize the scheduler */
116   client->schedule = silc_schedule_init(client->params->task_max ?
117                                         client->params->task_max : 200);
118   if (!client->schedule)
119     return FALSE;
120
121   return TRUE;
122 }
123
124 /* Stops the client. This is called to stop the client and thus to stop
125    the program. */
126
127 void silc_client_stop(SilcClient client)
128 {
129   SILC_LOG_DEBUG(("Stopping client"));
130
131   silc_schedule_stop(client->schedule);
132   silc_schedule_uninit(client->schedule);
133
134   silc_client_protocols_unregister();
135
136   SILC_LOG_DEBUG(("Client stopped"));
137 }
138
139 /* Runs the client. This starts the scheduler from the utility library.
140    When this functions returns the execution of the appliation is over. */
141
142 void silc_client_run(SilcClient client)
143 {
144   SILC_LOG_DEBUG(("Running client"));
145
146   /* Start the scheduler, the heart of the SILC client. When this returns
147      the program will be terminated. */
148   silc_schedule(client->schedule);
149 }
150
151 static void silc_client_entry_destructor(SilcIDCache cache,
152                                          SilcIDCacheEntry entry)
153 {
154   silc_free(entry->name);
155 }
156
157 /* Allocates and adds new connection to the client. This adds the allocated
158    connection to the connection table and returns a pointer to it. A client
159    can have multiple connections to multiple servers. Every connection must
160    be added to the client using this function. User data `context' may
161    be sent as argument. This function is normally used only if the 
162    application performed the connecting outside the library. The library
163    however may use this internally. */
164
165 SilcClientConnection silc_client_add_connection(SilcClient client,
166                                                 char *hostname,
167                                                 int port,
168                                                 void *context)
169 {
170   SilcClientConnection conn;
171   int i;
172
173   conn = silc_calloc(1, sizeof(*conn));
174
175   /* Initialize ID caches */
176   conn->client_cache = silc_idcache_alloc(0, SILC_ID_CLIENT, 
177                                           silc_client_entry_destructor);
178   conn->channel_cache = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
179   conn->server_cache = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
180   conn->client = client;
181   conn->remote_host = strdup(hostname);
182   conn->remote_port = port;
183   conn->context = context;
184   conn->pending_commands = silc_dlist_init();
185   conn->ftp_sessions = silc_dlist_init();
186
187   /* Add the connection to connections table */
188   for (i = 0; i < client->conns_count; i++)
189     if (client->conns && !client->conns[i]) {
190       client->conns[i] = conn;
191       return conn;
192     }
193
194   client->conns = silc_realloc(client->conns, sizeof(*client->conns)
195                                * (client->conns_count + 1));
196   client->conns[client->conns_count] = conn;
197   client->conns_count++;
198
199   return conn;
200 }
201
202 /* Removes connection from client. Frees all memory. */
203
204 void silc_client_del_connection(SilcClient client, SilcClientConnection conn)
205 {
206   int i;
207
208   for (i = 0; i < client->conns_count; i++)
209     if (client->conns[i] == conn) {
210
211       silc_idcache_free(conn->client_cache);
212       silc_idcache_free(conn->channel_cache);
213       silc_idcache_free(conn->server_cache);
214       if (conn->pending_commands)
215         silc_dlist_uninit(conn->pending_commands);
216       silc_free(conn->remote_host);
217       silc_dlist_uninit(conn->ftp_sessions);
218       silc_free(conn);
219
220       client->conns[i] = NULL;
221     }
222 }
223
224 /* Adds listener socket to the listener sockets table. This function is
225    used to add socket objects that are listeners to the client.  This should
226    not be used to add other connection objects. */
227
228 void silc_client_add_socket(SilcClient client, SilcSocketConnection sock)
229 {
230   int i;
231
232   if (!client->sockets) {
233     client->sockets = silc_calloc(1, sizeof(*client->sockets));
234     client->sockets[0] = silc_socket_dup(sock);
235     client->sockets_count = 1;
236     return;
237   }
238
239   for (i = 0; i < client->sockets_count; i++) {
240     if (client->sockets[i] == NULL) {
241       client->sockets[i] = silc_socket_dup(sock);
242       return;
243     }
244   }
245
246   client->sockets = silc_realloc(client->sockets, sizeof(*client->sockets) *
247                                  (client->sockets_count + 1));
248   client->sockets[client->sockets_count] = silc_socket_dup(sock);
249   client->sockets_count++;
250 }
251
252 /* Deletes listener socket from the listener sockets table. */
253
254 void silc_client_del_socket(SilcClient client, SilcSocketConnection sock)
255 {
256   int i;
257
258   if (!client->sockets)
259     return;
260
261   for (i = 0; i < client->sockets_count; i++) {
262     if (client->sockets[i] == sock) {
263       silc_socket_free(sock);
264       client->sockets[i] = NULL;
265       return;
266     }
267   }
268 }
269
270 static int 
271 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
272 {
273   int sock;
274
275   /* XXX In the future we should give up this non-blocking connect all
276      together and use threads instead. */
277   /* Create connection to server asynchronously */
278   sock = silc_net_create_connection_async(NULL, ctx->port, ctx->host);
279   if (sock < 0)
280     return -1;
281
282   /* Register task that will receive the async connect and will
283      read the result. */
284   ctx->task = silc_schedule_task_add(ctx->client->schedule, sock, 
285                                      silc_client_connect_to_server_start,
286                                      (void *)ctx, 0, 0, 
287                                      SILC_TASK_FD,
288                                      SILC_TASK_PRI_NORMAL);
289   silc_schedule_set_listen_fd(ctx->client->schedule, sock, SILC_TASK_WRITE);
290
291   ctx->sock = sock;
292
293   return sock;
294 }
295
296 /* Connects to remote server. This is the main routine used to connect
297    to SILC server. Returns -1 on error and the created socket otherwise. 
298    The `context' is user context that is saved into the SilcClientConnection
299    that is created after the connection is created. Note that application
300    may handle the connecting process outside the library. If this is the
301    case then this function is not used at all. When the connecting is
302    done the `connect' client operation is called. */
303
304 int silc_client_connect_to_server(SilcClient client, int port,
305                                   char *host, void *context)
306 {
307   SilcClientInternalConnectContext *ctx;
308   SilcClientConnection conn;
309   int sock;
310
311   SILC_LOG_DEBUG(("Connecting to port %d of server %s",
312                   port, host));
313
314   conn = silc_client_add_connection(client, host, port, context);
315
316   client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
317                    "Connecting to port %d of server %s", port, host);
318
319   /* Allocate internal context for connection process. This is
320      needed as we are doing async connecting. */
321   ctx = silc_calloc(1, sizeof(*ctx));
322   ctx->client = client;
323   ctx->conn = conn;
324   ctx->host = strdup(host);
325   ctx->port = port;
326   ctx->tries = 0;
327
328   /* Do the actual connecting process */
329   sock = silc_client_connect_to_server_internal(ctx);
330   if (sock == -1)
331     silc_client_del_connection(client, conn);
332   return sock;
333 }
334
335 /* Start SILC Key Exchange (SKE) protocol to negotiate shared secret
336    key material between client and server.  This function can be called
337    directly if application is performing its own connecting and does not
338    use the connecting provided by this library. This function is normally
339    used only if the application performed the connecting outside the library.
340    The library however may use this internally. */
341
342 bool silc_client_start_key_exchange(SilcClient client,
343                                     SilcClientConnection conn,
344                                     int fd)
345 {
346   SilcProtocol protocol;
347   SilcClientKEInternalContext *proto_ctx;
348   void *context;
349
350   /* Allocate new socket connection object */
351   silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, (void *)conn, &conn->sock);
352
353   /* Sometimes when doing quick reconnects the new socket may be same as
354      the old one and there might be pending stuff for the old socket. 
355      If new one is same then those pending sutff might cause problems.
356      Make sure they do not do that. */
357   silc_schedule_task_del_by_fd(client->schedule, fd);
358
359   conn->nickname = strdup(client->username);
360   conn->sock->hostname = conn->remote_host;
361   conn->sock->ip = strdup(conn->remote_host);
362   conn->sock->port = conn->remote_port;
363
364   /* Allocate internal Key Exchange context. This is sent to the
365      protocol as context. */
366   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
367   proto_ctx->client = (void *)client;
368   proto_ctx->sock = silc_socket_dup(conn->sock);
369   proto_ctx->rng = client->rng;
370   proto_ctx->responder = FALSE;
371   proto_ctx->send_packet = silc_client_protocol_ke_send_packet;
372   proto_ctx->verify = silc_client_protocol_ke_verify_key;
373
374   /* Perform key exchange protocol. silc_client_connect_to_server_final
375      will be called after the protocol is finished. */
376   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
377                       &protocol, (void *)proto_ctx,
378                       silc_client_connect_to_server_second);
379   if (!protocol) {
380     client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
381                      "Error: Could not start key exchange protocol");
382     return FALSE;
383   }
384   conn->sock->protocol = protocol;
385
386   /* Register the connection for network input and output. This sets
387      that scheduler will listen for incoming packets for this connection 
388      and sets that outgoing packets may be sent to this connection as well.
389      However, this doesn't set the scheduler for outgoing traffic, it will 
390      be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
391      later when outgoing data is available. */
392   context = (void *)client;
393   SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
394
395   /* Execute the protocol */
396   silc_protocol_execute(protocol, client->schedule, 0, 0);
397   return TRUE;
398 }
399
400 /* Start of the connection to the remote server. This is called after
401    succesful TCP/IP connection has been established to the remote host. */
402
403 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
404 {
405   SilcClientInternalConnectContext *ctx =
406     (SilcClientInternalConnectContext *)context;
407   SilcClient client = ctx->client;
408   SilcClientConnection conn = ctx->conn;
409   int opt, opt_len = sizeof(opt);
410
411   SILC_LOG_DEBUG(("Start"));
412
413   /* Check the socket status as it might be in error */
414   silc_net_get_socket_opt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
415   if (opt != 0) {
416     if (ctx->tries < 2) {
417       /* Connection failed but lets try again */
418       client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
419                        "Could not connect to server %s: %s",
420                        ctx->host, strerror(opt));
421       client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
422                        "Connecting to port %d of server %s resumed", 
423                        ctx->port, ctx->host);
424
425       /* Unregister old connection try */
426       silc_schedule_unset_listen_fd(client->schedule, fd);
427       silc_net_close_connection(fd);
428       silc_schedule_task_del(client->schedule, ctx->task);
429
430       /* Try again */
431       silc_client_connect_to_server_internal(ctx);
432       ctx->tries++;
433     } else {
434       /* Connection failed and we won't try anymore */
435       client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
436                        "Could not connect to server %s: %s",
437                        ctx->host, strerror(opt));
438       silc_schedule_unset_listen_fd(client->schedule, fd);
439       silc_net_close_connection(fd);
440       silc_schedule_task_del(client->schedule, ctx->task);
441       silc_free(ctx);
442
443       /* Notify application of failure */
444       client->ops->connect(client, conn, FALSE);
445       silc_client_del_connection(client, conn);
446     }
447     return;
448   }
449
450   silc_schedule_unset_listen_fd(client->schedule, fd);
451   silc_schedule_task_del(client->schedule, ctx->task);
452   silc_free(ctx);
453
454   if (!silc_client_start_key_exchange(client, conn, fd)) {
455     silc_net_close_connection(fd);
456     client->ops->connect(client, conn, FALSE);
457   }
458 }
459
460 /* Second part of the connecting to the server. This executed 
461    authentication protocol. */
462
463 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
464 {
465   SilcProtocol protocol = (SilcProtocol)context;
466   SilcClientKEInternalContext *ctx = 
467     (SilcClientKEInternalContext *)protocol->context;
468   SilcClient client = (SilcClient)ctx->client;
469   SilcSocketConnection sock = NULL;
470   SilcClientConnAuthInternalContext *proto_ctx;
471
472   SILC_LOG_DEBUG(("Start"));
473
474   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
475       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
476     /* Error occured during protocol */
477     SILC_LOG_DEBUG(("Error during KE protocol"));
478     silc_protocol_free(protocol);
479     silc_ske_free_key_material(ctx->keymat);
480     if (ctx->ske)
481       silc_ske_free(ctx->ske);
482     if (ctx->dest_id)
483       silc_free(ctx->dest_id);
484     ctx->sock->protocol = NULL;
485     silc_socket_free(ctx->sock);
486
487     /* Notify application of failure */
488     client->ops->connect(client, ctx->sock->user_data, FALSE);
489     silc_free(ctx);
490     return;
491   }
492
493   /* We now have the key material as the result of the key exchange
494      protocol. Take the key material into use. Free the raw key material
495      as soon as we've set them into use. */
496   silc_client_protocol_ke_set_keys(ctx->ske, ctx->sock, ctx->keymat,
497                                    ctx->ske->prop->cipher,
498                                    ctx->ske->prop->pkcs,
499                                    ctx->ske->prop->hash,
500                                    ctx->ske->prop->hmac,
501                                    ctx->ske->prop->group,
502                                    ctx->responder);
503   silc_ske_free_key_material(ctx->keymat);
504
505   /* Allocate internal context for the authentication protocol. This
506      is sent as context for the protocol. */
507   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
508   proto_ctx->client = (void *)client;
509   proto_ctx->sock = sock = ctx->sock;
510   proto_ctx->ske = ctx->ske;    /* Save SKE object from previous protocol */
511   proto_ctx->dest_id_type = ctx->dest_id_type;
512   proto_ctx->dest_id = ctx->dest_id;
513
514   /* Free old protocol as it is finished now */
515   silc_protocol_free(protocol);
516   if (ctx->packet)
517     silc_packet_context_free(ctx->packet);
518   silc_free(ctx);
519   sock->protocol = NULL;
520
521   /* Resolve the authentication method to be used in this connection. The
522      completion callback is called after the application has resolved
523      the authentication method. */
524   client->ops->get_auth_method(client, sock->user_data, sock->hostname,
525                                sock->port, silc_client_resolve_auth_method,
526                                proto_ctx);
527 }
528
529 /* Authentication method resolving callback. Application calls this function
530    after we've called the client->ops->get_auth_method client operation
531    to resolve the authentication method. We will continue the executiong
532    of the protocol in this function. */
533
534 void silc_client_resolve_auth_method(bool success,
535                                      SilcProtocolAuthMeth auth_meth,
536                                      const unsigned char *auth_data,
537                                      uint32 auth_data_len, void *context)
538 {
539   SilcClientConnAuthInternalContext *proto_ctx =
540     (SilcClientConnAuthInternalContext *)context;
541   SilcClient client = (SilcClient)proto_ctx->client;
542
543   if (!success)
544     auth_meth = SILC_AUTH_NONE;
545
546   proto_ctx->auth_meth = auth_meth;
547
548   if (auth_data && auth_data_len) {
549     proto_ctx->auth_data = silc_calloc(auth_data_len, sizeof(*auth_data));
550     memcpy(proto_ctx->auth_data, auth_data, auth_data_len);
551     proto_ctx->auth_data_len = auth_data_len;
552   }
553
554   /* Allocate the authenteication protocol and execute it. */
555   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH, 
556                       &proto_ctx->sock->protocol, (void *)proto_ctx, 
557                       silc_client_connect_to_server_final);
558
559   /* Execute the protocol */
560   silc_protocol_execute(proto_ctx->sock->protocol, client->schedule, 0, 0);
561 }
562
563 /* Finalizes the connection to the remote SILC server. This is called
564    after authentication protocol has been completed. This send our
565    user information to the server to receive our client ID from
566    server. */
567
568 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
569 {
570   SilcProtocol protocol = (SilcProtocol)context;
571   SilcClientConnAuthInternalContext *ctx = 
572     (SilcClientConnAuthInternalContext *)protocol->context;
573   SilcClient client = (SilcClient)ctx->client;
574   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
575   SilcBuffer packet;
576
577   SILC_LOG_DEBUG(("Start"));
578
579   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
580       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
581     /* Error occured during protocol */
582     SILC_LOG_DEBUG(("Error during authentication protocol"));
583     silc_protocol_free(protocol);
584     if (ctx->auth_data)
585       silc_free(ctx->auth_data);
586     if (ctx->ske)
587       silc_ske_free(ctx->ske);
588     if (ctx->dest_id)
589       silc_free(ctx->dest_id);
590     conn->sock->protocol = NULL;
591     silc_socket_free(ctx->sock);
592
593     /* Notify application of failure */
594     client->ops->connect(client, ctx->sock->user_data, FALSE);
595     silc_free(ctx);
596     return;
597   }
598
599   /* Send NEW_CLIENT packet to the server. We will become registered
600      to the SILC network after sending this packet and we will receive
601      client ID from the server. */
602   packet = silc_buffer_alloc(2 + 2 + strlen(client->username) + 
603                              strlen(client->realname));
604   silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
605   silc_buffer_format(packet,
606                      SILC_STR_UI_SHORT(strlen(client->username)),
607                      SILC_STR_UI_XNSTRING(client->username,
608                                           strlen(client->username)),
609                      SILC_STR_UI_SHORT(strlen(client->realname)),
610                      SILC_STR_UI_XNSTRING(client->realname,
611                                           strlen(client->realname)),
612                      SILC_STR_END);
613
614   /* Send the packet */
615   silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
616                           NULL, 0, NULL, NULL, 
617                           packet->data, packet->len, TRUE);
618   silc_buffer_free(packet);
619
620   /* Save remote ID. */
621   conn->remote_id = ctx->dest_id;
622   conn->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_SERVER);
623   conn->remote_id_data_len = silc_id_get_len(ctx->dest_id, SILC_ID_SERVER);
624
625   /* Register re-key timeout */
626   conn->rekey->timeout = client->params->rekey_secs;
627   conn->rekey->context = (void *)client;
628   silc_schedule_task_add(client->schedule, conn->sock->sock, 
629                          silc_client_rekey_callback,
630                          (void *)conn->sock, conn->rekey->timeout, 0,
631                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
632
633   silc_protocol_free(protocol);
634   if (ctx->auth_data)
635     silc_free(ctx->auth_data);
636   if (ctx->ske)
637     silc_ske_free(ctx->ske);
638   silc_socket_free(ctx->sock);
639   silc_free(ctx);
640   conn->sock->protocol = NULL;
641 }
642
643 /* Internal routine that sends packet or marks packet to be sent. This
644    is used directly only in special cases. Normal cases should use
645    silc_server_packet_send. Returns < 0 on error. */
646
647 int silc_client_packet_send_real(SilcClient client,
648                                  SilcSocketConnection sock,
649                                  bool force_send)
650 {
651   int ret;
652
653   /* If rekey protocol is active we must assure that all packets are
654      sent through packet queue. */
655   if (SILC_CLIENT_IS_REKEY(sock))
656     force_send = FALSE;
657
658   /* If outbound data is already pending do not force send */
659   if (SILC_IS_OUTBUF_PENDING(sock))
660     force_send = FALSE;
661
662   /* Send the packet */
663   ret = silc_packet_send(sock, force_send);
664   if (ret != -2)
665     return ret;
666
667   /* Mark that there is some outgoing data available for this connection. 
668      This call sets the connection both for input and output (the input
669      is set always and this call keeps the input setting, actually). 
670      Actual data sending is performed by silc_client_packet_process. */
671   SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(client->schedule, sock->sock);
672
673   /* Mark to socket that data is pending in outgoing buffer. This flag
674      is needed if new data is added to the buffer before the earlier
675      put data is sent to the network. */
676   SILC_SET_OUTBUF_PENDING(sock);
677
678   return 0;
679 }
680
681 /* Packet processing callback. This is used to send and receive packets
682    from network. This is generic task. */
683
684 SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
685 {
686   SilcClient client = (SilcClient)context;
687   SilcSocketConnection sock = NULL;
688   SilcClientConnection conn;
689   int ret;
690
691   SILC_LOG_DEBUG(("Processing packet"));
692
693   SILC_CLIENT_GET_SOCK(client, fd, sock);
694   if (sock == NULL)
695     return;
696
697   conn = (SilcClientConnection)sock->user_data;
698
699   /* Packet sending */
700   if (type == SILC_TASK_WRITE) {
701     /* Do not send data to disconnected connection */
702     if (SILC_IS_DISCONNECTED(sock))
703       return;
704
705     if (sock->outbuf->data - sock->outbuf->head)
706       silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
707
708     ret = silc_packet_send(sock, TRUE);
709
710     /* If returned -2 could not write to connection now, will do
711        it later. */
712     if (ret == -2)
713       return;
714
715     /* Error */
716     if (ret == -1)
717       return;
718     
719     /* The packet has been sent and now it is time to set the connection
720        back to only for input. When there is again some outgoing data 
721        available for this connection it will be set for output as well. 
722        This call clears the output setting and sets it only for input. */
723     SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, fd);
724     SILC_UNSET_OUTBUF_PENDING(sock);
725
726     silc_buffer_clear(sock->outbuf);
727     return;
728   }
729
730   /* Packet receiving */
731   if (type == SILC_TASK_READ) {
732     /* Read data from network */
733     ret = silc_packet_receive(sock);
734     if (ret < 0)
735       return;
736     
737     /* EOF */
738     if (ret == 0) {
739       SILC_LOG_DEBUG(("Read EOF"));
740
741       /* If connection is disconnecting already we will finally
742          close the connection */
743       if (SILC_IS_DISCONNECTING(sock)) {
744         if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
745           client->ops->disconnect(client, conn);
746         silc_client_close_connection(client, sock, conn);
747         return;
748       }
749       
750       SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
751       if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
752         client->ops->disconnect(client, conn);
753       silc_client_close_connection(client, sock, conn);
754       return;
755     }
756
757     /* Process the packet. This will call the parser that will then
758        decrypt and parse the packet. */
759     if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
760       silc_packet_receive_process(sock, FALSE, conn->receive_key, 
761                                   conn->hmac_receive, conn->psn_receive,
762                                   silc_client_packet_parse, client);
763     else
764       silc_packet_receive_process(sock, FALSE, NULL, NULL, 0, 
765                                   silc_client_packet_parse, client);
766   }
767 }
768
769 /* Parser callback called by silc_packet_receive_process. Thie merely
770    registers timeout that will handle the actual parsing when appropriate. */
771
772 static bool silc_client_packet_parse(SilcPacketParserContext *parser_context,
773                                      void *context)
774 {
775   SilcClient client = (SilcClient)context;
776   SilcSocketConnection sock = parser_context->sock;
777   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
778   SilcPacketContext *packet = parser_context->packet;
779   SilcPacketType ret;
780
781   if (conn && conn->hmac_receive && conn->sock == sock)
782     conn->psn_receive = parser_context->packet->sequence + 1;
783
784   /* Parse the packet immediately */
785   if (parser_context->normal)
786     ret = silc_packet_parse(packet, conn->receive_key);
787   else
788     ret = silc_packet_parse_special(packet, conn->receive_key);
789
790   if (ret == SILC_PACKET_NONE) {
791     silc_packet_context_free(packet);
792     silc_free(parser_context);
793     return FALSE;
794   }
795   
796   /* If protocol for this connection is key exchange or rekey then we'll
797      process all packets synchronously, since there might be packets in
798      queue that we are not able to decrypt without first processing the
799      packets before them. */
800   if ((ret == SILC_PACKET_REKEY || ret == SILC_PACKET_REKEY_DONE) ||
801       (sock->protocol && sock->protocol->protocol && 
802        (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
803         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY))) {
804
805     /* Parse the incoming packet type */
806     silc_client_packet_parse_type(client, sock, packet);
807     silc_packet_context_free(packet);
808     silc_free(parser_context);
809
810     /* Reprocess the buffer since we'll return FALSE. This is because
811        the `conn->receive_key' might have become valid by processing
812        the previous packet */
813     if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
814       silc_packet_receive_process(sock, FALSE, conn->receive_key, 
815                                   conn->hmac_receive, conn->psn_receive,
816                                   silc_client_packet_parse, client);
817     else
818       silc_packet_receive_process(sock, FALSE, NULL, NULL, 0, 
819                                   silc_client_packet_parse, client);
820     
821     return FALSE;
822   }
823
824   /* Parse the incoming packet type */
825   silc_client_packet_parse_type(client, sock, packet);
826   silc_packet_context_free(packet);
827   silc_free(parser_context);
828   return TRUE;
829 }
830
831 /* Parses the packet type and calls what ever routines the packet type
832    requires. This is done for all incoming packets. */
833
834 void silc_client_packet_parse_type(SilcClient client, 
835                                    SilcSocketConnection sock,
836                                    SilcPacketContext *packet)
837 {
838   SilcBuffer buffer = packet->buffer;
839   SilcPacketType type = packet->type;
840
841   SILC_LOG_DEBUG(("Parsing packet type %d", type));
842
843   /* Parse the packet type */
844   switch(type) {
845   case SILC_PACKET_DISCONNECT:
846     silc_client_disconnected_by_server(client, sock, buffer);
847     break;
848   case SILC_PACKET_SUCCESS:
849     /*
850      * Success received for something. For now we can have only
851      * one protocol for connection executing at once hence this
852      * success message is for whatever protocol is executing currently.
853      */
854     if (sock->protocol)
855       silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
856     break;
857   case SILC_PACKET_FAILURE:
858     /*
859      * Failure received for some protocol. Set the protocol state to 
860      * error and call the protocol callback. This fill cause error on
861      * protocol and it will call the final callback.
862      */
863     silc_client_process_failure(client, sock, packet);
864     break;
865   case SILC_PACKET_REJECT:
866     break;
867
868   case SILC_PACKET_NOTIFY:
869     /*
870      * Received notify message 
871      */
872     silc_client_notify_by_server(client, sock, packet);
873     break;
874
875   case SILC_PACKET_ERROR:
876     /*
877      * Received error message
878      */
879     silc_client_error_by_server(client, sock, buffer);
880     break;
881
882   case SILC_PACKET_CHANNEL_MESSAGE:
883     /*
884      * Received message to (from, actually) a channel
885      */
886     silc_client_channel_message(client, sock, packet);
887     break;
888   case SILC_PACKET_CHANNEL_KEY:
889     /*
890      * Received key for a channel. By receiving this key the client will be
891      * able to talk to the channel it has just joined. This can also be
892      * a new key for existing channel as keys expire peridiocally.
893      */
894     silc_client_receive_channel_key(client, sock, buffer);
895     break;
896
897   case SILC_PACKET_PRIVATE_MESSAGE:
898     /*
899      * Received private message
900      */
901     silc_client_private_message(client, sock, packet);
902     break;
903   case SILC_PACKET_PRIVATE_MESSAGE_KEY:
904     /*
905      * Received private message key
906      */
907     break;
908
909   case SILC_PACKET_COMMAND_REPLY:
910     /*
911      * Recived reply for a command
912      */
913     silc_client_command_reply_process(client, sock, packet);
914     break;
915
916   case SILC_PACKET_KEY_EXCHANGE:
917     if (sock->protocol && sock->protocol->protocol && 
918         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
919       SilcClientKEInternalContext *proto_ctx = 
920         (SilcClientKEInternalContext *)sock->protocol->context;
921
922       proto_ctx->packet = silc_packet_context_dup(packet);
923       proto_ctx->dest_id_type = packet->src_id_type;
924       proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
925                                           packet->src_id_type);
926       if (!proto_ctx->dest_id)
927         break;
928
929       /* Let the protocol handle the packet */
930       silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
931     } else {
932       SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
933                       "protocol active, packet dropped."));
934     }
935     break;
936
937   case SILC_PACKET_KEY_EXCHANGE_1:
938     if (sock->protocol && sock->protocol->protocol && 
939         (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
940          sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
941
942       if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
943         SilcClientRekeyInternalContext *proto_ctx = 
944           (SilcClientRekeyInternalContext *)sock->protocol->context;
945         
946         if (proto_ctx->packet)
947           silc_packet_context_free(proto_ctx->packet);
948         
949         proto_ctx->packet = silc_packet_context_dup(packet);
950
951         /* Let the protocol handle the packet */
952         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
953       } else {
954         SilcClientKEInternalContext *proto_ctx = 
955           (SilcClientKEInternalContext *)sock->protocol->context;
956         
957         if (proto_ctx->packet)
958           silc_packet_context_free(proto_ctx->packet);
959         
960         proto_ctx->packet = silc_packet_context_dup(packet);
961         proto_ctx->dest_id_type = packet->src_id_type;
962         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
963                                             packet->src_id_type);
964         if (!proto_ctx->dest_id)
965           break;
966         
967         /* Let the protocol handle the packet */
968         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
969       }
970     } else {
971       SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
972                       "protocol active, packet dropped."));
973     }
974     break;
975   case SILC_PACKET_KEY_EXCHANGE_2:
976     if (sock->protocol && sock->protocol->protocol && 
977         (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
978          sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
979
980       if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
981         SilcClientRekeyInternalContext *proto_ctx = 
982           (SilcClientRekeyInternalContext *)sock->protocol->context;
983         
984         if (proto_ctx->packet)
985           silc_packet_context_free(proto_ctx->packet);
986         
987         proto_ctx->packet = silc_packet_context_dup(packet);
988
989         /* Let the protocol handle the packet */
990         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
991       } else {
992         SilcClientKEInternalContext *proto_ctx = 
993           (SilcClientKEInternalContext *)sock->protocol->context;
994         
995         if (proto_ctx->packet)
996           silc_packet_context_free(proto_ctx->packet);
997         
998         proto_ctx->packet = silc_packet_context_dup(packet);
999         proto_ctx->dest_id_type = packet->src_id_type;
1000         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1001                                             packet->src_id_type);
1002         if (!proto_ctx->dest_id)
1003           break;
1004         
1005         /* Let the protocol handle the packet */
1006         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1007       }
1008     } else {
1009       SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1010                       "protocol active, packet dropped."));
1011     }
1012     break;
1013
1014   case SILC_PACKET_NEW_ID:
1015     {
1016       /*
1017        * Received new ID from server. This packet is received at
1018        * the connection to the server.  New ID is also received when 
1019        * user changes nickname but in that case the new ID is received
1020        * as command reply and not as this packet type.
1021        */
1022       SilcIDPayload idp;
1023
1024       idp = silc_id_payload_parse(buffer);
1025       if (!idp)
1026         break;
1027       if (silc_id_payload_get_type(idp) != SILC_ID_CLIENT)
1028         break;
1029
1030       silc_client_receive_new_id(client, sock, idp);
1031       silc_id_payload_free(idp);
1032       break;
1033     }
1034
1035   case SILC_PACKET_HEARTBEAT:
1036     /*
1037      * Received heartbeat packet
1038      */
1039     SILC_LOG_DEBUG(("Heartbeat packet"));
1040     break;
1041
1042   case SILC_PACKET_KEY_AGREEMENT:
1043     /*
1044      * Received key agreement packet
1045      */
1046     SILC_LOG_DEBUG(("Key agreement packet"));
1047     silc_client_key_agreement(client, sock, packet);
1048     break;
1049
1050   case SILC_PACKET_REKEY:
1051     SILC_LOG_DEBUG(("Re-key packet"));
1052     /* We ignore this for now */
1053     break;
1054
1055   case SILC_PACKET_REKEY_DONE:
1056     SILC_LOG_DEBUG(("Re-key done packet"));
1057
1058     if (sock->protocol && sock->protocol->protocol && 
1059         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
1060
1061       SilcClientRekeyInternalContext *proto_ctx = 
1062         (SilcClientRekeyInternalContext *)sock->protocol->context;
1063       
1064       if (proto_ctx->packet)
1065         silc_packet_context_free(proto_ctx->packet);
1066       
1067       proto_ctx->packet = silc_packet_context_dup(packet);
1068
1069       /* Let the protocol handle the packet */
1070       if (proto_ctx->responder == FALSE)
1071         silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1072       else
1073         /* Let the protocol handle the packet */
1074         silc_protocol_execute(sock->protocol, client->schedule, 
1075                               0, 100000);
1076     } else {
1077       SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
1078                       "protocol active, packet dropped."));
1079     }
1080     break;
1081
1082   case SILC_PACKET_CONNECTION_AUTH_REQUEST:
1083     /*
1084      * Reveived reply to our connection authentication method request
1085      * packet. This is used to resolve the authentication method for the
1086      * current session from the server if the client does not know it.
1087      */
1088     silc_client_connection_auth_request(client, sock, packet);
1089     break;
1090
1091   case SILC_PACKET_FTP:
1092     /* Received file transfer packet. */
1093     silc_client_ftp(client, sock, packet);
1094     break;
1095
1096   default:
1097     SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1098     break;
1099   }
1100 }
1101
1102 /* Sends packet. This doesn't actually send the packet instead it assembles
1103    it and marks it to be sent. However, if force_send is TRUE the packet
1104    is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1105    will be derived from sock argument. Otherwise the valid arguments sent
1106    are used. */
1107
1108 void silc_client_packet_send(SilcClient client, 
1109                              SilcSocketConnection sock,
1110                              SilcPacketType type, 
1111                              void *dst_id,
1112                              SilcIdType dst_id_type,
1113                              SilcCipher cipher,
1114                              SilcHmac hmac,
1115                              unsigned char *data, 
1116                              uint32 data_len, 
1117                              int force_send)
1118 {
1119   SilcPacketContext packetdata;
1120   int block_len;
1121   uint32 sequence = 0;
1122
1123   if (!sock)
1124     return;
1125
1126   SILC_LOG_DEBUG(("Sending packet, type %d", type));
1127
1128   /* Get data used in the packet sending, keys and stuff */
1129   if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1130     if (!cipher && ((SilcClientConnection)sock->user_data)->send_key)
1131       cipher = ((SilcClientConnection)sock->user_data)->send_key;
1132
1133     if (!hmac && ((SilcClientConnection)sock->user_data)->hmac_send)
1134       hmac = ((SilcClientConnection)sock->user_data)->hmac_send;
1135
1136     if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) {
1137       dst_id = ((SilcClientConnection)sock->user_data)->remote_id;
1138       dst_id_type = SILC_ID_SERVER;
1139     }
1140
1141     if (hmac)
1142       sequence = ((SilcClientConnection)sock->user_data)->psn_send++;
1143   }
1144
1145   block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
1146
1147   /* Set the packet context pointers */
1148   packetdata.flags = 0;
1149   packetdata.type = type;
1150   if (sock->user_data && 
1151       ((SilcClientConnection)sock->user_data)->local_id_data) {
1152     packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
1153     packetdata.src_id_len = 
1154       silc_id_get_len(((SilcClientConnection)sock->user_data)->local_id,
1155                       SILC_ID_CLIENT);
1156   } else { 
1157     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1158     packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1159   }
1160   packetdata.src_id_type = SILC_ID_CLIENT;
1161   if (dst_id) {
1162     packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1163     packetdata.dst_id_len = silc_id_get_len(dst_id, dst_id_type);
1164     packetdata.dst_id_type = dst_id_type;
1165   } else {
1166     packetdata.dst_id = NULL;
1167     packetdata.dst_id_len = 0;
1168     packetdata.dst_id_type = SILC_ID_NONE;
1169   }
1170   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
1171     packetdata.src_id_len + packetdata.dst_id_len;
1172   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len);
1173
1174   /* Prepare outgoing data buffer for packet sending */
1175   silc_packet_send_prepare(sock, 
1176                            SILC_PACKET_HEADER_LEN +
1177                            packetdata.src_id_len + 
1178                            packetdata.dst_id_len,
1179                            packetdata.padlen,
1180                            data_len);
1181
1182   SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1183
1184   packetdata.buffer = sock->outbuf;
1185
1186   /* Put the data to the buffer */
1187   if (data && data_len)
1188     silc_buffer_put(sock->outbuf, data, data_len);
1189
1190   /* Create the outgoing packet */
1191   silc_packet_assemble(&packetdata, cipher);
1192
1193   /* Encrypt the packet */
1194   if (cipher)
1195     silc_packet_encrypt(cipher, hmac, sequence, sock->outbuf, 
1196                         sock->outbuf->len);
1197
1198   SILC_LOG_HEXDUMP(("Packet (%d), len %d", sequence, sock->outbuf->len),
1199                    sock->outbuf->data, sock->outbuf->len);
1200
1201   /* Now actually send the packet */
1202   silc_client_packet_send_real(client, sock, force_send);
1203 }
1204
1205 void silc_client_packet_queue_purge(SilcClient client,
1206                                     SilcSocketConnection sock)
1207 {
1208   if (sock && SILC_IS_OUTBUF_PENDING(sock) && 
1209       (SILC_IS_DISCONNECTED(sock) == FALSE)) {
1210     if (sock->outbuf->data - sock->outbuf->head)
1211       silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
1212
1213     silc_packet_send(sock, TRUE);
1214
1215     SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, sock->sock);
1216     SILC_UNSET_OUTBUF_PENDING(sock);
1217     silc_buffer_clear(sock->outbuf);
1218   }
1219 }
1220
1221 /* Closes connection to remote end. Free's all allocated data except
1222    for some information such as nickname etc. that are valid at all time. 
1223    If the `sock' is NULL then the conn->sock will be used.  If `sock' is
1224    provided it will be checked whether the sock and `conn->sock' are the
1225    same (they can be different, ie. a socket can use `conn' as its
1226    connection but `conn->sock' might be actually a different connection
1227    than the `sock'). */
1228
1229 void silc_client_close_connection(SilcClient client,
1230                                   SilcSocketConnection sock,
1231                                   SilcClientConnection conn)
1232 {
1233   int del = FALSE;
1234
1235   SILC_LOG_DEBUG(("Start"));
1236
1237   if (!sock || (sock && conn->sock == sock))
1238     del = TRUE;
1239   if (!sock)
1240     sock = conn->sock;
1241
1242   /* We won't listen for this connection anymore */
1243   silc_schedule_unset_listen_fd(client->schedule, sock->sock);
1244
1245   /* Unregister all tasks */
1246   silc_schedule_task_del_by_fd(client->schedule, sock->sock);
1247   silc_schedule_task_del_by_fd(client->schedule, sock->sock);
1248
1249   /* Close the actual connection */
1250   silc_net_close_connection(sock->sock);
1251
1252   /* Cancel any active protocol */
1253   if (sock->protocol) {
1254     if (sock->protocol->protocol->type == 
1255         SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
1256         sock->protocol->protocol->type == 
1257         SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
1258       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1259       silc_protocol_execute_final(sock->protocol, client->schedule);
1260       /* The application will recall this function with these protocols
1261          (the ops->connect client operation). */
1262       return;
1263     } else {
1264       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1265       silc_protocol_execute_final(sock->protocol, client->schedule);
1266       sock->protocol = NULL;
1267     }
1268   }
1269
1270   /* Free everything */
1271   if (del && sock->user_data) {
1272     /* Free all cache entries */
1273     SilcIDCacheList list;
1274     SilcIDCacheEntry entry;
1275     bool ret;
1276
1277     if (silc_idcache_get_all(conn->client_cache, &list)) {
1278       ret = silc_idcache_list_first(list, &entry);
1279       while (ret) {
1280         silc_client_del_client(client, conn, entry->context);
1281         ret = silc_idcache_list_next(list, &entry);
1282       }
1283       silc_idcache_list_free(list);
1284     }
1285
1286     if (silc_idcache_get_all(conn->channel_cache, &list)) {
1287       ret = silc_idcache_list_first(list, &entry);
1288       while (ret) {
1289         silc_client_del_channel(client, conn, entry->context);
1290         ret = silc_idcache_list_next(list, &entry);
1291       }
1292       silc_idcache_list_free(list);
1293     }
1294
1295     if (silc_idcache_get_all(conn->server_cache, &list)) {
1296       ret = silc_idcache_list_first(list, &entry);
1297       while (ret) {
1298         silc_client_del_server(client, conn, entry->context);
1299         ret = silc_idcache_list_next(list, &entry);
1300       }
1301       silc_idcache_list_free(list);
1302     }
1303
1304     /* Clear ID caches */
1305     if (conn->client_cache)
1306       silc_idcache_del_all(conn->client_cache);
1307     if (conn->channel_cache)
1308       silc_idcache_del_all(conn->channel_cache);
1309     if (conn->server_cache)
1310       silc_idcache_del_all(conn->server_cache);
1311
1312     /* Free data (my ID is freed in above silc_client_del_client) */
1313     if (conn->remote_host)
1314       silc_free(conn->remote_host);
1315     if (conn->local_id_data)
1316       silc_free(conn->local_id_data);
1317     if (conn->send_key)
1318       silc_cipher_free(conn->send_key);
1319     if (conn->receive_key)
1320       silc_cipher_free(conn->receive_key);
1321     if (conn->hmac_send)
1322       silc_hmac_free(conn->hmac_send);
1323     if (conn->hmac_receive)
1324       silc_hmac_free(conn->hmac_receive);
1325     if (conn->pending_commands)
1326       silc_dlist_uninit(conn->pending_commands);
1327     if (conn->rekey)
1328       silc_free(conn->rekey);
1329
1330     if (conn->active_session) {
1331       sock->user_data = NULL;
1332       silc_client_ftp_session_free(conn->active_session);
1333       conn->active_session = NULL;
1334     }
1335
1336     silc_client_ftp_free_sessions(client, conn);
1337
1338     memset(conn, 0, sizeof(*conn));
1339     silc_client_del_connection(client, conn);
1340   }
1341
1342   silc_socket_free(sock);
1343 }
1344
1345 /* Called when we receive disconnection packet from server. This 
1346    closes our end properly and displays the reason of the disconnection
1347    on the screen. */
1348
1349 SILC_TASK_CALLBACK(silc_client_disconnected_by_server_later)
1350 {
1351   SilcClient client = (SilcClient)context;
1352   SilcSocketConnection sock;
1353
1354   SILC_CLIENT_GET_SOCK(client, fd, sock);
1355   if (sock == NULL)
1356     return;
1357
1358   silc_client_close_connection(client, sock, sock->user_data);
1359 }
1360
1361 /* Called when we receive disconnection packet from server. This 
1362    closes our end properly and displays the reason of the disconnection
1363    on the screen. */
1364
1365 void silc_client_disconnected_by_server(SilcClient client,
1366                                         SilcSocketConnection sock,
1367                                         SilcBuffer message)
1368 {
1369   char *msg;
1370
1371   SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
1372
1373   msg = silc_calloc(message->len + 1, sizeof(char));
1374   memcpy(msg, message->data, message->len);
1375   client->ops->say(client, sock->user_data, SILC_CLIENT_MESSAGE_AUDIT, msg);
1376   silc_free(msg);
1377
1378   SILC_SET_DISCONNECTED(sock);
1379
1380   /* Close connection through scheduler. */
1381   silc_schedule_task_add(client->schedule, sock->sock, 
1382                          silc_client_disconnected_by_server_later,
1383                          client, 0, 1, SILC_TASK_TIMEOUT, 
1384                          SILC_TASK_PRI_NORMAL);
1385 }
1386
1387 /* Received error message from server. Display it on the screen. 
1388    We don't take any action what so ever of the error message. */
1389
1390 void silc_client_error_by_server(SilcClient client,
1391                                  SilcSocketConnection sock,
1392                                  SilcBuffer message)
1393 {
1394   char *msg;
1395
1396   msg = silc_calloc(message->len + 1, sizeof(char));
1397   memcpy(msg, message->data, message->len);
1398   client->ops->say(client, sock->user_data, SILC_CLIENT_MESSAGE_AUDIT, msg);
1399   silc_free(msg);
1400 }
1401
1402 /* Processes the received new Client ID from server. Old Client ID is
1403    deleted from cache and new one is added. */
1404
1405 void silc_client_receive_new_id(SilcClient client,
1406                                 SilcSocketConnection sock,
1407                                 SilcIDPayload idp)
1408 {
1409   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1410   int connecting = FALSE;
1411   SilcBuffer sidp;
1412
1413   if (!conn->local_entry)
1414     connecting = TRUE;
1415
1416   /* Delete old ID from ID cache */
1417   if (conn->local_id) {
1418     silc_idcache_del_by_context(conn->client_cache, conn->local_entry);
1419     silc_free(conn->local_id);
1420   }
1421   
1422   /* Save the new ID */
1423
1424   if (conn->local_id_data)
1425     silc_free(conn->local_id_data);
1426
1427   conn->local_id = silc_id_payload_get_id(idp);
1428   conn->local_id_data = silc_id_payload_get_data(idp);
1429   conn->local_id_data_len = silc_id_payload_get_len(idp);;
1430
1431   if (!conn->local_entry)
1432     conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
1433
1434   conn->local_entry->nickname = conn->nickname;
1435   if (!conn->local_entry->username)
1436     conn->local_entry->username = strdup(client->username);
1437   if (!conn->local_entry->hostname)
1438     conn->local_entry->hostname = strdup(client->hostname);
1439   conn->local_entry->server = strdup(conn->remote_host);
1440   conn->local_entry->id = conn->local_id;
1441   conn->local_entry->valid = TRUE;
1442   
1443   /* Put it to the ID cache */
1444   silc_idcache_add(conn->client_cache, strdup(conn->nickname), conn->local_id, 
1445                    (void *)conn->local_entry, FALSE);
1446
1447   /* Issue INFO command to fetch the real server name and server information
1448      and other stuff. */
1449   sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
1450   silc_client_send_command(client, conn, SILC_COMMAND_INFO,
1451                            ++conn->cmd_ident, 1, 2, sidp->data, sidp->len);
1452   silc_buffer_free(sidp);
1453
1454   /* Notify application of successful connection. We do it here now that
1455      we've received the Client ID and are allowed to send traffic. */
1456   if (connecting)
1457     client->ops->connect(client, conn, TRUE);
1458 }
1459
1460 /* Processed received Channel ID for a channel. This is called when client
1461    joins to channel and server replies with channel ID. The ID is cached. 
1462    Returns the created channel entry. This is also called when received
1463    channel ID in for example USERS command reply that we do not have. */
1464
1465 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
1466                                             SilcSocketConnection sock,
1467                                             char *channel_name,
1468                                             uint32 mode, 
1469                                             SilcIDPayload idp)
1470 {
1471   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1472   SilcChannelEntry channel;
1473
1474   SILC_LOG_DEBUG(("New channel ID"));
1475
1476   channel = silc_calloc(1, sizeof(*channel));
1477   channel->channel_name = channel_name;
1478   channel->id = silc_id_payload_get_id(idp);
1479   channel->mode = mode;
1480   silc_list_init(channel->clients, struct SilcChannelUserStruct, next);
1481
1482   /* Put it to the ID cache */
1483   silc_idcache_add(conn->channel_cache, channel->channel_name, 
1484                    (void *)channel->id, (void *)channel, FALSE);
1485
1486   return channel;
1487 }
1488
1489 /* Removes a client entry from all channel it has joined. This really is
1490    a performance killer (client_entry should have pointers to channel 
1491    entry list). */
1492
1493 void silc_client_remove_from_channels(SilcClient client,
1494                                       SilcClientConnection conn,
1495                                       SilcClientEntry client_entry)
1496 {
1497   SilcIDCacheEntry id_cache;
1498   SilcIDCacheList list;
1499   SilcChannelEntry channel;
1500   SilcChannelUser chu;
1501
1502   if (!silc_idcache_get_all(conn->channel_cache, &list))
1503     return;
1504
1505   silc_idcache_list_first(list, &id_cache);
1506   channel = (SilcChannelEntry)id_cache->context;
1507   
1508   while (channel) {
1509     
1510     /* Remove client from channel */
1511     silc_list_start(channel->clients);
1512     while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
1513       if (chu->client == client_entry) {
1514         silc_list_del(channel->clients, chu);
1515         silc_free(chu);
1516         break;
1517       }
1518     }
1519
1520     if (!silc_idcache_list_next(list, &id_cache))
1521       break;
1522     
1523     channel = (SilcChannelEntry)id_cache->context;
1524   }
1525
1526   silc_idcache_list_free(list);
1527 }
1528
1529 /* Replaces `old' client entries from all channels to `new' client entry.
1530    This can be called for example when nickname changes and old ID entry
1531    is replaced from ID cache with the new one. If the old ID entry is only
1532    updated, then this fucntion needs not to be called. */
1533
1534 void silc_client_replace_from_channels(SilcClient client, 
1535                                        SilcClientConnection conn,
1536                                        SilcClientEntry old,
1537                                        SilcClientEntry new)
1538 {
1539   SilcIDCacheEntry id_cache;
1540   SilcIDCacheList list;
1541   SilcChannelEntry channel;
1542   SilcChannelUser chu;
1543
1544   if (!silc_idcache_get_all(conn->channel_cache, &list))
1545     return;
1546
1547   silc_idcache_list_first(list, &id_cache);
1548   channel = (SilcChannelEntry)id_cache->context;
1549   
1550   while (channel) {
1551     
1552     /* Replace client entry */
1553     silc_list_start(channel->clients);
1554     while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
1555       if (chu->client == old) {
1556         chu->client = new;
1557         break;
1558       }
1559     }
1560
1561     if (!silc_idcache_list_next(list, &id_cache))
1562       break;
1563     
1564     channel = (SilcChannelEntry)id_cache->context;
1565   }
1566
1567   silc_idcache_list_free(list);
1568 }
1569
1570 /* Registers failure timeout to process the received failure packet
1571    with timeout. */
1572
1573 void silc_client_process_failure(SilcClient client,
1574                                  SilcSocketConnection sock,
1575                                  SilcPacketContext *packet)
1576 {
1577   uint32 failure = 0;
1578
1579   if (sock->protocol) {
1580     if (packet->buffer->len >= 4)
1581       SILC_GET32_MSB(failure, packet->buffer->data);
1582
1583     /* Notify application */
1584     client->ops->failure(client, sock->user_data, sock->protocol,
1585                          (void *)failure);
1586   }
1587 }
1588
1589 /* A timeout callback for the re-key. We will be the initiator of the
1590    re-key protocol. */
1591
1592 SILC_TASK_CALLBACK(silc_client_rekey_callback)
1593 {
1594   SilcSocketConnection sock = (SilcSocketConnection)context;
1595   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1596   SilcClient client = (SilcClient)conn->rekey->context;
1597   SilcProtocol protocol;
1598   SilcClientRekeyInternalContext *proto_ctx;
1599
1600   SILC_LOG_DEBUG(("Start"));
1601
1602   /* Allocate internal protocol context. This is sent as context
1603      to the protocol. */
1604   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1605   proto_ctx->client = (void *)client;
1606   proto_ctx->sock = silc_socket_dup(sock);
1607   proto_ctx->responder = FALSE;
1608   proto_ctx->pfs = conn->rekey->pfs;
1609       
1610   /* Perform rekey protocol. Will call the final callback after the
1611      protocol is over. */
1612   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_REKEY, 
1613                       &protocol, proto_ctx, silc_client_rekey_final);
1614   sock->protocol = protocol;
1615       
1616   /* Run the protocol */
1617   silc_protocol_execute(protocol, client->schedule, 0, 0);
1618
1619   /* Re-register re-key timeout */
1620   silc_schedule_task_add(client->schedule, sock->sock, 
1621                          silc_client_rekey_callback,
1622                          context, conn->rekey->timeout, 0,
1623                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1624 }
1625
1626 /* The final callback for the REKEY protocol. This will actually take the
1627    new key material into use. */
1628
1629 SILC_TASK_CALLBACK(silc_client_rekey_final)
1630 {
1631   SilcProtocol protocol = (SilcProtocol)context;
1632   SilcClientRekeyInternalContext *ctx =
1633     (SilcClientRekeyInternalContext *)protocol->context;
1634   SilcClient client = (SilcClient)ctx->client;
1635   SilcSocketConnection sock = ctx->sock;
1636
1637   SILC_LOG_DEBUG(("Start"));
1638
1639   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1640       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1641     /* Error occured during protocol */
1642     silc_protocol_cancel(protocol, client->schedule);
1643     silc_protocol_free(protocol);
1644     sock->protocol = NULL;
1645     if (ctx->packet)
1646       silc_packet_context_free(ctx->packet);
1647     if (ctx->ske)
1648       silc_ske_free(ctx->ske);
1649     silc_socket_free(ctx->sock);
1650     silc_free(ctx);
1651     return;
1652   }
1653
1654   /* Purge the outgoing data queue to assure that all rekey packets really
1655      go to the network before we quit the protocol. */
1656   silc_client_packet_queue_purge(client, sock);
1657
1658   /* Cleanup */
1659   silc_protocol_free(protocol);
1660   sock->protocol = NULL;
1661   if (ctx->packet)
1662     silc_packet_context_free(ctx->packet);
1663   if (ctx->ske)
1664     silc_ske_free(ctx->ske);
1665   silc_socket_free(ctx->sock);
1666   silc_free(ctx);
1667 }
1668
1669 /* Processes incoming connection authentication method request packet.
1670    It is a reply to our previously sent request. The packet can be used
1671    to resolve the authentication method for the current session if the
1672    client does not know it beforehand. */
1673
1674 void silc_client_connection_auth_request(SilcClient client,
1675                                          SilcSocketConnection sock,
1676                                          SilcPacketContext *packet)
1677 {
1678   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1679   uint16 conn_type, auth_meth;
1680   int ret;
1681
1682   /* If we haven't send our request then ignore this one. */
1683   if (!conn->connauth)
1684     return;
1685
1686   /* Parse the payload */
1687   ret = silc_buffer_unformat(packet->buffer,
1688                              SILC_STR_UI_SHORT(&conn_type),
1689                              SILC_STR_UI_SHORT(&auth_meth),
1690                              SILC_STR_END);
1691   if (ret == -1)
1692     auth_meth = SILC_AUTH_NONE;
1693
1694   /* Call the request callback to notify application for received 
1695      authentication method information. */
1696   if (conn->connauth->callback)
1697     (*conn->connauth->callback)(client, conn, auth_meth,
1698                                 conn->connauth->context);
1699
1700   silc_schedule_task_del(client->schedule, conn->connauth->timeout);
1701
1702   silc_free(conn->connauth);
1703   conn->connauth = NULL;
1704 }
1705
1706 /* Timeout task callback called if the server does not reply to our 
1707    connection authentication method request in the specified time interval. */
1708
1709 SILC_TASK_CALLBACK(silc_client_request_authentication_method_timeout)
1710 {
1711   SilcClientConnection conn = (SilcClientConnection)context;
1712   SilcClient client = conn->client;
1713
1714   if (!conn->connauth)
1715     return;
1716
1717   /* Call the request callback to notify application */
1718   if (conn->connauth->callback)
1719     (*conn->connauth->callback)(client, conn, SILC_AUTH_NONE,
1720                                 conn->connauth->context);
1721
1722   silc_free(conn->connauth);
1723   conn->connauth = NULL;
1724 }
1725
1726 /* This function can be used to request the current authentication method
1727    from the server. This may be called when connecting to the server
1728    and the client library requests the authentication data from the
1729    application. If the application does not know the current authentication
1730    method it can request it from the server using this function.
1731    The `callback' with `context' will be called after the server has
1732    replied back with the current authentication method. */
1733
1734 void 
1735 silc_client_request_authentication_method(SilcClient client,
1736                                           SilcClientConnection conn,
1737                                           SilcConnectionAuthRequest callback,
1738                                           void *context)
1739 {
1740   SilcClientConnAuthRequest connauth;
1741   SilcBuffer packet;
1742
1743   connauth = silc_calloc(1, sizeof(*connauth));
1744   connauth->callback = callback;
1745   connauth->context = context;
1746
1747   if (conn->connauth)
1748     silc_free(conn->connauth);
1749
1750   conn->connauth = connauth;
1751
1752   /* Assemble the request packet and send it to the server */
1753   packet = silc_buffer_alloc(4);
1754   silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1755   silc_buffer_format(packet,
1756                      SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
1757                      SILC_STR_UI_SHORT(SILC_AUTH_NONE),
1758                      SILC_STR_END);
1759   silc_client_packet_send(client, conn->sock, 
1760                           SILC_PACKET_CONNECTION_AUTH_REQUEST,
1761                           NULL, 0, NULL, NULL, 
1762                           packet->data, packet->len, FALSE);
1763   silc_buffer_free(packet);
1764
1765   /* Register a timeout in case server does not reply anything back. */
1766   connauth->timeout =
1767     silc_schedule_task_add(client->schedule, conn->sock->sock, 
1768                            silc_client_request_authentication_method_timeout,
1769                            conn, client->params->connauth_request_secs, 0,
1770                            SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1771 }