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