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