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