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