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 /* Allocate PKCS to be used */
107 /* XXX Do we ever need to allocate PKCS for the connection??
108 If yes, we need to change KE protocol to get the initiators
110 silc_pkcs_alloc(pkcs->pkcs->name, &idata->pkcs);
111 idata->public_key = silc_pkcs_public_key_alloc(XXX);
112 silc_pkcs_set_public_key(idata->pkcs, ske->ke2_payload->pk_data,
113 ske->ke2_payload->pk_len);
116 /* Save HMAC key to be used in the communication. */
117 if (!silc_hmac_alloc(hmac->hmac->name, NULL, &idata->hmac)) {
118 silc_cipher_free(idata->send_key);
119 silc_cipher_free(idata->receive_key);
120 silc_free(conn_data);
123 silc_hmac_set_key(idata->hmac, keymat->hmac_key, keymat->hmac_key_len);
125 sock->user_data = (void *)conn_data;
130 /* Check remote host version string */
132 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
135 SilcSKEStatus status = SILC_SKE_STATUS_OK;
137 /* Check for initial version string */
138 if (!strstr(version, "SILC-1.0-"))
139 status = SILC_SKE_STATUS_BAD_VERSION;
141 /* Check software version */
143 if (len < strlen(silc_version_string))
144 status = SILC_SKE_STATUS_BAD_VERSION;
146 /* XXX for now there is no other tests due to the abnormal version
147 string that is used */
152 /* Performs key exchange protocol. This is used for both initiator
153 and responder key exchange. This is performed always when accepting
154 new connection to the server. This may be called recursively. */
156 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
158 SilcProtocol protocol = (SilcProtocol)context;
159 SilcServerKEInternalContext *ctx =
160 (SilcServerKEInternalContext *)protocol->context;
161 SilcServer server = (SilcServer)ctx->server;
162 SilcSKEStatus status = 0;
164 SILC_LOG_DEBUG(("Start"));
166 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
167 protocol->state = SILC_PROTOCOL_STATE_START;
169 SILC_LOG_DEBUG(("State=%d", protocol->state));
171 switch(protocol->state) {
172 case SILC_PROTOCOL_STATE_START:
179 /* Allocate Key Exchange object */
180 ske = silc_ske_alloc();
182 ske->rng = server->rng;
184 if (ctx->responder == TRUE) {
185 /* Start the key exchange by processing the received security
186 properties packet from initiator. */
187 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
189 ctx->packet->buffer, NULL, NULL);
191 SilcSKEStartPayload *start_payload;
193 /* Assemble security properties. */
194 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
198 /* Start the key exchange by sending our security properties
199 to the remote end. */
200 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
202 silc_server_protocol_ke_send_packet,
206 if (status != SILC_SKE_STATUS_OK) {
207 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
209 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
212 protocol->state = SILC_PROTOCOL_STATE_ERROR;
213 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
217 /* Advance protocol state and call the next state if we are responder */
219 if (ctx->responder == TRUE)
220 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
228 if (ctx->responder == TRUE) {
229 /* Sends the selected security properties to the initiator. */
231 silc_ske_responder_phase_1(ctx->ske,
232 ctx->ske->start_payload,
233 silc_server_protocol_ke_send_packet,
236 /* Call Phase-1 function. This processes the Key Exchange Start
237 paylaod reply we just got from the responder. The callback
238 function will receive the processed payload where we will
240 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer,
244 if (status != SILC_SKE_STATUS_OK) {
245 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
247 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
250 protocol->state = SILC_PROTOCOL_STATE_ERROR;
251 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
255 /* Advance protocol state and call next state if we are initiator */
257 if (ctx->responder == FALSE)
258 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
266 if (ctx->responder == TRUE) {
267 /* Process the received Key Exchange 1 Payload packet from
268 the initiator. This also creates our parts of the Diffie
269 Hellman algorithm. */
270 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
273 /* Call the Phase-2 function. This creates Diffie Hellman
274 key exchange parameters and sends our public part inside
275 Key Exhange 1 Payload to the responder. */
277 silc_ske_initiator_phase_2(ctx->ske,
279 silc_server_protocol_ke_send_packet,
283 if (status != SILC_SKE_STATUS_OK) {
284 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
286 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
289 protocol->state = SILC_PROTOCOL_STATE_ERROR;
290 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
294 /* Advance protocol state and call the next state if we are responder */
296 if (ctx->responder == TRUE)
297 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
305 if (ctx->responder == TRUE) {
306 /* This creates the key exchange material and sends our
307 public parts to the initiator inside Key Exchange 2 Payload. */
309 silc_ske_responder_finish(ctx->ske,
310 server->public_key, server->private_key,
311 SILC_SKE_PK_TYPE_SILC,
312 silc_server_protocol_ke_send_packet,
315 /* Finish the protocol. This verifies the Key Exchange 2 payload
316 sent by responder. */
317 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
318 NULL, NULL, 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;
342 case SILC_PROTOCOL_STATE_END:
347 SilcSKEKeyMaterial *keymat;
348 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
349 int hash_len = ctx->ske->prop->hash->hash->hash_len;
351 /* Process the key material */
352 keymat = silc_calloc(1, sizeof(*keymat));
353 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
355 if (status != SILC_SKE_STATUS_OK) {
356 protocol->state = SILC_PROTOCOL_STATE_ERROR;
357 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
358 silc_ske_free_key_material(keymat);
361 ctx->keymat = keymat;
363 /* Send Ok to the other end if we are responder. If we are initiator
364 we have sent this already. */
365 if (ctx->responder == TRUE)
366 silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
368 /* Unregister the timeout task since the protocol has ended.
369 This was the timeout task to be executed if the protocol is
370 not completed fast enough. */
371 if (ctx->timeout_task)
372 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
374 /* Call the final callback */
375 if (protocol->final_callback)
376 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
378 silc_protocol_free(protocol);
382 case SILC_PROTOCOL_STATE_ERROR:
387 /* Send abort notification */
388 silc_ske_abort(ctx->ske, ctx->ske->status,
389 silc_server_protocol_ke_send_packet,
392 /* Unregister the timeout task since the protocol has ended.
393 This was the timeout task to be executed if the protocol is
394 not completed fast enough. */
395 if (ctx->timeout_task)
396 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
398 /* On error the final callback is always called. */
399 if (protocol->final_callback)
400 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
402 silc_protocol_free(protocol);
405 case SILC_PROTOCOL_STATE_FAILURE:
407 * We have received failure from remote
410 /* Unregister the timeout task since the protocol has ended.
411 This was the timeout task to be executed if the protocol is
412 not completed fast enough. */
413 if (ctx->timeout_task)
414 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
416 /* On error the final callback is always called. */
417 if (protocol->final_callback)
418 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
420 silc_protocol_free(protocol);
423 case SILC_PROTOCOL_STATE_UNKNOWN:
429 * Connection Authentication protocol functions
432 /* XXX move these to somehwere else */
434 int silc_server_password_authentication(SilcServer server, char *auth1,
437 if (!auth1 || !auth2)
440 if (!memcmp(auth1, auth2, strlen(auth1)))
446 int silc_server_public_key_authentication(SilcServer server,
449 unsigned int sign_len,
452 SilcPublicKey pub_key;
457 if (!pkfile || !sign)
460 /* Load public key from file */
461 if (!silc_pkcs_load_public_key(pkfile, &pub_key, SILC_PKCS_FILE_PEM))
462 if (!silc_pkcs_load_public_key(pkfile, &pub_key, SILC_PKCS_FILE_BIN))
465 silc_pkcs_alloc(pub_key->name, &pkcs);
466 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
467 silc_pkcs_free(pkcs);
471 /* Make the authentication data. Protocol says it is HASH plus
473 len = ske->hash_len + ske->start_payload_copy->len;
474 auth = silc_buffer_alloc(len);
475 silc_buffer_pull_tail(auth, len);
476 silc_buffer_format(auth,
477 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
478 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
479 ske->start_payload_copy->len),
482 /* Verify signature */
483 if (pkcs->pkcs->verify(pkcs->context, sign, sign_len,
484 auth->data, auth->len))
486 silc_pkcs_free(pkcs);
487 silc_pkcs_public_key_free(pub_key);
488 silc_buffer_free(auth);
492 silc_pkcs_free(pkcs);
493 silc_pkcs_public_key_free(pub_key);
494 silc_buffer_free(auth);
498 /* Performs connection authentication protocol. If responder, we
499 authenticate the remote data received. If initiator, we will send
500 authentication data to the remote end. */
502 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
504 SilcProtocol protocol = (SilcProtocol)context;
505 SilcServerConnAuthInternalContext *ctx =
506 (SilcServerConnAuthInternalContext *)protocol->context;
507 SilcServer server = (SilcServer)ctx->server;
509 SILC_LOG_DEBUG(("Start"));
511 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
512 protocol->state = SILC_PROTOCOL_STATE_START;
514 SILC_LOG_DEBUG(("State=%d", protocol->state));
516 switch(protocol->state) {
517 case SILC_PROTOCOL_STATE_START:
523 if (ctx->responder == TRUE) {
525 * We are receiving party
528 unsigned short payload_len;
529 unsigned short conn_type;
530 unsigned char *auth_data;
532 SILC_LOG_INFO(("Performing authentication protocol for %s (%s)",
533 ctx->sock->hostname, ctx->sock->ip));
535 /* Parse the received authentication data packet. The received
536 payload is Connection Auth Payload. */
537 ret = silc_buffer_unformat(ctx->packet->buffer,
538 SILC_STR_UI_SHORT(&payload_len),
539 SILC_STR_UI_SHORT(&conn_type),
542 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
543 protocol->state = SILC_PROTOCOL_STATE_ERROR;
544 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
548 if (payload_len != ctx->packet->buffer->len) {
549 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
550 protocol->state = SILC_PROTOCOL_STATE_ERROR;
551 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
557 if (conn_type < SILC_SOCKET_TYPE_CLIENT ||
558 conn_type > SILC_SOCKET_TYPE_ROUTER) {
559 SILC_LOG_ERROR(("Bad connection type %d", conn_type));
560 protocol->state = SILC_PROTOCOL_STATE_ERROR;
561 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
565 if (payload_len > 0) {
566 /* Get authentication data */
567 silc_buffer_pull(ctx->packet->buffer, 4);
568 ret = silc_buffer_unformat(ctx->packet->buffer,
569 SILC_STR_UI_XNSTRING_ALLOC(&auth_data,
573 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
574 protocol->state = SILC_PROTOCOL_STATE_ERROR;
575 protocol->execute(server->timeout_queue, 0,
576 protocol, fd, 0, 300000);
584 * Check the remote connection type and make sure that we have
585 * configured this connection. If we haven't allowed this connection
586 * the authentication must be failed.
589 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
591 /* Remote end is client */
592 if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
593 SilcServerConfigSectionClientConnection *client = NULL;
595 silc_server_config_find_client_conn(server->config,
600 silc_server_config_find_client_conn(server->config,
605 switch(client->auth_meth) {
607 /* No authentication required */
608 SILC_LOG_DEBUG(("No authentication required"));
611 case SILC_AUTH_PASSWORD:
612 /* Password authentication */
613 SILC_LOG_DEBUG(("Password authentication"));
614 ret = silc_server_password_authentication(server, auth_data,
618 memset(auth_data, 0, payload_len);
619 silc_free(auth_data);
624 /* Authentication failed */
625 SILC_LOG_ERROR(("Authentication failed"));
626 SILC_LOG_DEBUG(("Authentication failed"));
627 protocol->state = SILC_PROTOCOL_STATE_ERROR;
628 protocol->execute(server->timeout_queue, 0,
629 protocol, fd, 0, 300000);
633 case SILC_AUTH_PUBLIC_KEY:
634 /* Public key authentication */
635 SILC_LOG_DEBUG(("Public key authentication"));
636 ret = silc_server_public_key_authentication(server,
643 memset(auth_data, 0, payload_len);
644 silc_free(auth_data);
649 SILC_LOG_ERROR(("Authentication failed"));
650 SILC_LOG_DEBUG(("Authentication failed"));
651 protocol->state = SILC_PROTOCOL_STATE_ERROR;
652 protocol->execute(server->timeout_queue, 0,
653 protocol, fd, 0, 300000);
657 SILC_LOG_DEBUG(("No configuration for remote connection"));
658 SILC_LOG_ERROR(("Remote connection not configured"));
659 SILC_LOG_ERROR(("Authentication failed"));
660 memset(auth_data, 0, payload_len);
661 silc_free(auth_data);
663 protocol->state = SILC_PROTOCOL_STATE_ERROR;
664 protocol->execute(server->timeout_queue, 0,
665 protocol, fd, 0, 300000);
670 /* Remote end is server */
671 if (conn_type == SILC_SOCKET_TYPE_SERVER) {
672 SilcServerConfigSectionServerConnection *serv = NULL;
674 silc_server_config_find_server_conn(server->config,
679 silc_server_config_find_server_conn(server->config,
684 switch(serv->auth_meth) {
686 /* No authentication required */
687 SILC_LOG_DEBUG(("No authentication required"));
690 case SILC_AUTH_PASSWORD:
691 /* Password authentication */
692 SILC_LOG_DEBUG(("Password authentication"));
693 ret = silc_server_password_authentication(server, auth_data,
697 memset(auth_data, 0, payload_len);
698 silc_free(auth_data);
703 /* Authentication failed */
704 SILC_LOG_ERROR(("Authentication failed"));
705 SILC_LOG_DEBUG(("Authentication failed"));
706 protocol->state = SILC_PROTOCOL_STATE_ERROR;
707 protocol->execute(server->timeout_queue, 0,
708 protocol, fd, 0, 300000);
712 case SILC_AUTH_PUBLIC_KEY:
713 /* Public key authentication */
714 SILC_LOG_DEBUG(("Public key authentication"));
715 ret = silc_server_public_key_authentication(server,
722 memset(auth_data, 0, payload_len);
723 silc_free(auth_data);
728 SILC_LOG_ERROR(("Authentication failed"));
729 SILC_LOG_DEBUG(("Authentication failed"));
730 protocol->state = SILC_PROTOCOL_STATE_ERROR;
731 protocol->execute(server->timeout_queue, 0,
732 protocol, fd, 0, 300000);
736 SILC_LOG_DEBUG(("No configuration for remote connection"));
737 SILC_LOG_ERROR(("Remote connection not configured"));
738 SILC_LOG_ERROR(("Authentication failed"));
739 memset(auth_data, 0, payload_len);
740 silc_free(auth_data);
742 protocol->state = SILC_PROTOCOL_STATE_ERROR;
743 protocol->execute(server->timeout_queue, 0,
744 protocol, fd, 0, 300000);
749 /* Remote end is router */
750 if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
751 SilcServerConfigSectionServerConnection *serv = NULL;
753 silc_server_config_find_router_conn(server->config,
758 silc_server_config_find_router_conn(server->config,
763 switch(serv->auth_meth) {
765 /* No authentication required */
766 SILC_LOG_DEBUG(("No authentication required"));
769 case SILC_AUTH_PASSWORD:
770 /* Password authentication */
771 SILC_LOG_DEBUG(("Password authentication"));
772 ret = silc_server_password_authentication(server, auth_data,
776 memset(auth_data, 0, payload_len);
777 silc_free(auth_data);
782 /* Authentication failed */
783 SILC_LOG_ERROR(("Authentication failed"));
784 SILC_LOG_DEBUG(("Authentication failed"));
785 protocol->state = SILC_PROTOCOL_STATE_ERROR;
786 protocol->execute(server->timeout_queue, 0,
787 protocol, fd, 0, 300000);
791 case SILC_AUTH_PUBLIC_KEY:
792 /* Public key authentication */
793 SILC_LOG_DEBUG(("Public key authentication"));
794 ret = silc_server_public_key_authentication(server,
801 memset(auth_data, 0, payload_len);
802 silc_free(auth_data);
807 SILC_LOG_ERROR(("Authentication failed"));
808 SILC_LOG_DEBUG(("Authentication failed"));
809 protocol->state = SILC_PROTOCOL_STATE_ERROR;
810 protocol->execute(server->timeout_queue, 0,
811 protocol, fd, 0, 300000);
815 SILC_LOG_DEBUG(("No configuration for remote connection"));
816 SILC_LOG_ERROR(("Remote connection not configured"));
817 SILC_LOG_ERROR(("Authentication failed"));
818 memset(auth_data, 0, payload_len);
819 silc_free(auth_data);
821 protocol->state = SILC_PROTOCOL_STATE_ERROR;
822 protocol->execute(server->timeout_queue, 0,
823 protocol, fd, 0, 300000);
829 memset(auth_data, 0, payload_len);
830 silc_free(auth_data);
833 /* Save connection type. This is later used to create the
834 ID for the connection. */
835 ctx->conn_type = conn_type;
837 /* Advance protocol state. */
838 protocol->state = SILC_PROTOCOL_STATE_END;
839 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
843 * We are initiator. We are authenticating ourselves to a
844 * remote server. We will send the authentication data to the
845 * other end for verify.
849 unsigned char *auth_data = NULL;
850 unsigned int auth_data_len = 0;
852 switch(ctx->auth_meth) {
854 /* No authentication required */
857 case SILC_AUTH_PASSWORD:
858 /* Password authentication */
859 if (ctx->auth_data && ctx->auth_data_len) {
860 auth_data = ctx->auth_data;
861 auth_data_len = ctx->auth_data_len;
865 /* No authentication data exits. Ask interactively from user. */
870 case SILC_AUTH_PUBLIC_KEY:
871 /* Public key authentication */
876 payload_len = 4 + auth_data_len;
877 packet = silc_buffer_alloc(payload_len);
878 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
879 silc_buffer_format(packet,
880 SILC_STR_UI_SHORT(payload_len),
881 SILC_STR_UI_SHORT(server->server_type
883 SILC_SOCKET_TYPE_SERVER :
884 SILC_SOCKET_TYPE_ROUTER),
885 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
888 /* Send the packet to server */
889 silc_server_packet_send(server, ctx->sock,
890 SILC_PACKET_CONNECTION_AUTH, 0,
891 packet->data, packet->len, TRUE);
894 memset(auth_data, 0, auth_data_len);
895 silc_free(auth_data);
897 silc_buffer_free(packet);
899 /* Next state is end of protocol */
900 protocol->state = SILC_PROTOCOL_STATE_END;
905 case SILC_PROTOCOL_STATE_END:
912 SILC_PUT32_MSB(SILC_AUTH_OK, ok);
914 /* Authentication failed */
915 silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS,
918 /* Unregister the timeout task since the protocol has ended.
919 This was the timeout task to be executed if the protocol is
920 not completed fast enough. */
921 if (ctx->timeout_task)
922 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
924 /* Protocol has ended, call the final callback */
925 if (protocol->final_callback)
926 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
928 silc_protocol_free(protocol);
931 case SILC_PROTOCOL_STATE_ERROR:
934 * Error. Send notify to remote.
936 unsigned char error[4];
938 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
940 /* Authentication failed */
941 silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
944 /* Unregister the timeout task since the protocol has ended.
945 This was the timeout task to be executed if the protocol is
946 not completed fast enough. */
947 if (ctx->timeout_task)
948 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
950 /* On error the final callback is always called. */
951 if (protocol->final_callback)
952 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
954 silc_protocol_free(protocol);
958 case SILC_PROTOCOL_STATE_FAILURE:
960 * We have received failure from remote
963 /* Unregister the timeout task since the protocol has ended.
964 This was the timeout task to be executed if the protocol is
965 not completed fast enough. */
966 if (ctx->timeout_task)
967 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
969 /* On error the final callback is always called. */
970 if (protocol->final_callback)
971 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
973 silc_protocol_free(protocol);
976 case SILC_PROTOCOL_STATE_UNKNOWN:
981 /* Registers protocols used in server. */
983 void silc_server_protocols_register(void)
985 silc_protocol_register(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
986 silc_server_protocol_connection_auth);
987 silc_protocol_register(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
988 silc_server_protocol_key_exchange);
991 /* Unregisters protocols */
993 void silc_server_protocols_unregister(void)
995 silc_protocol_unregister(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
996 silc_server_protocol_connection_auth);
997 silc_protocol_unregister(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
998 silc_server_protocol_key_exchange);