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