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