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.10 2000/10/09 11:41:17 priikone
27 * Changed to use new generic payloads.
28 * Implemented new protocol compliant notify messages.
29 * Implemented protocol compliant channel messages.
32 * Revision 1.9 2000/07/20 10:17:25 priikone
33 * Added dynamic protocol registering/unregistering support. The
34 * patch was provided by cras.
36 * Revision 1.8 2000/07/19 07:08:09 priikone
37 * Added version detection support to SKE.
39 * Revision 1.7 2000/07/14 06:14:20 priikone
40 * Put the HMAC keys into the HMAC object instead of having them
41 * saved elsewhere; now we can use silc_hmac_make insteaad of
42 * silc_hmac_make_with_key.
44 * Revision 1.6 2000/07/12 05:59:41 priikone
45 * Major rewrite of ID Cache system. Support added for the new
46 * ID cache system. Major rewrite of ID List stuff on server. All
47 * SilcXXXList's are now called SilcXXXEntry's and they are pointers
48 * by default. A lot rewritten ID list functions.
50 * Revision 1.5 2000/07/10 05:42:14 priikone
51 * Support for public key encoding functions added.
53 * Revision 1.4 2000/07/07 06:55:59 priikone
54 * Added SILC style public key support and made server to use
57 * Revision 1.3 2000/07/06 07:15:31 priikone
58 * Cleaner code fro password and public key authentication.
59 * Deprecated old `channel_auth' protocol.
61 * Revision 1.2 2000/07/05 06:13:04 priikone
62 * Support for SILC style public keys added.
64 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
65 * Imported from internal CVS/Added Log headers.
70 #include "serverincludes.h"
71 #include "server_internal.h"
73 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth);
74 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange);
76 extern char *silc_version_string;
79 * Key Exhange protocol functions
82 /* Packet sending callback. This function is provided as packet sending
83 routine to the Key Exchange functions. */
85 static void silc_server_protocol_ke_send_packet(SilcSKE ske,
90 SilcProtocol protocol = (SilcProtocol)context;
91 SilcServerKEInternalContext *ctx =
92 (SilcServerKEInternalContext *)protocol->context;
93 SilcServer server = (SilcServer)ctx->server;
95 /* Send the packet immediately */
96 silc_server_packet_send(server, ske->sock,
97 type, 0, packet->data, packet->len, TRUE);
100 /* Sets the negotiated key material into use for particular connection. */
102 static void silc_server_protocol_ke_set_keys(SilcSKE ske,
103 SilcSocketConnection sock,
104 SilcSKEKeyMaterial *keymat,
110 SilcUnknownEntry conn_data;
113 SILC_LOG_DEBUG(("Setting new key into use"));
115 conn_data = silc_calloc(1, sizeof(*conn_data));
117 /* Allocate cipher to be used in the communication */
118 silc_cipher_alloc(cipher->cipher->name, &conn_data->send_key);
119 silc_cipher_alloc(cipher->cipher->name, &conn_data->receive_key);
121 if (is_responder == TRUE) {
122 conn_data->send_key->cipher->set_key(conn_data->send_key->context,
123 keymat->receive_enc_key,
124 keymat->enc_key_len);
125 conn_data->send_key->set_iv(conn_data->send_key, keymat->receive_iv);
126 conn_data->receive_key->cipher->set_key(conn_data->receive_key->context,
127 keymat->send_enc_key,
128 keymat->enc_key_len);
129 conn_data->receive_key->set_iv(conn_data->receive_key, keymat->send_iv);
132 conn_data->send_key->cipher->set_key(conn_data->send_key->context,
133 keymat->send_enc_key,
134 keymat->enc_key_len);
135 conn_data->send_key->set_iv(conn_data->send_key, keymat->send_iv);
136 conn_data->receive_key->cipher->set_key(conn_data->receive_key->context,
137 keymat->receive_enc_key,
138 keymat->enc_key_len);
139 conn_data->receive_key->set_iv(conn_data->receive_key, keymat->receive_iv);
142 /* Allocate PKCS to be used */
144 /* XXX Do we ever need to allocate PKCS for the connection??
145 If yes, we need to change KE protocol to get the initiators
147 silc_pkcs_alloc(pkcs->pkcs->name, &conn_data->pkcs);
148 conn_data->public_key = silc_pkcs_public_key_alloc(XXX);
149 silc_pkcs_set_public_key(conn_data->pkcs, ske->ke2_payload->pk_data,
150 ske->ke2_payload->pk_len);
153 /* Save HMAC key to be used in the communication. */
154 silc_hash_alloc(hash->hash->name, &nhash);
155 silc_hmac_alloc(nhash, &conn_data->hmac);
156 silc_hmac_set_key(conn_data->hmac, keymat->hmac_key, keymat->hmac_key_len);
158 sock->user_data = (void *)conn_data;
161 /* Performs key exchange protocol. This is used for both initiator
162 and responder key exchange. This is performed always when accepting
163 new connection to the server. This may be called recursively. */
165 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
167 SilcProtocol protocol = (SilcProtocol)context;
168 SilcServerKEInternalContext *ctx =
169 (SilcServerKEInternalContext *)protocol->context;
170 SilcServer server = (SilcServer)ctx->server;
171 SilcSKEStatus status = 0;
173 SILC_LOG_DEBUG(("Start"));
175 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
176 protocol->state = SILC_PROTOCOL_STATE_START;
178 SILC_LOG_DEBUG(("State=%d", protocol->state));
180 switch(protocol->state) {
181 case SILC_PROTOCOL_STATE_START:
188 /* Allocate Key Exchange object */
189 ske = silc_ske_alloc();
191 ske->rng = server->rng;
193 if (ctx->responder == TRUE) {
194 /* Start the key exchange by processing the received security
195 properties packet from initiator. */
196 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
198 ctx->packet, NULL, NULL);
200 SilcSKEStartPayload *start_payload;
202 /* Assemble security properties. */
203 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
207 /* Start the key exchange by sending our security properties
208 to the remote end. */
209 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
211 silc_server_protocol_ke_send_packet,
215 if (status != SILC_SKE_STATUS_OK) {
216 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
218 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
221 protocol->state = SILC_PROTOCOL_STATE_ERROR;
222 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
226 /* Advance protocol state and call the next state if we are responder */
228 if (ctx->responder == TRUE)
229 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
237 if (ctx->responder == TRUE) {
238 /* Sends the selected security properties to the initiator. */
240 silc_ske_responder_phase_1(ctx->ske,
241 ctx->ske->start_payload,
242 silc_server_protocol_ke_send_packet,
245 /* Call Phase-1 function. This processes the Key Exchange Start
246 paylaod reply we just got from the responder. The callback
247 function will receive the processed payload where we will
250 silc_ske_initiator_phase_1(ctx->ske,
255 if (status != SILC_SKE_STATUS_OK) {
256 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
258 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
261 protocol->state = SILC_PROTOCOL_STATE_ERROR;
262 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
266 /* Advance protocol state and call next state if we are initiator */
268 if (ctx->responder == FALSE)
269 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
277 if (ctx->responder == TRUE) {
278 /* Process the received Key Exchange 1 Payload packet from
279 the initiator. This also creates our parts of the Diffie
280 Hellman algorithm. */
282 silc_ske_responder_phase_2(ctx->ske, ctx->packet, NULL, NULL);
284 /* Call the Phase-2 function. This creates Diffie Hellman
285 key exchange parameters and sends our public part inside
286 Key Exhange 1 Payload to the responder. */
288 silc_ske_initiator_phase_2(ctx->ske,
290 silc_server_protocol_ke_send_packet,
294 if (status != SILC_SKE_STATUS_OK) {
295 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
297 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
300 protocol->state = SILC_PROTOCOL_STATE_ERROR;
301 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
305 /* Advance protocol state and call the next state if we are responder */
307 if (ctx->responder == TRUE)
308 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
316 if (ctx->responder == TRUE) {
317 /* This creates the key exchange material and sends our
318 public parts to the initiator inside Key Exchange 2 Payload. */
320 silc_ske_responder_finish(ctx->ske,
321 server->public_key, server->private_key,
322 SILC_SKE_PK_TYPE_SILC,
323 silc_server_protocol_ke_send_packet,
326 /* Finish the protocol. This verifies the Key Exchange 2 payload
327 sent by responder. */
329 silc_ske_initiator_finish(ctx->ske,
330 ctx->packet, NULL, NULL, NULL, NULL);
333 if (status != SILC_SKE_STATUS_OK) {
334 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
336 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
339 protocol->state = SILC_PROTOCOL_STATE_ERROR;
340 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
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);
349 /* End the protocol on the next round */
350 protocol->state = SILC_PROTOCOL_STATE_END;
353 case SILC_PROTOCOL_STATE_END:
358 SilcSKEKeyMaterial *keymat;
360 /* Send Ok to the other end if we are responder. If we are
361 initiator we have sent this already. */
362 if (ctx->responder == TRUE)
363 silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
365 /* Process the key material */
366 keymat = silc_calloc(1, sizeof(*keymat));
367 silc_ske_process_key_material(ctx->ske, 16, (16 * 8), 16, keymat);
369 /* Take the new keys into use. */
370 silc_server_protocol_ke_set_keys(ctx->ske, ctx->sock, keymat,
371 ctx->ske->prop->cipher,
372 ctx->ske->prop->pkcs,
373 ctx->ske->prop->hash,
376 /* Unregister the timeout task since the protocol has ended.
377 This was the timeout task to be executed if the protocol is
378 not completed fast enough. */
379 if (ctx->timeout_task)
380 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
382 /* Call the final callback */
383 if (protocol->final_callback)
384 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
386 silc_protocol_free(protocol);
389 case SILC_PROTOCOL_STATE_ERROR:
394 /* Unregister the timeout task since the protocol has ended.
395 This was the timeout task to be executed if the protocol is
396 not completed fast enough. */
397 if (ctx->timeout_task)
398 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
400 /* On error the final callback is always called. */
401 if (protocol->final_callback)
402 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
404 silc_protocol_free(protocol);
406 case SILC_PROTOCOL_STATE_UNKNOWN:
412 * Connection Authentication protocol functions
415 /* XXX move these to somehwere else */
417 int silc_server_password_authentication(SilcServer server, char *auth1,
420 if (!auth1 || !auth2)
423 if (!memcmp(auth1, auth2, strlen(auth1)))
429 int silc_server_public_key_authentication(SilcServer server,
432 unsigned int sign_len,
435 SilcPublicKey pub_key;
440 if (!pkfile || !sign)
443 /* Load public key from file */
444 if (!silc_pkcs_load_public_key(pkfile, &pub_key, SILC_PKCS_FILE_PEM))
445 if (!silc_pkcs_load_public_key(pkfile, &pub_key, SILC_PKCS_FILE_BIN))
448 silc_pkcs_alloc(pub_key->name, &pkcs);
449 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
450 silc_pkcs_free(pkcs);
454 /* Make the authentication data. Protocol says it is HASH plus
456 len = ske->hash_len + ske->start_payload_copy->len;
457 auth = silc_buffer_alloc(len);
458 silc_buffer_pull_tail(auth, len);
459 silc_buffer_format(auth,
460 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
461 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
462 ske->start_payload_copy->len),
465 /* Verify signature */
466 if (pkcs->pkcs->verify(pkcs->context, sign, sign_len,
467 auth->data, auth->len))
469 silc_pkcs_free(pkcs);
470 silc_pkcs_public_key_free(pub_key);
471 silc_buffer_free(auth);
475 silc_pkcs_free(pkcs);
476 silc_pkcs_public_key_free(pub_key);
477 silc_buffer_free(auth);
481 /* Performs connection authentication protocol. If responder, we
482 authenticate the remote data received. If initiator, we will send
483 authentication data to the remote end. */
485 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
487 SilcProtocol protocol = (SilcProtocol)context;
488 SilcServerConnAuthInternalContext *ctx =
489 (SilcServerConnAuthInternalContext *)protocol->context;
490 SilcServer server = (SilcServer)ctx->server;
492 SILC_LOG_DEBUG(("Start"));
494 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
495 protocol->state = SILC_PROTOCOL_STATE_START;
497 SILC_LOG_DEBUG(("State=%d", protocol->state));
499 switch(protocol->state) {
500 case SILC_PROTOCOL_STATE_START:
506 if (ctx->responder == TRUE) {
508 * We are receiving party
511 unsigned short payload_len;
512 unsigned short conn_type;
513 unsigned char *auth_data;
515 SILC_LOG_INFO(("Performing authentication protocol for %s",
516 ctx->sock->hostname ? ctx->sock->hostname :
519 /* Parse the received authentication data packet. The received
520 payload is Connection Auth Payload. */
521 silc_buffer_unformat(ctx->packet,
522 SILC_STR_UI_SHORT(&payload_len),
523 SILC_STR_UI_SHORT(&conn_type),
526 if (payload_len != ctx->packet->len) {
527 SILC_LOG_ERROR(("Bad payload in authentication packet"));
528 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
529 protocol->state = SILC_PROTOCOL_STATE_ERROR;
530 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
536 if (conn_type < SILC_SOCKET_TYPE_CLIENT ||
537 conn_type > SILC_SOCKET_TYPE_ROUTER) {
538 SILC_LOG_ERROR(("Bad connection type %d", conn_type));
539 SILC_LOG_DEBUG(("Bad connection type %d", conn_type));
540 protocol->state = SILC_PROTOCOL_STATE_ERROR;
541 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
545 if (payload_len > 0) {
546 /* Get authentication data */
547 silc_buffer_pull(ctx->packet, 4);
548 silc_buffer_unformat(ctx->packet,
549 SILC_STR_UI_XNSTRING_ALLOC(&auth_data,
557 * Check the remote connection type and make sure that we have
558 * configured this connection. If we haven't allowed this connection
559 * the authentication must be failed.
562 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
564 /* Remote end is client */
565 if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
566 SilcConfigServerSectionClientConnection *client = NULL;
568 silc_config_server_find_client_conn(server->config,
573 silc_config_server_find_client_conn(server->config,
578 switch(client->auth_meth) {
579 case SILC_PROTOCOL_CONN_AUTH_NONE:
580 /* No authentication required */
581 SILC_LOG_DEBUG(("No authentication required"));
584 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
585 /* Password authentication */
586 SILC_LOG_DEBUG(("Password authentication"));
587 ret = silc_server_password_authentication(server, auth_data,
591 memset(auth_data, 0, payload_len);
592 silc_free(auth_data);
597 /* Authentication failed */
598 SILC_LOG_ERROR(("Authentication failed"));
599 SILC_LOG_DEBUG(("Authentication failed"));
600 protocol->state = SILC_PROTOCOL_STATE_ERROR;
601 protocol->execute(server->timeout_queue, 0,
602 protocol, fd, 0, 300000);
606 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
607 /* Public key authentication */
608 SILC_LOG_DEBUG(("Public key authentication"));
609 ret = silc_server_public_key_authentication(server,
616 memset(auth_data, 0, payload_len);
617 silc_free(auth_data);
622 SILC_LOG_ERROR(("Authentication failed"));
623 SILC_LOG_DEBUG(("Authentication failed"));
624 protocol->state = SILC_PROTOCOL_STATE_ERROR;
625 protocol->execute(server->timeout_queue, 0,
626 protocol, fd, 0, 300000);
630 SILC_LOG_DEBUG(("No configuration for remote connection"));
631 SILC_LOG_ERROR(("Remote connection not configured"));
632 SILC_LOG_ERROR(("Authentication failed"));
633 memset(auth_data, 0, payload_len);
634 silc_free(auth_data);
636 protocol->state = SILC_PROTOCOL_STATE_ERROR;
637 protocol->execute(server->timeout_queue, 0,
638 protocol, fd, 0, 300000);
643 /* Remote end is server */
644 if (conn_type == SILC_SOCKET_TYPE_SERVER) {
645 SilcConfigServerSectionServerConnection *serv = NULL;
647 silc_config_server_find_server_conn(server->config,
652 silc_config_server_find_server_conn(server->config,
657 switch(serv->auth_meth) {
658 case SILC_PROTOCOL_CONN_AUTH_NONE:
659 /* No authentication required */
660 SILC_LOG_DEBUG(("No authentication required"));
663 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
664 /* Password authentication */
665 SILC_LOG_DEBUG(("Password authentication"));
666 ret = silc_server_password_authentication(server, auth_data,
670 memset(auth_data, 0, payload_len);
671 silc_free(auth_data);
676 /* Authentication failed */
677 SILC_LOG_ERROR(("Authentication failed"));
678 SILC_LOG_DEBUG(("Authentication failed"));
679 protocol->state = SILC_PROTOCOL_STATE_ERROR;
680 protocol->execute(server->timeout_queue, 0,
681 protocol, fd, 0, 300000);
685 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
686 /* Public key authentication */
687 SILC_LOG_DEBUG(("Public key authentication"));
688 ret = silc_server_public_key_authentication(server,
695 memset(auth_data, 0, payload_len);
696 silc_free(auth_data);
701 SILC_LOG_ERROR(("Authentication failed"));
702 SILC_LOG_DEBUG(("Authentication failed"));
703 protocol->state = SILC_PROTOCOL_STATE_ERROR;
704 protocol->execute(server->timeout_queue, 0,
705 protocol, fd, 0, 300000);
709 SILC_LOG_DEBUG(("No configuration for remote connection"));
710 SILC_LOG_ERROR(("Remote connection not configured"));
711 SILC_LOG_ERROR(("Authentication failed"));
712 memset(auth_data, 0, payload_len);
713 silc_free(auth_data);
715 protocol->state = SILC_PROTOCOL_STATE_ERROR;
716 protocol->execute(server->timeout_queue, 0,
717 protocol, fd, 0, 300000);
722 /* Remote end is router */
723 if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
724 SilcConfigServerSectionServerConnection *serv = NULL;
726 silc_config_server_find_router_conn(server->config,
731 silc_config_server_find_router_conn(server->config,
736 switch(serv->auth_meth) {
737 case SILC_PROTOCOL_CONN_AUTH_NONE:
738 /* No authentication required */
739 SILC_LOG_DEBUG(("No authentication required"));
742 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
743 /* Password authentication */
744 SILC_LOG_DEBUG(("Password authentication"));
745 ret = silc_server_password_authentication(server, auth_data,
749 memset(auth_data, 0, payload_len);
750 silc_free(auth_data);
755 /* Authentication failed */
756 SILC_LOG_ERROR(("Authentication failed"));
757 SILC_LOG_DEBUG(("Authentication failed"));
758 protocol->state = SILC_PROTOCOL_STATE_ERROR;
759 protocol->execute(server->timeout_queue, 0,
760 protocol, fd, 0, 300000);
764 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
765 /* Public key authentication */
766 SILC_LOG_DEBUG(("Public key authentication"));
767 ret = silc_server_public_key_authentication(server,
774 memset(auth_data, 0, payload_len);
775 silc_free(auth_data);
780 SILC_LOG_ERROR(("Authentication failed"));
781 SILC_LOG_DEBUG(("Authentication failed"));
782 protocol->state = SILC_PROTOCOL_STATE_ERROR;
783 protocol->execute(server->timeout_queue, 0,
784 protocol, fd, 0, 300000);
788 SILC_LOG_DEBUG(("No configuration for remote connection"));
789 SILC_LOG_ERROR(("Remote connection not configured"));
790 SILC_LOG_ERROR(("Authentication failed"));
791 memset(auth_data, 0, payload_len);
792 silc_free(auth_data);
794 protocol->state = SILC_PROTOCOL_STATE_ERROR;
795 protocol->execute(server->timeout_queue, 0,
796 protocol, fd, 0, 300000);
802 memset(auth_data, 0, payload_len);
803 silc_free(auth_data);
806 /* Save connection type. This is later used to create the
807 ID for the connection. */
808 ctx->conn_type = conn_type;
810 /* Advance protocol state. */
811 protocol->state = SILC_PROTOCOL_STATE_END;
812 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
816 * We are initiator. We are authenticating ourselves to a
817 * remote server. We will send the authentication data to the
818 * other end for verify.
822 unsigned char *auth_data = NULL;
823 unsigned int auth_data_len = 0;
825 switch(ctx->auth_meth) {
826 case SILC_PROTOCOL_CONN_AUTH_NONE:
827 /* No authentication required */
830 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
831 /* Password authentication */
832 if (ctx->auth_data && ctx->auth_data_len) {
833 auth_data = ctx->auth_data;
834 auth_data_len = ctx->auth_data_len;
838 /* No authentication data exits. Ask interactively from user. */
843 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
844 /* Public key authentication */
849 payload_len = 4 + auth_data_len;
850 packet = silc_buffer_alloc(payload_len);
851 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
852 silc_buffer_format(packet,
853 SILC_STR_UI_SHORT(payload_len),
854 SILC_STR_UI_SHORT(server->server_type
856 SILC_SOCKET_TYPE_SERVER :
857 SILC_SOCKET_TYPE_ROUTER),
858 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
861 /* Send the packet to server */
862 silc_server_packet_send(server, ctx->sock,
863 SILC_PACKET_CONNECTION_AUTH, 0,
864 packet->data, packet->len, TRUE);
867 memset(auth_data, 0, auth_data_len);
868 silc_free(auth_data);
870 silc_buffer_free(packet);
872 /* Next state is end of protocol */
873 protocol->state = SILC_PROTOCOL_STATE_END;
878 case SILC_PROTOCOL_STATE_END:
884 /* Succesfully authenticated */
885 silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS,
888 /* Unregister the timeout task since the protocol has ended.
889 This was the timeout task to be executed if the protocol is
890 not completed fast enough. */
891 if (ctx->timeout_task)
892 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
894 /* Protocol has ended, call the final callback */
895 if (protocol->final_callback)
896 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
898 silc_protocol_free(protocol);
901 case SILC_PROTOCOL_STATE_ERROR:
907 /* Authentication failed */
908 silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
911 /* Unregister the timeout task since the protocol has ended.
912 This was the timeout task to be executed if the protocol is
913 not completed fast enough. */
914 if (ctx->timeout_task)
915 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
917 /* On error the final callback is always called. */
918 if (protocol->final_callback)
919 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
921 silc_protocol_free(protocol);
924 case SILC_PROTOCOL_STATE_UNKNOWN:
929 /* Registers protocols used in server. */
931 void silc_server_protocols_register(void)
933 silc_protocol_register(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
934 silc_server_protocol_connection_auth);
935 silc_protocol_register(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
936 silc_server_protocol_key_exchange);
939 /* Unregisters protocols */
941 void silc_server_protocols_unregister(void)
943 silc_protocol_unregister(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
944 silc_server_protocol_connection_auth);
945 silc_protocol_unregister(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
946 silc_server_protocol_key_exchange);