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.4 2000/07/07 06:55:59 priikone
27 * Added SILC style public key support and made server to use
30 * Revision 1.3 2000/07/06 07:15:31 priikone
31 * Cleaner code fro password and public key authentication.
32 * Deprecated old `channel_auth' protocol.
34 * Revision 1.2 2000/07/05 06:13:04 priikone
35 * Support for SILC style public keys added.
37 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
38 * Imported from internal CVS/Added Log headers.
43 #include "serverincludes.h"
44 #include "server_internal.h"
46 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth);
47 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange);
49 /* SILC client protocol list */
50 const SilcProtocolObject silc_protocol_list[] =
52 { SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
53 silc_server_protocol_connection_auth },
54 { SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
55 silc_server_protocol_key_exchange },
57 { SILC_PROTOCOL_SERVER_NONE, NULL },
61 * Key Exhange protocol functions
64 /* Packet sending callback. This function is provided as packet sending
65 routine to the Key Exchange functions. */
67 static void silc_server_protocol_ke_send_packet(SilcSKE ske,
72 SilcProtocol protocol = (SilcProtocol)context;
73 SilcServerKEInternalContext *ctx =
74 (SilcServerKEInternalContext *)protocol->context;
75 SilcServer server = (SilcServer)ctx->server;
77 /* Send the packet immediately */
78 silc_server_packet_send(server, ske->sock,
79 type, 0, packet->data, packet->len, TRUE);
82 /* Sets the negotiated key material into use for particular connection. */
84 static void silc_server_protocol_ke_set_keys(SilcSKE ske,
85 SilcSocketConnection sock,
86 SilcSKEKeyMaterial *keymat,
92 SilcIDListUnknown *conn_data;
95 SILC_LOG_DEBUG(("Setting new key into use"));
97 conn_data = silc_calloc(1, sizeof(*conn_data));
99 /* Allocate cipher to be used in the communication */
100 silc_cipher_alloc(cipher->cipher->name, &conn_data->send_key);
101 silc_cipher_alloc(cipher->cipher->name, &conn_data->receive_key);
103 if (is_responder == TRUE) {
104 conn_data->send_key->cipher->set_key(conn_data->send_key->context,
105 keymat->receive_enc_key,
106 keymat->enc_key_len);
107 conn_data->send_key->set_iv(conn_data->send_key, keymat->receive_iv);
108 conn_data->receive_key->cipher->set_key(conn_data->receive_key->context,
109 keymat->send_enc_key,
110 keymat->enc_key_len);
111 conn_data->receive_key->set_iv(conn_data->receive_key, keymat->send_iv);
114 conn_data->send_key->cipher->set_key(conn_data->send_key->context,
115 keymat->send_enc_key,
116 keymat->enc_key_len);
117 conn_data->send_key->set_iv(conn_data->send_key, keymat->send_iv);
118 conn_data->receive_key->cipher->set_key(conn_data->receive_key->context,
119 keymat->receive_enc_key,
120 keymat->enc_key_len);
121 conn_data->receive_key->set_iv(conn_data->receive_key, keymat->receive_iv);
124 /* Allocate PKCS to be used */
126 /* XXX Do we ever need to allocate PKCS for the connection??
127 If yes, we need to change KE protocol to get the initiators
129 silc_pkcs_alloc(pkcs->pkcs->name, &conn_data->pkcs);
130 conn_data->public_key = silc_pkcs_public_key_alloc(XXX);
131 silc_pkcs_set_public_key(conn_data->pkcs, ske->ke2_payload->pk_data,
132 ske->ke2_payload->pk_len);
135 /* Save HMAC key to be used in the communication. */
136 silc_hash_alloc(hash->hash->name, &nhash);
137 silc_hmac_alloc(nhash, &conn_data->hmac);
138 conn_data->hmac_key_len = keymat->hmac_key_len;
139 conn_data->hmac_key = silc_calloc(conn_data->hmac_key_len,
140 sizeof(unsigned char));
141 memcpy(conn_data->hmac_key, keymat->hmac_key, keymat->hmac_key_len);
143 sock->user_data = (void *)conn_data;
146 /* Performs key exchange protocol. This is used for both initiator
147 and responder key exchange. This is performed always when accepting
148 new connection to the server. This may be called recursively. */
150 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
152 SilcProtocol protocol = (SilcProtocol)context;
153 SilcServerKEInternalContext *ctx =
154 (SilcServerKEInternalContext *)protocol->context;
155 SilcServer server = (SilcServer)ctx->server;
156 SilcSKEStatus status = 0;
158 SILC_LOG_DEBUG(("Start"));
160 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
161 protocol->state = SILC_PROTOCOL_STATE_START;
163 SILC_LOG_DEBUG(("State=%d", protocol->state));
165 switch(protocol->state) {
166 case SILC_PROTOCOL_STATE_START:
173 /* Allocate Key Exchange object */
174 ske = silc_ske_alloc();
177 if (ctx->responder == TRUE) {
178 /* Start the key exchange by processing the received security
179 properties packet from initiator. */
180 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
181 ctx->packet, NULL, NULL);
183 SilcSKEStartPayload *start_payload;
185 /* Assemble security properties. */
186 silc_ske_assemble_security_properties(ske, &start_payload);
188 /* Start the key exchange by sending our security properties
189 to the remote end. */
190 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
192 silc_server_protocol_ke_send_packet,
196 if (status != SILC_SKE_STATUS_OK) {
197 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
199 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
202 protocol->state = SILC_PROTOCOL_STATE_ERROR;
203 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
207 /* Advance protocol state and call the next state if we are responder */
209 if (ctx->responder == TRUE)
210 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
218 if (ctx->responder == TRUE) {
219 /* Sends the selected security properties to the initiator. */
221 silc_ske_responder_phase_1(ctx->ske,
222 ctx->ske->start_payload,
223 silc_server_protocol_ke_send_packet,
226 /* Call Phase-1 function. This processes the Key Exchange Start
227 paylaod reply we just got from the responder. The callback
228 function will receive the processed payload where we will
231 silc_ske_initiator_phase_1(ctx->ske,
236 if (status != SILC_SKE_STATUS_OK) {
237 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
239 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
242 protocol->state = SILC_PROTOCOL_STATE_ERROR;
243 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
247 /* Advance protocol state and call next state if we are initiator */
249 if (ctx->responder == FALSE)
250 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
258 if (ctx->responder == TRUE) {
259 /* Process the received Key Exchange 1 Payload packet from
260 the initiator. This also creates our parts of the Diffie
261 Hellman algorithm. */
263 silc_ske_responder_phase_2(ctx->ske, ctx->packet, NULL, NULL);
265 /* Call the Phase-2 function. This creates Diffie Hellman
266 key exchange parameters and sends our public part inside
267 Key Exhange 1 Payload to the responder. */
269 silc_ske_initiator_phase_2(ctx->ske,
270 silc_server_protocol_ke_send_packet,
274 if (status != SILC_SKE_STATUS_OK) {
275 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
277 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
280 protocol->state = SILC_PROTOCOL_STATE_ERROR;
281 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
285 /* Advance protocol state and call the next state if we are responder */
287 if (ctx->responder == TRUE)
288 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
296 if (ctx->responder == TRUE) {
297 /* This creates the key exchange material and sends our
298 public parts to the initiator inside Key Exchange 2 Payload. */
300 silc_ske_responder_finish(ctx->ske,
301 server->public_key, server->private_key,
302 SILC_SKE_PK_TYPE_SILC,
303 silc_server_protocol_ke_send_packet,
306 /* Finish the protocol. This verifies the Key Exchange 2 payload
307 sent by responder. */
309 silc_ske_initiator_finish(ctx->ske,
310 ctx->packet, NULL, NULL, NULL, NULL);
313 if (status != SILC_SKE_STATUS_OK) {
314 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
316 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
319 protocol->state = SILC_PROTOCOL_STATE_ERROR;
320 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
324 /* Send Ok to the other end. We will end the protocol as responder
325 sends Ok to us when we will take the new keys into use. */
326 if (ctx->responder == FALSE)
327 silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
329 /* End the protocol on the next round */
330 protocol->state = SILC_PROTOCOL_STATE_END;
333 case SILC_PROTOCOL_STATE_END:
338 SilcSKEKeyMaterial *keymat;
340 /* Send Ok to the other end if we are responder. If we are
341 initiator we have sent this already. */
342 if (ctx->responder == TRUE)
343 silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
345 /* Process the key material */
346 keymat = silc_calloc(1, sizeof(*keymat));
347 silc_ske_process_key_material(ctx->ske, 16, (16 * 8), 16, keymat);
349 /* Take the new keys into use. */
350 silc_server_protocol_ke_set_keys(ctx->ske, ctx->sock, keymat,
351 ctx->ske->prop->cipher,
352 ctx->ske->prop->pkcs,
353 ctx->ske->prop->hash,
356 /* Unregister the timeout task since the protocol has ended.
357 This was the timeout task to be executed if the protocol is
358 not completed fast enough. */
359 if (ctx->timeout_task)
360 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
362 /* Call the final callback */
363 if (protocol->final_callback)
364 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
366 silc_protocol_free(protocol);
369 case SILC_PROTOCOL_STATE_ERROR:
374 /* Unregister the timeout task since the protocol has ended.
375 This was the timeout task to be executed if the protocol is
376 not completed fast enough. */
377 if (ctx->timeout_task)
378 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
380 /* On error the final callback is always called. */
381 if (protocol->final_callback)
382 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
384 silc_protocol_free(protocol);
386 case SILC_PROTOCOL_STATE_UNKNOWN:
392 * Connection Authentication protocol functions
395 /* XXX move these to somehwere else */
397 int silc_server_password_authentication(SilcServer server, char *auth1,
400 if (!auth1 || !auth2)
403 if (!memcmp(auth1, auth2, strlen(auth1)))
409 int silc_server_public_key_authentication(SilcServer server,
412 unsigned int sign_len,
415 SilcPublicKey pub_key;
420 if (!pkfile || !sign)
423 /* Load public key from file */
424 if (!silc_pkcs_load_public_key(pkfile, &pub_key))
427 silc_pkcs_alloc(pub_key->name, &pkcs);
428 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
429 silc_pkcs_free(pkcs);
433 /* Make the authentication data. Protocol says it is HASH plus
435 len = ske->hash_len + ske->start_payload_copy->len;
436 auth = silc_buffer_alloc(len);
437 silc_buffer_pull_tail(auth, len);
438 silc_buffer_format(auth,
439 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
440 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
441 ske->start_payload_copy->len),
444 /* Verify signature */
445 if (pkcs->pkcs->verify(pkcs->context, sign, sign_len,
446 auth->data, auth->len))
448 silc_pkcs_free(pkcs);
449 silc_pkcs_public_key_free(pub_key);
450 silc_buffer_free(auth);
454 silc_pkcs_free(pkcs);
455 silc_pkcs_public_key_free(pub_key);
456 silc_buffer_free(auth);
460 /* Performs connection authentication protocol. If responder, we
461 authenticate the remote data received. If initiator, we will send
462 authentication data to the remote end. */
464 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
466 SilcProtocol protocol = (SilcProtocol)context;
467 SilcServerConnAuthInternalContext *ctx =
468 (SilcServerConnAuthInternalContext *)protocol->context;
469 SilcServer server = (SilcServer)ctx->server;
471 SILC_LOG_DEBUG(("Start"));
473 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
474 protocol->state = SILC_PROTOCOL_STATE_START;
476 SILC_LOG_DEBUG(("State=%d", protocol->state));
478 switch(protocol->state) {
479 case SILC_PROTOCOL_STATE_START:
485 if (ctx->responder == TRUE) {
487 * We are receiving party
490 unsigned short payload_len;
491 unsigned short conn_type;
492 unsigned char *auth_data;
494 SILC_LOG_INFO(("Performing authentication protocol for %s",
495 ctx->sock->hostname ? ctx->sock->hostname :
498 /* Parse the received authentication data packet. The received
499 payload is Connection Auth Payload. */
500 silc_buffer_unformat(ctx->packet,
501 SILC_STR_UI_SHORT(&payload_len),
502 SILC_STR_UI_SHORT(&conn_type),
505 if (payload_len != ctx->packet->len) {
506 SILC_LOG_ERROR(("Bad payload in authentication packet"));
507 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
508 protocol->state = SILC_PROTOCOL_STATE_ERROR;
509 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
515 if (conn_type < SILC_SOCKET_TYPE_CLIENT ||
516 conn_type > SILC_SOCKET_TYPE_ROUTER) {
517 SILC_LOG_ERROR(("Bad connection type %d", conn_type));
518 SILC_LOG_DEBUG(("Bad connection type %d", conn_type));
519 protocol->state = SILC_PROTOCOL_STATE_ERROR;
520 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
524 if (payload_len > 0) {
525 /* Get authentication data */
526 silc_buffer_pull(ctx->packet, 4);
527 silc_buffer_unformat(ctx->packet,
528 SILC_STR_UI_XNSTRING_ALLOC(&auth_data,
536 * Check the remote connection type and make sure that we have
537 * configured this connection. If we haven't allowed this connection
538 * the authentication must be failed.
541 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
543 /* Remote end is client */
544 if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
545 SilcConfigServerSectionClientConnection *client = NULL;
547 silc_config_server_find_client_conn(server->config,
552 silc_config_server_find_client_conn(server->config,
557 switch(client->auth_meth) {
558 case SILC_PROTOCOL_CONN_AUTH_NONE:
559 /* No authentication required */
560 SILC_LOG_DEBUG(("No authentication required"));
563 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
564 /* Password authentication */
565 SILC_LOG_DEBUG(("Password authentication"));
566 ret = silc_server_password_authentication(server, auth_data,
570 memset(auth_data, 0, payload_len);
571 silc_free(auth_data);
576 /* Authentication failed */
577 SILC_LOG_ERROR(("Authentication failed"));
578 SILC_LOG_DEBUG(("Authentication failed"));
579 protocol->state = SILC_PROTOCOL_STATE_ERROR;
580 protocol->execute(server->timeout_queue, 0,
581 protocol, fd, 0, 300000);
585 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
586 /* Public key authentication */
587 SILC_LOG_DEBUG(("Public key authentication"));
588 ret = silc_server_public_key_authentication(server,
595 memset(auth_data, 0, payload_len);
596 silc_free(auth_data);
601 SILC_LOG_ERROR(("Authentication failed"));
602 SILC_LOG_DEBUG(("Authentication failed"));
603 protocol->state = SILC_PROTOCOL_STATE_ERROR;
604 protocol->execute(server->timeout_queue, 0,
605 protocol, fd, 0, 300000);
609 SILC_LOG_DEBUG(("No configuration for remote connection"));
610 SILC_LOG_ERROR(("Remote connection not configured"));
611 SILC_LOG_ERROR(("Authentication failed"));
612 memset(auth_data, 0, payload_len);
613 silc_free(auth_data);
615 protocol->state = SILC_PROTOCOL_STATE_ERROR;
616 protocol->execute(server->timeout_queue, 0,
617 protocol, fd, 0, 300000);
622 /* Remote end is server */
623 if (conn_type == SILC_SOCKET_TYPE_SERVER) {
624 SilcConfigServerSectionServerConnection *serv = NULL;
626 silc_config_server_find_server_conn(server->config,
631 silc_config_server_find_server_conn(server->config,
636 switch(serv->auth_meth) {
637 case SILC_PROTOCOL_CONN_AUTH_NONE:
638 /* No authentication required */
639 SILC_LOG_DEBUG(("No authentication required"));
642 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
643 /* Password authentication */
644 SILC_LOG_DEBUG(("Password authentication"));
645 ret = silc_server_password_authentication(server, auth_data,
649 memset(auth_data, 0, payload_len);
650 silc_free(auth_data);
655 /* Authentication failed */
656 SILC_LOG_ERROR(("Authentication failed"));
657 SILC_LOG_DEBUG(("Authentication failed"));
658 protocol->state = SILC_PROTOCOL_STATE_ERROR;
659 protocol->execute(server->timeout_queue, 0,
660 protocol, fd, 0, 300000);
664 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
665 /* Public key authentication */
666 SILC_LOG_DEBUG(("Public key authentication"));
667 ret = silc_server_public_key_authentication(server,
674 memset(auth_data, 0, payload_len);
675 silc_free(auth_data);
680 SILC_LOG_ERROR(("Authentication failed"));
681 SILC_LOG_DEBUG(("Authentication failed"));
682 protocol->state = SILC_PROTOCOL_STATE_ERROR;
683 protocol->execute(server->timeout_queue, 0,
684 protocol, fd, 0, 300000);
688 SILC_LOG_DEBUG(("No configuration for remote connection"));
689 SILC_LOG_ERROR(("Remote connection not configured"));
690 SILC_LOG_ERROR(("Authentication failed"));
691 memset(auth_data, 0, payload_len);
692 silc_free(auth_data);
694 protocol->state = SILC_PROTOCOL_STATE_ERROR;
695 protocol->execute(server->timeout_queue, 0,
696 protocol, fd, 0, 300000);
701 /* Remote end is router */
702 if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
703 SilcConfigServerSectionServerConnection *serv = NULL;
705 silc_config_server_find_router_conn(server->config,
710 silc_config_server_find_router_conn(server->config,
715 switch(serv->auth_meth) {
716 case SILC_PROTOCOL_CONN_AUTH_NONE:
717 /* No authentication required */
718 SILC_LOG_DEBUG(("No authentication required"));
721 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
722 /* Password authentication */
723 SILC_LOG_DEBUG(("Password authentication"));
724 ret = silc_server_password_authentication(server, auth_data,
728 memset(auth_data, 0, payload_len);
729 silc_free(auth_data);
734 /* Authentication failed */
735 SILC_LOG_ERROR(("Authentication failed"));
736 SILC_LOG_DEBUG(("Authentication failed"));
737 protocol->state = SILC_PROTOCOL_STATE_ERROR;
738 protocol->execute(server->timeout_queue, 0,
739 protocol, fd, 0, 300000);
743 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
744 /* Public key authentication */
745 SILC_LOG_DEBUG(("Public key authentication"));
746 ret = silc_server_public_key_authentication(server,
753 memset(auth_data, 0, payload_len);
754 silc_free(auth_data);
759 SILC_LOG_ERROR(("Authentication failed"));
760 SILC_LOG_DEBUG(("Authentication failed"));
761 protocol->state = SILC_PROTOCOL_STATE_ERROR;
762 protocol->execute(server->timeout_queue, 0,
763 protocol, fd, 0, 300000);
767 SILC_LOG_DEBUG(("No configuration for remote connection"));
768 SILC_LOG_ERROR(("Remote connection not configured"));
769 SILC_LOG_ERROR(("Authentication failed"));
770 memset(auth_data, 0, payload_len);
771 silc_free(auth_data);
773 protocol->state = SILC_PROTOCOL_STATE_ERROR;
774 protocol->execute(server->timeout_queue, 0,
775 protocol, fd, 0, 300000);
781 memset(auth_data, 0, payload_len);
782 silc_free(auth_data);
785 /* Save connection type. This is later used to create the
786 ID for the connection. */
787 ctx->conn_type = conn_type;
789 /* Advance protocol state. */
790 protocol->state = SILC_PROTOCOL_STATE_END;
791 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
795 * We are initiator. We are authenticating ourselves to a
796 * remote server. We will send the authentication data to the
797 * other end for verify.
801 unsigned char *auth_data = NULL;
802 unsigned int auth_data_len = 0;
804 switch(ctx->auth_meth) {
805 case SILC_PROTOCOL_CONN_AUTH_NONE:
806 /* No authentication required */
809 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
810 /* Password authentication */
811 if (ctx->auth_data && ctx->auth_data_len) {
812 auth_data = ctx->auth_data;
813 auth_data_len = ctx->auth_data_len;
817 /* No authentication data exits. Ask interactively from user. */
822 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
823 /* Public key authentication */
828 payload_len = 4 + auth_data_len;
829 packet = silc_buffer_alloc(payload_len);
830 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
831 silc_buffer_format(packet,
832 SILC_STR_UI_SHORT(payload_len),
833 SILC_STR_UI_SHORT(server->server_type
835 SILC_SOCKET_TYPE_SERVER :
836 SILC_SOCKET_TYPE_ROUTER),
837 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
840 /* Send the packet to server */
841 silc_server_packet_send(server, ctx->sock,
842 SILC_PACKET_CONNECTION_AUTH, 0,
843 packet->data, packet->len, TRUE);
846 memset(auth_data, 0, auth_data_len);
847 silc_free(auth_data);
849 silc_buffer_free(packet);
851 /* Next state is end of protocol */
852 protocol->state = SILC_PROTOCOL_STATE_END;
857 case SILC_PROTOCOL_STATE_END:
863 /* Succesfully authenticated */
864 silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS,
867 /* Unregister the timeout task since the protocol has ended.
868 This was the timeout task to be executed if the protocol is
869 not completed fast enough. */
870 if (ctx->timeout_task)
871 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
873 /* Protocol has ended, call the final callback */
874 if (protocol->final_callback)
875 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
877 silc_protocol_free(protocol);
880 case SILC_PROTOCOL_STATE_ERROR:
886 /* Authentication failed */
887 silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
890 /* Unregister the timeout task since the protocol has ended.
891 This was the timeout task to be executed if the protocol is
892 not completed fast enough. */
893 if (ctx->timeout_task)
894 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
896 /* On error the final callback is always called. */
897 if (protocol->final_callback)
898 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
900 silc_protocol_free(protocol);
903 case SILC_PROTOCOL_STATE_UNKNOWN: