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