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 static int silc_server_protocol_ke_set_keys(SilcSKE ske,
58 SilcSocketConnection sock,
59 SilcSKEKeyMaterial *keymat,
65 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_hash_alloc(hash->hash->name, &nhash)) {
118 silc_cipher_free(idata->send_key);
119 silc_cipher_free(idata->receive_key);
120 silc_free(conn_data);
123 silc_hmac_alloc(nhash, &idata->hmac);
124 silc_hmac_set_key(idata->hmac, keymat->hmac_key, keymat->hmac_key_len);
126 sock->user_data = (void *)conn_data;
131 /* Check remote host version string */
133 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
136 SilcSKEStatus status = SILC_SKE_STATUS_OK;
138 /* Check for initial version string */
139 if (!strstr(version, "SILC-1.0-"))
140 status = SILC_SKE_STATUS_BAD_VERSION;
142 /* Check software version */
144 if (len < strlen(silc_version_string))
145 status = SILC_SKE_STATUS_BAD_VERSION;
147 /* XXX for now there is no other tests due to the abnormal version
148 string that is used */
153 /* Performs key exchange protocol. This is used for both initiator
154 and responder key exchange. This is performed always when accepting
155 new connection to the server. This may be called recursively. */
157 SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
159 SilcProtocol protocol = (SilcProtocol)context;
160 SilcServerKEInternalContext *ctx =
161 (SilcServerKEInternalContext *)protocol->context;
162 SilcServer server = (SilcServer)ctx->server;
163 SilcSKEStatus status = 0;
165 SILC_LOG_DEBUG(("Start"));
167 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
168 protocol->state = SILC_PROTOCOL_STATE_START;
170 SILC_LOG_DEBUG(("State=%d", protocol->state));
172 switch(protocol->state) {
173 case SILC_PROTOCOL_STATE_START:
180 /* Allocate Key Exchange object */
181 ske = silc_ske_alloc();
183 ske->rng = server->rng;
185 if (ctx->responder == TRUE) {
186 /* Start the key exchange by processing the received security
187 properties packet from initiator. */
188 status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
190 ctx->packet->buffer, NULL, NULL);
192 SilcSKEStartPayload *start_payload;
194 /* Assemble security properties. */
195 silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
199 /* Start the key exchange by sending our security properties
200 to the remote end. */
201 status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
203 silc_server_protocol_ke_send_packet,
207 if (status != SILC_SKE_STATUS_OK) {
208 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
210 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
213 protocol->state = SILC_PROTOCOL_STATE_ERROR;
214 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
218 /* Advance protocol state and call the next state if we are responder */
220 if (ctx->responder == TRUE)
221 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
229 if (ctx->responder == TRUE) {
230 /* Sends the selected security properties to the initiator. */
232 silc_ske_responder_phase_1(ctx->ske,
233 ctx->ske->start_payload,
234 silc_server_protocol_ke_send_packet,
237 /* Call Phase-1 function. This processes the Key Exchange Start
238 paylaod reply we just got from the responder. The callback
239 function will receive the processed payload where we will
241 status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer,
245 if (status != SILC_SKE_STATUS_OK) {
246 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
248 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
251 protocol->state = SILC_PROTOCOL_STATE_ERROR;
252 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
256 /* Advance protocol state and call next state if we are initiator */
258 if (ctx->responder == FALSE)
259 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
267 if (ctx->responder == TRUE) {
268 /* Process the received Key Exchange 1 Payload packet from
269 the initiator. This also creates our parts of the Diffie
270 Hellman algorithm. */
271 status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
274 /* Call the Phase-2 function. This creates Diffie Hellman
275 key exchange parameters and sends our public part inside
276 Key Exhange 1 Payload to the responder. */
278 silc_ske_initiator_phase_2(ctx->ske,
280 silc_server_protocol_ke_send_packet,
284 if (status != SILC_SKE_STATUS_OK) {
285 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
287 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
290 protocol->state = SILC_PROTOCOL_STATE_ERROR;
291 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
295 /* Advance protocol state and call the next state if we are responder */
297 if (ctx->responder == TRUE)
298 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 100000);
306 if (ctx->responder == TRUE) {
307 /* This creates the key exchange material and sends our
308 public parts to the initiator inside Key Exchange 2 Payload. */
310 silc_ske_responder_finish(ctx->ske,
311 server->public_key, server->private_key,
312 SILC_SKE_PK_TYPE_SILC,
313 silc_server_protocol_ke_send_packet,
316 /* Finish the protocol. This verifies the Key Exchange 2 payload
317 sent by responder. */
318 status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
319 NULL, NULL, NULL, NULL);
322 if (status != SILC_SKE_STATUS_OK) {
323 SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
325 SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
328 protocol->state = SILC_PROTOCOL_STATE_ERROR;
329 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
333 /* Send Ok to the other end. We will end the protocol as responder
334 sends Ok to us when we will take the new keys into use. */
335 if (ctx->responder == FALSE)
336 silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
338 /* End the protocol on the next round */
339 protocol->state = SILC_PROTOCOL_STATE_END;
343 case SILC_PROTOCOL_STATE_END:
348 SilcSKEKeyMaterial *keymat;
350 /* Send Ok to the other end if we are responder. If we are
351 initiator we have sent this already. */
352 if (ctx->responder == TRUE)
353 silc_ske_end(ctx->ske, silc_server_protocol_ke_send_packet, context);
355 /* Process the key material */
356 keymat = silc_calloc(1, sizeof(*keymat));
357 silc_ske_process_key_material(ctx->ske, 16, (16 * 8), 16, keymat);
359 /* Take the new keys into use. */
360 if (!silc_server_protocol_ke_set_keys(ctx->ske, ctx->sock, keymat,
361 ctx->ske->prop->cipher,
362 ctx->ske->prop->pkcs,
363 ctx->ske->prop->hash,
365 protocol->state = SILC_PROTOCOL_STATE_ERROR;
366 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
370 /* Unregister the timeout task since the protocol has ended.
371 This was the timeout task to be executed if the protocol is
372 not completed fast enough. */
373 if (ctx->timeout_task)
374 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
376 /* Call the final callback */
377 if (protocol->final_callback)
378 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
380 silc_protocol_free(protocol);
384 case SILC_PROTOCOL_STATE_ERROR:
389 /* Send abort notification */
390 silc_ske_abort(ctx->ske, ctx->ske->status,
391 silc_server_protocol_ke_send_packet,
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);
407 case SILC_PROTOCOL_STATE_FAILURE:
409 * We have received failure from remote
412 /* Unregister the timeout task since the protocol has ended.
413 This was the timeout task to be executed if the protocol is
414 not completed fast enough. */
415 if (ctx->timeout_task)
416 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
418 /* On error the final callback is always called. */
419 if (protocol->final_callback)
420 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
422 silc_protocol_free(protocol);
425 case SILC_PROTOCOL_STATE_UNKNOWN:
431 * Connection Authentication protocol functions
434 /* XXX move these to somehwere else */
436 int silc_server_password_authentication(SilcServer server, char *auth1,
439 if (!auth1 || !auth2)
442 if (!memcmp(auth1, auth2, strlen(auth1)))
448 int silc_server_public_key_authentication(SilcServer server,
451 unsigned int sign_len,
454 SilcPublicKey pub_key;
459 if (!pkfile || !sign)
462 /* Load public key from file */
463 if (!silc_pkcs_load_public_key(pkfile, &pub_key, SILC_PKCS_FILE_PEM))
464 if (!silc_pkcs_load_public_key(pkfile, &pub_key, SILC_PKCS_FILE_BIN))
467 silc_pkcs_alloc(pub_key->name, &pkcs);
468 if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
469 silc_pkcs_free(pkcs);
473 /* Make the authentication data. Protocol says it is HASH plus
475 len = ske->hash_len + ske->start_payload_copy->len;
476 auth = silc_buffer_alloc(len);
477 silc_buffer_pull_tail(auth, len);
478 silc_buffer_format(auth,
479 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
480 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
481 ske->start_payload_copy->len),
484 /* Verify signature */
485 if (pkcs->pkcs->verify(pkcs->context, sign, sign_len,
486 auth->data, auth->len))
488 silc_pkcs_free(pkcs);
489 silc_pkcs_public_key_free(pub_key);
490 silc_buffer_free(auth);
494 silc_pkcs_free(pkcs);
495 silc_pkcs_public_key_free(pub_key);
496 silc_buffer_free(auth);
500 /* Performs connection authentication protocol. If responder, we
501 authenticate the remote data received. If initiator, we will send
502 authentication data to the remote end. */
504 SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
506 SilcProtocol protocol = (SilcProtocol)context;
507 SilcServerConnAuthInternalContext *ctx =
508 (SilcServerConnAuthInternalContext *)protocol->context;
509 SilcServer server = (SilcServer)ctx->server;
511 SILC_LOG_DEBUG(("Start"));
513 if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
514 protocol->state = SILC_PROTOCOL_STATE_START;
516 SILC_LOG_DEBUG(("State=%d", protocol->state));
518 switch(protocol->state) {
519 case SILC_PROTOCOL_STATE_START:
525 if (ctx->responder == TRUE) {
527 * We are receiving party
530 unsigned short payload_len;
531 unsigned short conn_type;
532 unsigned char *auth_data;
534 SILC_LOG_INFO(("Performing authentication protocol for %s (%s)",
535 ctx->sock->hostname, ctx->sock->ip));
537 /* Parse the received authentication data packet. The received
538 payload is Connection Auth Payload. */
539 ret = silc_buffer_unformat(ctx->packet->buffer,
540 SILC_STR_UI_SHORT(&payload_len),
541 SILC_STR_UI_SHORT(&conn_type),
544 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
545 protocol->state = SILC_PROTOCOL_STATE_ERROR;
546 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
550 if (payload_len != ctx->packet->buffer->len) {
551 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
552 protocol->state = SILC_PROTOCOL_STATE_ERROR;
553 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
559 if (conn_type < SILC_SOCKET_TYPE_CLIENT ||
560 conn_type > SILC_SOCKET_TYPE_ROUTER) {
561 SILC_LOG_ERROR(("Bad connection type %d", conn_type));
562 protocol->state = SILC_PROTOCOL_STATE_ERROR;
563 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 300000);
567 if (payload_len > 0) {
568 /* Get authentication data */
569 silc_buffer_pull(ctx->packet->buffer, 4);
570 ret = silc_buffer_unformat(ctx->packet->buffer,
571 SILC_STR_UI_XNSTRING_ALLOC(&auth_data,
575 SILC_LOG_DEBUG(("Bad payload in authentication packet"));
576 protocol->state = SILC_PROTOCOL_STATE_ERROR;
577 protocol->execute(server->timeout_queue, 0,
578 protocol, fd, 0, 300000);
586 * Check the remote connection type and make sure that we have
587 * configured this connection. If we haven't allowed this connection
588 * the authentication must be failed.
591 SILC_LOG_DEBUG(("Remote connection type %d", conn_type));
593 /* Remote end is client */
594 if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
595 SilcConfigServerSectionClientConnection *client = NULL;
597 silc_config_server_find_client_conn(server->config,
602 silc_config_server_find_client_conn(server->config,
607 switch(client->auth_meth) {
608 case SILC_PROTOCOL_CONN_AUTH_NONE:
609 /* No authentication required */
610 SILC_LOG_DEBUG(("No authentication required"));
613 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
614 /* Password authentication */
615 SILC_LOG_DEBUG(("Password authentication"));
616 ret = silc_server_password_authentication(server, auth_data,
620 memset(auth_data, 0, payload_len);
621 silc_free(auth_data);
626 /* Authentication failed */
627 SILC_LOG_ERROR(("Authentication failed"));
628 SILC_LOG_DEBUG(("Authentication failed"));
629 protocol->state = SILC_PROTOCOL_STATE_ERROR;
630 protocol->execute(server->timeout_queue, 0,
631 protocol, fd, 0, 300000);
635 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
636 /* Public key authentication */
637 SILC_LOG_DEBUG(("Public key authentication"));
638 ret = silc_server_public_key_authentication(server,
645 memset(auth_data, 0, payload_len);
646 silc_free(auth_data);
651 SILC_LOG_ERROR(("Authentication failed"));
652 SILC_LOG_DEBUG(("Authentication failed"));
653 protocol->state = SILC_PROTOCOL_STATE_ERROR;
654 protocol->execute(server->timeout_queue, 0,
655 protocol, fd, 0, 300000);
659 SILC_LOG_DEBUG(("No configuration for remote connection"));
660 SILC_LOG_ERROR(("Remote connection not configured"));
661 SILC_LOG_ERROR(("Authentication failed"));
662 memset(auth_data, 0, payload_len);
663 silc_free(auth_data);
665 protocol->state = SILC_PROTOCOL_STATE_ERROR;
666 protocol->execute(server->timeout_queue, 0,
667 protocol, fd, 0, 300000);
672 /* Remote end is server */
673 if (conn_type == SILC_SOCKET_TYPE_SERVER) {
674 SilcConfigServerSectionServerConnection *serv = NULL;
676 silc_config_server_find_server_conn(server->config,
681 silc_config_server_find_server_conn(server->config,
686 switch(serv->auth_meth) {
687 case SILC_PROTOCOL_CONN_AUTH_NONE:
688 /* No authentication required */
689 SILC_LOG_DEBUG(("No authentication required"));
692 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
693 /* Password authentication */
694 SILC_LOG_DEBUG(("Password authentication"));
695 ret = silc_server_password_authentication(server, auth_data,
699 memset(auth_data, 0, payload_len);
700 silc_free(auth_data);
705 /* Authentication failed */
706 SILC_LOG_ERROR(("Authentication failed"));
707 SILC_LOG_DEBUG(("Authentication failed"));
708 protocol->state = SILC_PROTOCOL_STATE_ERROR;
709 protocol->execute(server->timeout_queue, 0,
710 protocol, fd, 0, 300000);
714 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
715 /* Public key authentication */
716 SILC_LOG_DEBUG(("Public key authentication"));
717 ret = silc_server_public_key_authentication(server,
724 memset(auth_data, 0, payload_len);
725 silc_free(auth_data);
730 SILC_LOG_ERROR(("Authentication failed"));
731 SILC_LOG_DEBUG(("Authentication failed"));
732 protocol->state = SILC_PROTOCOL_STATE_ERROR;
733 protocol->execute(server->timeout_queue, 0,
734 protocol, fd, 0, 300000);
738 SILC_LOG_DEBUG(("No configuration for remote connection"));
739 SILC_LOG_ERROR(("Remote connection not configured"));
740 SILC_LOG_ERROR(("Authentication failed"));
741 memset(auth_data, 0, payload_len);
742 silc_free(auth_data);
744 protocol->state = SILC_PROTOCOL_STATE_ERROR;
745 protocol->execute(server->timeout_queue, 0,
746 protocol, fd, 0, 300000);
751 /* Remote end is router */
752 if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
753 SilcConfigServerSectionServerConnection *serv = NULL;
755 silc_config_server_find_router_conn(server->config,
760 silc_config_server_find_router_conn(server->config,
765 switch(serv->auth_meth) {
766 case SILC_PROTOCOL_CONN_AUTH_NONE:
767 /* No authentication required */
768 SILC_LOG_DEBUG(("No authentication required"));
771 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
772 /* Password authentication */
773 SILC_LOG_DEBUG(("Password authentication"));
774 ret = silc_server_password_authentication(server, auth_data,
778 memset(auth_data, 0, payload_len);
779 silc_free(auth_data);
784 /* Authentication failed */
785 SILC_LOG_ERROR(("Authentication failed"));
786 SILC_LOG_DEBUG(("Authentication failed"));
787 protocol->state = SILC_PROTOCOL_STATE_ERROR;
788 protocol->execute(server->timeout_queue, 0,
789 protocol, fd, 0, 300000);
793 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
794 /* Public key authentication */
795 SILC_LOG_DEBUG(("Public key authentication"));
796 ret = silc_server_public_key_authentication(server,
803 memset(auth_data, 0, payload_len);
804 silc_free(auth_data);
809 SILC_LOG_ERROR(("Authentication failed"));
810 SILC_LOG_DEBUG(("Authentication failed"));
811 protocol->state = SILC_PROTOCOL_STATE_ERROR;
812 protocol->execute(server->timeout_queue, 0,
813 protocol, fd, 0, 300000);
817 SILC_LOG_DEBUG(("No configuration for remote connection"));
818 SILC_LOG_ERROR(("Remote connection not configured"));
819 SILC_LOG_ERROR(("Authentication failed"));
820 memset(auth_data, 0, payload_len);
821 silc_free(auth_data);
823 protocol->state = SILC_PROTOCOL_STATE_ERROR;
824 protocol->execute(server->timeout_queue, 0,
825 protocol, fd, 0, 300000);
831 memset(auth_data, 0, payload_len);
832 silc_free(auth_data);
835 /* Save connection type. This is later used to create the
836 ID for the connection. */
837 ctx->conn_type = conn_type;
839 /* Advance protocol state. */
840 protocol->state = SILC_PROTOCOL_STATE_END;
841 protocol->execute(server->timeout_queue, 0, protocol, fd, 0, 0);
845 * We are initiator. We are authenticating ourselves to a
846 * remote server. We will send the authentication data to the
847 * other end for verify.
851 unsigned char *auth_data = NULL;
852 unsigned int auth_data_len = 0;
854 switch(ctx->auth_meth) {
855 case SILC_PROTOCOL_CONN_AUTH_NONE:
856 /* No authentication required */
859 case SILC_PROTOCOL_CONN_AUTH_PASSWORD:
860 /* Password authentication */
861 if (ctx->auth_data && ctx->auth_data_len) {
862 auth_data = ctx->auth_data;
863 auth_data_len = ctx->auth_data_len;
867 /* No authentication data exits. Ask interactively from user. */
872 case SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY:
873 /* Public key authentication */
878 payload_len = 4 + auth_data_len;
879 packet = silc_buffer_alloc(payload_len);
880 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
881 silc_buffer_format(packet,
882 SILC_STR_UI_SHORT(payload_len),
883 SILC_STR_UI_SHORT(server->server_type
885 SILC_SOCKET_TYPE_SERVER :
886 SILC_SOCKET_TYPE_ROUTER),
887 SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
890 /* Send the packet to server */
891 silc_server_packet_send(server, ctx->sock,
892 SILC_PACKET_CONNECTION_AUTH, 0,
893 packet->data, packet->len, TRUE);
896 memset(auth_data, 0, auth_data_len);
897 silc_free(auth_data);
899 silc_buffer_free(packet);
901 /* Next state is end of protocol */
902 protocol->state = SILC_PROTOCOL_STATE_END;
907 case SILC_PROTOCOL_STATE_END:
914 SILC_PUT32_MSB(SILC_CONN_AUTH_OK, ok);
916 /* Authentication failed */
917 silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS,
920 /* Unregister the timeout task since the protocol has ended.
921 This was the timeout task to be executed if the protocol is
922 not completed fast enough. */
923 if (ctx->timeout_task)
924 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
926 /* Protocol has ended, call the final callback */
927 if (protocol->final_callback)
928 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
930 silc_protocol_free(protocol);
933 case SILC_PROTOCOL_STATE_ERROR:
936 * Error. Send notify to remote.
938 unsigned char error[4];
940 SILC_PUT32_MSB(SILC_CONN_AUTH_FAILED, error);
942 /* Authentication failed */
943 silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
946 /* Unregister the timeout task since the protocol has ended.
947 This was the timeout task to be executed if the protocol is
948 not completed fast enough. */
949 if (ctx->timeout_task)
950 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
952 /* On error the final callback is always called. */
953 if (protocol->final_callback)
954 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
956 silc_protocol_free(protocol);
960 case SILC_PROTOCOL_STATE_FAILURE:
962 * We have received failure from remote
965 /* Unregister the timeout task since the protocol has ended.
966 This was the timeout task to be executed if the protocol is
967 not completed fast enough. */
968 if (ctx->timeout_task)
969 silc_task_unregister(server->timeout_queue, ctx->timeout_task);
971 /* On error the final callback is always called. */
972 if (protocol->final_callback)
973 protocol->execute_final(server->timeout_queue, 0, protocol, fd);
975 silc_protocol_free(protocol);
978 case SILC_PROTOCOL_STATE_UNKNOWN:
983 /* Registers protocols used in server. */
985 void silc_server_protocols_register(void)
987 silc_protocol_register(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
988 silc_server_protocol_connection_auth);
989 silc_protocol_register(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
990 silc_server_protocol_key_exchange);
993 /* Unregisters protocols */
995 void silc_server_protocols_unregister(void)
997 silc_protocol_unregister(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
998 silc_server_protocol_connection_auth);
999 silc_protocol_unregister(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
1000 silc_server_protocol_key_exchange);