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