Added require_reverse_mapping for ServerParams.
[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 (%s)",
518                        ctx->sock->hostname, ctx->sock->ip));
519
520         /* Parse the received authentication data packet. The received
521            payload is Connection Auth Payload. */
522         silc_buffer_unformat(ctx->packet->buffer,
523                              SILC_STR_UI_SHORT(&payload_len),
524                              SILC_STR_UI_SHORT(&conn_type),
525                              SILC_STR_END);
526         
527         if (payload_len != ctx->packet->buffer->len) {
528           SILC_LOG_ERROR(("Bad payload in authentication packet"));
529           SILC_LOG_DEBUG(("Bad payload in authentication packet"));
530           protocol->state = SILC_PROTOCOL_STATE_ERROR;
531           protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
532           return;
533         }
534         
535         payload_len -= 4;
536         
537         if (conn_type < SILC_SOCKET_TYPE_CLIENT || 
538             conn_type > SILC_SOCKET_TYPE_ROUTER) {
539           SILC_LOG_ERROR(("Bad connection type %d", conn_type));
540           SILC_LOG_DEBUG(("Bad connection type %d", conn_type));
541           protocol->state = SILC_PROTOCOL_STATE_ERROR;
542           protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
543           return;
544         }
545         
546         if (payload_len > 0) {
547           /* Get authentication data */
548           silc_buffer_pull(ctx->packet->buffer, 4);
549           silc_buffer_unformat(ctx->packet->buffer,
550                                SILC_STR_UI_XNSTRING_ALLOC(&auth_data, 
551                                                           payload_len),
552                                SILC_STR_END);
553         } else {
554           auth_data = NULL;
555         }
556
557         /* 
558          * Check the remote connection type and make sure that we have
559          * configured this connection. If we haven't allowed this connection
560          * the authentication must be failed.
561          */
562
563         SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
564
565         /* Remote end is client */
566         if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
567           SilcConfigServerSectionClientConnection *client = NULL;
568           client = 
569             silc_config_server_find_client_conn(server->config,
570                                                 ctx->sock->ip,
571                                                 ctx->sock->port);
572           if (!client)
573             client = 
574               silc_config_server_find_client_conn(server->config,
575                                                   ctx->sock->hostname,
576                                                   ctx->sock->port);
577           
578           if (client) {
579             switch(client->auth_meth) {
580             case SILC_PROTOCOL_CONN_AUTH_NONE:
581               /* No authentication required */
582               SILC_LOG_DEBUG(("No authentication required"));
583               break;
584               
585             case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
586               /* Password authentication */
587               SILC_LOG_DEBUG(("Password authentication"));
588               ret = silc_server_password_authentication(server, auth_data,
589                                                         client->auth_data);
590
591               if (ret) {
592                 memset(auth_data, 0, payload_len);
593                 silc_free(auth_data);
594                 auth_data = NULL;
595                 break;
596               }
597
598               /* Authentication failed */
599               SILC_LOG_ERROR(("Authentication failed"));
600               SILC_LOG_DEBUG(("Authentication failed"));
601               protocol->state = SILC_PROTOCOL_STATE_ERROR;
602               protocol->execute(server->timeout_queue, 0, 
603                                 protocol, fd, 0, 300000);
604               return;
605               break;
606               
607             case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
608               /* Public key authentication */
609               SILC_LOG_DEBUG(("Public key authentication"));
610               ret = silc_server_public_key_authentication(server, 
611                                                           client->auth_data,
612                                                           auth_data,
613                                                           payload_len, 
614                                                           ctx->ske);
615                                                           
616               if (ret) {
617                 memset(auth_data, 0, payload_len);
618                 silc_free(auth_data);
619                 auth_data = NULL;
620                 break;
621               }
622
623               SILC_LOG_ERROR(("Authentication failed"));
624               SILC_LOG_DEBUG(("Authentication failed"));
625               protocol->state = SILC_PROTOCOL_STATE_ERROR;
626               protocol->execute(server->timeout_queue, 0, 
627                                 protocol, fd, 0, 300000);
628               return;
629             }
630           } else {
631             SILC_LOG_DEBUG(("No configuration for remote connection"));
632             SILC_LOG_ERROR(("Remote connection not configured"));
633             SILC_LOG_ERROR(("Authentication failed"));
634             memset(auth_data, 0, payload_len);
635             silc_free(auth_data);
636             auth_data = NULL;
637             protocol->state = SILC_PROTOCOL_STATE_ERROR;
638             protocol->execute(server->timeout_queue, 0, 
639                               protocol, fd, 0, 300000);
640             return;
641           }
642         }
643         
644         /* Remote end is server */
645         if (conn_type == SILC_SOCKET_TYPE_SERVER) {
646           SilcConfigServerSectionServerConnection *serv = NULL;
647           serv = 
648             silc_config_server_find_server_conn(server->config,
649                                                 ctx->sock->ip,
650                                                 ctx->sock->port);
651           if (!serv)
652             serv = 
653               silc_config_server_find_server_conn(server->config,
654                                                   ctx->sock->hostname,
655                                                   ctx->sock->port);
656           
657           if (serv) {
658             switch(serv->auth_meth) {
659             case SILC_PROTOCOL_CONN_AUTH_NONE:
660               /* No authentication required */
661               SILC_LOG_DEBUG(("No authentication required"));
662               break;
663               
664             case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
665               /* Password authentication */
666               SILC_LOG_DEBUG(("Password authentication"));
667               ret = silc_server_password_authentication(server, auth_data,
668                                                         serv->auth_data);
669
670               if (ret) {
671                 memset(auth_data, 0, payload_len);
672                 silc_free(auth_data);
673                 auth_data = NULL;
674                 break;
675               }
676               
677               /* Authentication failed */
678               SILC_LOG_ERROR(("Authentication failed"));
679               SILC_LOG_DEBUG(("Authentication failed"));
680               protocol->state = SILC_PROTOCOL_STATE_ERROR;
681               protocol->execute(server->timeout_queue, 0, 
682                                 protocol, fd, 0, 300000);
683               return;
684               break;
685               
686             case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
687               /* Public key authentication */
688               SILC_LOG_DEBUG(("Public key authentication"));
689               ret = silc_server_public_key_authentication(server, 
690                                                           serv->auth_data,
691                                                           auth_data,
692                                                           payload_len, 
693                                                           ctx->ske);
694                                                           
695               if (ret) {
696                 memset(auth_data, 0, payload_len);
697                 silc_free(auth_data);
698                 auth_data = NULL;
699                 break;
700               }
701
702               SILC_LOG_ERROR(("Authentication failed"));
703               SILC_LOG_DEBUG(("Authentication failed"));
704               protocol->state = SILC_PROTOCOL_STATE_ERROR;
705               protocol->execute(server->timeout_queue, 0, 
706                                 protocol, fd, 0, 300000);
707               return;
708             }
709           } else {
710             SILC_LOG_DEBUG(("No configuration for remote connection"));
711             SILC_LOG_ERROR(("Remote connection not configured"));
712             SILC_LOG_ERROR(("Authentication failed"));
713             memset(auth_data, 0, payload_len);
714             silc_free(auth_data);
715             auth_data = NULL;
716             protocol->state = SILC_PROTOCOL_STATE_ERROR;
717             protocol->execute(server->timeout_queue, 0, 
718                               protocol, fd, 0, 300000);
719             return;
720           }
721         }
722         
723         /* Remote end is router */
724         if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
725           SilcConfigServerSectionServerConnection *serv = NULL;
726           serv = 
727             silc_config_server_find_router_conn(server->config,
728                                                 ctx->sock->ip,
729                                                 ctx->sock->port);
730           if (!serv)
731             serv = 
732               silc_config_server_find_router_conn(server->config,
733                                                   ctx->sock->hostname,
734                                                   ctx->sock->port);
735           
736           if (serv) {
737             switch(serv->auth_meth) {
738             case SILC_PROTOCOL_CONN_AUTH_NONE:
739               /* No authentication required */
740               SILC_LOG_DEBUG(("No authentication required"));
741               break;
742               
743             case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
744               /* Password authentication */
745               SILC_LOG_DEBUG(("Password authentication"));
746               ret = silc_server_password_authentication(server, auth_data,
747                                                         serv->auth_data);
748
749               if (ret) {
750                 memset(auth_data, 0, payload_len);
751                 silc_free(auth_data);
752                 auth_data = NULL;
753                 break;
754               }
755               
756               /* Authentication failed */
757               SILC_LOG_ERROR(("Authentication failed"));
758               SILC_LOG_DEBUG(("Authentication failed"));
759               protocol->state = SILC_PROTOCOL_STATE_ERROR;
760               protocol->execute(server->timeout_queue, 0, 
761                                 protocol, fd, 0, 300000);
762               return;
763               break;
764               
765             case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
766               /* Public key authentication */
767               SILC_LOG_DEBUG(("Public key authentication"));
768               ret = silc_server_public_key_authentication(server, 
769                                                           serv->auth_data,
770                                                           auth_data,
771                                                           payload_len, 
772                                                           ctx->ske);
773                                                           
774               if (ret) {
775                 memset(auth_data, 0, payload_len);
776                 silc_free(auth_data);
777                 auth_data = NULL;
778                 break;
779               }
780
781               SILC_LOG_ERROR(("Authentication failed"));
782               SILC_LOG_DEBUG(("Authentication failed"));
783               protocol->state = SILC_PROTOCOL_STATE_ERROR;
784               protocol->execute(server->timeout_queue, 0, 
785                                 protocol, fd, 0, 300000);
786               return;
787             }
788           } else {
789             SILC_LOG_DEBUG(("No configuration for remote connection"));
790             SILC_LOG_ERROR(("Remote connection not configured"));
791             SILC_LOG_ERROR(("Authentication failed"));
792             memset(auth_data, 0, payload_len);
793             silc_free(auth_data);
794             auth_data = NULL;
795             protocol->state = SILC_PROTOCOL_STATE_ERROR;
796             protocol->execute(server->timeout_queue, 0, 
797                               protocol, fd, 0, 300000);
798             return;
799           }
800         }
801         
802         if (auth_data) {
803           memset(auth_data, 0, payload_len);
804           silc_free(auth_data);
805         }
806         
807         /* Save connection type. This is later used to create the
808            ID for the connection. */
809         ctx->conn_type = conn_type;
810           
811         /* Advance protocol state. */
812         protocol->state = SILC_PROTOCOL_STATE_END;
813         protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
814
815       } else {
816         /* 
817          * We are initiator. We are authenticating ourselves to a
818          * remote server. We will send the authentication data to the
819          * other end for verify. 
820          */
821         SilcBuffer packet;
822         int payload_len = 0;
823         unsigned char *auth_data = NULL;
824         unsigned int auth_data_len = 0;
825         
826         switch(ctx->auth_meth) {
827         case SILC_PROTOCOL_CONN_AUTH_NONE:
828           /* No authentication required */
829           break;
830           
831         case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
832           /* Password authentication */
833           if (ctx->auth_data && ctx->auth_data_len) {
834             auth_data = ctx->auth_data;
835             auth_data_len = ctx->auth_data_len;
836             break;
837           }
838
839           /* No authentication data exits. Ask interactively from user. */
840           /* XXX */
841
842           break;
843           
844         case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
845           /* Public key authentication */
846           /* XXX TODO */
847           break;
848         }
849         
850         payload_len = 4 + auth_data_len;
851         packet = silc_buffer_alloc(payload_len);
852         silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
853         silc_buffer_format(packet,
854                            SILC_STR_UI_SHORT(payload_len),
855                            SILC_STR_UI_SHORT(server->server_type 
856                                               == SILC_SERVER ?
857                                               SILC_SOCKET_TYPE_SERVER :
858                                               SILC_SOCKET_TYPE_ROUTER),
859                            SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
860                            SILC_STR_END);
861         
862         /* Send the packet to server */
863         silc_server_packet_send(server, ctx->sock,
864                                 SILC_PACKET_CONNECTION_AUTH, 0, 
865                                 packet->data, packet->len, TRUE);
866         
867         if (auth_data) {
868           memset(auth_data, 0, auth_data_len);
869           silc_free(auth_data);
870         }
871         silc_buffer_free(packet);
872         
873         /* Next state is end of protocol */
874         protocol->state = SILC_PROTOCOL_STATE_END;
875       }
876     }
877     break;
878
879   case SILC_PROTOCOL_STATE_END:
880     {
881       /* 
882        * End protocol
883        */
884       unsigned char ok[4];
885
886       SILC_PUT32_MSB(SILC_CONN_AUTH_OK, ok);
887
888       /* Authentication failed */
889       silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
890                               0, ok, 4, TRUE);
891
892       /* Unregister the timeout task since the protocol has ended. 
893          This was the timeout task to be executed if the protocol is
894          not completed fast enough. */
895       if (ctx->timeout_task)
896         silc_task_unregister(server->timeout_queue, ctx->timeout_task);
897
898       /* Protocol has ended, call the final callback */
899       if (protocol->final_callback)
900         protocol->execute_final(server->timeout_queue, 0, protocol, fd);
901       else
902         silc_protocol_free(protocol);
903     }
904     break;
905   case SILC_PROTOCOL_STATE_ERROR:
906     {
907       /*
908        * Error. Send notify to remote.
909        */
910       unsigned char error[4];
911
912       SILC_PUT32_MSB(SILC_CONN_AUTH_FAILED, error);
913
914       /* Authentication failed */
915       silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
916                               0, error, 4, TRUE);
917
918       /* Unregister the timeout task since the protocol has ended. 
919          This was the timeout task to be executed if the protocol is
920          not completed fast enough. */
921       if (ctx->timeout_task)
922         silc_task_unregister(server->timeout_queue, ctx->timeout_task);
923
924       /* On error the final callback is always called. */
925       if (protocol->final_callback)
926         protocol->execute_final(server->timeout_queue, 0, protocol, fd);
927       else
928         silc_protocol_free(protocol);
929     }
930     break;
931
932   case SILC_PROTOCOL_STATE_FAILURE:
933     /*
934      * We have received failure from remote
935      */
936
937     /* Unregister the timeout task since the protocol has ended. 
938        This was the timeout task to be executed if the protocol is
939        not completed fast enough. */
940     if (ctx->timeout_task)
941       silc_task_unregister(server->timeout_queue, ctx->timeout_task);
942
943     /* On error the final callback is always called. */
944     if (protocol->final_callback)
945       protocol->execute_final(server->timeout_queue, 0, protocol, fd);
946     else
947       silc_protocol_free(protocol);
948     break;
949
950   case SILC_PROTOCOL_STATE_UNKNOWN:
951     break;
952   }
953 }
954
955 /* Registers protocols used in server. */
956
957 void silc_server_protocols_register(void)
958 {
959   silc_protocol_register(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
960                          silc_server_protocol_connection_auth);
961   silc_protocol_register(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
962                          silc_server_protocol_key_exchange);
963 }
964
965 /* Unregisters protocols */
966
967 void silc_server_protocols_unregister(void)
968 {
969   silc_protocol_unregister(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
970                            silc_server_protocol_connection_auth);
971   silc_protocol_unregister(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
972                            silc_server_protocol_key_exchange);
973 }