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] = 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_SERVER_LEN;
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   else 
1094     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1095   packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1096   packetdata.src_id_type = SILC_ID_CLIENT;
1097   if (dst_id) {
1098     packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1099     packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1100     packetdata.dst_id_type = dst_id_type;
1101   } else {
1102     packetdata.dst_id = NULL;
1103     packetdata.dst_id_len = 0;
1104     packetdata.dst_id_type = SILC_ID_NONE;
1105   }
1106   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
1107     packetdata.src_id_len + packetdata.dst_id_len;
1108   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1109
1110   /* Prepare outgoing data buffer for packet sending */
1111   silc_packet_send_prepare(sock, 
1112                            SILC_PACKET_HEADER_LEN +
1113                            packetdata.src_id_len + 
1114                            packetdata.dst_id_len,
1115                            packetdata.padlen,
1116                            data_len);
1117
1118   SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1119
1120   packetdata.buffer = sock->outbuf;
1121
1122   /* Put the data to the buffer */
1123   if (data && data_len)
1124     silc_buffer_put(sock->outbuf, data, data_len);
1125
1126   /* Create the outgoing packet */
1127   silc_packet_assemble(&packetdata);
1128
1129   /* Encrypt the packet */
1130   if (cipher)
1131     silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
1132
1133   SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1134                    sock->outbuf->data, sock->outbuf->len);
1135
1136   /* Now actually send the packet */
1137   silc_client_packet_send_real(client, sock, force_send, FALSE);
1138 }
1139
1140 void silc_client_packet_send_flush(SilcClient client, 
1141                                    SilcSocketConnection sock,
1142                                    SilcPacketType type, 
1143                                    void *dst_id,
1144                                    SilcIdType dst_id_type,
1145                                    SilcCipher cipher,
1146                                    SilcHmac hmac,
1147                                    unsigned char *data, 
1148                                    uint32 data_len)
1149 {
1150   SilcPacketContext packetdata;
1151
1152   /* First flush the packet queue. */
1153   
1154   if (sock->outbuf->data - sock->outbuf->head)
1155     silc_buffer_push(sock->outbuf, 
1156                      sock->outbuf->data - sock->outbuf->head);
1157   
1158   silc_client_packet_send_real(client, sock, TRUE, TRUE);
1159   
1160   /* The packet has been sent and now it is time to set the connection
1161      back to only for input. When there is again some outgoing data 
1162      available for this connection it will be set for output as well. 
1163      This call clears the output setting and sets it only for input. */
1164   SILC_CLIENT_SET_CONNECTION_FOR_INPUT(sock->sock);
1165   SILC_UNSET_OUTBUF_PENDING(sock);
1166   silc_buffer_clear(sock->outbuf);
1167
1168   SILC_LOG_DEBUG(("Sending packet, type %d", type));
1169
1170   /* Get data used in the packet sending, keys and stuff */
1171   if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1172     if (!cipher && ((SilcClientConnection)sock->user_data)->send_key)
1173       cipher = ((SilcClientConnection)sock->user_data)->send_key;
1174
1175     if (!hmac && ((SilcClientConnection)sock->user_data)->hmac_send)
1176       hmac = ((SilcClientConnection)sock->user_data)->hmac_send;
1177
1178     if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) {
1179       dst_id = ((SilcClientConnection)sock->user_data)->remote_id;
1180       dst_id_type = SILC_ID_SERVER;
1181     }
1182   }
1183
1184   /* Set the packet context pointers */
1185   packetdata.flags = 0;
1186   packetdata.type = type;
1187   if (sock->user_data && 
1188       ((SilcClientConnection)sock->user_data)->local_id_data)
1189     packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
1190   else 
1191     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1192   packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1193   packetdata.src_id_type = SILC_ID_CLIENT;
1194   if (dst_id) {
1195     packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1196     packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1197     packetdata.dst_id_type = dst_id_type;
1198   } else {
1199     packetdata.dst_id = NULL;
1200     packetdata.dst_id_len = 0;
1201     packetdata.dst_id_type = SILC_ID_NONE;
1202   }
1203   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
1204     packetdata.src_id_len + packetdata.dst_id_len;
1205   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1206
1207   /* Prepare outgoing data buffer for packet sending */
1208   silc_packet_send_prepare(sock, 
1209                            SILC_PACKET_HEADER_LEN +
1210                            packetdata.src_id_len + 
1211                            packetdata.dst_id_len,
1212                            packetdata.padlen,
1213                            data_len);
1214
1215   SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1216
1217   packetdata.buffer = sock->outbuf;
1218
1219   /* Put the data to the buffer */
1220   if (data && data_len)
1221     silc_buffer_put(sock->outbuf, data, data_len);
1222
1223   /* Create the outgoing packet */
1224   silc_packet_assemble(&packetdata);
1225
1226   /* Encrypt the packet */
1227   if (cipher)
1228     silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
1229
1230   SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1231                    sock->outbuf->data, sock->outbuf->len);
1232
1233   /* Now actually send the packet */
1234   silc_client_packet_send_real(client, sock, TRUE, TRUE);
1235 }
1236
1237 /* Closes connection to remote end. Free's all allocated data except
1238    for some information such as nickname etc. that are valid at all time. 
1239    If the `sock' is NULL then the conn->sock will be used.  If `sock' is
1240    provided it will be checked whether the sock and `conn->sock' are the
1241    same (they can be different, ie. a socket can use `conn' as its
1242    connection but `conn->sock' might be actually a different connection
1243    than the `sock'). */
1244
1245 void silc_client_close_connection(SilcClient client,
1246                                   SilcSocketConnection sock,
1247                                   SilcClientConnection conn)
1248 {
1249   int del = FALSE;
1250
1251   if (!sock || (sock && conn->sock == sock))
1252     del = TRUE;
1253   if (!sock)
1254     sock = conn->sock;
1255
1256   /* We won't listen for this connection anymore */
1257   silc_schedule_unset_listen_fd(sock->sock);
1258
1259   /* Unregister all tasks */
1260   silc_task_unregister_by_fd(client->io_queue, sock->sock);
1261   silc_task_unregister_by_fd(client->timeout_queue, sock->sock);
1262
1263   /* Close the actual connection */
1264   silc_net_close_connection(sock->sock);
1265
1266   /* Free everything */
1267   if (del && sock->user_data) {
1268     /* XXX Free all client entries and channel entries. */
1269
1270     client->ops->say(client, sock->user_data,
1271                      "Closed connection to host %s", sock->hostname);
1272
1273     /* Clear ID caches */
1274     silc_idcache_del_all(conn->client_cache);
1275     silc_idcache_del_all(conn->channel_cache);
1276
1277     /* Free data */
1278     if (conn->remote_host)
1279       silc_free(conn->remote_host);
1280     if (conn->local_id)
1281       silc_free(conn->local_id);
1282     if (conn->local_id_data)
1283       silc_free(conn->local_id_data);
1284     if (conn->send_key)
1285       silc_cipher_free(conn->send_key);
1286     if (conn->receive_key)
1287       silc_cipher_free(conn->receive_key);
1288     if (conn->hmac_send)        /* conn->hmac_receive is same */
1289       silc_hmac_free(conn->hmac_send);
1290     if (conn->pending_commands)
1291       silc_dlist_uninit(conn->pending_commands);
1292     if (conn->rekey)
1293       silc_free(conn->rekey);
1294
1295     conn->sock = NULL;
1296     conn->remote_port = 0;
1297     conn->remote_type = 0;
1298     conn->send_key = NULL;
1299     conn->receive_key = NULL;
1300     conn->hmac_send = NULL;
1301     conn->hmac_receive = NULL;
1302     conn->local_id = NULL;
1303     conn->local_id_data = NULL;
1304     conn->remote_host = NULL;
1305     conn->current_channel = NULL;
1306     conn->pending_commands = NULL;
1307     conn->rekey = NULL;
1308
1309     silc_client_del_connection(client, conn);
1310   }
1311
1312   if (sock->protocol) {
1313     silc_protocol_free(sock->protocol);
1314     sock->protocol = NULL;
1315   }
1316   silc_socket_free(sock);
1317 }
1318
1319 /* Called when we receive disconnection packet from server. This 
1320    closes our end properly and displays the reason of the disconnection
1321    on the screen. */
1322
1323 void silc_client_disconnected_by_server(SilcClient client,
1324                                         SilcSocketConnection sock,
1325                                         SilcBuffer message)
1326 {
1327   char *msg;
1328
1329   SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
1330
1331   msg = silc_calloc(message->len + 1, sizeof(char));
1332   memcpy(msg, message->data, message->len);
1333   client->ops->say(client, sock->user_data, msg);
1334   silc_free(msg);
1335
1336   SILC_SET_DISCONNECTED(sock);
1337   silc_client_close_connection(client, sock, sock->user_data);
1338 }
1339
1340 /* Received error message from server. Display it on the screen. 
1341    We don't take any action what so ever of the error message. */
1342
1343 void silc_client_error_by_server(SilcClient client,
1344                                  SilcSocketConnection sock,
1345                                  SilcBuffer message)
1346 {
1347   char *msg;
1348
1349   msg = silc_calloc(message->len + 1, sizeof(char));
1350   memcpy(msg, message->data, message->len);
1351   client->ops->say(client, sock->user_data, msg);
1352   silc_free(msg);
1353 }
1354
1355 /* Processes the received new Client ID from server. Old Client ID is
1356    deleted from cache and new one is added. */
1357
1358 void silc_client_receive_new_id(SilcClient client,
1359                                 SilcSocketConnection sock,
1360                                 SilcIDPayload idp)
1361 {
1362   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1363   int connecting = FALSE;
1364
1365   if (!conn->local_entry)
1366     connecting = TRUE;
1367
1368   /* Delete old ID from ID cache */
1369   silc_idcache_del_by_id(conn->client_cache, SILC_ID_CLIENT, conn->local_id);
1370   
1371   /* Save the new ID */
1372   if (conn->local_id)
1373     silc_free(conn->local_id);
1374   if (conn->local_id_data)
1375     silc_free(conn->local_id_data);
1376
1377   conn->local_id = silc_id_payload_get_id(idp);
1378   conn->local_id_data = silc_id_payload_get_data(idp);
1379   conn->local_id_data_len = silc_id_payload_get_len(idp);;
1380
1381   if (!conn->local_entry)
1382     conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
1383
1384   conn->local_entry->nickname = conn->nickname;
1385   if (!conn->local_entry->username) {
1386     conn->local_entry->username = 
1387       silc_calloc(strlen(client->username) + strlen(client->hostname) + 1,
1388                   sizeof(conn->local_entry->username));
1389     sprintf(conn->local_entry->username, "%s@%s", client->username,
1390             client->hostname);
1391   }
1392   conn->local_entry->server = strdup(conn->remote_host);
1393   conn->local_entry->id = conn->local_id;
1394   
1395   /* Put it to the ID cache */
1396   silc_idcache_add(conn->client_cache, conn->nickname, strlen(conn->nickname),
1397                    SILC_ID_CLIENT, conn->local_id, (void *)conn->local_entry,
1398                    TRUE, FALSE);
1399
1400   /* Notify application of successful connection. We do it here now that
1401      we've received the Client ID and are allowed to send traffic. */
1402   if (connecting)
1403     client->ops->connect(client, conn, TRUE);
1404 }
1405
1406 /* Processed received Channel ID for a channel. This is called when client
1407    joins to channel and server replies with channel ID. The ID is cached. 
1408    Returns the created channel entry. */
1409
1410 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
1411                                             SilcSocketConnection sock,
1412                                             char *channel_name,
1413                                             uint32 mode, 
1414                                             SilcIDPayload idp)
1415 {
1416   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1417   SilcChannelEntry channel;
1418
1419   SILC_LOG_DEBUG(("New channel ID"));
1420
1421   channel = silc_calloc(1, sizeof(*channel));
1422   channel->channel_name = channel_name;
1423   channel->id = silc_id_payload_get_id(idp);
1424   channel->mode = mode;
1425   silc_list_init(channel->clients, struct SilcChannelUserStruct, next);
1426
1427   conn->current_channel = channel;
1428
1429   /* Put it to the ID cache */
1430   silc_idcache_add(conn->channel_cache, channel_name, strlen(channel_name),
1431                    SILC_ID_CHANNEL, (void *)channel->id, (void *)channel, 
1432                    TRUE, FALSE);
1433
1434   return channel;
1435 }
1436
1437 /* Removes a client entry from all channel it has joined. This really is
1438    a performance killer (client_entry should have pointers to channel 
1439    entry list). */
1440
1441 void silc_client_remove_from_channels(SilcClient client,
1442                                       SilcClientConnection conn,
1443                                       SilcClientEntry client_entry)
1444 {
1445   SilcIDCacheEntry id_cache;
1446   SilcIDCacheList list;
1447   SilcChannelEntry channel;
1448   SilcChannelUser chu;
1449
1450   if (!silc_idcache_find_by_id(conn->channel_cache, SILC_ID_CACHE_ANY,
1451                                SILC_ID_CHANNEL, &list))
1452     return;
1453
1454   silc_idcache_list_first(list, &id_cache);
1455   channel = (SilcChannelEntry)id_cache->context;
1456   
1457   while (channel) {
1458     
1459     /* Remove client from channel */
1460     silc_list_start(channel->clients);
1461     while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
1462       if (chu->client == client_entry) {
1463         silc_list_del(channel->clients, chu);
1464         silc_free(chu);
1465         break;
1466       }
1467     }
1468
1469     if (!silc_idcache_list_next(list, &id_cache))
1470       break;
1471     
1472     channel = (SilcChannelEntry)id_cache->context;
1473   }
1474
1475   silc_idcache_list_free(list);
1476 }
1477
1478 /* Replaces `old' client entries from all channels to `new' client entry.
1479    This can be called for example when nickname changes and old ID entry
1480    is replaced from ID cache with the new one. If the old ID entry is only
1481    updated, then this fucntion needs not to be called. */
1482
1483 void silc_client_replace_from_channels(SilcClient client, 
1484                                        SilcClientConnection conn,
1485                                        SilcClientEntry old,
1486                                        SilcClientEntry new)
1487 {
1488   SilcIDCacheEntry id_cache;
1489   SilcIDCacheList list;
1490   SilcChannelEntry channel;
1491   SilcChannelUser chu;
1492
1493   if (!silc_idcache_find_by_id(conn->channel_cache, SILC_ID_CACHE_ANY,
1494                                SILC_ID_CHANNEL, &list))
1495     return;
1496
1497   silc_idcache_list_first(list, &id_cache);
1498   channel = (SilcChannelEntry)id_cache->context;
1499   
1500   while (channel) {
1501     
1502     /* Replace client entry */
1503     silc_list_start(channel->clients);
1504     while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
1505       if (chu->client == old) {
1506         chu->client = new;
1507         break;
1508       }
1509     }
1510
1511     if (!silc_idcache_list_next(list, &id_cache))
1512       break;
1513     
1514     channel = (SilcChannelEntry)id_cache->context;
1515   }
1516
1517   silc_idcache_list_free(list);
1518 }
1519
1520 /* Parses mode mask and returns the mode as string. */
1521
1522 char *silc_client_chmode(uint32 mode, SilcChannelEntry channel)
1523 {
1524   char string[100];
1525
1526   if (!mode)
1527     return NULL;
1528
1529   memset(string, 0, sizeof(string));
1530
1531   if (mode & SILC_CHANNEL_MODE_PRIVATE)
1532     strncat(string, "p", 1);
1533
1534   if (mode & SILC_CHANNEL_MODE_SECRET)
1535     strncat(string, "s", 1);
1536
1537   if (mode & SILC_CHANNEL_MODE_PRIVKEY)
1538     strncat(string, "k", 1);
1539
1540   if (mode & SILC_CHANNEL_MODE_INVITE)
1541     strncat(string, "i", 1);
1542
1543   if (mode & SILC_CHANNEL_MODE_TOPIC)
1544     strncat(string, "t", 1);
1545
1546   if (mode & SILC_CHANNEL_MODE_ULIMIT)
1547     strncat(string, "l", 1);
1548
1549   if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
1550     strncat(string, "a", 1);
1551
1552   if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
1553     strncat(string, "f", 1);
1554
1555   if (mode & SILC_CHANNEL_MODE_CIPHER) {
1556     char cipher[30];
1557     memset(cipher, 0, sizeof(cipher));
1558     snprintf(cipher, sizeof(cipher), " c (%s)", 
1559              channel->channel_key->cipher->name);
1560     strncat(string, cipher, strlen(cipher));
1561   }
1562
1563   if (mode & SILC_CHANNEL_MODE_HMAC) {
1564     char hmac[30];
1565     memset(hmac, 0, sizeof(hmac));
1566     snprintf(hmac, sizeof(hmac), " h (%s)", 
1567              channel->hmac->hmac->name);
1568     strncat(string, hmac, strlen(hmac));
1569   }
1570
1571   /* Rest of mode is ignored */
1572
1573   return strdup(string);
1574 }
1575
1576 /* Parses channel user mode mask and returns te mode as string */
1577
1578 char *silc_client_chumode(uint32 mode)
1579 {
1580   char string[4];
1581
1582   if (!mode)
1583     return NULL;
1584
1585   memset(string, 0, sizeof(string));
1586
1587   if (mode & SILC_CHANNEL_UMODE_CHANFO)
1588     strncat(string, "f", 1);
1589
1590   if (mode & SILC_CHANNEL_UMODE_CHANOP)
1591     strncat(string, "o", 1);
1592
1593   return strdup(string);
1594 }
1595
1596 /* Parses channel user mode and returns it as special mode character. */
1597
1598 char *silc_client_chumode_char(uint32 mode)
1599 {
1600   char string[4];
1601
1602   if (!mode)
1603     return NULL;
1604
1605   memset(string, 0, sizeof(string));
1606
1607   if (mode & SILC_CHANNEL_UMODE_CHANFO)
1608     strncat(string, "*", 1);
1609
1610   if (mode & SILC_CHANNEL_UMODE_CHANOP)
1611     strncat(string, "@", 1);
1612
1613   return strdup(string);
1614 }
1615
1616 /* Registers failure timeout to process the received failure packet
1617    with timeout. */
1618
1619 void silc_client_process_failure(SilcClient client,
1620                                  SilcSocketConnection sock,
1621                                  SilcPacketContext *packet)
1622 {
1623   uint32 failure = 0;
1624
1625   if (sock->protocol) {
1626     if (packet->buffer->len >= 4)
1627       SILC_GET32_MSB(failure, packet->buffer->data);
1628
1629     /* Notify application */
1630     client->ops->failure(client, sock->user_data, sock->protocol,
1631                          (void *)failure);
1632   }
1633 }
1634
1635 /* A timeout callback for the re-key. We will be the initiator of the
1636    re-key protocol. */
1637
1638 SILC_TASK_CALLBACK(silc_client_rekey_callback)
1639 {
1640   SilcSocketConnection sock = (SilcSocketConnection)context;
1641   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1642   SilcClient client = (SilcClient)conn->rekey->context;
1643   SilcProtocol protocol;
1644   SilcClientRekeyInternalContext *proto_ctx;
1645
1646   SILC_LOG_DEBUG(("Start"));
1647
1648   /* Allocate internal protocol context. This is sent as context
1649      to the protocol. */
1650   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1651   proto_ctx->client = (void *)client;
1652   proto_ctx->sock = silc_socket_dup(sock);
1653   proto_ctx->responder = FALSE;
1654   proto_ctx->pfs = conn->rekey->pfs;
1655       
1656   /* Perform rekey protocol. Will call the final callback after the
1657      protocol is over. */
1658   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_REKEY, 
1659                       &protocol, proto_ctx, silc_client_rekey_final);
1660   sock->protocol = protocol;
1661       
1662   /* Run the protocol */
1663   protocol->execute(client->timeout_queue, 0, protocol, 
1664                     sock->sock, 0, 0);
1665
1666   /* Re-register re-key timeout */
1667   silc_task_register(client->timeout_queue, sock->sock, 
1668                      silc_client_rekey_callback,
1669                      context, conn->rekey->timeout, 0,
1670                      SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1671 }
1672
1673 /* The final callback for the REKEY protocol. This will actually take the
1674    new key material into use. */
1675
1676 SILC_TASK_CALLBACK(silc_client_rekey_final)
1677 {
1678   SilcProtocol protocol = (SilcProtocol)context;
1679   SilcClientRekeyInternalContext *ctx =
1680     (SilcClientRekeyInternalContext *)protocol->context;
1681   SilcClient client = (SilcClient)ctx->client;
1682   SilcSocketConnection sock = ctx->sock;
1683
1684   SILC_LOG_DEBUG(("Start"));
1685
1686   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1687       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1688     /* Error occured during protocol */
1689     silc_protocol_cancel(client->timeout_queue, protocol);
1690     silc_protocol_free(protocol);
1691     sock->protocol = NULL;
1692     if (ctx->packet)
1693       silc_packet_context_free(ctx->packet);
1694     if (ctx->ske)
1695       silc_ske_free(ctx->ske);
1696     silc_socket_free(ctx->sock);
1697     silc_free(ctx);
1698     return;
1699   }
1700
1701   /* Cleanup */
1702   silc_protocol_free(protocol);
1703   sock->protocol = NULL;
1704   if (ctx->packet)
1705     silc_packet_context_free(ctx->packet);
1706   if (ctx->ske)
1707     silc_ske_free(ctx->ske);
1708   silc_socket_free(ctx->sock);
1709   silc_free(ctx);
1710 }