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