Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2002 Pekka Riikonen
+ Copyright (C) 1997 - 2003 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Key Exhange protocol functions
*/
-static bool
+static bool
silc_verify_public_key_internal(SilcServer server, SilcSocketConnection sock,
SilcSocketType conn_type,
- unsigned char *pk, SilcUInt32 pk_len,
+ unsigned char *pk, SilcUInt32 pk_len,
SilcSKEPKType pk_type)
{
char file[256], filename[256], *fingerprint;
struct stat st;
if (pk_type != SILC_SKE_PK_TYPE_SILC) {
- SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
+ SILC_LOG_WARNING(("We don't support %s (%s) port %d public key type %d",
sock->hostname, sock->ip, sock->port, pk_type));
return FALSE;
}
conn auth protocol with public key we MUST have the key already. */
return TRUE;
/* Rest is unreachable code! */
-
+
memset(filename, 0, sizeof(filename));
memset(file, 0, sizeof(file));
- snprintf(file, sizeof(file) - 1, "serverkey_%s_%d.pub", sock->hostname,
+ snprintf(file, sizeof(file) - 1, "serverkey_%s_%d.pub", sock->hostname,
sock->port);
- snprintf(filename, sizeof(filename) - 1, SILC_ETCDIR "/serverkeys/%s",
+ snprintf(filename, sizeof(filename) - 1, SILC_ETCDIR "/serverkeys/%s",
file);
/* Create serverkeys directory if it doesn't exist. */
if (stat(SILC_ETCDIR "/serverkeys", &st) < 0) {
/* If dir doesn't exist */
- if (errno == ENOENT) {
+ if (errno == ENOENT) {
if (mkdir(SILC_ETCDIR "/serverkeys", 0755) < 0) {
- SILC_LOG_ERROR(("Couldn't create `%s' directory\n",
+ SILC_LOG_ERROR(("Couldn't create `%s' directory\n",
SILC_ETCDIR "/serverkeys"));
return TRUE;
}
/* Take fingerprint of the public key */
fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- SILC_LOG_DEBUG(("Received server %s (%s) port %d public key (%s)",
+ SILC_LOG_DEBUG(("Received server %s (%s) port %d public key (%s)",
sock->hostname, sock->ip, sock->port, fingerprint));
silc_free(fingerprint);
/* We don't have it, then cache it. */
SILC_LOG_DEBUG(("New public key from server"));
- silc_pkcs_save_public_key_data(filename, pk, pk_len,
+ silc_pkcs_save_public_key_data(filename, pk, pk_len,
SILC_PKCS_FILE_PEM);
return TRUE;
} else {
SILC_LOG_DEBUG(("We have the public key saved locally"));
/* Load the key file */
- if (!silc_pkcs_load_public_key(filename, &public_key,
+ if (!silc_pkcs_load_public_key(filename, &public_key,
SILC_PKCS_FILE_PEM))
- if (!silc_pkcs_load_public_key(filename, &public_key,
+ if (!silc_pkcs_load_public_key(filename, &public_key,
SILC_PKCS_FILE_BIN)) {
SILC_LOG_WARNING(("Could not load local copy of the %s (%s) port %d "
- "server public key", sock->hostname, sock->ip,
+ "server public key", sock->hostname, sock->ip,
sock->port));
/* Save the key for future checking */
SILC_PKCS_FILE_PEM);
return TRUE;
}
-
+
/* Encode the key data */
encpk = silc_pkcs_public_key_encode(public_key, &encpk_len);
if (!encpk) {
if (memcmp(pk, encpk, encpk_len)) {
SILC_LOG_WARNING(("%s (%s) port %d server public key does not match "
- "with local copy", sock->hostname, sock->ip,
+ "with local copy", sock->hostname, sock->ip,
sock->port));
SILC_LOG_WARNING(("It is possible that the key has expired or changed"));
SILC_LOG_WARNING(("It is also possible that some one is performing "
/* Callback that is called when we have received KE2 payload from
responder. We try to verify the public key now. */
-static void
+static void
silc_server_protocol_ke_verify_key(SilcSKE ske,
unsigned char *pk_data,
SilcUInt32 pk_len,
void *completion_context)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcServerKEInternalContext *ctx =
+ SilcServerKEInternalContext *ctx =
(SilcServerKEInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
SILC_LOG_DEBUG(("Verifying received public key"));
if (silc_verify_public_key_internal(
- server, ctx->sock,
+ server, ctx->sock,
(ctx->responder == FALSE ?
SILC_SOCKET_TYPE_ROUTER:
ctx->sconfig.ref_ptr ? SILC_SOCKET_TYPE_SERVER :
pk_data, pk_len, pk_type))
completion(ske, SILC_SKE_STATUS_OK, completion_context);
else
- completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
+ completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
completion_context);
}
void *context)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcServerKEInternalContext *ctx =
+ SilcServerKEInternalContext *ctx =
(SilcServerKEInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
SILC_LOG_ERROR(("Cannot allocate algorithm: %s", cname));
return FALSE;
}
-
- if (!silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL,
+
+ if (!silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL,
&idata->hmac_send)) {
silc_cipher_free(idata->send_key);
silc_cipher_free(idata->receive_key);
silc_free(conn_data);
- SILC_LOG_ERROR(("Cannot allocate algorithm: %s",
+ SILC_LOG_ERROR(("Cannot allocate algorithm: %s",
silc_hmac_get_name(hmac)));
return FALSE;
}
- if (!silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL,
+ if (!silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL,
&idata->hmac_receive)) {
silc_cipher_free(idata->send_key);
silc_cipher_free(idata->receive_key);
silc_hmac_free(idata->hmac_send);
silc_free(conn_data);
- SILC_LOG_ERROR(("Cannot allocate algorithm: %s",
+ SILC_LOG_ERROR(("Cannot allocate algorithm: %s",
silc_hmac_get_name(hmac)));
return FALSE;
}
if (is_responder == TRUE) {
- silc_cipher_set_key(idata->send_key, keymat->receive_enc_key,
+ silc_cipher_set_key(idata->send_key, keymat->receive_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(idata->send_key, keymat->receive_iv);
- silc_cipher_set_key(idata->receive_key, keymat->send_enc_key,
+ silc_cipher_set_key(idata->receive_key, keymat->send_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(idata->receive_key, keymat->send_iv);
- silc_hmac_set_key(idata->hmac_send, keymat->receive_hmac_key,
+ silc_hmac_set_key(idata->hmac_send, keymat->receive_hmac_key,
keymat->hmac_key_len);
- silc_hmac_set_key(idata->hmac_receive, keymat->send_hmac_key,
+ silc_hmac_set_key(idata->hmac_receive, keymat->send_hmac_key,
keymat->hmac_key_len);
} else {
- silc_cipher_set_key(idata->send_key, keymat->send_enc_key,
+ silc_cipher_set_key(idata->send_key, keymat->send_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(idata->send_key, keymat->send_iv);
- silc_cipher_set_key(idata->receive_key, keymat->receive_enc_key,
+ silc_cipher_set_key(idata->receive_key, keymat->receive_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(idata->receive_key, keymat->receive_iv);
- silc_hmac_set_key(idata->hmac_send, keymat->send_hmac_key,
+ silc_hmac_set_key(idata->hmac_send, keymat->send_hmac_key,
keymat->hmac_key_len);
- silc_hmac_set_key(idata->hmac_receive, keymat->receive_hmac_key,
+ silc_hmac_set_key(idata->hmac_receive, keymat->receive_hmac_key,
keymat->hmac_key_len);
}
silc_hmac_free(idata->hmac_send);
silc_hmac_free(idata->hmac_receive);
silc_free(conn_data);
- SILC_LOG_ERROR(("Cannot allocate algorithm: %s",
+ SILC_LOG_ERROR(("Cannot allocate algorithm: %s",
silc_hash_get_name(hash)));
return FALSE;
}
/* Save the remote host's public key */
- silc_pkcs_public_key_decode(ske->ke1_payload->pk_data,
+ silc_pkcs_public_key_decode(ske->ke1_payload->pk_data,
ske->ke1_payload->pk_len, &idata->public_key);
if (ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL)
silc_hash_make(server->sha1hash, ske->ke1_payload->pk_data,
sock->user_data = (void *)conn_data;
- SILC_LOG_INFO(("%s (%s) security properties: %s %s %s %s",
+ SILC_LOG_INFO(("%s (%s) security properties: %s %s %s %s",
sock->hostname, sock->ip,
silc_cipher_get_name(idata->send_key),
(char *)silc_hmac_get_name(idata->hmac_send),
if (!silc_parse_version_string(version, &r_protocol_version, NULL, NULL,
NULL, NULL)) {
- SILC_LOG_ERROR(("%s (%s) %s is not allowed/supported version",
+ SILC_LOG_ERROR(("%s (%s) %s is not allowed/supported version",
ske->sock->hostname, ske->sock->ip, version));
return SILC_SKE_STATUS_BAD_VERSION;
}
- if (!silc_parse_version_string(silc_version_string,
+ if (!silc_parse_version_string(silc_version_string,
&l_protocol_version, NULL, NULL,
NULL, NULL)) {
- SILC_LOG_ERROR(("%s (%s) %s is not allowed/supported version",
+ SILC_LOG_ERROR(("%s (%s) %s is not allowed/supported version",
ske->sock->hostname, ske->sock->ip, version));
return SILC_SKE_STATUS_BAD_VERSION;
}
/* If remote is too new, don't connect */
if (l_protocol_version < r_protocol_version) {
- SILC_LOG_ERROR(("%s (%s) %s is not allowed/supported version",
+ SILC_LOG_ERROR(("%s (%s) %s is not allowed/supported version",
ske->sock->hostname, ske->sock->ip, version));
return SILC_SKE_STATUS_BAD_VERSION;
}
static void silc_server_protocol_ke_continue(SilcSKE ske, void *context)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcServerKEInternalContext *ctx =
+ SilcServerKEInternalContext *ctx =
(SilcServerKEInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
protocol->state = SILC_PROTOCOL_STATE_END;
}
- /* Advance protocol state and call the next state if we are responder.
+ /* Advance protocol state and call the next state if we are responder.
This happens when this callback was sent to silc_ske_responder_phase_2
function. */
if (ctx->responder == TRUE) {
SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcServerKEInternalContext *ctx =
+ SilcServerKEInternalContext *ctx =
(SilcServerKEInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
SilcSKEStatus status = SILC_SKE_STATUS_OK;
/* Allocate Key Exchange object */
ctx->ske = ske = silc_ske_alloc(server->rng, server);
-
+
silc_ske_set_callbacks(ske, silc_server_protocol_ke_send_packet, NULL,
silc_server_protocol_ke_verify_key,
silc_server_protocol_ke_continue,
silc_ske_check_version, context);
-
+
if (ctx->responder == TRUE) {
/* Start the key exchange by processing the received security
properties packet from initiator. */
SILC_LOG_DEBUG(("Send security property list (KE)"));
/* Assemble security properties. */
- silc_ske_assemble_security_properties(ske, ctx->flags,
+ silc_ske_assemble_security_properties(ske, ctx->flags,
silc_version_string,
&start_payload);
break;
case 2:
{
- /*
- * Phase 1
+ /*
+ * Phase 1
*/
if (ctx->responder == TRUE) {
/* Sends the selected security properties to the initiator. */
break;
case 3:
{
- /*
- * Phase 2
+ /*
+ * Phase 2
*/
if (ctx->responder == TRUE) {
/* Process the received Key Exchange 1 Payload packet from
break;
case 4:
{
- /*
+ /*
* Finish protocol
*/
if (ctx->responder == TRUE) {
/* This creates the key exchange material and sends our
public parts to the initiator inside Key Exchange 2 Payload. */
SILC_LOG_DEBUG(("Process KE2 packet"));
- status = silc_ske_responder_finish(ctx->ske,
- server->public_key,
+ status = silc_ske_responder_finish(ctx->ske,
+ server->public_key,
server->private_key,
SILC_SKE_PK_TYPE_SILC);
case SILC_PROTOCOL_STATE_END:
{
- /*
+ /*
* End protocol
*/
SilcSKEKeyMaterial *keymat;
silc_ske_end(ctx->ske);
}
- /* Unregister the timeout task since the protocol has ended.
+ /* Unregister the timeout task since the protocol has ended.
This was the timeout task to be executed if the protocol is
not completed fast enough. */
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
/* Assure that after calling final callback there cannot be pending
- executions for this protocol anymore. This just unregisters any
+ executions for this protocol anymore. This just unregisters any
timeout callbacks for this protocol. */
silc_protocol_cancel(protocol, server->schedule);
/* Send abort notification */
silc_ske_abort(ctx->ske, ctx->ske->status);
- /* Unregister the timeout task since the protocol has ended.
+ /* Unregister the timeout task since the protocol has ended.
This was the timeout task to be executed if the protocol is
not completed fast enough. */
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
/* Assure that after calling final callback there cannot be pending
- executions for this protocol anymore. This just unregisters any
+ executions for this protocol anymore. This just unregisters any
timeout callbacks for this protocol. */
silc_protocol_cancel(protocol, server->schedule);
* We have received failure from remote
*/
- /* Unregister the timeout task since the protocol has ended.
+ /* Unregister the timeout task since the protocol has ended.
This was the timeout task to be executed if the protocol is
not completed fast enough. */
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
/* Assure that after calling final callback there cannot be pending
- executions for this protocol anymore. This just unregisters any
+ executions for this protocol anymore. This just unregisters any
timeout callbacks for this protocol. */
silc_protocol_cancel(protocol, server->schedule);
-
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
* Connection Authentication protocol functions
*/
-static int
-silc_server_password_authentication(SilcServer server, char *local_auth,
+static int
+silc_server_password_authentication(SilcServer server, char *local_auth,
char *remote_auth)
{
if (!remote_auth || !local_auth || strlen(local_auth) != strlen(remote_auth))
SILC_STR_END);
/* Verify signature */
- if (silc_pkcs_verify_with_hash(pkcs, ske->prop->hash, sign, sign_len,
+ if (silc_pkcs_verify_with_hash(pkcs, ske->prop->hash, sign, sign_len,
auth->data, auth->len)) {
silc_pkcs_free(pkcs);
silc_buffer_free(auth);
*auth_data = silc_calloc((silc_pkcs_get_key_len(pkcs) / 8) + 1,
sizeof(**auth_data));
- if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
+ if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
auth->len, *auth_data, auth_data_len)) {
silc_buffer_free(auth);
return TRUE;
/* Function that actually performs the authentication to the remote. This
supports both passphrase and public key authentication. */
-static bool
+static bool
silc_server_get_authentication(SilcServerConnAuthInternalContext *ctx,
char *local_passphrase,
SilcHashTable local_publickeys,
/* If we don't have authentication data set at all we do not require
authentication at all */
- if (!local_passphrase && (!local_publickeys ||
+ if (!local_passphrase && (!local_publickeys ||
!silc_hash_table_count(local_publickeys))) {
SILC_LOG_DEBUG(("No authentication required"));
return TRUE;
/* Try public key authenetication */
if (!result && local_publickeys) {
SilcPublicKey cached_key;
- SilcPublicKey remote_key =
+ SilcPublicKey remote_key =
((SilcIDListData)ctx->sock->user_data)->public_key;
SILC_LOG_DEBUG(("Public key authentication"));
return result;
}
-/* Performs connection authentication protocol. If responder, we
+/* Performs connection authentication protocol. If responder, we
authenticate the remote data received. If initiator, we will send
authentication data to the remote end. */
SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcServerConnAuthInternalContext *ctx =
+ SilcServerConnAuthInternalContext *ctx =
(SilcServerConnAuthInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
switch(protocol->state) {
case SILC_PROTOCOL_STATE_START:
{
- /*
+ /*
* Start protocol.
*/
silc_protocol_execute(protocol, server->schedule, 0, 300000);
return;
}
-
+
if (payload_len != ctx->packet->buffer->len) {
SILC_LOG_ERROR(("Bad payload length in authentication packet"));
protocol->state = SILC_PROTOCOL_STATE_ERROR;
silc_protocol_execute(protocol, server->schedule, 0, 300000);
return;
}
-
+
payload_len -= 4;
-
- if (conn_type < SILC_SOCKET_TYPE_CLIENT ||
+
+ if (conn_type < SILC_SOCKET_TYPE_CLIENT ||
conn_type > SILC_SOCKET_TYPE_ROUTER) {
SILC_LOG_ERROR(("Bad connection type (%d) in authentication packet",
conn_type));
silc_protocol_execute(protocol, server->schedule, 0, 300000);
return;
}
-
+
if (payload_len > 0) {
/* Get authentication data */
silc_buffer_pull(ctx->packet->buffer, 4);
ret = silc_buffer_unformat(ctx->packet->buffer,
- SILC_STR_UI_XNSTRING_ALLOC(&auth_data,
+ SILC_STR_UI_XNSTRING_ALLOC(&auth_data,
payload_len),
SILC_STR_END);
if (ret == -1) {
}
}
- /*
+ /*
* Check the remote connection type and make sure that we have
* configured this connection. If we haven't allowed this connection
* the authentication must be failed.
SILC_LOG_ERROR(("Authentication failed"));
silc_free(auth_data);
protocol->state = SILC_PROTOCOL_STATE_ERROR;
- silc_protocol_execute(protocol, server->schedule,
+ silc_protocol_execute(protocol, server->schedule,
0, 300000);
return;
}
}
-
+
/* Remote end is server */
if (conn_type == SILC_SOCKET_TYPE_SERVER) {
SilcServerConfigServer *serv = ctx->sconfig.ref_ptr;
SILC_LOG_ERROR(("Remote server connection not configured"));
SILC_LOG_ERROR(("Authentication failed"));
protocol->state = SILC_PROTOCOL_STATE_ERROR;
- silc_protocol_execute(protocol, server->schedule,
+ silc_protocol_execute(protocol, server->schedule,
0, 300000);
silc_free(auth_data);
return;
}
}
-
+
/* Remote end is router */
if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
SilcServerConfigRouter *serv = ctx->rconfig.ref_ptr;
SILC_LOG_ERROR(("Authentication failed"));
silc_free(auth_data);
protocol->state = SILC_PROTOCOL_STATE_ERROR;
- silc_protocol_execute(protocol, server->schedule,
+ silc_protocol_execute(protocol, server->schedule,
0, 300000);
return;
}
}
-
+
silc_free(auth_data);
/* Save connection type. This is later used to create the
ID for the connection. */
ctx->conn_type = conn_type;
-
+
/* Advance protocol state. */
protocol->state = SILC_PROTOCOL_STATE_END;
silc_protocol_execute(protocol, server->schedule, 0, 0);
} else {
- /*
+ /*
* We are initiator. We are authenticating ourselves to a
* remote server. We will send the authentication data to the
- * other end for verify.
+ * other end for verify.
*/
SilcBuffer packet;
int payload_len = 0;
unsigned char *auth_data = NULL;
SilcUInt32 auth_data_len = 0;
-
+
switch(ctx->auth_meth) {
case SILC_AUTH_NONE:
/* No authentication required */
break;
-
+
case SILC_AUTH_PASSWORD:
/* Password authentication */
if (ctx->auth_data && ctx->auth_data_len) {
break;
}
break;
-
+
case SILC_AUTH_PUBLIC_KEY:
{
/* Public key authentication */
break;
}
}
-
+
payload_len = 4 + auth_data_len;
packet = silc_buffer_alloc(payload_len);
silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
silc_buffer_format(packet,
SILC_STR_UI_SHORT(payload_len),
- SILC_STR_UI_SHORT(server->server_type
+ SILC_STR_UI_SHORT(server->server_type
== SILC_SERVER ?
SILC_SOCKET_TYPE_SERVER :
SILC_SOCKET_TYPE_ROUTER),
SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
SILC_STR_END);
-
+
/* Send the packet to server */
silc_server_packet_send(server, ctx->sock,
- SILC_PACKET_CONNECTION_AUTH, 0,
+ SILC_PACKET_CONNECTION_AUTH, 0,
packet->data, packet->len, TRUE);
-
+
if (auth_data) {
memset(auth_data, 0, auth_data_len);
silc_free(auth_data);
}
silc_buffer_free(packet);
-
+
/* Next state is end of protocol */
protocol->state = SILC_PROTOCOL_STATE_END;
}
case SILC_PROTOCOL_STATE_END:
{
- /*
+ /*
* End protocol
*/
unsigned char ok[4];
silc_server_packet_send(server, ctx->sock, SILC_PACKET_SUCCESS,
0, ok, 4, TRUE);
- /* Unregister the timeout task since the protocol has ended.
+ /* Unregister the timeout task since the protocol has ended.
This was the timeout task to be executed if the protocol is
not completed fast enough. */
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
/* Assure that after calling final callback there cannot be pending
- executions for this protocol anymore. This just unregisters any
+ executions for this protocol anymore. This just unregisters any
timeout callbacks for this protocol. */
silc_protocol_cancel(protocol, server->schedule);
-
+
/* Protocol has ended, call the final callback */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
silc_server_packet_send(server, ctx->sock, SILC_PACKET_FAILURE,
0, error, 4, TRUE);
- /* Unregister the timeout task since the protocol has ended.
+ /* Unregister the timeout task since the protocol has ended.
This was the timeout task to be executed if the protocol is
not completed fast enough. */
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
/* Assure that after calling final callback there cannot be pending
- executions for this protocol anymore. This just unregisters any
+ executions for this protocol anymore. This just unregisters any
timeout callbacks for this protocol. */
silc_protocol_cancel(protocol, server->schedule);
-
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
SILC_LOG_ERROR(("Received Authentication Failure"));
- /* Unregister the timeout task since the protocol has ended.
+ /* Unregister the timeout task since the protocol has ended.
This was the timeout task to be executed if the protocol is
not completed fast enough. */
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
/* Assure that after calling final callback there cannot be pending
- executions for this protocol anymore. This just unregisters any
+ executions for this protocol anymore. This just unregisters any
timeout callbacks for this protocol. */
silc_protocol_cancel(protocol, server->schedule);
-
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
/* Actually takes the new keys into use. */
-static void
+static void
silc_server_protocol_rekey_validate(SilcServer server,
SilcServerRekeyInternalContext *ctx,
SilcIDListData idata,
{
if (ctx->responder == TRUE) {
if (send) {
- silc_cipher_set_key(idata->send_key, keymat->receive_enc_key,
+ silc_cipher_set_key(idata->send_key, keymat->receive_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(idata->send_key, keymat->receive_iv);
- silc_hmac_set_key(idata->hmac_send, keymat->receive_hmac_key,
+ silc_hmac_set_key(idata->hmac_send, keymat->receive_hmac_key,
keymat->hmac_key_len);
} else {
- silc_cipher_set_key(idata->receive_key, keymat->send_enc_key,
+ silc_cipher_set_key(idata->receive_key, keymat->send_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(idata->receive_key, keymat->send_iv);
- silc_hmac_set_key(idata->hmac_receive, keymat->send_hmac_key,
+ silc_hmac_set_key(idata->hmac_receive, keymat->send_hmac_key,
keymat->hmac_key_len);
}
} else {
if (send) {
- silc_cipher_set_key(idata->send_key, keymat->send_enc_key,
+ silc_cipher_set_key(idata->send_key, keymat->send_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(idata->send_key, keymat->send_iv);
- silc_hmac_set_key(idata->hmac_send, keymat->send_hmac_key,
+ silc_hmac_set_key(idata->hmac_send, keymat->send_hmac_key,
keymat->hmac_key_len);
} else {
- silc_cipher_set_key(idata->receive_key, keymat->receive_enc_key,
+ silc_cipher_set_key(idata->receive_key, keymat->receive_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(idata->receive_key, keymat->receive_iv);
- silc_hmac_set_key(idata->hmac_receive, keymat->receive_hmac_key,
+ silc_hmac_set_key(idata->hmac_receive, keymat->receive_hmac_key,
keymat->hmac_key_len);
}
}
keymat = silc_calloc(1, sizeof(*keymat));
silc_ske_process_key_material_data(idata->rekey->send_enc_key,
idata->rekey->enc_key_len,
- 16, key_len, hash_len,
+ 16, key_len, hash_len,
idata->hash, keymat);
/* Set the keys into use */
/* This function actually re-generates (with PFS) the keys and
takes them into use. */
-void
+void
silc_server_protocol_rekey_generate_pfs(SilcServer server,
SilcServerRekeyInternalContext *ctx,
bool send)
/* Generate the new key */
keymat = silc_calloc(1, sizeof(*keymat));
- silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
+ silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
idata->hash, keymat);
/* Set the keys into use */
/* Packet sending callback. This function is provided as packet sending
routine to the Key Exchange functions. */
-static void
+static void
silc_server_protocol_rekey_send_packet(SilcSKE ske,
SilcBuffer packet,
SilcPacketType type,
void *context)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcServerRekeyInternalContext *ctx =
+ SilcServerRekeyInternalContext *ctx =
(SilcServerRekeyInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
SILC_TASK_CALLBACK(silc_server_protocol_rekey)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcServerRekeyInternalContext *ctx =
+ SilcServerRekeyInternalContext *ctx =
(SilcServerRekeyInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
SilcIDListData idata = (SilcIDListData)ctx->sock->user_data;
switch(protocol->state) {
case SILC_PROTOCOL_STATE_START:
{
- /*
+ /*
* Start protocol.
*/
*/
if (ctx->pfs == TRUE) {
- /*
+ /*
* Use Perfect Forward Secrecy, ie. negotiate the key material
* using the SKE protocol.
*/
if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
SILC_LOG_ERROR(("Error during Re-key (R PFS): re-key state is "
"incorrect (received %d, expected %d packet), "
- "with %s (%s)", ctx->packet->type,
+ "with %s (%s)", ctx->packet->type,
SILC_PACKET_KEY_EXCHANGE_1, ctx->sock->hostname,
ctx->sock->ip));
protocol->state = SILC_PROTOCOL_STATE_ERROR;
silc_ske_group_get_by_number(idata->rekey->ske_group,
&ctx->ske->prop->group);
- silc_ske_set_callbacks(ctx->ske,
- silc_server_protocol_rekey_send_packet,
+ silc_ske_set_callbacks(ctx->ske,
+ silc_server_protocol_rekey_send_packet,
NULL, NULL, NULL, silc_ske_check_version,
context);
-
+
status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
if (status != SILC_SKE_STATUS_OK) {
SILC_LOG_ERROR(("Error (%s) during Re-key (R PFS), with %s (%s)",
/* The protocol ends in next stage. */
protocol->state = SILC_PROTOCOL_STATE_END;
}
-
+
} else {
/*
* We are the initiator of this protocol
0, NULL, 0, FALSE);
if (ctx->pfs == TRUE) {
- /*
+ /*
* Use Perfect Forward Secrecy, ie. negotiate the key material
* using the SKE protocol.
*/
silc_ske_group_get_by_number(idata->rekey->ske_group,
&ctx->ske->prop->group);
- silc_ske_set_callbacks(ctx->ske,
- silc_server_protocol_rekey_send_packet,
+ silc_ske_set_callbacks(ctx->ske,
+ silc_server_protocol_rekey_send_packet,
NULL, NULL, NULL, silc_ske_check_version,
context);
-
+
status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
if (status != SILC_SKE_STATUS_OK) {
SILC_LOG_ERROR(("Error (%s) during Re-key (I PFS), with %s (%s)",
* Do normal and simple re-key.
*/
- /* Send the REKEY_DONE to indicate we will take new keys into use
- now. */
+ /* Send the REKEY_DONE to indicate we will take new keys into use
+ now. */
silc_server_packet_send(server, ctx->sock, SILC_PACKET_REKEY_DONE,
0, NULL, 0, FALSE);
* Send our KE packe to the initiator now that we've processed
* the initiator's KE packet.
*/
- status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
+ status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
SILC_SKE_PK_TYPE_SILC);
if (status != SILC_SKE_STATUS_OK) {
SILC_LOG_ERROR(("Error (%s) during Re-key (R PFS), with %s (%s)",
if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
SILC_LOG_ERROR(("Error during Re-key (I PFS): re-key state is "
"incorrect (received %d, expected %d packet), "
- "with %s (%s)", ctx->packet->type,
+ "with %s (%s)", ctx->packet->type,
SILC_PACKET_KEY_EXCHANGE_2, ctx->sock->hostname,
ctx->sock->ip));
protocol->state = SILC_PROTOCOL_STATE_ERROR;
silc_protocol_execute(protocol, server->schedule, 0, 300000);
return;
}
-
+
status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
if (status != SILC_SKE_STATUS_OK) {
SILC_LOG_ERROR(("Error (%s) during Re-key (I PFS), with %s (%s)",
}
}
- /* Send the REKEY_DONE to indicate we will take new keys into use
- now. */
+ /* Send the REKEY_DONE to indicate we will take new keys into use
+ now. */
silc_server_packet_send(server, ctx->sock, SILC_PACKET_REKEY_DONE,
0, NULL, 0, FALSE);
-
+
/* After we send REKEY_DONE we must set the sending encryption
key to the new key since all packets after this packet must
encrypted with the new key. */
break;
case SILC_PROTOCOL_STATE_END:
- /*
+ /*
* End protocol
*/
silc_server_protocol_rekey_generate(server, ctx, FALSE);
/* Assure that after calling final callback there cannot be pending
- executions for this protocol anymore. This just unregisters any
+ executions for this protocol anymore. This just unregisters any
timeout callbacks for this protocol. */
silc_protocol_cancel(protocol, server->schedule);
-
+
/* Protocol has ended, call the final callback */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
silc_ske_abort(ctx->ske, ctx->ske->status);
/* Assure that after calling final callback there cannot be pending
- executions for this protocol anymore. This just unregisters any
+ executions for this protocol anymore. This just unregisters any
timeout callbacks for this protocol. */
silc_protocol_cancel(protocol, server->schedule);
-
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
SILC_LOG_ERROR(("Error during Re-Key: received Failure"));
/* Assure that after calling final callback there cannot be pending
- executions for this protocol anymore. This just unregisters any
+ executions for this protocol anymore. This just unregisters any
timeout callbacks for this protocol. */
silc_protocol_cancel(protocol, server->schedule);
-
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
/*
- server.c
+ server.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2002 Pekka Riikonen
+ Copyright (C) 1997 - 2003 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
SilcSocketConnection newsocket = NULL;
SilcServerConfigServerInfoInterface *interface;
- for (interface = server->config->server_info->secondary; interface;
+ for (interface = server->config->server_info->secondary; interface;
interface = interface->next, sock++) {
if (!silc_server_listen(server,
if (silc_server_init_secondary(server) == FALSE)
goto err;
-
+
server->listenning = TRUE;
/* If server connections has been configured then we must be router as
/* Reinit scheduler if necessary */
if (newconfig->param.connections_max > server->config->param.connections_max)
- if (!silc_schedule_reinit(server->schedule,
+ if (!silc_schedule_reinit(server->schedule,
newconfig->param.connections_max))
return FALSE;
/* Update the idcache list with a fresh pointer */
silc_free(server->id_entry->server_name);
server->id_entry->server_name = strdup(server->server_name);
- if (!silc_idcache_del_by_context(server->local_list->servers,
+ if (!silc_idcache_del_by_context(server->local_list->servers,
server->id_entry))
return FALSE;
if (!silc_idcache_add(server->local_list->servers,
/* Check whether new config has this one too */
for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
- if (silc_string_compare(newptr->host, ptr->host) &&
+ if (silc_string_compare(newptr->host, ptr->host) &&
newptr->port == ptr->port &&
newptr->initiator == ptr->initiator) {
found = TRUE;
silc_schedule_task_del_by_context(server->schedule,
server->sockets[i]);
- silc_server_disconnect_remote(server, server->sockets[i],
- SILC_STATUS_OK,
+ silc_server_disconnect_remote(server, server->sockets[i],
+ SILC_STATUS_OK,
"Server is shutting down");
if (sock->user_data)
silc_server_free_sock_user_data(server, sock,
if (ptr->initiator) {
/* Check whether we are connecting or connected to this host already */
- if (silc_server_num_sockets_by_remote(server,
+ if (silc_server_num_sockets_by_remote(server,
silc_net_is_ip(ptr->host) ?
ptr->host : NULL,
silc_net_is_ip(ptr->host) ?
SILC_LOG_DEBUG(("We are already connected to this router"));
continue;
}
- if (silc_server_num_sockets_by_remote(server,
+ if (silc_server_num_sockets_by_remote(server,
silc_net_is_ip(ptr->host) ?
ptr->host : NULL,
silc_net_is_ip(ptr->host) ?
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
silc_free(ctx);
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
/* Try reconnecting if configuration wants it */
silc_ske_free(ctx->ske);
silc_free(ctx->dest_id);
silc_free(ctx);
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
/* Try reconnecting if configuration wants it */
silc_free(sconn->remote_host);
silc_free(sconn->backup_replace_ip);
silc_free(sconn);
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
return;
}
silc_server_config_unref(&ctx->sconfig);
silc_server_config_unref(&ctx->rconfig);
silc_free(ctx);
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
NULL);
server->stat.auth_failures++;
silc_server_config_unref(&ctx->sconfig);
silc_server_config_unref(&ctx->rconfig);
silc_free(ctx);
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
server->stat.auth_failures++;
return;
SILC_TASK_PRI_LOW);
}
-/* After this is called, server don't wait for backup router anymore.
+/* After this is called, server don't wait for backup router anymore.
This gets called automatically even after we have backup router
connection established. */
router->backup_replace_ip, 0)) {
SILC_LOG_INFO(("Will not accept connections because we do "
"not have backup router connection established"));
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_PERM_DENIED,
"We do not have connection to backup "
"router established, try later");
if (!client) {
SILC_LOG_ERROR(("Could not add new client to cache"));
silc_free(sock->user_data);
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_AUTH_FAILED, NULL);
server->stat.auth_failures++;
goto out;
!SILC_PRIMARY_ROUTE(server)) {
SILC_LOG_INFO(("Will not accept server connection because we do "
"not have primary router connection established"));
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_PERM_DENIED,
"We do not have connection to primary "
"router established, try later");
router->backup_replace_ip, 0)) {
SILC_LOG_INFO(("Will not accept connections because we do "
"not have backup router connection established"));
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_PERM_DENIED,
"We do not have connection to backup "
"router established, try later");
if (!new_server) {
SILC_LOG_ERROR(("Could not add new server to cache"));
silc_free(sock->user_data);
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_AUTH_FAILED, NULL);
server->stat.auth_failures++;
goto out;
local_is_router = (server->server_type == SILC_ROUTER);
/* If socket connection is our primary, we are backup and we are doing
- backup resuming, we won't process the packet as being a router
+ backup resuming, we won't process the packet as being a router
(affects channel message decryption). */
if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) &&
SILC_PRIMARY_ROUTE(server) == sock)
/* If processing failed the connection is closed. */
if (!ret) {
- /* On packet processing errors we may close our primary router
+ /* On packet processing errors we may close our primary router
connection but won't become primary router if we are the backup
since this is local error condition. */
if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
ret = silc_packet_parse_special(packet, idata ? idata->receive_key : NULL);
/* If entry is disabled ignore what we got. */
- if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
+ if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
ret != SILC_PACKET_HEARTBEAT && ret != SILC_PACKET_RESUME_ROUTER &&
ret != SILC_PACKET_REKEY && ret != SILC_PACKET_REKEY_DONE) {
SILC_LOG_DEBUG(("Connection is disabled"));
silc_server_packet_parse, server);
if (!ret) {
- /* On packet processing errors we may close our primary router
+ /* On packet processing errors we may close our primary router
connection but won't become primary router if we are the backup
since this is local error condition. */
if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
message = silc_memdup(packet->buffer->data + 1,
packet->buffer->len - 1);
- SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s",
+ SILC_LOG_INFO(("Disconnected by %s (%s): %s (%d) %s",
sock->ip, sock->hostname,
silc_get_status_message(status), status,
message ? message : ""));
SilcBuffer clidp;
SILC_LOG_DEBUG(("Removing %s from channel %s",
- silc_id_render(client->id, SILC_ID_CLIENT),
+ silc_id_render(client->id, SILC_ID_CLIENT),
channel->channel_name));
/* Get the entry to the channel, if this client is not on the channel
return;
}
- silc_server_disconnect_remote(server, sock,
- protocol ==
+ silc_server_disconnect_remote(server, sock,
+ protocol ==
SILC_PROTOCOL_SERVER_CONNECTION_AUTH ?
SILC_STATUS_ERR_AUTH_FAILED :
SILC_STATUS_ERR_KEY_EXCHANGE_FAILED,
{
SilcServer server = hb_context;
- SILC_LOG_DEBUG(("Sending heartbeat to %s:%d (%s)", sock->hostname,
+ SILC_LOG_DEBUG(("Sending heartbeat to %s:%d (%s)", sock->hostname,
sock->port, sock->ip));
/* Send the heartbeat */
hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL;
if (channel->founder_key)
fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
- tmp =
+ tmp =
silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE,
6, csidp->data, csidp->len,
mode, sizeof(mode),
sizeof(**channel_ids) * (i + 1));
(*channel_ids)[i] = NULL;
silc_server_announce_get_channel_users(server, channel,
- &(*channel_modes)[i],
+ &(*channel_modes)[i],
channel_users,
&(*channel_users_modes)[i]);
(*channel_ids)[i] = channel->id;
if (!channels || !channels_user_modes ||
!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
goto out;
-
+
ch = silc_channel_payload_parse_list(channels->data, channels->len);
if (ch && silc_get_mode_list(channels_user_modes, silc_dlist_count(ch),
&chumodes)) {
- ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
+ ht = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
NULL, NULL, NULL, TRUE);
silc_dlist_start(ch);
while ((entry = silc_dlist_get(ch)) != SILC_LIST_END) {
/* Check if we have this channel, and add it if we don't have it.
Also add the client on the channel unless it is there already. */
channel_id = silc_channel_get_id_parse(entry);
- channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel = silc_idlist_find_channel_by_id(server->local_list,
channel_id, NULL);
if (!channel)
channel = silc_idlist_find_channel_by_id(server->global_list,
i++;
continue;
}
-
+
/* We don't have that channel anywhere, add it. */
name = silc_channel_get_name(entry, NULL);
channel = silc_idlist_add_channel(server->global_list, strdup(name), 0,
if (!server->standalone) {
idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
- packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
+ packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
++server->cmd_ident, 1,
1, idp->data, idp->len);
silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),