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