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