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