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