5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 Pekka Riikonen
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.
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.
21 * Server side of the protocols.
26 * Revision 1.2 2000/07/05 06:13:04 priikone
27 * Support for SILC style public keys added.
29 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
30 * Imported from internal CVS/Added Log headers.
35 #include "serverincludes.h"
36 #include "server_internal.h"
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);
42 /* SILC client protocol list */
43 const SilcProtocolObject silc_protocol_list[] =
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 },
52 { SILC_PROTOCOL_SERVER_NONE, NULL },
56 * Key Exhange protocol functions
59 /* Packet sending callback. This function is provided as packet sending
60 routine to the Key Exchange functions. */
62 static void silc_server_protocol_ke_send_packet(SilcSKE ske,
67 SilcProtocol protocol = (SilcProtocol)context;
68 SilcServerKEInternalContext *ctx =
69 (SilcServerKEInternalContext *)protocol->context;
70 SilcServer server = (SilcServer)ctx->server;
72 /* Send the packet immediately */
73 silc_server_packet_send(server, ske->sock,
74 type, 0, packet->data, packet->len, TRUE);
77 /* Sets the negotiated key material into use for particular connection. */
79 static void silc_server_protocol_ke_set_keys(SilcSKE ske,
80 SilcSocketConnection sock,
81 SilcSKEKeyMaterial *keymat,
87 SilcIDListUnknown *conn_data;
90 SILC_LOG_DEBUG(("Setting new key into use"));
92 conn_data = silc_calloc(1, sizeof(*conn_data));
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);
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);
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);
119 /* Allocate PKCS to be used */
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
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);
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);
137 sock->user_data = (void *)conn_data;
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. */
144 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
146 SilcProtocol protocol = (SilcProtocol)context;
147 SilcServerKEInternalContext *ctx =
148 (SilcServerKEInternalContext *)protocol->context;
149 SilcServer server = (SilcServer)ctx->server;
150 SilcSKEStatus status = 0;
152 SILC_LOG_DEBUG(("Start"));
154 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
155 protocol->state = SILC_PROTOCOL_STATE_START;
157 SILC_LOG_DEBUG(("State=%d", protocol->state));
159 switch(protocol->state) {
160 case SILC_PROTOCOL_STATE_START:
167 /* Allocate Key Exchange object */
168 ske = silc_ske_alloc();
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);
177 SilcSKEStartPayload *start_payload;
179 /* Assemble security properties. */
180 silc_ske_assemble_security_properties(ske, &start_payload);
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,
186 silc_server_protocol_ke_send_packet,
190 if (status != SILC_SKE_STATUS_OK) {
191 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
193 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
196 protocol->state = SILC_PROTOCOL_STATE_ERROR;
197 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
201 /* Advance protocol state and call the next state if we are responder */
203 if (ctx->responder == TRUE)
204 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
212 if (ctx->responder == TRUE) {
213 /* Sends the selected security properties to the initiator. */
215 silc_ske_responder_phase_1(ctx->ske,
216 ctx->ske->start_payload,
217 silc_server_protocol_ke_send_packet,
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
225 silc_ske_initiator_phase_1(ctx->ske,
230 if (status != SILC_SKE_STATUS_OK) {
231 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
233 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
236 protocol->state = SILC_PROTOCOL_STATE_ERROR;
237 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
241 /* Advance protocol state and call next state if we are initiator */
243 if (ctx->responder == FALSE)
244 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
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. */
257 silc_ske_responder_phase_2(ctx->ske, ctx->packet, NULL, NULL);
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. */
263 silc_ske_initiator_phase_2(ctx->ske,
264 silc_server_protocol_ke_send_packet,
268 if (status != SILC_SKE_STATUS_OK) {
269 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
271 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
274 protocol->state = SILC_PROTOCOL_STATE_ERROR;
275 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
279 /* Advance protocol state and call the next state if we are responder */
281 if (ctx->responder == TRUE)
282 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
290 if (ctx->responder == TRUE) {
291 unsigned char *pk, *prv;
292 unsigned int pk_len, prv_len;
294 /* Get our public key to be sent to the initiator */
295 pk = silc_pkcs_get_public_key(server->public_key, &pk_len);
297 /* Get out private key to sign some data. */
298 prv = silc_pkcs_get_private_key(server->public_key, &prv_len);
300 /* This creates the key exchange material and sends our
301 public parts to the initiator inside Key Exchange 2 Payload. */
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,
309 memset(pk, 0, pk_len);
310 memset(prv, 0, prv_len);
314 /* Finish the protocol. This verifies the Key Exchange 2 payload
315 sent by responder. */
317 silc_ske_initiator_finish(ctx->ske,
318 ctx->packet, NULL, NULL);
321 if (status != SILC_SKE_STATUS_OK) {
322 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
324 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
327 protocol->state = SILC_PROTOCOL_STATE_ERROR;
328 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
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);
337 /* End the protocol on the next round */
338 protocol->state = SILC_PROTOCOL_STATE_END;
341 case SILC_PROTOCOL_STATE_END:
346 SilcSKEKeyMaterial *keymat;
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);
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);
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,
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);
370 /* Call the final callback */
371 if (protocol->final_callback)
372 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
374 silc_protocol_free(protocol);
377 case SILC_PROTOCOL_STATE_ERROR:
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);
388 /* On error the final callback is always called. */
389 if (protocol->final_callback)
390 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
392 silc_protocol_free(protocol);
394 case SILC_PROTOCOL_STATE_UNKNOWN:
400 * Connection Authentication protocol functions
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. */
407 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
409 SilcProtocol protocol = (SilcProtocol)context;
410 SilcServerConnAuthInternalContext *ctx =
411 (SilcServerConnAuthInternalContext *)protocol->context;
412 SilcServer server = (SilcServer)ctx->server;
414 SILC_LOG_DEBUG(("Start"));
416 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
417 protocol->state = SILC_PROTOCOL_STATE_START;
419 SILC_LOG_DEBUG(("State=%d", protocol->state));
421 switch(protocol->state) {
422 case SILC_PROTOCOL_STATE_START:
428 if (ctx->responder == TRUE) {
430 * We are receiving party
432 unsigned short payload_len;
433 unsigned short conn_type;
434 unsigned char *auth_data;
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),
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);
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);
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,
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.
479 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
481 /* Remote end is client */
482 if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
483 SilcConfigServerSectionClientConnection *client = NULL;
485 silc_config_server_find_client_conn(server->config,
490 silc_config_server_find_client_conn(server->config,
495 switch(client->auth_meth) {
496 case SILC_PROTOCOL_CONN_AUTH_NONE:
497 /* No authentication required */
498 SILC_LOG_DEBUG(("No authentication required"));
501 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
502 /* Password authentication */
503 SILC_LOG_DEBUG(("Password authentication"));
505 if (!memcmp(client->auth_data, auth_data, strlen(auth_data))) {
506 memset(auth_data, 0, payload_len);
507 silc_free(auth_data);
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);
522 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
523 /* Public key authentication */
524 SILC_LOG_DEBUG(("Public key authentication"));
526 SilcIDListUnknown *conn_data;
527 SilcPublicKey pub_key;
530 conn_data = (SilcIDListUnknown *)ctx->sock->user_data;
532 /* Load public key from file */
533 if (silc_pkcs_load_public_key(client->auth_data,
534 &pub_key) == FALSE) {
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);
542 protocol->state = SILC_PROTOCOL_STATE_ERROR;
543 protocol->execute(server->timeout_queue, 0,
544 protocol, fd, 0, 300000);
548 silc_pkcs_alloc(pub_key->name, &pkcs);
550 /* Verify hash value HASH from KE protocol */
551 if (pkcs->pkcs->verify(pkcs->context,
552 auth_data, payload_len,
556 silc_pkcs_free(pkcs);
557 silc_pkcs_public_key_free(pub_key);
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);
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);
576 protocol->state = SILC_PROTOCOL_STATE_ERROR;
577 protocol->execute(server->timeout_queue, 0,
578 protocol, fd, 0, 300000);
583 /* Remote end is server */
584 if (conn_type == SILC_SOCKET_TYPE_SERVER) {
585 SilcConfigServerSectionServerConnection *serv = NULL;
587 silc_config_server_find_server_conn(server->config,
592 silc_config_server_find_server_conn(server->config,
597 switch(serv->auth_meth) {
598 case SILC_PROTOCOL_CONN_AUTH_NONE:
599 /* No authentication required */
600 SILC_LOG_DEBUG(("No authentication required"));
603 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
604 /* Password authentication */
605 SILC_LOG_DEBUG(("Password authentication"));
607 if (!memcmp(serv->auth_data, auth_data, strlen(auth_data))) {
608 memset(auth_data, 0, payload_len);
609 silc_free(auth_data);
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);
624 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
625 /* Public key authentication */
626 SILC_LOG_DEBUG(("Public key authentication"));
628 SilcIDListUnknown *conn_data;
629 SilcPublicKey pub_key;
632 conn_data = (SilcIDListUnknown *)ctx->sock->user_data;
634 /* Load public key from file */
635 if (silc_pkcs_load_public_key(serv->auth_data,
636 &pub_key) == FALSE) {
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);
644 protocol->state = SILC_PROTOCOL_STATE_ERROR;
645 protocol->execute(server->timeout_queue, 0,
646 protocol, fd, 0, 300000);
650 silc_pkcs_alloc(pub_key->name, &pkcs);
652 /* Verify hash value HASH from KE protocol */
653 if (pkcs->pkcs->verify(pkcs->context,
654 auth_data, payload_len,
658 silc_pkcs_free(pkcs);
659 silc_pkcs_public_key_free(pub_key);
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);
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);
678 protocol->state = SILC_PROTOCOL_STATE_ERROR;
679 protocol->execute(server->timeout_queue, 0,
680 protocol, fd, 0, 300000);
685 /* Remote end is router */
686 if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
687 SilcConfigServerSectionServerConnection *serv = NULL;
689 silc_config_server_find_router_conn(server->config,
694 silc_config_server_find_router_conn(server->config,
699 switch(serv->auth_meth) {
700 case SILC_PROTOCOL_CONN_AUTH_NONE:
701 /* No authentication required */
702 SILC_LOG_DEBUG(("No authentication required"));
705 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
706 /* Password authentication */
707 SILC_LOG_DEBUG(("Password authentication"));
709 if (!memcmp(serv->auth_data, auth_data, strlen(auth_data))) {
710 memset(auth_data, 0, payload_len);
711 silc_free(auth_data);
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);
726 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
727 /* Public key authentication */
728 SILC_LOG_DEBUG(("Public key authentication"));
730 SilcIDListUnknown *conn_data;
731 SilcPublicKey pub_key;
734 conn_data = (SilcIDListUnknown *)ctx->sock->user_data;
736 /* Load public key from file */
737 if (silc_pkcs_load_public_key(serv->auth_data,
738 &pub_key) == FALSE) {
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);
746 protocol->state = SILC_PROTOCOL_STATE_ERROR;
747 protocol->execute(server->timeout_queue, 0,
748 protocol, fd, 0, 300000);
752 silc_pkcs_alloc(pub_key->name, &pkcs);
754 /* Verify hash value HASH from KE protocol */
755 if (pkcs->pkcs->verify(pkcs->context,
756 auth_data, payload_len,
760 silc_pkcs_public_key_free(pub_key);
761 silc_pkcs_free(pkcs);
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);
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);
780 protocol->state = SILC_PROTOCOL_STATE_ERROR;
781 protocol->execute(server->timeout_queue, 0,
782 protocol, fd, 0, 300000);
788 memset(auth_data, 0, payload_len);
789 silc_free(auth_data);
792 /* Save connection type. This is later used to create the
793 ID for the connection. */
794 ctx->conn_type = conn_type;
796 /* Advance protocol state. */
797 protocol->state = SILC_PROTOCOL_STATE_END;
798 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
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.
808 unsigned char *auth_data = NULL;
809 unsigned int auth_data_len = 0;
811 switch(ctx->auth_meth) {
812 case SILC_PROTOCOL_CONN_AUTH_NONE:
813 /* No authentication required */
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;
824 /* No authentication data exits. Ask interactively from user. */
829 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
830 /* Public key authentication */
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
842 SILC_SOCKET_TYPE_SERVER :
843 SILC_SOCKET_TYPE_ROUTER),
844 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
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);
853 memset(auth_data, 0, auth_data_len);
854 silc_free(auth_data);
856 silc_buffer_free(packet);
858 /* Next state is end of protocol */
859 protocol->state = SILC_PROTOCOL_STATE_END;
864 case SILC_PROTOCOL_STATE_END:
870 /* Succesfully authenticated */
871 silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS,
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);
880 /* Protocol has ended, call the final callback */
881 if (protocol->final_callback)
882 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
884 silc_protocol_free(protocol);
887 case SILC_PROTOCOL_STATE_ERROR:
893 /* Authentication failed */
894 silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
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);
903 /* On error the final callback is always called. */
904 if (protocol->final_callback)
905 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
907 silc_protocol_free(protocol);
910 case SILC_PROTOCOL_STATE_UNKNOWN:
915 SILC_TASK_CALLBACK(silc_server_protocol_channel_auth)