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