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 = 30; /* 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, FALSE);
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,
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, buffer, packet,
742                               silc_client_packet_decrypt_check, parse_ctx);
743   else
744     ret = silc_packet_decrypt(NULL, NULL, buffer, packet,
745                               silc_client_packet_decrypt_check, parse_ctx);
746
747   if (ret < 0)
748     goto out;
749
750   if (ret == 0) {
751     /* Parse the packet. Packet type is returned. */
752     ret = silc_packet_parse(packet);
753   } else {
754     /* Parse the packet header in special way as this is "special"
755        packet type. */
756     ret = silc_packet_parse_special(packet);
757   }
758
759   if (ret == SILC_PACKET_NONE)
760     goto out;
761
762   /* Parse the incoming packet type */
763   silc_client_packet_parse_type(client, sock, packet);
764
765  out:
766   /*  silc_buffer_clear(sock->inbuf); */
767   silc_packet_context_free(packet);
768   silc_free(parse_ctx);
769 }
770
771 /* Parser callback called by silc_packet_receive_process. Thie merely
772    registers timeout that will handle the actual parsing when appropriate. */
773
774 void silc_client_packet_parse(SilcPacketParserContext *parser_context)
775 {
776   SilcClient client = (SilcClient)parser_context->context;
777
778   /* Parse the packet */
779
780   /* If REKEY protocol is active we must proccess the packets synchronously
781      since we must assure that incoming packets that are encrypted with
782      the old key is processed before the new keys is set to use. */
783   if (SILC_CLIENT_IS_REKEY(parser_context->sock))
784     silc_client_packet_parse_real(client->timeout_queue, SILC_TASK_READ,
785                                   (void *)parser_context, 
786                                   parser_context->sock->sock);
787   else
788     silc_task_register(client->timeout_queue, parser_context->sock->sock, 
789                        silc_client_packet_parse_real,
790                        (void *)parser_context, 0, 1, 
791                        SILC_TASK_TIMEOUT,
792                        SILC_TASK_PRI_NORMAL);
793 }
794
795 /* Parses the packet type and calls what ever routines the packet type
796    requires. This is done for all incoming packets. */
797
798 void silc_client_packet_parse_type(SilcClient client, 
799                                    SilcSocketConnection sock,
800                                    SilcPacketContext *packet)
801 {
802   SilcBuffer buffer = packet->buffer;
803   SilcPacketType type = packet->type;
804
805   SILC_LOG_DEBUG(("Parsing packet type %d", type));
806
807   /* Parse the packet type */
808   switch(type) {
809   case SILC_PACKET_DISCONNECT:
810     silc_client_disconnected_by_server(client, sock, buffer);
811     break;
812   case SILC_PACKET_SUCCESS:
813     /*
814      * Success received for something. For now we can have only
815      * one protocol for connection executing at once hence this
816      * success message is for whatever protocol is executing currently.
817      */
818     if (sock->protocol) {
819       sock->protocol->execute(client->timeout_queue, 0,
820                               sock->protocol, sock->sock, 0, 0);
821     }
822     break;
823   case SILC_PACKET_FAILURE:
824     /*
825      * Failure received for some protocol. Set the protocol state to 
826      * error and call the protocol callback. This fill cause error on
827      * protocol and it will call the final callback.
828      */
829     silc_client_process_failure(client, sock, packet);
830     break;
831   case SILC_PACKET_REJECT:
832     break;
833
834   case SILC_PACKET_NOTIFY:
835     /*
836      * Received notify message 
837      */
838     silc_client_notify_by_server(client, sock, packet);
839     break;
840
841   case SILC_PACKET_ERROR:
842     /*
843      * Received error message
844      */
845     silc_client_error_by_server(client, sock, buffer);
846     break;
847
848   case SILC_PACKET_CHANNEL_MESSAGE:
849     /*
850      * Received message to (from, actually) a channel
851      */
852     silc_client_channel_message(client, sock, packet);
853     break;
854   case SILC_PACKET_CHANNEL_KEY:
855     /*
856      * Received key for a channel. By receiving this key the client will be
857      * able to talk to the channel it has just joined. This can also be
858      * a new key for existing channel as keys expire peridiocally.
859      */
860     silc_client_receive_channel_key(client, sock, buffer);
861     break;
862
863   case SILC_PACKET_PRIVATE_MESSAGE:
864     /*
865      * Received private message
866      */
867     silc_client_private_message(client, sock, packet);
868     break;
869   case SILC_PACKET_PRIVATE_MESSAGE_KEY:
870     /*
871      * Received private message key
872      */
873     break;
874
875   case SILC_PACKET_COMMAND_REPLY:
876     /*
877      * Recived reply for a command
878      */
879     silc_client_command_reply_process(client, sock, packet);
880     break;
881
882   case SILC_PACKET_KEY_EXCHANGE:
883     if (sock->protocol && sock->protocol->protocol && 
884         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
885       SilcClientKEInternalContext *proto_ctx = 
886         (SilcClientKEInternalContext *)sock->protocol->context;
887
888       proto_ctx->packet = silc_packet_context_dup(packet);
889       proto_ctx->dest_id_type = packet->src_id_type;
890       proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
891                                           packet->src_id_type);
892       if (!proto_ctx->dest_id)
893         break;
894
895       /* Let the protocol handle the packet */
896       sock->protocol->execute(client->timeout_queue, 0,
897                               sock->protocol, sock->sock, 0, 0);
898     } else {
899       SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
900                       "protocol active, packet dropped."));
901
902       /* XXX Trigger KE protocol?? Rekey actually! */
903     }
904     break;
905
906   case SILC_PACKET_KEY_EXCHANGE_1:
907     if (sock->protocol && sock->protocol->protocol && 
908         (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
909          sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
910
911       if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
912         SilcClientRekeyInternalContext *proto_ctx = 
913           (SilcClientRekeyInternalContext *)sock->protocol->context;
914         
915         if (proto_ctx->packet)
916           silc_packet_context_free(proto_ctx->packet);
917         
918         proto_ctx->packet = silc_packet_context_dup(packet);
919
920         /* Let the protocol handle the packet */
921         sock->protocol->execute(client->timeout_queue, 0, 
922                                 sock->protocol, sock->sock, 0, 0);
923       } else {
924         SilcClientKEInternalContext *proto_ctx = 
925           (SilcClientKEInternalContext *)sock->protocol->context;
926         
927         if (proto_ctx->packet)
928           silc_packet_context_free(proto_ctx->packet);
929         
930         proto_ctx->packet = silc_packet_context_dup(packet);
931         proto_ctx->dest_id_type = packet->src_id_type;
932         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
933                                             packet->src_id_type);
934         if (!proto_ctx->dest_id)
935           break;
936         
937         /* Let the protocol handle the packet */
938         sock->protocol->execute(client->timeout_queue, 0,
939                                 sock->protocol, sock->sock, 0, 0);
940       }
941     } else {
942       SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
943                       "protocol active, packet dropped."));
944     }
945     break;
946   case SILC_PACKET_KEY_EXCHANGE_2:
947     if (sock->protocol && sock->protocol->protocol && 
948         (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
949          sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
950
951       if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
952         SilcClientRekeyInternalContext *proto_ctx = 
953           (SilcClientRekeyInternalContext *)sock->protocol->context;
954         
955         if (proto_ctx->packet)
956           silc_packet_context_free(proto_ctx->packet);
957         
958         proto_ctx->packet = silc_packet_context_dup(packet);
959
960         /* Let the protocol handle the packet */
961         sock->protocol->execute(client->timeout_queue, 0, 
962                                 sock->protocol, sock->sock, 0, 0);
963       } else {
964         SilcClientKEInternalContext *proto_ctx = 
965           (SilcClientKEInternalContext *)sock->protocol->context;
966         
967         if (proto_ctx->packet)
968           silc_packet_context_free(proto_ctx->packet);
969         
970         proto_ctx->packet = silc_packet_context_dup(packet);
971         proto_ctx->dest_id_type = packet->src_id_type;
972         proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
973                                             packet->src_id_type);
974         if (!proto_ctx->dest_id)
975           break;
976         
977         /* Let the protocol handle the packet */
978         sock->protocol->execute(client->timeout_queue, 0,
979                                 sock->protocol, sock->sock, 0, 0);
980       }
981     } else {
982       SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
983                       "protocol active, packet dropped."));
984     }
985     break;
986
987   case SILC_PACKET_NEW_ID:
988     {
989       /*
990        * Received new ID from server. This packet is received at
991        * the connection to the server.  New ID is also received when 
992        * user changes nickname but in that case the new ID is received
993        * as command reply and not as this packet type.
994        */
995       SilcIDPayload idp;
996
997       idp = silc_id_payload_parse(buffer);
998       if (!idp)
999         break;
1000       if (silc_id_payload_get_type(idp) != SILC_ID_CLIENT)
1001         break;
1002
1003       silc_client_receive_new_id(client, sock, idp);
1004       silc_id_payload_free(idp);
1005       break;
1006     }
1007
1008   case SILC_PACKET_HEARTBEAT:
1009     /*
1010      * Received heartbeat packet
1011      */
1012     SILC_LOG_DEBUG(("Heartbeat packet"));
1013     break;
1014
1015   case SILC_PACKET_KEY_AGREEMENT:
1016     /*
1017      * Received key agreement packet
1018      */
1019     SILC_LOG_DEBUG(("Key agreement packet"));
1020     silc_client_key_agreement(client, sock, packet);
1021     break;
1022
1023   case SILC_PACKET_REKEY:
1024     SILC_LOG_DEBUG(("Re-key packet"));
1025     /* We ignore this for now */
1026     break;
1027
1028   case SILC_PACKET_REKEY_DONE:
1029     SILC_LOG_DEBUG(("Re-key done packet"));
1030
1031     if (sock->protocol && sock->protocol->protocol && 
1032         sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
1033
1034       SilcClientRekeyInternalContext *proto_ctx = 
1035         (SilcClientRekeyInternalContext *)sock->protocol->context;
1036       
1037       if (proto_ctx->packet)
1038         silc_packet_context_free(proto_ctx->packet);
1039       
1040       proto_ctx->packet = silc_packet_context_dup(packet);
1041
1042       /* Let the protocol handle the packet */
1043       if (proto_ctx->responder == FALSE)
1044         sock->protocol->execute(client->timeout_queue, 0, 
1045                                 sock->protocol, sock->sock, 0, 0);
1046       else
1047         /* Let the protocol handle the packet */
1048         sock->protocol->execute(client->timeout_queue, 0, 
1049                                 sock->protocol, sock->sock, 0, 100000);
1050     } else {
1051       SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
1052                       "protocol active, packet dropped."));
1053     }
1054     break;
1055
1056   default:
1057     SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1058     break;
1059   }
1060 }
1061
1062 /* Sends packet. This doesn't actually send the packet instead it assembles
1063    it and marks it to be sent. However, if force_send is TRUE the packet
1064    is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1065    will be derived from sock argument. Otherwise the valid arguments sent
1066    are used. */
1067
1068 void silc_client_packet_send(SilcClient client, 
1069                              SilcSocketConnection sock,
1070                              SilcPacketType type, 
1071                              void *dst_id,
1072                              SilcIdType dst_id_type,
1073                              SilcCipher cipher,
1074                              SilcHmac hmac,
1075                              unsigned char *data, 
1076                              uint32 data_len, 
1077                              int force_send)
1078 {
1079   SilcPacketContext packetdata;
1080
1081   SILC_LOG_DEBUG(("Sending packet, type %d", type));
1082
1083   /* Get data used in the packet sending, keys and stuff */
1084   if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1085     if (!cipher && ((SilcClientConnection)sock->user_data)->send_key)
1086       cipher = ((SilcClientConnection)sock->user_data)->send_key;
1087
1088     if (!hmac && ((SilcClientConnection)sock->user_data)->hmac)
1089       hmac = ((SilcClientConnection)sock->user_data)->hmac;
1090
1091     if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) {
1092       dst_id = ((SilcClientConnection)sock->user_data)->remote_id;
1093       dst_id_type = SILC_ID_SERVER;
1094     }
1095   }
1096
1097   /* Set the packet context pointers */
1098   packetdata.flags = 0;
1099   packetdata.type = type;
1100   if (sock->user_data && 
1101       ((SilcClientConnection)sock->user_data)->local_id_data)
1102     packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
1103   else 
1104     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1105   packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1106   packetdata.src_id_type = SILC_ID_CLIENT;
1107   if (dst_id) {
1108     packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1109     packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1110     packetdata.dst_id_type = dst_id_type;
1111   } else {
1112     packetdata.dst_id = NULL;
1113     packetdata.dst_id_len = 0;
1114     packetdata.dst_id_type = SILC_ID_NONE;
1115   }
1116   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
1117     packetdata.src_id_len + packetdata.dst_id_len;
1118   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1119
1120   /* Prepare outgoing data buffer for packet sending */
1121   silc_packet_send_prepare(sock, 
1122                            SILC_PACKET_HEADER_LEN +
1123                            packetdata.src_id_len + 
1124                            packetdata.dst_id_len,
1125                            packetdata.padlen,
1126                            data_len);
1127
1128   SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1129
1130   packetdata.buffer = sock->outbuf;
1131
1132   /* Put the data to the buffer */
1133   if (data && data_len)
1134     silc_buffer_put(sock->outbuf, data, data_len);
1135
1136   /* Create the outgoing packet */
1137   silc_packet_assemble(&packetdata);
1138
1139   /* Encrypt the packet */
1140   if (cipher)
1141     silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
1142
1143   SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1144                    sock->outbuf->data, sock->outbuf->len);
1145
1146   /* Now actually send the packet */
1147   silc_client_packet_send_real(client, sock, force_send, FALSE);
1148 }
1149
1150 void silc_client_packet_send_flush(SilcClient client, 
1151                                    SilcSocketConnection sock,
1152                                    SilcPacketType type, 
1153                                    void *dst_id,
1154                                    SilcIdType dst_id_type,
1155                                    SilcCipher cipher,
1156                                    SilcHmac hmac,
1157                                    unsigned char *data, 
1158                                    uint32 data_len)
1159 {
1160   SilcPacketContext packetdata;
1161
1162   /* First flush the packet queue. */
1163   
1164   if (sock->outbuf->data - sock->outbuf->head)
1165     silc_buffer_push(sock->outbuf, 
1166                      sock->outbuf->data - sock->outbuf->head);
1167   
1168   silc_client_packet_send_real(client, sock, TRUE, TRUE);
1169   
1170   /* The packet has been sent and now it is time to set the connection
1171      back to only for input. When there is again some outgoing data 
1172      available for this connection it will be set for output as well. 
1173      This call clears the output setting and sets it only for input. */
1174   SILC_CLIENT_SET_CONNECTION_FOR_INPUT(sock->sock);
1175   SILC_UNSET_OUTBUF_PENDING(sock);
1176   silc_buffer_clear(sock->outbuf);
1177
1178   SILC_LOG_DEBUG(("Sending packet, type %d", type));
1179
1180   /* Get data used in the packet sending, keys and stuff */
1181   if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1182     if (!cipher && ((SilcClientConnection)sock->user_data)->send_key)
1183       cipher = ((SilcClientConnection)sock->user_data)->send_key;
1184
1185     if (!hmac && ((SilcClientConnection)sock->user_data)->hmac)
1186       hmac = ((SilcClientConnection)sock->user_data)->hmac;
1187
1188     if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) {
1189       dst_id = ((SilcClientConnection)sock->user_data)->remote_id;
1190       dst_id_type = SILC_ID_SERVER;
1191     }
1192   }
1193
1194   /* Set the packet context pointers */
1195   packetdata.flags = 0;
1196   packetdata.type = type;
1197   if (sock->user_data && 
1198       ((SilcClientConnection)sock->user_data)->local_id_data)
1199     packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
1200   else 
1201     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1202   packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1203   packetdata.src_id_type = SILC_ID_CLIENT;
1204   if (dst_id) {
1205     packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1206     packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1207     packetdata.dst_id_type = dst_id_type;
1208   } else {
1209     packetdata.dst_id = NULL;
1210     packetdata.dst_id_len = 0;
1211     packetdata.dst_id_type = SILC_ID_NONE;
1212   }
1213   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
1214     packetdata.src_id_len + packetdata.dst_id_len;
1215   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1216
1217   /* Prepare outgoing data buffer for packet sending */
1218   silc_packet_send_prepare(sock, 
1219                            SILC_PACKET_HEADER_LEN +
1220                            packetdata.src_id_len + 
1221                            packetdata.dst_id_len,
1222                            packetdata.padlen,
1223                            data_len);
1224
1225   SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1226
1227   packetdata.buffer = sock->outbuf;
1228
1229   /* Put the data to the buffer */
1230   if (data && data_len)
1231     silc_buffer_put(sock->outbuf, data, data_len);
1232
1233   /* Create the outgoing packet */
1234   silc_packet_assemble(&packetdata);
1235
1236   /* Encrypt the packet */
1237   if (cipher)
1238     silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
1239
1240   SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1241                    sock->outbuf->data, sock->outbuf->len);
1242
1243   /* Now actually send the packet */
1244   silc_client_packet_send_real(client, sock, TRUE, TRUE);
1245 }
1246
1247 /* Closes connection to remote end. Free's all allocated data except
1248    for some information such as nickname etc. that are valid at all time. 
1249    If the `sock' is NULL then the conn->sock will be used.  If `sock' is
1250    provided it will be checked whether the sock and `conn->sock' are the
1251    same (they can be different, ie. a socket can use `conn' as its
1252    connection but `conn->sock' might be actually a different connection
1253    than the `sock'). */
1254
1255 void silc_client_close_connection(SilcClient client,
1256                                   SilcSocketConnection sock,
1257                                   SilcClientConnection conn)
1258 {
1259   int del = FALSE;
1260
1261   if (!sock || (sock && conn->sock == sock))
1262     del = TRUE;
1263   if (!sock)
1264     sock = conn->sock;
1265
1266   /* We won't listen for this connection anymore */
1267   silc_schedule_unset_listen_fd(sock->sock);
1268
1269   /* Unregister all tasks */
1270   silc_task_unregister_by_fd(client->io_queue, sock->sock);
1271   silc_task_unregister_by_fd(client->timeout_queue, sock->sock);
1272
1273   /* Close the actual connection */
1274   silc_net_close_connection(sock->sock);
1275
1276   /* Free everything */
1277   if (del && sock->user_data) {
1278     /* XXX Free all client entries and channel entries. */
1279
1280     client->ops->say(client, sock->user_data,
1281                      "Closed connection to host %s", sock->hostname);
1282
1283     /* Clear ID caches */
1284     silc_idcache_del_all(conn->client_cache);
1285     silc_idcache_del_all(conn->channel_cache);
1286
1287     /* Free data */
1288     if (conn->remote_host)
1289       silc_free(conn->remote_host);
1290     if (conn->local_id)
1291       silc_free(conn->local_id);
1292     if (conn->local_id_data)
1293       silc_free(conn->local_id_data);
1294     if (conn->send_key)
1295       silc_cipher_free(conn->send_key);
1296     if (conn->receive_key)
1297       silc_cipher_free(conn->receive_key);
1298     if (conn->hmac)
1299       silc_hmac_free(conn->hmac);
1300     if (conn->pending_commands)
1301       silc_dlist_uninit(conn->pending_commands);
1302     if (conn->rekey)
1303       silc_free(conn->rekey);
1304
1305     conn->sock = NULL;
1306     conn->remote_port = 0;
1307     conn->remote_type = 0;
1308     conn->send_key = NULL;
1309     conn->receive_key = NULL;
1310     conn->hmac = NULL;
1311     conn->local_id = NULL;
1312     conn->local_id_data = NULL;
1313     conn->remote_host = NULL;
1314     conn->current_channel = NULL;
1315     conn->pending_commands = NULL;
1316     conn->rekey = NULL;
1317
1318     silc_client_del_connection(client, conn);
1319   }
1320
1321   if (sock->protocol) {
1322     silc_protocol_free(sock->protocol);
1323     sock->protocol = NULL;
1324   }
1325   silc_socket_free(sock);
1326 }
1327
1328 /* Called when we receive disconnection packet from server. This 
1329    closes our end properly and displays the reason of the disconnection
1330    on the screen. */
1331
1332 void silc_client_disconnected_by_server(SilcClient client,
1333                                         SilcSocketConnection sock,
1334                                         SilcBuffer message)
1335 {
1336   char *msg;
1337
1338   SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
1339
1340   msg = silc_calloc(message->len + 1, sizeof(char));
1341   memcpy(msg, message->data, message->len);
1342   client->ops->say(client, sock->user_data, msg);
1343   silc_free(msg);
1344
1345   SILC_SET_DISCONNECTED(sock);
1346   silc_client_close_connection(client, sock, sock->user_data);
1347 }
1348
1349 /* Received error message from server. Display it on the screen. 
1350    We don't take any action what so ever of the error message. */
1351
1352 void silc_client_error_by_server(SilcClient client,
1353                                  SilcSocketConnection sock,
1354                                  SilcBuffer message)
1355 {
1356   char *msg;
1357
1358   msg = silc_calloc(message->len + 1, sizeof(char));
1359   memcpy(msg, message->data, message->len);
1360   client->ops->say(client, sock->user_data, msg);
1361   silc_free(msg);
1362 }
1363
1364 /* Processes the received new Client ID from server. Old Client ID is
1365    deleted from cache and new one is added. */
1366
1367 void silc_client_receive_new_id(SilcClient client,
1368                                 SilcSocketConnection sock,
1369                                 SilcIDPayload idp)
1370 {
1371   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1372   int connecting = FALSE;
1373
1374   if (!conn->local_entry)
1375     connecting = TRUE;
1376
1377   /* Delete old ID from ID cache */
1378   silc_idcache_del_by_id(conn->client_cache, SILC_ID_CLIENT, conn->local_id);
1379   
1380   /* Save the new ID */
1381   if (conn->local_id)
1382     silc_free(conn->local_id);
1383   if (conn->local_id_data)
1384     silc_free(conn->local_id_data);
1385
1386   conn->local_id = silc_id_payload_get_id(idp);
1387   conn->local_id_data = silc_id_payload_get_data(idp);
1388   conn->local_id_data_len = silc_id_payload_get_len(idp);;
1389
1390   if (!conn->local_entry)
1391     conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
1392
1393   conn->local_entry->nickname = conn->nickname;
1394   if (!conn->local_entry->username) {
1395     conn->local_entry->username = 
1396       silc_calloc(strlen(client->username) + strlen(client->hostname) + 1,
1397                   sizeof(conn->local_entry->username));
1398     sprintf(conn->local_entry->username, "%s@%s", client->username,
1399             client->hostname);
1400   }
1401   conn->local_entry->server = strdup(conn->remote_host);
1402   conn->local_entry->id = conn->local_id;
1403   
1404   /* Put it to the ID cache */
1405   silc_idcache_add(conn->client_cache, conn->nickname, strlen(conn->nickname),
1406                    SILC_ID_CLIENT, conn->local_id, (void *)conn->local_entry,
1407                    TRUE, FALSE);
1408
1409   /* Notify application of successful connection. We do it here now that
1410      we've received the Client ID and are allowed to send traffic. */
1411   if (connecting)
1412     client->ops->connect(client, conn, TRUE);
1413 }
1414
1415 /* Processed received Channel ID for a channel. This is called when client
1416    joins to channel and server replies with channel ID. The ID is cached. 
1417    Returns the created channel entry. */
1418
1419 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
1420                                             SilcSocketConnection sock,
1421                                             char *channel_name,
1422                                             uint32 mode, 
1423                                             SilcIDPayload idp)
1424 {
1425   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1426   SilcChannelEntry channel;
1427
1428   SILC_LOG_DEBUG(("New channel ID"));
1429
1430   channel = silc_calloc(1, sizeof(*channel));
1431   channel->channel_name = channel_name;
1432   channel->id = silc_id_payload_get_id(idp);
1433   channel->mode = mode;
1434   silc_list_init(channel->clients, struct SilcChannelUserStruct, next);
1435
1436   conn->current_channel = channel;
1437
1438   /* Put it to the ID cache */
1439   silc_idcache_add(conn->channel_cache, channel_name, strlen(channel_name),
1440                    SILC_ID_CHANNEL, (void *)channel->id, (void *)channel, 
1441                    TRUE, FALSE);
1442
1443   return channel;
1444 }
1445
1446 /* Removes a client entry from all channel it has joined. This really is
1447    a performance killer (client_entry should have pointers to channel 
1448    entry list). */
1449
1450 void silc_client_remove_from_channels(SilcClient client,
1451                                       SilcClientConnection conn,
1452                                       SilcClientEntry client_entry)
1453 {
1454   SilcIDCacheEntry id_cache;
1455   SilcIDCacheList list;
1456   SilcChannelEntry channel;
1457   SilcChannelUser chu;
1458
1459   if (!silc_idcache_find_by_id(conn->channel_cache, SILC_ID_CACHE_ANY,
1460                                SILC_ID_CHANNEL, &list))
1461     return;
1462
1463   silc_idcache_list_first(list, &id_cache);
1464   channel = (SilcChannelEntry)id_cache->context;
1465   
1466   while (channel) {
1467     
1468     /* Remove client from channel */
1469     silc_list_start(channel->clients);
1470     while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
1471       if (chu->client == client_entry) {
1472         silc_list_del(channel->clients, chu);
1473         silc_free(chu);
1474         break;
1475       }
1476     }
1477
1478     if (!silc_idcache_list_next(list, &id_cache))
1479       break;
1480     
1481     channel = (SilcChannelEntry)id_cache->context;
1482   }
1483
1484   silc_idcache_list_free(list);
1485 }
1486
1487 /* Replaces `old' client entries from all channels to `new' client entry.
1488    This can be called for example when nickname changes and old ID entry
1489    is replaced from ID cache with the new one. If the old ID entry is only
1490    updated, then this fucntion needs not to be called. */
1491
1492 void silc_client_replace_from_channels(SilcClient client, 
1493                                        SilcClientConnection conn,
1494                                        SilcClientEntry old,
1495                                        SilcClientEntry new)
1496 {
1497   SilcIDCacheEntry id_cache;
1498   SilcIDCacheList list;
1499   SilcChannelEntry channel;
1500   SilcChannelUser chu;
1501
1502   if (!silc_idcache_find_by_id(conn->channel_cache, SILC_ID_CACHE_ANY,
1503                                SILC_ID_CHANNEL, &list))
1504     return;
1505
1506   silc_idcache_list_first(list, &id_cache);
1507   channel = (SilcChannelEntry)id_cache->context;
1508   
1509   while (channel) {
1510     
1511     /* Replace client entry */
1512     silc_list_start(channel->clients);
1513     while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
1514       if (chu->client == old) {
1515         chu->client = new;
1516         break;
1517       }
1518     }
1519
1520     if (!silc_idcache_list_next(list, &id_cache))
1521       break;
1522     
1523     channel = (SilcChannelEntry)id_cache->context;
1524   }
1525
1526   silc_idcache_list_free(list);
1527 }
1528
1529 /* Parses mode mask and returns the mode as string. */
1530
1531 char *silc_client_chmode(uint32 mode, SilcChannelEntry channel)
1532 {
1533   char string[100];
1534
1535   if (!mode)
1536     return NULL;
1537
1538   memset(string, 0, sizeof(string));
1539
1540   if (mode & SILC_CHANNEL_MODE_PRIVATE)
1541     strncat(string, "p", 1);
1542
1543   if (mode & SILC_CHANNEL_MODE_SECRET)
1544     strncat(string, "s", 1);
1545
1546   if (mode & SILC_CHANNEL_MODE_PRIVKEY)
1547     strncat(string, "k", 1);
1548
1549   if (mode & SILC_CHANNEL_MODE_INVITE)
1550     strncat(string, "i", 1);
1551
1552   if (mode & SILC_CHANNEL_MODE_TOPIC)
1553     strncat(string, "t", 1);
1554
1555   if (mode & SILC_CHANNEL_MODE_ULIMIT)
1556     strncat(string, "l", 1);
1557
1558   if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
1559     strncat(string, "a", 1);
1560
1561   if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
1562     strncat(string, "f", 1);
1563
1564   if (mode & SILC_CHANNEL_MODE_CIPHER) {
1565     char cipher[30];
1566     memset(cipher, 0, sizeof(cipher));
1567     snprintf(cipher, sizeof(cipher), " c (%s)", 
1568              channel->channel_key->cipher->name);
1569     strncat(string, cipher, strlen(cipher));
1570   }
1571
1572   if (mode & SILC_CHANNEL_MODE_HMAC) {
1573     char hmac[30];
1574     memset(hmac, 0, sizeof(hmac));
1575     snprintf(hmac, sizeof(hmac), " h (%s)", 
1576              channel->hmac->hmac->name);
1577     strncat(string, hmac, strlen(hmac));
1578   }
1579
1580   /* Rest of mode is ignored */
1581
1582   return strdup(string);
1583 }
1584
1585 /* Parses channel user mode mask and returns te mode as string */
1586
1587 char *silc_client_chumode(uint32 mode)
1588 {
1589   char string[4];
1590
1591   if (!mode)
1592     return NULL;
1593
1594   memset(string, 0, sizeof(string));
1595
1596   if (mode & SILC_CHANNEL_UMODE_CHANFO)
1597     strncat(string, "f", 1);
1598
1599   if (mode & SILC_CHANNEL_UMODE_CHANOP)
1600     strncat(string, "o", 1);
1601
1602   return strdup(string);
1603 }
1604
1605 /* Parses channel user mode and returns it as special mode character. */
1606
1607 char *silc_client_chumode_char(uint32 mode)
1608 {
1609   char string[4];
1610
1611   if (!mode)
1612     return NULL;
1613
1614   memset(string, 0, sizeof(string));
1615
1616   if (mode & SILC_CHANNEL_UMODE_CHANFO)
1617     strncat(string, "*", 1);
1618
1619   if (mode & SILC_CHANNEL_UMODE_CHANOP)
1620     strncat(string, "@", 1);
1621
1622   return strdup(string);
1623 }
1624
1625 /* Failure timeout callback. If this is called then we will immediately
1626    process the received failure. We always process the failure with timeout
1627    since we do not want to blindly trust to received failure packets. 
1628    This won't be called (the timeout is cancelled) if the failure was
1629    bogus (it is bogus if remote does not close the connection after sending
1630    the failure). */
1631
1632 SILC_TASK_CALLBACK_GLOBAL(silc_client_failure_callback)
1633 {
1634   SilcClientFailureContext *f = (SilcClientFailureContext *)context;
1635
1636   if (f->sock->protocol) {
1637     f->sock->protocol->state = SILC_PROTOCOL_STATE_FAILURE;
1638     f->sock->protocol->execute(f->client->timeout_queue, 0,
1639                                f->sock->protocol, f->sock->sock, 0, 0);
1640     
1641     /* Notify application */
1642     f->client->ops->failure(f->client, f->sock->user_data, f->sock->protocol,
1643                             (void *)f->failure);
1644   }
1645
1646   silc_free(f);
1647 }
1648
1649 /* Registers failure timeout to process the received failure packet
1650    with timeout. */
1651
1652 void silc_client_process_failure(SilcClient client,
1653                                  SilcSocketConnection sock,
1654                                  SilcPacketContext *packet)
1655 {
1656   SilcClientFailureContext *f;
1657   uint32 failure = 0;
1658
1659   if (sock->protocol) {
1660     if (packet->buffer->len >= 4)
1661       SILC_GET32_MSB(failure, packet->buffer->data);
1662
1663     f = silc_calloc(1, sizeof(*f));
1664     f->client = client;
1665     f->sock = sock;
1666     f->failure = failure;
1667
1668     /* We will wait 5 seconds to process this failure packet */
1669     silc_task_register(client->timeout_queue, sock->sock,
1670                        silc_client_failure_callback, (void *)f, 5, 0,
1671                        SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1672   }
1673 }
1674
1675 /* A timeout callback for the re-key. We will be the initiator of the
1676    re-key protocol. */
1677
1678 SILC_TASK_CALLBACK(silc_client_rekey_callback)
1679 {
1680   SilcSocketConnection sock = (SilcSocketConnection)context;
1681   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1682   SilcClient client = (SilcClient)conn->rekey->context;
1683   SilcProtocol protocol;
1684   SilcClientRekeyInternalContext *proto_ctx;
1685
1686   SILC_LOG_DEBUG(("Start"));
1687
1688   /* Allocate internal protocol context. This is sent as context
1689      to the protocol. */
1690   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1691   proto_ctx->client = (void *)client;
1692   proto_ctx->sock = sock;
1693   proto_ctx->responder = FALSE;
1694   proto_ctx->pfs = conn->rekey->pfs;
1695       
1696   /* Perform rekey protocol. Will call the final callback after the
1697      protocol is over. */
1698   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_REKEY, 
1699                       &protocol, proto_ctx, silc_client_rekey_final);
1700   sock->protocol = protocol;
1701       
1702   /* Run the protocol */
1703   protocol->execute(client->timeout_queue, 0, protocol, 
1704                     sock->sock, 0, 0);
1705
1706   /* Re-register re-key timeout */
1707   silc_task_register(client->timeout_queue, sock->sock, 
1708                      silc_client_rekey_callback,
1709                      context, conn->rekey->timeout, 0,
1710                      SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1711 }
1712
1713 /* The final callback for the REKEY protocol. This will actually take the
1714    new key material into use. */
1715
1716 SILC_TASK_CALLBACK(silc_client_rekey_final)
1717 {
1718   SilcProtocol protocol = (SilcProtocol)context;
1719   SilcClientRekeyInternalContext *ctx =
1720     (SilcClientRekeyInternalContext *)protocol->context;
1721   SilcClient client = (SilcClient)ctx->client;
1722   SilcSocketConnection sock = ctx->sock;
1723
1724   SILC_LOG_DEBUG(("Start"));
1725
1726   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1727       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1728     /* Error occured during protocol */
1729     silc_protocol_cancel(client->timeout_queue, protocol);
1730     silc_protocol_free(protocol);
1731     sock->protocol = NULL;
1732     if (ctx->packet)
1733       silc_packet_context_free(ctx->packet);
1734     if (ctx->ske)
1735       silc_ske_free(ctx->ske);
1736     silc_free(ctx);
1737     return;
1738   }
1739
1740   /* Take the keys into use */
1741   if (ctx->pfs == TRUE)
1742     silc_client_protocol_rekey_generate_pfs(client, ctx);
1743   else
1744     silc_client_protocol_rekey_generate(client, ctx);
1745
1746   /* Cleanup */
1747   silc_protocol_free(protocol);
1748   sock->protocol = NULL;
1749   if (ctx->packet)
1750     silc_packet_context_free(ctx->packet);
1751   if (ctx->ske)
1752     silc_ske_free(ctx->ske);
1753   silc_free(ctx);
1754 }