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