5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 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.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth);
29 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange);
31 extern char *silc_version_string;
34 * Key Exhange protocol functions
37 /* Packet sending callback. This function is provided as packet sending
38 routine to the Key Exchange functions. */
40 static void silc_server_protocol_ke_send_packet(SilcSKE ske,
45 SilcProtocol protocol = (SilcProtocol)context;
46 SilcServerKEInternalContext *ctx =
47 (SilcServerKEInternalContext *)protocol->context;
48 SilcServer server = (SilcServer)ctx->server;
50 /* Send the packet immediately */
51 silc_server_packet_send(server, ske->sock,
52 type, 0, packet->data, packet->len, TRUE);
55 /* Sets the negotiated key material into use for particular connection. */
57 int silc_server_protocol_ke_set_keys(SilcSKE ske,
58 SilcSocketConnection sock,
59 SilcSKEKeyMaterial *keymat,
66 SilcUnknownEntry conn_data;
69 SILC_LOG_DEBUG(("Setting new key into use"));
71 conn_data = silc_calloc(1, sizeof(*conn_data));
72 idata = (SilcIDListData)conn_data;
74 /* Allocate cipher to be used in the communication */
75 if (!silc_cipher_alloc(cipher->cipher->name, &idata->send_key)) {
79 if (!silc_cipher_alloc(cipher->cipher->name, &idata->receive_key)) {
84 if (is_responder == TRUE) {
85 idata->send_key->cipher->set_key(idata->send_key->context,
86 keymat->receive_enc_key,
88 idata->send_key->set_iv(idata->send_key, keymat->receive_iv);
89 idata->receive_key->cipher->set_key(idata->receive_key->context,
92 idata->receive_key->set_iv(idata->receive_key, keymat->send_iv);
95 idata->send_key->cipher->set_key(idata->send_key->context,
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);
105 /* Save the remote host's public key */
106 silc_pkcs_public_key_decode(ske->ke1_payload->pk_data,
107 ske->ke1_payload->pk_len, &idata->public_key);
110 if (!silc_hash_alloc(hash->hash->name, &idata->hash)) {
111 silc_cipher_free(idata->send_key);
112 silc_cipher_free(idata->receive_key);
113 silc_free(conn_data);
117 /* Save HMAC key to be used in the communication. */
118 if (!silc_hmac_alloc(hmac->hmac->name, NULL, &idata->hmac)) {
119 silc_cipher_free(idata->send_key);
120 silc_cipher_free(idata->receive_key);
121 silc_hash_free(idata->hash);
122 silc_free(conn_data);
125 silc_hmac_set_key(idata->hmac, keymat->hmac_key, keymat->hmac_key_len);
127 sock->user_data = (void *)conn_data;
132 /* Check remote host version string */
134 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
137 SilcSKEStatus status = SILC_SKE_STATUS_OK;
139 SILC_LOG_INFO(("%s (%s) is version %s", ske->sock->hostname,
140 ske->sock->ip, version));
142 /* Check for initial version string */
143 if (!strstr(version, "SILC-1.0-"))
144 status = SILC_SKE_STATUS_BAD_VERSION;
146 /* Check software version */
148 if (len < strlen(silc_version_string))
149 status = SILC_SKE_STATUS_BAD_VERSION;
151 /* XXX for now there is no other tests due to the abnormal version
152 string that is used */
157 /* Performs key exchange protocol. This is used for both initiator
158 and responder key exchange. This is performed always when accepting
159 new connection to the server. This may be called recursively. */
161 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
163 SilcProtocol protocol = (SilcProtocol)context;
164 SilcServerKEInternalContext *ctx =
165 (SilcServerKEInternalContext *)protocol->context;
166 SilcServer server = (SilcServer)ctx->server;
167 SilcSKEStatus status = 0;
169 SILC_LOG_DEBUG(("Start"));
171 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
172 protocol->state = SILC_PROTOCOL_STATE_START;
174 SILC_LOG_DEBUG(("State=%d", protocol->state));
176 switch(protocol->state) {
177 case SILC_PROTOCOL_STATE_START:
184 /* Allocate Key Exchange object */
185 ske = silc_ske_alloc();
187 ske->rng = server->rng;
189 if (ctx->responder == TRUE) {
190 /* Start the key exchange by processing the received security
191 properties packet from initiator. */
192 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
194 ctx->packet->buffer, FALSE,
197 SilcSKEStartPayload *start_payload;
199 /* Assemble security properties. */
200 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
204 /* Start the key exchange by sending our security properties
205 to the remote end. */
206 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
208 silc_server_protocol_ke_send_packet,
212 if (status != SILC_SKE_STATUS_OK) {
213 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
215 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
218 protocol->state = SILC_PROTOCOL_STATE_ERROR;
219 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
223 /* Advance protocol state and call the next state if we are responder */
225 if (ctx->responder == TRUE)
226 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
234 if (ctx->responder == TRUE) {
235 /* Sends the selected security properties to the initiator. */
237 silc_ske_responder_phase_1(ctx->ske,
238 ctx->ske->start_payload,
239 silc_server_protocol_ke_send_packet,
242 /* Call Phase-1 function. This processes the Key Exchange Start
243 paylaod reply we just got from the responder. The callback
244 function will receive the processed payload where we will
246 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer,
250 if (status != SILC_SKE_STATUS_OK) {
251 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
253 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
256 protocol->state = SILC_PROTOCOL_STATE_ERROR;
257 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
261 /* Advance protocol state and call next state if we are initiator */
263 if (ctx->responder == FALSE)
264 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
272 if (ctx->responder == TRUE) {
273 /* Process the received Key Exchange 1 Payload packet from
274 the initiator. This also creates our parts of the Diffie
275 Hellman algorithm. */
276 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
277 NULL, NULL, NULL, NULL);
279 /* Call the Phase-2 function. This creates Diffie Hellman
280 key exchange parameters and sends our public part inside
281 Key Exhange 1 Payload to the responder. */
283 silc_ske_initiator_phase_2(ctx->ske,
286 silc_server_protocol_ke_send_packet,
290 if (status != SILC_SKE_STATUS_OK) {
291 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
293 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
296 protocol->state = SILC_PROTOCOL_STATE_ERROR;
297 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
301 /* Advance protocol state and call the next state if we are responder */
303 if (ctx->responder == TRUE)
304 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
312 if (ctx->responder == TRUE) {
313 /* This creates the key exchange material and sends our
314 public parts to the initiator inside Key Exchange 2 Payload. */
316 silc_ske_responder_finish(ctx->ske,
317 server->public_key, server->private_key,
318 SILC_SKE_PK_TYPE_SILC,
319 silc_server_protocol_ke_send_packet,
322 /* Finish the protocol. This verifies the Key Exchange 2 payload
323 sent by responder. */
324 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
325 NULL, NULL, NULL, NULL);
328 if (status != SILC_SKE_STATUS_OK) {
329 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
331 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
334 protocol->state = SILC_PROTOCOL_STATE_ERROR;
335 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
339 /* Send Ok to the other end. We will end the protocol as responder
340 sends Ok to us when we will take the new keys into use. */
341 if (ctx->responder == FALSE)
342 silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
344 /* End the protocol on the next round */
345 protocol->state = SILC_PROTOCOL_STATE_END;
349 case SILC_PROTOCOL_STATE_END:
354 SilcSKEKeyMaterial *keymat;
355 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
356 int hash_len = ctx->ske->prop->hash->hash->hash_len;
358 /* Process the key material */
359 keymat = silc_calloc(1, sizeof(*keymat));
360 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
362 if (status != SILC_SKE_STATUS_OK) {
363 protocol->state = SILC_PROTOCOL_STATE_ERROR;
364 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
365 silc_ske_free_key_material(keymat);
368 ctx->keymat = keymat;
370 /* Send Ok to the other end if we are responder. If we are initiator
371 we have sent this already. */
372 if (ctx->responder == TRUE)
373 silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
375 /* Unregister the timeout task since the protocol has ended.
376 This was the timeout task to be executed if the protocol is
377 not completed fast enough. */
378 if (ctx->timeout_task)
379 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
381 /* Call the final callback */
382 if (protocol->final_callback)
383 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
385 silc_protocol_free(protocol);
389 case SILC_PROTOCOL_STATE_ERROR:
394 /* Send abort notification */
395 silc_ske_abort(ctx->ske, ctx->ske->status,
396 silc_server_protocol_ke_send_packet,
399 /* Unregister the timeout task since the protocol has ended.
400 This was the timeout task to be executed if the protocol is
401 not completed fast enough. */
402 if (ctx->timeout_task)
403 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
405 /* On error the final callback is always called. */
406 if (protocol->final_callback)
407 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
409 silc_protocol_free(protocol);
412 case SILC_PROTOCOL_STATE_FAILURE:
414 * We have received failure from remote
417 /* Unregister the timeout task since the protocol has ended.
418 This was the timeout task to be executed if the protocol is
419 not completed fast enough. */
420 if (ctx->timeout_task)
421 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
423 /* On error the final callback is always called. */
424 if (protocol->final_callback)
425 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
427 silc_protocol_free(protocol);
430 case SILC_PROTOCOL_STATE_UNKNOWN:
436 * Connection Authentication protocol functions
440 silc_server_password_authentication(SilcServer server, char *auth1,
443 if (!auth1 || !auth2)
446 if (!memcmp(auth1, auth2, strlen(auth1)))
453 silc_server_public_key_authentication(SilcServer server,
454 SilcPublicKey pub_key,
456 unsigned int sign_len,
463 if (!pub_key || !sign)
466 silc_pkcs_alloc(pub_key->name, &pkcs);
467 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
468 silc_pkcs_free(pkcs);
472 /* Make the authentication data. Protocol says it is HASH plus
474 len = ske->hash_len + ske->start_payload_copy->len;
475 auth = silc_buffer_alloc(len);
476 silc_buffer_pull_tail(auth, len);
477 silc_buffer_format(auth,
478 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
479 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
480 ske->start_payload_copy->len),
483 /* Verify signature */
484 if (silc_pkcs_verify(pkcs, sign, sign_len, auth->data, auth->len)) {
485 silc_pkcs_free(pkcs);
486 silc_buffer_free(auth);
490 silc_pkcs_free(pkcs);
491 silc_buffer_free(auth);
496 silc_server_get_public_key_auth(SilcServer server,
497 SilcPublicKey pub_key,
498 unsigned char *auth_data,
499 unsigned int *auth_data_len,
509 silc_pkcs_alloc(pub_key->name, &pkcs);
510 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
511 silc_pkcs_free(pkcs);
515 /* Make the authentication data. Protocol says it is HASH plus
517 len = ske->hash_len + ske->start_payload_copy->len;
518 auth = silc_buffer_alloc(len);
519 silc_buffer_pull_tail(auth, len);
520 silc_buffer_format(auth,
521 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
522 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
523 ske->start_payload_copy->len),
526 if (silc_pkcs_sign(pkcs, auth->data, auth->len, auth_data, auth_data_len)) {
527 silc_pkcs_free(pkcs);
528 silc_buffer_free(auth);
532 silc_pkcs_free(pkcs);
533 silc_buffer_free(auth);
537 /* Performs connection authentication protocol. If responder, we
538 authenticate the remote data received. If initiator, we will send
539 authentication data to the remote end. */
541 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
543 SilcProtocol protocol = (SilcProtocol)context;
544 SilcServerConnAuthInternalContext *ctx =
545 (SilcServerConnAuthInternalContext *)protocol->context;
546 SilcServer server = (SilcServer)ctx->server;
548 SILC_LOG_DEBUG(("Start"));
550 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
551 protocol->state = SILC_PROTOCOL_STATE_START;
553 SILC_LOG_DEBUG(("State=%d", protocol->state));
555 switch(protocol->state) {
556 case SILC_PROTOCOL_STATE_START:
562 if (ctx->responder == TRUE) {
564 * We are receiving party
567 unsigned short payload_len;
568 unsigned short conn_type;
569 unsigned char *auth_data = NULL;
571 SILC_LOG_INFO(("Performing authentication protocol for %s (%s)",
572 ctx->sock->hostname, ctx->sock->ip));
574 /* Parse the received authentication data packet. The received
575 payload is Connection Auth Payload. */
576 ret = silc_buffer_unformat(ctx->packet->buffer,
577 SILC_STR_UI_SHORT(&payload_len),
578 SILC_STR_UI_SHORT(&conn_type),
581 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
582 protocol->state = SILC_PROTOCOL_STATE_ERROR;
583 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
587 if (payload_len != ctx->packet->buffer->len) {
588 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
589 protocol->state = SILC_PROTOCOL_STATE_ERROR;
590 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
596 if (conn_type < SILC_SOCKET_TYPE_CLIENT ||
597 conn_type > SILC_SOCKET_TYPE_ROUTER) {
598 SILC_LOG_ERROR(("Bad connection type %d", conn_type));
599 protocol->state = SILC_PROTOCOL_STATE_ERROR;
600 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
604 if (payload_len > 0) {
605 /* Get authentication data */
606 silc_buffer_pull(ctx->packet->buffer, 4);
607 ret = silc_buffer_unformat(ctx->packet->buffer,
608 SILC_STR_UI_XNSTRING_ALLOC(&auth_data,
612 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
613 protocol->state = SILC_PROTOCOL_STATE_ERROR;
614 protocol->execute(server->timeout_queue, 0,
615 protocol, fd, 0, 300000);
621 * Check the remote connection type and make sure that we have
622 * configured this connection. If we haven't allowed this connection
623 * the authentication must be failed.
626 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
628 /* Remote end is client */
629 if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
630 SilcServerConfigSectionClientConnection *client = NULL;
631 client = silc_server_config_find_client_conn(server->config,
635 client = silc_server_config_find_client_conn(server->config,
640 switch(client->auth_meth) {
642 /* No authentication required */
643 SILC_LOG_DEBUG(("No authentication required"));
646 case SILC_AUTH_PASSWORD:
647 /* Password authentication */
648 SILC_LOG_DEBUG(("Password authentication"));
649 ret = silc_server_password_authentication(server, auth_data,
655 /* Authentication failed */
656 SILC_LOG_ERROR(("Authentication failed"));
657 SILC_LOG_DEBUG(("Authentication failed"));
658 silc_free(auth_data);
659 protocol->state = SILC_PROTOCOL_STATE_ERROR;
660 protocol->execute(server->timeout_queue, 0,
661 protocol, fd, 0, 300000);
665 case SILC_AUTH_PUBLIC_KEY:
666 /* Public key authentication */
667 SILC_LOG_DEBUG(("Public key authentication"));
668 ret = silc_server_public_key_authentication(server,
677 SILC_LOG_ERROR(("Authentication failed"));
678 SILC_LOG_DEBUG(("Authentication failed"));
679 silc_free(auth_data);
680 protocol->state = SILC_PROTOCOL_STATE_ERROR;
681 protocol->execute(server->timeout_queue, 0,
682 protocol, fd, 0, 300000);
686 SILC_LOG_DEBUG(("No configuration for remote connection"));
687 SILC_LOG_ERROR(("Remote connection not configured"));
688 SILC_LOG_ERROR(("Authentication failed"));
689 silc_free(auth_data);
690 protocol->state = SILC_PROTOCOL_STATE_ERROR;
691 protocol->execute(server->timeout_queue, 0,
692 protocol, fd, 0, 300000);
697 /* Remote end is server */
698 if (conn_type == SILC_SOCKET_TYPE_SERVER) {
699 SilcServerConfigSectionServerConnection *serv = NULL;
700 serv = silc_server_config_find_server_conn(server->config,
704 serv = silc_server_config_find_server_conn(server->config,
709 switch(serv->auth_meth) {
711 /* No authentication required */
712 SILC_LOG_DEBUG(("No authentication required"));
715 case SILC_AUTH_PASSWORD:
716 /* Password authentication */
717 SILC_LOG_DEBUG(("Password authentication"));
718 ret = silc_server_password_authentication(server, auth_data,
724 /* Authentication failed */
725 SILC_LOG_ERROR(("Authentication failed"));
726 SILC_LOG_DEBUG(("Authentication failed"));
727 silc_free(auth_data);
728 protocol->state = SILC_PROTOCOL_STATE_ERROR;
729 protocol->execute(server->timeout_queue, 0,
730 protocol, fd, 0, 300000);
734 case SILC_AUTH_PUBLIC_KEY:
735 /* Public key authentication */
736 SILC_LOG_DEBUG(("Public key authentication"));
737 ret = silc_server_public_key_authentication(server,
746 SILC_LOG_ERROR(("Authentication failed"));
747 SILC_LOG_DEBUG(("Authentication failed"));
748 silc_free(auth_data);
749 protocol->state = SILC_PROTOCOL_STATE_ERROR;
750 protocol->execute(server->timeout_queue, 0,
751 protocol, fd, 0, 300000);
755 SILC_LOG_DEBUG(("No configuration for remote connection"));
756 SILC_LOG_ERROR(("Remote connection not configured"));
757 SILC_LOG_ERROR(("Authentication failed"));
758 protocol->state = SILC_PROTOCOL_STATE_ERROR;
759 protocol->execute(server->timeout_queue, 0,
760 protocol, fd, 0, 300000);
761 silc_free(auth_data);
766 /* Remote end is router */
767 if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
768 SilcServerConfigSectionServerConnection *serv = NULL;
769 serv = silc_server_config_find_router_conn(server->config,
773 serv = silc_server_config_find_router_conn(server->config,
778 switch(serv->auth_meth) {
780 /* No authentication required */
781 SILC_LOG_DEBUG(("No authentication required"));
784 case SILC_AUTH_PASSWORD:
785 /* Password authentication */
786 SILC_LOG_DEBUG(("Password authentication"));
787 ret = silc_server_password_authentication(server, auth_data,
793 /* Authentication failed */
794 SILC_LOG_ERROR(("Authentication failed"));
795 SILC_LOG_DEBUG(("Authentication failed"));
796 silc_free(auth_data);
797 protocol->state = SILC_PROTOCOL_STATE_ERROR;
798 protocol->execute(server->timeout_queue, 0,
799 protocol, fd, 0, 300000);
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,
815 SILC_LOG_ERROR(("Authentication failed"));
816 SILC_LOG_DEBUG(("Authentication failed"));
817 silc_free(auth_data);
818 protocol->state = SILC_PROTOCOL_STATE_ERROR;
819 protocol->execute(server->timeout_queue, 0,
820 protocol, fd, 0, 300000);
824 SILC_LOG_DEBUG(("No configuration for remote connection"));
825 SILC_LOG_ERROR(("Remote connection not configured"));
826 SILC_LOG_ERROR(("Authentication failed"));
827 silc_free(auth_data);
828 protocol->state = SILC_PROTOCOL_STATE_ERROR;
829 protocol->execute(server->timeout_queue, 0,
830 protocol, fd, 0, 300000);
835 silc_free(auth_data);
837 /* Save connection type. This is later used to create the
838 ID for the connection. */
839 ctx->conn_type = conn_type;
841 /* Advance protocol state. */
842 protocol->state = SILC_PROTOCOL_STATE_END;
843 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
847 * We are initiator. We are authenticating ourselves to a
848 * remote server. We will send the authentication data to the
849 * other end for verify.
853 unsigned char *auth_data = NULL;
854 unsigned int auth_data_len = 0;
856 switch(ctx->auth_meth) {
858 /* No authentication required */
861 case SILC_AUTH_PASSWORD:
862 /* Password authentication */
863 if (ctx->auth_data && ctx->auth_data_len) {
864 auth_data = strdup(ctx->auth_data);
865 auth_data_len = ctx->auth_data_len;
870 case SILC_AUTH_PUBLIC_KEY:
872 unsigned char sign[1024];
874 /* Public key authentication */
875 silc_server_get_public_key_auth(server, ctx->auth_data,
876 sign, &auth_data_len,
882 payload_len = 4 + auth_data_len;
883 packet = silc_buffer_alloc(payload_len);
884 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
885 silc_buffer_format(packet,
886 SILC_STR_UI_SHORT(payload_len),
887 SILC_STR_UI_SHORT(server->server_type
889 SILC_SOCKET_TYPE_SERVER :
890 SILC_SOCKET_TYPE_ROUTER),
891 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
894 /* Send the packet to server */
895 silc_server_packet_send(server, ctx->sock,
896 SILC_PACKET_CONNECTION_AUTH, 0,
897 packet->data, packet->len, TRUE);
900 memset(auth_data, 0, auth_data_len);
901 silc_free(auth_data);
903 silc_buffer_free(packet);
905 /* Next state is end of protocol */
906 protocol->state = SILC_PROTOCOL_STATE_END;
911 case SILC_PROTOCOL_STATE_END:
918 SILC_PUT32_MSB(SILC_AUTH_OK, ok);
920 /* Authentication failed */
921 silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS,
924 /* Unregister the timeout task since the protocol has ended.
925 This was the timeout task to be executed if the protocol is
926 not completed fast enough. */
927 if (ctx->timeout_task)
928 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
930 /* Protocol has ended, call the final callback */
931 if (protocol->final_callback)
932 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
934 silc_protocol_free(protocol);
937 case SILC_PROTOCOL_STATE_ERROR:
940 * Error. Send notify to remote.
942 unsigned char error[4];
944 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
946 /* Authentication failed */
947 silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
950 /* Unregister the timeout task since the protocol has ended.
951 This was the timeout task to be executed if the protocol is
952 not completed fast enough. */
953 if (ctx->timeout_task)
954 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
956 /* On error the final callback is always called. */
957 if (protocol->final_callback)
958 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
960 silc_protocol_free(protocol);
964 case SILC_PROTOCOL_STATE_FAILURE:
966 * We have received failure from remote
969 /* Unregister the timeout task since the protocol has ended.
970 This was the timeout task to be executed if the protocol is
971 not completed fast enough. */
972 if (ctx->timeout_task)
973 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
975 /* On error the final callback is always called. */
976 if (protocol->final_callback)
977 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
979 silc_protocol_free(protocol);
982 case SILC_PROTOCOL_STATE_UNKNOWN:
987 /* Registers protocols used in server. */
989 void silc_server_protocols_register(void)
991 silc_protocol_register(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
992 silc_server_protocol_connection_auth);
993 silc_protocol_register(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
994 silc_server_protocol_key_exchange);
997 /* Unregisters protocols */
999 void silc_server_protocols_unregister(void)
1001 silc_protocol_unregister(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1002 silc_server_protocol_connection_auth);
1003 silc_protocol_unregister(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1004 silc_server_protocol_key_exchange);