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);
117 if (!silc_hash_alloc(hash->hash->name, &idata->hash)) {
118 silc_cipher_free(idata->send_key);
119 silc_cipher_free(idata->receive_key);
120 silc_free(conn_data);
124 /* Save HMAC key to be used in the communication. */
125 if (!silc_hmac_alloc(hmac->hmac->name, NULL, &idata->hmac)) {
126 silc_cipher_free(idata->send_key);
127 silc_cipher_free(idata->receive_key);
128 silc_hash_free(idata->hash);
129 silc_free(conn_data);
132 silc_hmac_set_key(idata->hmac, keymat->hmac_key, keymat->hmac_key_len);
134 sock->user_data = (void *)conn_data;
139 /* Check remote host version string */
141 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
144 SilcSKEStatus status = SILC_SKE_STATUS_OK;
146 SILC_LOG_INFO(("%s (%s) is version %s", ske->sock->hostname,
147 ske->sock->ip, version));
149 /* Check for initial version string */
150 if (!strstr(version, "SILC-1.0-"))
151 status = SILC_SKE_STATUS_BAD_VERSION;
153 /* Check software version */
155 if (len < strlen(silc_version_string))
156 status = SILC_SKE_STATUS_BAD_VERSION;
158 /* XXX for now there is no other tests due to the abnormal version
159 string that is used */
164 /* Performs key exchange protocol. This is used for both initiator
165 and responder key exchange. This is performed always when accepting
166 new connection to the server. This may be called recursively. */
168 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
170 SilcProtocol protocol = (SilcProtocol)context;
171 SilcServerKEInternalContext *ctx =
172 (SilcServerKEInternalContext *)protocol->context;
173 SilcServer server = (SilcServer)ctx->server;
174 SilcSKEStatus status = 0;
176 SILC_LOG_DEBUG(("Start"));
178 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
179 protocol->state = SILC_PROTOCOL_STATE_START;
181 SILC_LOG_DEBUG(("State=%d", protocol->state));
183 switch(protocol->state) {
184 case SILC_PROTOCOL_STATE_START:
191 /* Allocate Key Exchange object */
192 ske = silc_ske_alloc();
194 ske->rng = server->rng;
196 if (ctx->responder == TRUE) {
197 /* Start the key exchange by processing the received security
198 properties packet from initiator. */
199 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
201 ctx->packet->buffer, NULL, NULL);
203 SilcSKEStartPayload *start_payload;
205 /* Assemble security properties. */
206 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
210 /* Start the key exchange by sending our security properties
211 to the remote end. */
212 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
214 silc_server_protocol_ke_send_packet,
218 if (status != SILC_SKE_STATUS_OK) {
219 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
221 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
224 protocol->state = SILC_PROTOCOL_STATE_ERROR;
225 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
229 /* Advance protocol state and call the next state if we are responder */
231 if (ctx->responder == TRUE)
232 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
240 if (ctx->responder == TRUE) {
241 /* Sends the selected security properties to the initiator. */
243 silc_ske_responder_phase_1(ctx->ske,
244 ctx->ske->start_payload,
245 silc_server_protocol_ke_send_packet,
248 /* Call Phase-1 function. This processes the Key Exchange Start
249 paylaod reply we just got from the responder. The callback
250 function will receive the processed payload where we will
252 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer,
256 if (status != SILC_SKE_STATUS_OK) {
257 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
259 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
262 protocol->state = SILC_PROTOCOL_STATE_ERROR;
263 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
267 /* Advance protocol state and call next state if we are initiator */
269 if (ctx->responder == FALSE)
270 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
278 if (ctx->responder == TRUE) {
279 /* Process the received Key Exchange 1 Payload packet from
280 the initiator. This also creates our parts of the Diffie
281 Hellman algorithm. */
282 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
285 /* Call the Phase-2 function. This creates Diffie Hellman
286 key exchange parameters and sends our public part inside
287 Key Exhange 1 Payload to the responder. */
289 silc_ske_initiator_phase_2(ctx->ske,
291 silc_server_protocol_ke_send_packet,
295 if (status != SILC_SKE_STATUS_OK) {
296 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
298 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
301 protocol->state = SILC_PROTOCOL_STATE_ERROR;
302 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
306 /* Advance protocol state and call the next state if we are responder */
308 if (ctx->responder == TRUE)
309 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
317 if (ctx->responder == TRUE) {
318 /* This creates the key exchange material and sends our
319 public parts to the initiator inside Key Exchange 2 Payload. */
321 silc_ske_responder_finish(ctx->ske,
322 server->public_key, server->private_key,
323 SILC_SKE_PK_TYPE_SILC,
324 silc_server_protocol_ke_send_packet,
327 /* Finish the protocol. This verifies the Key Exchange 2 payload
328 sent by responder. */
329 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
330 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;
354 case SILC_PROTOCOL_STATE_END:
359 SilcSKEKeyMaterial *keymat;
360 int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
361 int hash_len = ctx->ske->prop->hash->hash->hash_len;
363 /* Process the key material */
364 keymat = silc_calloc(1, sizeof(*keymat));
365 status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
367 if (status != SILC_SKE_STATUS_OK) {
368 protocol->state = SILC_PROTOCOL_STATE_ERROR;
369 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
370 silc_ske_free_key_material(keymat);
373 ctx->keymat = keymat;
375 /* Send Ok to the other end if we are responder. If we are initiator
376 we have sent this already. */
377 if (ctx->responder == TRUE)
378 silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
380 /* Unregister the timeout task since the protocol has ended.
381 This was the timeout task to be executed if the protocol is
382 not completed fast enough. */
383 if (ctx->timeout_task)
384 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
386 /* Call the final callback */
387 if (protocol->final_callback)
388 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
390 silc_protocol_free(protocol);
394 case SILC_PROTOCOL_STATE_ERROR:
399 /* Send abort notification */
400 silc_ske_abort(ctx->ske, ctx->ske->status,
401 silc_server_protocol_ke_send_packet,
404 /* Unregister the timeout task since the protocol has ended.
405 This was the timeout task to be executed if the protocol is
406 not completed fast enough. */
407 if (ctx->timeout_task)
408 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
410 /* On error the final callback is always called. */
411 if (protocol->final_callback)
412 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
414 silc_protocol_free(protocol);
417 case SILC_PROTOCOL_STATE_FAILURE:
419 * We have received failure from remote
422 /* Unregister the timeout task since the protocol has ended.
423 This was the timeout task to be executed if the protocol is
424 not completed fast enough. */
425 if (ctx->timeout_task)
426 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
428 /* On error the final callback is always called. */
429 if (protocol->final_callback)
430 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
432 silc_protocol_free(protocol);
435 case SILC_PROTOCOL_STATE_UNKNOWN:
441 * Connection Authentication protocol functions
444 /* XXX move these to somehwere else */
446 int silc_server_password_authentication(SilcServer server, char *auth1,
449 if (!auth1 || !auth2)
452 if (!memcmp(auth1, auth2, strlen(auth1)))
458 int silc_server_public_key_authentication(SilcServer server,
461 unsigned int sign_len,
464 SilcPublicKey pub_key;
469 if (!pkfile || !sign)
472 /* Load public key from file */
473 if (!silc_pkcs_load_public_key(pkfile, &pub_key, SILC_PKCS_FILE_PEM))
474 if (!silc_pkcs_load_public_key(pkfile, &pub_key, SILC_PKCS_FILE_BIN))
477 silc_pkcs_alloc(pub_key->name, &pkcs);
478 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
479 silc_pkcs_free(pkcs);
483 /* Make the authentication data. Protocol says it is HASH plus
485 len = ske->hash_len + ske->start_payload_copy->len;
486 auth = silc_buffer_alloc(len);
487 silc_buffer_pull_tail(auth, len);
488 silc_buffer_format(auth,
489 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
490 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
491 ske->start_payload_copy->len),
494 /* Verify signature */
495 if (pkcs->pkcs->verify(pkcs->context, sign, sign_len,
496 auth->data, auth->len))
498 silc_pkcs_free(pkcs);
499 silc_pkcs_public_key_free(pub_key);
500 silc_buffer_free(auth);
504 silc_pkcs_free(pkcs);
505 silc_pkcs_public_key_free(pub_key);
506 silc_buffer_free(auth);
510 /* Performs connection authentication protocol. If responder, we
511 authenticate the remote data received. If initiator, we will send
512 authentication data to the remote end. */
514 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
516 SilcProtocol protocol = (SilcProtocol)context;
517 SilcServerConnAuthInternalContext *ctx =
518 (SilcServerConnAuthInternalContext *)protocol->context;
519 SilcServer server = (SilcServer)ctx->server;
521 SILC_LOG_DEBUG(("Start"));
523 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
524 protocol->state = SILC_PROTOCOL_STATE_START;
526 SILC_LOG_DEBUG(("State=%d", protocol->state));
528 switch(protocol->state) {
529 case SILC_PROTOCOL_STATE_START:
535 if (ctx->responder == TRUE) {
537 * We are receiving party
540 unsigned short payload_len;
541 unsigned short conn_type;
542 unsigned char *auth_data;
544 SILC_LOG_INFO(("Performing authentication protocol for %s (%s)",
545 ctx->sock->hostname, ctx->sock->ip));
547 /* Parse the received authentication data packet. The received
548 payload is Connection Auth Payload. */
549 ret = silc_buffer_unformat(ctx->packet->buffer,
550 SILC_STR_UI_SHORT(&payload_len),
551 SILC_STR_UI_SHORT(&conn_type),
554 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
555 protocol->state = SILC_PROTOCOL_STATE_ERROR;
556 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
560 if (payload_len != ctx->packet->buffer->len) {
561 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
562 protocol->state = SILC_PROTOCOL_STATE_ERROR;
563 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
569 if (conn_type < SILC_SOCKET_TYPE_CLIENT ||
570 conn_type > SILC_SOCKET_TYPE_ROUTER) {
571 SILC_LOG_ERROR(("Bad connection type %d", conn_type));
572 protocol->state = SILC_PROTOCOL_STATE_ERROR;
573 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
577 if (payload_len > 0) {
578 /* Get authentication data */
579 silc_buffer_pull(ctx->packet->buffer, 4);
580 ret = silc_buffer_unformat(ctx->packet->buffer,
581 SILC_STR_UI_XNSTRING_ALLOC(&auth_data,
585 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
586 protocol->state = SILC_PROTOCOL_STATE_ERROR;
587 protocol->execute(server->timeout_queue, 0,
588 protocol, fd, 0, 300000);
596 * Check the remote connection type and make sure that we have
597 * configured this connection. If we haven't allowed this connection
598 * the authentication must be failed.
601 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
603 /* Remote end is client */
604 if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
605 SilcServerConfigSectionClientConnection *client = NULL;
607 silc_server_config_find_client_conn(server->config,
612 silc_server_config_find_client_conn(server->config,
617 switch(client->auth_meth) {
619 /* No authentication required */
620 SILC_LOG_DEBUG(("No authentication required"));
623 case SILC_AUTH_PASSWORD:
624 /* Password authentication */
625 SILC_LOG_DEBUG(("Password authentication"));
626 ret = silc_server_password_authentication(server, auth_data,
630 memset(auth_data, 0, payload_len);
631 silc_free(auth_data);
636 /* Authentication failed */
637 SILC_LOG_ERROR(("Authentication failed"));
638 SILC_LOG_DEBUG(("Authentication failed"));
639 protocol->state = SILC_PROTOCOL_STATE_ERROR;
640 protocol->execute(server->timeout_queue, 0,
641 protocol, fd, 0, 300000);
645 case SILC_AUTH_PUBLIC_KEY:
646 /* Public key authentication */
647 SILC_LOG_DEBUG(("Public key authentication"));
648 ret = silc_server_public_key_authentication(server,
655 memset(auth_data, 0, payload_len);
656 silc_free(auth_data);
661 SILC_LOG_ERROR(("Authentication failed"));
662 SILC_LOG_DEBUG(("Authentication failed"));
663 protocol->state = SILC_PROTOCOL_STATE_ERROR;
664 protocol->execute(server->timeout_queue, 0,
665 protocol, fd, 0, 300000);
669 SILC_LOG_DEBUG(("No configuration for remote connection"));
670 SILC_LOG_ERROR(("Remote connection not configured"));
671 SILC_LOG_ERROR(("Authentication failed"));
672 memset(auth_data, 0, payload_len);
673 silc_free(auth_data);
675 protocol->state = SILC_PROTOCOL_STATE_ERROR;
676 protocol->execute(server->timeout_queue, 0,
677 protocol, fd, 0, 300000);
682 /* Remote end is server */
683 if (conn_type == SILC_SOCKET_TYPE_SERVER) {
684 SilcServerConfigSectionServerConnection *serv = NULL;
686 silc_server_config_find_server_conn(server->config,
691 silc_server_config_find_server_conn(server->config,
696 switch(serv->auth_meth) {
698 /* No authentication required */
699 SILC_LOG_DEBUG(("No authentication required"));
702 case SILC_AUTH_PASSWORD:
703 /* Password authentication */
704 SILC_LOG_DEBUG(("Password authentication"));
705 ret = silc_server_password_authentication(server, auth_data,
709 memset(auth_data, 0, payload_len);
710 silc_free(auth_data);
715 /* Authentication failed */
716 SILC_LOG_ERROR(("Authentication failed"));
717 SILC_LOG_DEBUG(("Authentication failed"));
718 protocol->state = SILC_PROTOCOL_STATE_ERROR;
719 protocol->execute(server->timeout_queue, 0,
720 protocol, fd, 0, 300000);
724 case SILC_AUTH_PUBLIC_KEY:
725 /* Public key authentication */
726 SILC_LOG_DEBUG(("Public key authentication"));
727 ret = silc_server_public_key_authentication(server,
734 memset(auth_data, 0, payload_len);
735 silc_free(auth_data);
740 SILC_LOG_ERROR(("Authentication failed"));
741 SILC_LOG_DEBUG(("Authentication failed"));
742 protocol->state = SILC_PROTOCOL_STATE_ERROR;
743 protocol->execute(server->timeout_queue, 0,
744 protocol, fd, 0, 300000);
748 SILC_LOG_DEBUG(("No configuration for remote connection"));
749 SILC_LOG_ERROR(("Remote connection not configured"));
750 SILC_LOG_ERROR(("Authentication failed"));
751 memset(auth_data, 0, payload_len);
752 silc_free(auth_data);
754 protocol->state = SILC_PROTOCOL_STATE_ERROR;
755 protocol->execute(server->timeout_queue, 0,
756 protocol, fd, 0, 300000);
761 /* Remote end is router */
762 if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
763 SilcServerConfigSectionServerConnection *serv = NULL;
765 silc_server_config_find_router_conn(server->config,
770 silc_server_config_find_router_conn(server->config,
775 switch(serv->auth_meth) {
777 /* No authentication required */
778 SILC_LOG_DEBUG(("No authentication required"));
781 case SILC_AUTH_PASSWORD:
782 /* Password authentication */
783 SILC_LOG_DEBUG(("Password authentication"));
784 ret = silc_server_password_authentication(server, auth_data,
788 memset(auth_data, 0, payload_len);
789 silc_free(auth_data);
794 /* Authentication failed */
795 SILC_LOG_ERROR(("Authentication failed"));
796 SILC_LOG_DEBUG(("Authentication failed"));
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,
813 memset(auth_data, 0, payload_len);
814 silc_free(auth_data);
819 SILC_LOG_ERROR(("Authentication failed"));
820 SILC_LOG_DEBUG(("Authentication failed"));
821 protocol->state = SILC_PROTOCOL_STATE_ERROR;
822 protocol->execute(server->timeout_queue, 0,
823 protocol, fd, 0, 300000);
827 SILC_LOG_DEBUG(("No configuration for remote connection"));
828 SILC_LOG_ERROR(("Remote connection not configured"));
829 SILC_LOG_ERROR(("Authentication failed"));
830 memset(auth_data, 0, payload_len);
831 silc_free(auth_data);
833 protocol->state = SILC_PROTOCOL_STATE_ERROR;
834 protocol->execute(server->timeout_queue, 0,
835 protocol, fd, 0, 300000);
841 memset(auth_data, 0, payload_len);
842 silc_free(auth_data);
845 /* Save connection type. This is later used to create the
846 ID for the connection. */
847 ctx->conn_type = conn_type;
849 /* Advance protocol state. */
850 protocol->state = SILC_PROTOCOL_STATE_END;
851 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
855 * We are initiator. We are authenticating ourselves to a
856 * remote server. We will send the authentication data to the
857 * other end for verify.
861 unsigned char *auth_data = NULL;
862 unsigned int auth_data_len = 0;
864 switch(ctx->auth_meth) {
866 /* No authentication required */
869 case SILC_AUTH_PASSWORD:
870 /* Password authentication */
871 if (ctx->auth_data && ctx->auth_data_len) {
872 auth_data = ctx->auth_data;
873 auth_data_len = ctx->auth_data_len;
877 /* No authentication data exits. Ask interactively from user. */
882 case SILC_AUTH_PUBLIC_KEY:
883 /* Public key authentication */
888 payload_len = 4 + auth_data_len;
889 packet = silc_buffer_alloc(payload_len);
890 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
891 silc_buffer_format(packet,
892 SILC_STR_UI_SHORT(payload_len),
893 SILC_STR_UI_SHORT(server->server_type
895 SILC_SOCKET_TYPE_SERVER :
896 SILC_SOCKET_TYPE_ROUTER),
897 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
900 /* Send the packet to server */
901 silc_server_packet_send(server, ctx->sock,
902 SILC_PACKET_CONNECTION_AUTH, 0,
903 packet->data, packet->len, TRUE);
906 memset(auth_data, 0, auth_data_len);
907 silc_free(auth_data);
909 silc_buffer_free(packet);
911 /* Next state is end of protocol */
912 protocol->state = SILC_PROTOCOL_STATE_END;
917 case SILC_PROTOCOL_STATE_END:
924 SILC_PUT32_MSB(SILC_AUTH_OK, ok);
926 /* Authentication failed */
927 silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS,
930 /* Unregister the timeout task since the protocol has ended.
931 This was the timeout task to be executed if the protocol is
932 not completed fast enough. */
933 if (ctx->timeout_task)
934 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
936 /* Protocol has ended, call the final callback */
937 if (protocol->final_callback)
938 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
940 silc_protocol_free(protocol);
943 case SILC_PROTOCOL_STATE_ERROR:
946 * Error. Send notify to remote.
948 unsigned char error[4];
950 SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
952 /* Authentication failed */
953 silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
956 /* Unregister the timeout task since the protocol has ended.
957 This was the timeout task to be executed if the protocol is
958 not completed fast enough. */
959 if (ctx->timeout_task)
960 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
962 /* On error the final callback is always called. */
963 if (protocol->final_callback)
964 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
966 silc_protocol_free(protocol);
970 case SILC_PROTOCOL_STATE_FAILURE:
972 * We have received failure from remote
975 /* Unregister the timeout task since the protocol has ended.
976 This was the timeout task to be executed if the protocol is
977 not completed fast enough. */
978 if (ctx->timeout_task)
979 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
981 /* On error the final callback is always called. */
982 if (protocol->final_callback)
983 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
985 silc_protocol_free(protocol);
988 case SILC_PROTOCOL_STATE_UNKNOWN:
993 /* Registers protocols used in server. */
995 void silc_server_protocols_register(void)
997 silc_protocol_register(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
998 silc_server_protocol_connection_auth);
999 silc_protocol_register(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1000 silc_server_protocol_key_exchange);
1003 /* Unregisters protocols */
1005 void silc_server_protocols_unregister(void)
1007 silc_protocol_unregister(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
1008 silc_server_protocol_connection_auth);
1009 silc_protocol_unregister(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1010 silc_server_protocol_key_exchange);