Cleaner code fro password and public key authentication.
[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.3  2000/07/06 07:15:31  priikone
27  *      Cleaner code fro password and public key authentication.
28  *      Deprecated old `channel_auth' protocol.
29  *
30  * Revision 1.2  2000/07/05 06:13:04  priikone
31  *      Support for SILC style public keys added.
32  *
33  * Revision 1.1.1.1  2000/06/27 11:36:56  priikone
34  *      Imported from internal CVS/Added Log headers.
35  *
36  *
37  */
38
39 #include "serverincludes.h"
40 #include "server_internal.h"
41
42 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth);
43 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange);
44
45 /* SILC client protocol list */
46 const SilcProtocolObject silc_protocol_list[] =
47 {
48   { SILC_PROTOCOL_SERVER_CONNECTION_AUTH, 
49     silc_server_protocol_connection_auth },
50   { SILC_PROTOCOL_SERVER_KEY_EXCHANGE, 
51     silc_server_protocol_key_exchange },
52
53   { SILC_PROTOCOL_SERVER_NONE, NULL },
54 };
55
56 /*
57  * Key Exhange protocol functions
58  */
59
60 /* Packet sending callback. This function is provided as packet sending
61    routine to the Key Exchange functions. */
62
63 static void silc_server_protocol_ke_send_packet(SilcSKE ske,
64                                                 SilcBuffer packet,
65                                                 SilcPacketType type,
66                                                 void *context)
67 {
68   SilcProtocol protocol = (SilcProtocol)context;
69   SilcServerKEInternalContext *ctx = 
70     (SilcServerKEInternalContext *)protocol->context;
71   SilcServer server = (SilcServer)ctx->server;
72
73   /* Send the packet immediately */
74   silc_server_packet_send(server, ske->sock,
75                           type, 0, packet->data, packet->len, TRUE);
76 }
77
78 /* Sets the negotiated key material into use for particular connection. */
79
80 static void silc_server_protocol_ke_set_keys(SilcSKE ske,
81                                              SilcSocketConnection sock,
82                                              SilcSKEKeyMaterial *keymat,
83                                              SilcCipher cipher,
84                                              SilcPKCS pkcs,
85                                              SilcHash hash,
86                                              int is_responder)
87 {
88   SilcIDListUnknown *conn_data;
89   SilcHash nhash;
90
91   SILC_LOG_DEBUG(("Setting new key into use"));
92
93   conn_data = silc_calloc(1, sizeof(*conn_data));
94
95   /* Allocate cipher to be used in the communication */
96   silc_cipher_alloc(cipher->cipher->name, &conn_data->send_key);
97   silc_cipher_alloc(cipher->cipher->name, &conn_data->receive_key);
98   
99   if (is_responder == TRUE) {
100     conn_data->send_key->cipher->set_key(conn_data->send_key->context, 
101                                          keymat->receive_enc_key, 
102                                          keymat->enc_key_len);
103     conn_data->send_key->set_iv(conn_data->send_key, keymat->receive_iv);
104     conn_data->receive_key->cipher->set_key(conn_data->receive_key->context, 
105                                             keymat->send_enc_key, 
106                                             keymat->enc_key_len);
107     conn_data->receive_key->set_iv(conn_data->receive_key, keymat->send_iv);
108     
109   } else {
110     conn_data->send_key->cipher->set_key(conn_data->send_key->context, 
111                                          keymat->send_enc_key, 
112                                          keymat->enc_key_len);
113     conn_data->send_key->set_iv(conn_data->send_key, keymat->send_iv);
114     conn_data->receive_key->cipher->set_key(conn_data->receive_key->context, 
115                                             keymat->receive_enc_key, 
116                                             keymat->enc_key_len);
117     conn_data->receive_key->set_iv(conn_data->receive_key, keymat->receive_iv);
118   }
119
120   /* Allocate PKCS to be used */
121 #if 0
122   /* XXX Do we ever need to allocate PKCS for the connection??
123      If yes, we need to change KE protocol to get the initiators
124      public key. */
125   silc_pkcs_alloc(pkcs->pkcs->name, &conn_data->pkcs);
126   conn_data->public_key = silc_pkcs_public_key_alloc(XXX);
127   silc_pkcs_set_public_key(conn_data->pkcs, ske->ke2_payload->pk_data, 
128                            ske->ke2_payload->pk_len);
129 #endif
130
131   /* Save HMAC key to be used in the communication. */
132   silc_hash_alloc(hash->hash->name, &nhash);
133   silc_hmac_alloc(nhash, &conn_data->hmac);
134   conn_data->hmac_key_len = keymat->hmac_key_len;
135   conn_data->hmac_key = silc_calloc(conn_data->hmac_key_len,
136                                     sizeof(unsigned char));
137   memcpy(conn_data->hmac_key, keymat->hmac_key, keymat->hmac_key_len);
138
139   sock->user_data = (void *)conn_data;
140 }
141
142 /* Performs key exchange protocol. This is used for both initiator
143    and responder key exchange. This is performed always when accepting
144    new connection to the server. This may be called recursively. */
145
146 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
147 {
148   SilcProtocol protocol = (SilcProtocol)context;
149   SilcServerKEInternalContext *ctx = 
150     (SilcServerKEInternalContext *)protocol->context;
151   SilcServer server = (SilcServer)ctx->server;
152   SilcSKEStatus status = 0;
153
154   SILC_LOG_DEBUG(("Start"));
155
156   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
157     protocol->state = SILC_PROTOCOL_STATE_START;
158
159   SILC_LOG_DEBUG(("State=%d", protocol->state));
160
161   switch(protocol->state) {
162   case SILC_PROTOCOL_STATE_START:
163     {
164       /*
165        * Start protocol
166        */
167       SilcSKE ske;
168
169       /* Allocate Key Exchange object */
170       ske = silc_ske_alloc();
171       ctx->ske = ske;
172       
173       if (ctx->responder == TRUE) {
174         /* Start the key exchange by processing the received security
175            properties packet from initiator. */
176         status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
177                                           ctx->packet, NULL, NULL);
178       } else {
179         SilcSKEStartPayload *start_payload;
180
181         /* Assemble security properties. */
182         silc_ske_assemble_security_properties(ske, &start_payload);
183
184         /* Start the key exchange by sending our security properties
185            to the remote end. */
186         status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
187                                           start_payload,
188                                           silc_server_protocol_ke_send_packet,
189                                           context);
190       }
191
192       if (status != SILC_SKE_STATUS_OK) {
193         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
194                           status));
195         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
196                         status));
197
198         protocol->state = SILC_PROTOCOL_STATE_ERROR;
199         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
200         return;
201       }
202
203       /* Advance protocol state and call the next state if we are responder */
204       protocol->state++;
205       if (ctx->responder == TRUE)
206         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
207     }
208     break;
209   case 2:
210     {
211       /* 
212        * Phase 1 
213        */
214       if (ctx->responder == TRUE) {
215         /* Sends the selected security properties to the initiator. */
216         status = 
217           silc_ske_responder_phase_1(ctx->ske, 
218                                      ctx->ske->start_payload,
219                                      silc_server_protocol_ke_send_packet,
220                                      context);
221       } else {
222         /* Call Phase-1 function. This processes the Key Exchange Start
223            paylaod reply we just got from the responder. The callback
224            function will receive the processed payload where we will
225            save it. */
226         status = 
227           silc_ske_initiator_phase_1(ctx->ske,
228                                      ctx->packet,
229                                      NULL, NULL);
230       }
231
232       if (status != SILC_SKE_STATUS_OK) {
233         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
234                           status));
235         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
236                         status));
237
238         protocol->state = SILC_PROTOCOL_STATE_ERROR;
239         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
240         return;
241       }
242
243       /* Advance protocol state and call next state if we are initiator */
244       protocol->state++;
245       if (ctx->responder == FALSE)
246         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
247     }
248     break;
249   case 3:
250     {
251       /* 
252        * Phase 2 
253        */
254       if (ctx->responder == TRUE) {
255         /* Process the received Key Exchange 1 Payload packet from
256            the initiator. This also creates our parts of the Diffie
257            Hellman algorithm. */
258         status = 
259           silc_ske_responder_phase_2(ctx->ske, ctx->packet, NULL, NULL);
260       } else {
261         /* Call the Phase-2 function. This creates Diffie Hellman
262            key exchange parameters and sends our public part inside
263            Key Exhange 1 Payload to the responder. */
264         status = 
265           silc_ske_initiator_phase_2(ctx->ske,
266                                      silc_server_protocol_ke_send_packet,
267                                      context);
268       }
269
270       if (status != SILC_SKE_STATUS_OK) {
271         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
272                           status));
273         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
274                         status));
275
276         protocol->state = SILC_PROTOCOL_STATE_ERROR;
277         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
278         return;
279       }
280
281       /* Advance protocol state and call the next state if we are responder */
282       protocol->state++;
283       if (ctx->responder == TRUE)
284         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
285     }
286     break;
287   case 4:
288     {
289       /* 
290        * Finish protocol
291        */
292       if (ctx->responder == TRUE) {
293         unsigned char *pk, *prv;
294         unsigned int pk_len, prv_len;
295
296         /* Get our public key to be sent to the initiator */
297         pk = silc_pkcs_get_public_key(server->public_key, &pk_len);
298
299         /* Get out private key to sign some data. */
300         prv = silc_pkcs_get_private_key(server->public_key, &prv_len);
301
302         /* This creates the key exchange material and sends our
303            public parts to the initiator inside Key Exchange 2 Payload. */
304         status = 
305           silc_ske_responder_finish(ctx->ske, 
306                                     pk, pk_len, prv, prv_len,
307                                     SILC_SKE_PK_TYPE_SILC,
308                                     silc_server_protocol_ke_send_packet,
309                                     context);
310
311         memset(pk, 0, pk_len);
312         memset(prv, 0, prv_len);
313         silc_free(pk);
314         silc_free(prv);
315       } else {
316         /* Finish the protocol. This verifies the Key Exchange 2 payload
317            sent by responder. */
318         status = 
319           silc_ske_initiator_finish(ctx->ske,
320                                     ctx->packet, NULL, NULL);
321       }
322
323       if (status != SILC_SKE_STATUS_OK) {
324         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
325                           status));
326         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
327                         status));
328
329         protocol->state = SILC_PROTOCOL_STATE_ERROR;
330         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
331         return;
332       }
333
334       /* Send Ok to the other end. We will end the protocol as responder
335          sends Ok to us when we will take the new keys into use. */
336       if (ctx->responder == FALSE)
337         silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
338
339       /* End the protocol on the next round */
340       protocol->state = SILC_PROTOCOL_STATE_END;
341     }
342     break;
343   case SILC_PROTOCOL_STATE_END:
344     {
345       /* 
346        * End protocol
347        */
348       SilcSKEKeyMaterial *keymat;
349
350       /* Send Ok to the other end if we are responder. If we are 
351          initiator we have sent this already. */
352       if (ctx->responder == TRUE)
353         silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
354
355       /* Process the key material */
356       keymat = silc_calloc(1, sizeof(*keymat));
357       silc_ske_process_key_material(ctx->ske, 16, (16 * 8), 16, keymat);
358
359       /* Take the new keys into use. */
360       silc_server_protocol_ke_set_keys(ctx->ske, ctx->sock, keymat,
361                                        ctx->ske->prop->cipher,
362                                        ctx->ske->prop->pkcs,
363                                        ctx->ske->prop->hash,
364                                        ctx->responder);
365
366       /* Unregister the timeout task since the protocol has ended. 
367          This was the timeout task to be executed if the protocol is
368          not completed fast enough. */
369       if (ctx->timeout_task)
370         silc_task_unregister(server->timeout_queue, ctx->timeout_task);
371
372       /* Call the final callback */
373       if (protocol->final_callback)
374         protocol->execute_final(server->timeout_queue, 0, protocol, fd);
375       else
376         silc_protocol_free(protocol);
377     }
378     break;
379   case SILC_PROTOCOL_STATE_ERROR:
380     /*
381      * Error occured
382      */
383
384     /* Unregister the timeout task since the protocol has ended. 
385        This was the timeout task to be executed if the protocol is
386        not completed fast enough. */
387     if (ctx->timeout_task)
388       silc_task_unregister(server->timeout_queue, ctx->timeout_task);
389
390     /* On error the final callback is always called. */
391     if (protocol->final_callback)
392       protocol->execute_final(server->timeout_queue, 0, protocol, fd);
393     else
394       silc_protocol_free(protocol);
395     break;
396   case SILC_PROTOCOL_STATE_UNKNOWN:
397     break;
398   }
399 }
400
401 /*
402  * Connection Authentication protocol functions
403  */
404
405 /* XXX move these to somehwere else */
406
407 int silc_server_password_authentication(SilcServer server, char *auth1, 
408                                         char *auth2)
409 {
410   if (!auth1 || !auth2)
411     return FALSE;
412
413   if (!memcmp(auth1, auth2, strlen(auth1)))
414     return TRUE;
415
416   return FALSE;
417 }
418
419 int silc_server_public_key_authentication(SilcServer server,
420                                           char *pkfile,
421                                           unsigned char *sign,
422                                           unsigned int sign_len,
423                                           SilcSKE ske)
424 {
425   SilcPublicKey pub_key;
426   SilcPKCS pkcs;
427   int len;
428   SilcBuffer auth;
429
430   if (!pkfile || !sign)
431     return FALSE;
432
433   /* Load public key from file */
434   if (!silc_pkcs_load_public_key(pkfile, &pub_key))
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 }