Major rewrite of ID Cache system. Support added for the new
[silc.git] / apps / silcd / protocol.c
1 /*
2
3   protocol.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 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 /*
21  * Server side of the protocols.
22  */
23 /*
24  * $Id$
25  * $Log$
26  * Revision 1.6  2000/07/12 05:59:41  priikone
27  *      Major rewrite of ID Cache system. Support added for the new
28  *      ID cache system. Major rewrite of ID List stuff on server.  All
29  *      SilcXXXList's are now called SilcXXXEntry's and they are pointers
30  *      by default. A lot rewritten ID list functions.
31  *
32  * Revision 1.5  2000/07/10 05:42:14  priikone
33  *      Support for public key encoding functions added.
34  *
35  * Revision 1.4  2000/07/07 06:55:59  priikone
36  *      Added SILC style public key support and made server to use
37  *      it at all time.
38  *
39  * Revision 1.3  2000/07/06 07:15:31  priikone
40  *      Cleaner code fro password and public key authentication.
41  *      Deprecated old `channel_auth' protocol.
42  *
43  * Revision 1.2  2000/07/05 06:13:04  priikone
44  *      Support for SILC style public keys added.
45  *
46  * Revision 1.1.1.1  2000/06/27 11:36:56  priikone
47  *      Imported from internal CVS/Added Log headers.
48  *
49  *
50  */
51
52 #include "serverincludes.h"
53 #include "server_internal.h"
54
55 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth);
56 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange);
57
58 /* SILC client protocol list */
59 const SilcProtocolObject silc_protocol_list[] =
60 {
61   { SILC_PROTOCOL_SERVER_CONNECTION_AUTH, 
62     silc_server_protocol_connection_auth },
63   { SILC_PROTOCOL_SERVER_KEY_EXCHANGE, 
64     silc_server_protocol_key_exchange },
65
66   { SILC_PROTOCOL_SERVER_NONE, NULL },
67 };
68
69 /*
70  * Key Exhange protocol functions
71  */
72
73 /* Packet sending callback. This function is provided as packet sending
74    routine to the Key Exchange functions. */
75
76 static void silc_server_protocol_ke_send_packet(SilcSKE ske,
77                                                 SilcBuffer packet,
78                                                 SilcPacketType type,
79                                                 void *context)
80 {
81   SilcProtocol protocol = (SilcProtocol)context;
82   SilcServerKEInternalContext *ctx = 
83     (SilcServerKEInternalContext *)protocol->context;
84   SilcServer server = (SilcServer)ctx->server;
85
86   /* Send the packet immediately */
87   silc_server_packet_send(server, ske->sock,
88                           type, 0, packet->data, packet->len, TRUE);
89 }
90
91 /* Sets the negotiated key material into use for particular connection. */
92
93 static void silc_server_protocol_ke_set_keys(SilcSKE ske,
94                                              SilcSocketConnection sock,
95                                              SilcSKEKeyMaterial *keymat,
96                                              SilcCipher cipher,
97                                              SilcPKCS pkcs,
98                                              SilcHash hash,
99                                              int is_responder)
100 {
101   SilcUnknownEntry conn_data;
102   SilcHash nhash;
103
104   SILC_LOG_DEBUG(("Setting new key into use"));
105
106   conn_data = silc_calloc(1, sizeof(*conn_data));
107
108   /* Allocate cipher to be used in the communication */
109   silc_cipher_alloc(cipher->cipher->name, &conn_data->send_key);
110   silc_cipher_alloc(cipher->cipher->name, &conn_data->receive_key);
111   
112   if (is_responder == TRUE) {
113     conn_data->send_key->cipher->set_key(conn_data->send_key->context, 
114                                          keymat->receive_enc_key, 
115                                          keymat->enc_key_len);
116     conn_data->send_key->set_iv(conn_data->send_key, keymat->receive_iv);
117     conn_data->receive_key->cipher->set_key(conn_data->receive_key->context, 
118                                             keymat->send_enc_key, 
119                                             keymat->enc_key_len);
120     conn_data->receive_key->set_iv(conn_data->receive_key, keymat->send_iv);
121     
122   } else {
123     conn_data->send_key->cipher->set_key(conn_data->send_key->context, 
124                                          keymat->send_enc_key, 
125                                          keymat->enc_key_len);
126     conn_data->send_key->set_iv(conn_data->send_key, keymat->send_iv);
127     conn_data->receive_key->cipher->set_key(conn_data->receive_key->context, 
128                                             keymat->receive_enc_key, 
129                                             keymat->enc_key_len);
130     conn_data->receive_key->set_iv(conn_data->receive_key, keymat->receive_iv);
131   }
132
133   /* Allocate PKCS to be used */
134 #if 0
135   /* XXX Do we ever need to allocate PKCS for the connection??
136      If yes, we need to change KE protocol to get the initiators
137      public key. */
138   silc_pkcs_alloc(pkcs->pkcs->name, &conn_data->pkcs);
139   conn_data->public_key = silc_pkcs_public_key_alloc(XXX);
140   silc_pkcs_set_public_key(conn_data->pkcs, ske->ke2_payload->pk_data, 
141                            ske->ke2_payload->pk_len);
142 #endif
143
144   /* Save HMAC key to be used in the communication. */
145   silc_hash_alloc(hash->hash->name, &nhash);
146   silc_hmac_alloc(nhash, &conn_data->hmac);
147   conn_data->hmac_key_len = keymat->hmac_key_len;
148   conn_data->hmac_key = silc_calloc(conn_data->hmac_key_len,
149                                     sizeof(unsigned char));
150   memcpy(conn_data->hmac_key, keymat->hmac_key, keymat->hmac_key_len);
151
152   sock->user_data = (void *)conn_data;
153 }
154
155 /* Performs key exchange protocol. This is used for both initiator
156    and responder key exchange. This is performed always when accepting
157    new connection to the server. This may be called recursively. */
158
159 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
160 {
161   SilcProtocol protocol = (SilcProtocol)context;
162   SilcServerKEInternalContext *ctx = 
163     (SilcServerKEInternalContext *)protocol->context;
164   SilcServer server = (SilcServer)ctx->server;
165   SilcSKEStatus status = 0;
166
167   SILC_LOG_DEBUG(("Start"));
168
169   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
170     protocol->state = SILC_PROTOCOL_STATE_START;
171
172   SILC_LOG_DEBUG(("State=%d", protocol->state));
173
174   switch(protocol->state) {
175   case SILC_PROTOCOL_STATE_START:
176     {
177       /*
178        * Start protocol
179        */
180       SilcSKE ske;
181
182       /* Allocate Key Exchange object */
183       ske = silc_ske_alloc();
184       ctx->ske = ske;
185       
186       if (ctx->responder == TRUE) {
187         /* Start the key exchange by processing the received security
188            properties packet from initiator. */
189         status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
190                                           ctx->packet, NULL, NULL);
191       } else {
192         SilcSKEStartPayload *start_payload;
193
194         /* Assemble security properties. */
195         silc_ske_assemble_security_properties(ske, &start_payload);
196
197         /* Start the key exchange by sending our security properties
198            to the remote end. */
199         status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
200                                           start_payload,
201                                           silc_server_protocol_ke_send_packet,
202                                           context);
203       }
204
205       if (status != SILC_SKE_STATUS_OK) {
206         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
207                           status));
208         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
209                         status));
210
211         protocol->state = SILC_PROTOCOL_STATE_ERROR;
212         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
213         return;
214       }
215
216       /* Advance protocol state and call the next state if we are responder */
217       protocol->state++;
218       if (ctx->responder == TRUE)
219         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
220     }
221     break;
222   case 2:
223     {
224       /* 
225        * Phase 1 
226        */
227       if (ctx->responder == TRUE) {
228         /* Sends the selected security properties to the initiator. */
229         status = 
230           silc_ske_responder_phase_1(ctx->ske, 
231                                      ctx->ske->start_payload,
232                                      silc_server_protocol_ke_send_packet,
233                                      context);
234       } else {
235         /* Call Phase-1 function. This processes the Key Exchange Start
236            paylaod reply we just got from the responder. The callback
237            function will receive the processed payload where we will
238            save it. */
239         status = 
240           silc_ske_initiator_phase_1(ctx->ske,
241                                      ctx->packet,
242                                      NULL, NULL);
243       }
244
245       if (status != SILC_SKE_STATUS_OK) {
246         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
247                           status));
248         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
249                         status));
250
251         protocol->state = SILC_PROTOCOL_STATE_ERROR;
252         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
253         return;
254       }
255
256       /* Advance protocol state and call next state if we are initiator */
257       protocol->state++;
258       if (ctx->responder == FALSE)
259         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
260     }
261     break;
262   case 3:
263     {
264       /* 
265        * Phase 2 
266        */
267       if (ctx->responder == TRUE) {
268         /* Process the received Key Exchange 1 Payload packet from
269            the initiator. This also creates our parts of the Diffie
270            Hellman algorithm. */
271         status = 
272           silc_ske_responder_phase_2(ctx->ske, ctx->packet, NULL, NULL);
273       } else {
274         /* Call the Phase-2 function. This creates Diffie Hellman
275            key exchange parameters and sends our public part inside
276            Key Exhange 1 Payload to the responder. */
277         status = 
278           silc_ske_initiator_phase_2(ctx->ske,
279                                      silc_server_protocol_ke_send_packet,
280                                      context);
281       }
282
283       if (status != SILC_SKE_STATUS_OK) {
284         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
285                           status));
286         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
287                         status));
288
289         protocol->state = SILC_PROTOCOL_STATE_ERROR;
290         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
291         return;
292       }
293
294       /* Advance protocol state and call the next state if we are responder */
295       protocol->state++;
296       if (ctx->responder == TRUE)
297         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
298     }
299     break;
300   case 4:
301     {
302       /* 
303        * Finish protocol
304        */
305       if (ctx->responder == TRUE) {
306         /* This creates the key exchange material and sends our
307            public parts to the initiator inside Key Exchange 2 Payload. */
308         status = 
309           silc_ske_responder_finish(ctx->ske, 
310                                     server->public_key, server->private_key,
311                                     SILC_SKE_PK_TYPE_SILC,
312                                     silc_server_protocol_ke_send_packet,
313                                     context);
314       } else {
315         /* Finish the protocol. This verifies the Key Exchange 2 payload
316            sent by responder. */
317         status = 
318           silc_ske_initiator_finish(ctx->ske,
319                                     ctx->packet, NULL, NULL, NULL, NULL);
320       }
321
322       if (status != SILC_SKE_STATUS_OK) {
323         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
324                           status));
325         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
326                         status));
327
328         protocol->state = SILC_PROTOCOL_STATE_ERROR;
329         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
330         return;
331       }
332
333       /* Send Ok to the other end. We will end the protocol as responder
334          sends Ok to us when we will take the new keys into use. */
335       if (ctx->responder == FALSE)
336         silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
337
338       /* End the protocol on the next round */
339       protocol->state = SILC_PROTOCOL_STATE_END;
340     }
341     break;
342   case SILC_PROTOCOL_STATE_END:
343     {
344       /* 
345        * End protocol
346        */
347       SilcSKEKeyMaterial *keymat;
348
349       /* Send Ok to the other end if we are responder. If we are 
350          initiator we have sent this already. */
351       if (ctx->responder == TRUE)
352         silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
353
354       /* Process the key material */
355       keymat = silc_calloc(1, sizeof(*keymat));
356       silc_ske_process_key_material(ctx->ske, 16, (16 * 8), 16, keymat);
357
358       /* Take the new keys into use. */
359       silc_server_protocol_ke_set_keys(ctx->ske, ctx->sock, keymat,
360                                        ctx->ske->prop->cipher,
361                                        ctx->ske->prop->pkcs,
362                                        ctx->ske->prop->hash,
363                                        ctx->responder);
364
365       /* Unregister the timeout task since the protocol has ended. 
366          This was the timeout task to be executed if the protocol is
367          not completed fast enough. */
368       if (ctx->timeout_task)
369         silc_task_unregister(server->timeout_queue, ctx->timeout_task);
370
371       /* Call the final callback */
372       if (protocol->final_callback)
373         protocol->execute_final(server->timeout_queue, 0, protocol, fd);
374       else
375         silc_protocol_free(protocol);
376     }
377     break;
378   case SILC_PROTOCOL_STATE_ERROR:
379     /*
380      * Error occured
381      */
382
383     /* Unregister the timeout task since the protocol has ended. 
384        This was the timeout task to be executed if the protocol is
385        not completed fast enough. */
386     if (ctx->timeout_task)
387       silc_task_unregister(server->timeout_queue, ctx->timeout_task);
388
389     /* On error the final callback is always called. */
390     if (protocol->final_callback)
391       protocol->execute_final(server->timeout_queue, 0, protocol, fd);
392     else
393       silc_protocol_free(protocol);
394     break;
395   case SILC_PROTOCOL_STATE_UNKNOWN:
396     break;
397   }
398 }
399
400 /*
401  * Connection Authentication protocol functions
402  */
403
404 /* XXX move these to somehwere else */
405
406 int silc_server_password_authentication(SilcServer server, char *auth1, 
407                                         char *auth2)
408 {
409   if (!auth1 || !auth2)
410     return FALSE;
411
412   if (!memcmp(auth1, auth2, strlen(auth1)))
413     return TRUE;
414
415   return FALSE;
416 }
417
418 int silc_server_public_key_authentication(SilcServer server,
419                                           char *pkfile,
420                                           unsigned char *sign,
421                                           unsigned int sign_len,
422                                           SilcSKE ske)
423 {
424   SilcPublicKey pub_key;
425   SilcPKCS pkcs;
426   int len;
427   SilcBuffer auth;
428
429   if (!pkfile || !sign)
430     return FALSE;
431
432   /* Load public key from file */
433   if (!silc_pkcs_load_public_key(pkfile, &pub_key, SILC_PKCS_FILE_PEM))
434     if (!silc_pkcs_load_public_key(pkfile, &pub_key, SILC_PKCS_FILE_BIN))
435       return FALSE;
436
437   silc_pkcs_alloc(pub_key->name, &pkcs);
438   if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
439     silc_pkcs_free(pkcs);
440     return FALSE;
441   }
442
443   /* Make the authentication data. Protocol says it is HASH plus
444      KE Start Payload. */
445   len = ske->hash_len + ske->start_payload_copy->len;
446   auth = silc_buffer_alloc(len);
447   silc_buffer_pull_tail(auth, len);
448   silc_buffer_format(auth,
449                      SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
450                      SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
451                                           ske->start_payload_copy->len),
452                      SILC_STR_END);
453
454   /* Verify signature */
455   if (pkcs->pkcs->verify(pkcs->context, sign, sign_len,
456                          auth->data, auth->len))
457     {
458       silc_pkcs_free(pkcs);
459       silc_pkcs_public_key_free(pub_key);
460       silc_buffer_free(auth);
461       return TRUE;
462     }
463
464   silc_pkcs_free(pkcs);
465   silc_pkcs_public_key_free(pub_key);
466   silc_buffer_free(auth);
467   return FALSE;
468 }
469
470 /* Performs connection authentication protocol. If responder, we 
471    authenticate the remote data received. If initiator, we will send
472    authentication data to the remote end. */
473
474 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
475 {
476   SilcProtocol protocol = (SilcProtocol)context;
477   SilcServerConnAuthInternalContext *ctx = 
478     (SilcServerConnAuthInternalContext *)protocol->context;
479   SilcServer server = (SilcServer)ctx->server;
480
481   SILC_LOG_DEBUG(("Start"));
482
483   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
484     protocol->state = SILC_PROTOCOL_STATE_START;
485
486   SILC_LOG_DEBUG(("State=%d", protocol->state));
487
488   switch(protocol->state) {
489   case SILC_PROTOCOL_STATE_START:
490     {
491       /* 
492        * Start protocol.
493        */
494
495       if (ctx->responder == TRUE) {
496         /*
497          * We are receiving party
498          */
499         int ret;
500         unsigned short payload_len;
501         unsigned short conn_type;
502         unsigned char *auth_data;
503
504         SILC_LOG_INFO(("Performing authentication protocol for %s",
505                        ctx->sock->hostname ? ctx->sock->hostname :
506                        ctx->sock->ip));
507
508         /* Parse the received authentication data packet. The received
509            payload is Connection Auth Payload. */
510         silc_buffer_unformat(ctx->packet,
511                              SILC_STR_UI_SHORT(&payload_len),
512                              SILC_STR_UI_SHORT(&conn_type),
513                              SILC_STR_END);
514         
515         if (payload_len != ctx->packet->len) {
516           SILC_LOG_ERROR(("Bad payload in authentication packet"));
517           SILC_LOG_DEBUG(("Bad payload in authentication packet"));
518           protocol->state = SILC_PROTOCOL_STATE_ERROR;
519           protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
520           return;
521         }
522         
523         payload_len -= 4;
524         
525         if (conn_type < SILC_SOCKET_TYPE_CLIENT || 
526             conn_type > SILC_SOCKET_TYPE_ROUTER) {
527           SILC_LOG_ERROR(("Bad connection type %d", conn_type));
528           SILC_LOG_DEBUG(("Bad connection type %d", conn_type));
529           protocol->state = SILC_PROTOCOL_STATE_ERROR;
530           protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
531           return;
532         }
533         
534         if (payload_len > 0) {
535           /* Get authentication data */
536           silc_buffer_pull(ctx->packet, 4);
537           silc_buffer_unformat(ctx->packet,
538                                SILC_STR_UI_XNSTRING_ALLOC(&auth_data, 
539                                                           payload_len),
540                                SILC_STR_END);
541         } else {
542           auth_data = NULL;
543         }
544
545         /* 
546          * Check the remote connection type and make sure that we have
547          * configured this connection. If we haven't allowed this connection
548          * the authentication must be failed.
549          */
550
551         SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
552
553         /* Remote end is client */
554         if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
555           SilcConfigServerSectionClientConnection *client = NULL;
556           client = 
557             silc_config_server_find_client_conn(server->config,
558                                                 ctx->sock->ip,
559                                                 ctx->sock->port);
560           if (!client)
561             client = 
562               silc_config_server_find_client_conn(server->config,
563                                                   ctx->sock->hostname,
564                                                   ctx->sock->port);
565           
566           if (client) {
567             switch(client->auth_meth) {
568             case SILC_PROTOCOL_CONN_AUTH_NONE:
569               /* No authentication required */
570               SILC_LOG_DEBUG(("No authentication required"));
571               break;
572               
573             case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
574               /* Password authentication */
575               SILC_LOG_DEBUG(("Password authentication"));
576               ret = silc_server_password_authentication(server, auth_data,
577                                                         client->auth_data);
578
579               if (ret) {
580                 memset(auth_data, 0, payload_len);
581                 silc_free(auth_data);
582                 auth_data = NULL;
583                 break;
584               }
585
586               /* Authentication failed */
587               SILC_LOG_ERROR(("Authentication failed"));
588               SILC_LOG_DEBUG(("Authentication failed"));
589               protocol->state = SILC_PROTOCOL_STATE_ERROR;
590               protocol->execute(server->timeout_queue, 0, 
591                                 protocol, fd, 0, 300000);
592               return;
593               break;
594               
595             case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
596               /* Public key authentication */
597               SILC_LOG_DEBUG(("Public key authentication"));
598               ret = silc_server_public_key_authentication(server, 
599                                                           client->auth_data,
600                                                           auth_data,
601                                                           payload_len, 
602                                                           ctx->ske);
603                                                           
604               if (ret) {
605                 memset(auth_data, 0, payload_len);
606                 silc_free(auth_data);
607                 auth_data = NULL;
608                 break;
609               }
610
611               SILC_LOG_ERROR(("Authentication failed"));
612               SILC_LOG_DEBUG(("Authentication failed"));
613               protocol->state = SILC_PROTOCOL_STATE_ERROR;
614               protocol->execute(server->timeout_queue, 0, 
615                                 protocol, fd, 0, 300000);
616               return;
617             }
618           } else {
619             SILC_LOG_DEBUG(("No configuration for remote connection"));
620             SILC_LOG_ERROR(("Remote connection not configured"));
621             SILC_LOG_ERROR(("Authentication failed"));
622             memset(auth_data, 0, payload_len);
623             silc_free(auth_data);
624             auth_data = NULL;
625             protocol->state = SILC_PROTOCOL_STATE_ERROR;
626             protocol->execute(server->timeout_queue, 0, 
627                               protocol, fd, 0, 300000);
628             return;
629           }
630         }
631         
632         /* Remote end is server */
633         if (conn_type == SILC_SOCKET_TYPE_SERVER) {
634           SilcConfigServerSectionServerConnection *serv = NULL;
635           serv = 
636             silc_config_server_find_server_conn(server->config,
637                                                 ctx->sock->ip,
638                                                 ctx->sock->port);
639           if (!serv)
640             serv = 
641               silc_config_server_find_server_conn(server->config,
642                                                   ctx->sock->hostname,
643                                                   ctx->sock->port);
644           
645           if (serv) {
646             switch(serv->auth_meth) {
647             case SILC_PROTOCOL_CONN_AUTH_NONE:
648               /* No authentication required */
649               SILC_LOG_DEBUG(("No authentication required"));
650               break;
651               
652             case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
653               /* Password authentication */
654               SILC_LOG_DEBUG(("Password authentication"));
655               ret = silc_server_password_authentication(server, auth_data,
656                                                         serv->auth_data);
657
658               if (ret) {
659                 memset(auth_data, 0, payload_len);
660                 silc_free(auth_data);
661                 auth_data = NULL;
662                 break;
663               }
664               
665               /* Authentication failed */
666               SILC_LOG_ERROR(("Authentication failed"));
667               SILC_LOG_DEBUG(("Authentication failed"));
668               protocol->state = SILC_PROTOCOL_STATE_ERROR;
669               protocol->execute(server->timeout_queue, 0, 
670                                 protocol, fd, 0, 300000);
671               return;
672               break;
673               
674             case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
675               /* Public key authentication */
676               SILC_LOG_DEBUG(("Public key authentication"));
677               ret = silc_server_public_key_authentication(server, 
678                                                           serv->auth_data,
679                                                           auth_data,
680                                                           payload_len, 
681                                                           ctx->ske);
682                                                           
683               if (ret) {
684                 memset(auth_data, 0, payload_len);
685                 silc_free(auth_data);
686                 auth_data = NULL;
687                 break;
688               }
689
690               SILC_LOG_ERROR(("Authentication failed"));
691               SILC_LOG_DEBUG(("Authentication failed"));
692               protocol->state = SILC_PROTOCOL_STATE_ERROR;
693               protocol->execute(server->timeout_queue, 0, 
694                                 protocol, fd, 0, 300000);
695               return;
696             }
697           } else {
698             SILC_LOG_DEBUG(("No configuration for remote connection"));
699             SILC_LOG_ERROR(("Remote connection not configured"));
700             SILC_LOG_ERROR(("Authentication failed"));
701             memset(auth_data, 0, payload_len);
702             silc_free(auth_data);
703             auth_data = NULL;
704             protocol->state = SILC_PROTOCOL_STATE_ERROR;
705             protocol->execute(server->timeout_queue, 0, 
706                               protocol, fd, 0, 300000);
707             return;
708           }
709         }
710         
711         /* Remote end is router */
712         if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
713           SilcConfigServerSectionServerConnection *serv = NULL;
714           serv = 
715             silc_config_server_find_router_conn(server->config,
716                                                 ctx->sock->ip,
717                                                 ctx->sock->port);
718           if (!serv)
719             serv = 
720               silc_config_server_find_router_conn(server->config,
721                                                   ctx->sock->hostname,
722                                                   ctx->sock->port);
723           
724           if (serv) {
725             switch(serv->auth_meth) {
726             case SILC_PROTOCOL_CONN_AUTH_NONE:
727               /* No authentication required */
728               SILC_LOG_DEBUG(("No authentication required"));
729               break;
730               
731             case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
732               /* Password authentication */
733               SILC_LOG_DEBUG(("Password authentication"));
734               ret = silc_server_password_authentication(server, auth_data,
735                                                         serv->auth_data);
736
737               if (ret) {
738                 memset(auth_data, 0, payload_len);
739                 silc_free(auth_data);
740                 auth_data = NULL;
741                 break;
742               }
743               
744               /* Authentication failed */
745               SILC_LOG_ERROR(("Authentication failed"));
746               SILC_LOG_DEBUG(("Authentication failed"));
747               protocol->state = SILC_PROTOCOL_STATE_ERROR;
748               protocol->execute(server->timeout_queue, 0, 
749                                 protocol, fd, 0, 300000);
750               return;
751               break;
752               
753             case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
754               /* Public key authentication */
755               SILC_LOG_DEBUG(("Public key authentication"));
756               ret = silc_server_public_key_authentication(server, 
757                                                           serv->auth_data,
758                                                           auth_data,
759                                                           payload_len, 
760                                                           ctx->ske);
761                                                           
762               if (ret) {
763                 memset(auth_data, 0, payload_len);
764                 silc_free(auth_data);
765                 auth_data = NULL;
766                 break;
767               }
768
769               SILC_LOG_ERROR(("Authentication failed"));
770               SILC_LOG_DEBUG(("Authentication failed"));
771               protocol->state = SILC_PROTOCOL_STATE_ERROR;
772               protocol->execute(server->timeout_queue, 0, 
773                                 protocol, fd, 0, 300000);
774               return;
775             }
776           } else {
777             SILC_LOG_DEBUG(("No configuration for remote connection"));
778             SILC_LOG_ERROR(("Remote connection not configured"));
779             SILC_LOG_ERROR(("Authentication failed"));
780             memset(auth_data, 0, payload_len);
781             silc_free(auth_data);
782             auth_data = NULL;
783             protocol->state = SILC_PROTOCOL_STATE_ERROR;
784             protocol->execute(server->timeout_queue, 0, 
785                               protocol, fd, 0, 300000);
786             return;
787           }
788         }
789         
790         if (auth_data) {
791           memset(auth_data, 0, payload_len);
792           silc_free(auth_data);
793         }
794         
795         /* Save connection type. This is later used to create the
796            ID for the connection. */
797         ctx->conn_type = conn_type;
798           
799         /* Advance protocol state. */
800         protocol->state = SILC_PROTOCOL_STATE_END;
801         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
802
803       } else {
804         /* 
805          * We are initiator. We are authenticating ourselves to a
806          * remote server. We will send the authentication data to the
807          * other end for verify. 
808          */
809         SilcBuffer packet;
810         int payload_len = 0;
811         unsigned char *auth_data = NULL;
812         unsigned int auth_data_len = 0;
813         
814         switch(ctx->auth_meth) {
815         case SILC_PROTOCOL_CONN_AUTH_NONE:
816           /* No authentication required */
817           break;
818           
819         case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
820           /* Password authentication */
821           if (ctx->auth_data && ctx->auth_data_len) {
822             auth_data = ctx->auth_data;
823             auth_data_len = ctx->auth_data_len;
824             break;
825           }
826
827           /* No authentication data exits. Ask interactively from user. */
828           /* XXX */
829
830           break;
831           
832         case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
833           /* Public key authentication */
834           /* XXX TODO */
835           break;
836         }
837         
838         payload_len = 4 + auth_data_len;
839         packet = silc_buffer_alloc(payload_len);
840         silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
841         silc_buffer_format(packet,
842                            SILC_STR_UI_SHORT(payload_len),
843                            SILC_STR_UI_SHORT(server->server_type 
844                                               == SILC_SERVER ?
845                                               SILC_SOCKET_TYPE_SERVER :
846                                               SILC_SOCKET_TYPE_ROUTER),
847                            SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
848                            SILC_STR_END);
849         
850         /* Send the packet to server */
851         silc_server_packet_send(server, ctx->sock,
852                                 SILC_PACKET_CONNECTION_AUTH, 0, 
853                                 packet->data, packet->len, TRUE);
854         
855         if (auth_data) {
856           memset(auth_data, 0, auth_data_len);
857           silc_free(auth_data);
858         }
859         silc_buffer_free(packet);
860         
861         /* Next state is end of protocol */
862         protocol->state = SILC_PROTOCOL_STATE_END;
863       }
864     }
865     break;
866
867   case SILC_PROTOCOL_STATE_END:
868     {
869       /* 
870        * End protocol
871        */
872
873       /* Succesfully authenticated */
874       silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS, 
875                               0, NULL, 0, TRUE);
876
877       /* Unregister the timeout task since the protocol has ended. 
878          This was the timeout task to be executed if the protocol is
879          not completed fast enough. */
880       if (ctx->timeout_task)
881         silc_task_unregister(server->timeout_queue, ctx->timeout_task);
882
883       /* Protocol has ended, call the final callback */
884       if (protocol->final_callback)
885         protocol->execute_final(server->timeout_queue, 0, protocol, fd);
886       else
887         silc_protocol_free(protocol);
888     }
889     break;
890   case SILC_PROTOCOL_STATE_ERROR:
891     {
892       /*
893        * Error 
894        */
895
896       /* Authentication failed */
897       silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
898                               0, NULL, 0, TRUE);
899
900       /* Unregister the timeout task since the protocol has ended. 
901          This was the timeout task to be executed if the protocol is
902          not completed fast enough. */
903       if (ctx->timeout_task)
904         silc_task_unregister(server->timeout_queue, ctx->timeout_task);
905
906       /* On error the final callback is always called. */
907       if (protocol->final_callback)
908         protocol->execute_final(server->timeout_queue, 0, protocol, fd);
909       else
910         silc_protocol_free(protocol);
911     }
912     break;
913   case SILC_PROTOCOL_STATE_UNKNOWN:
914     break;
915   }
916 }