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