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