Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2003 Pekka Riikonen
+ Copyright (C) 1997 - 2006 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
SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
SilcUInt32 len, void *context)
{
- SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
+ SilcUInt32 r_protocol_version = 0;
SILC_LOG_INFO(("%s (%s) is version %s", ske->sock->hostname,
ske->sock->ip, version));
return SILC_SKE_STATUS_BAD_VERSION;
}
- 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",
- 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",
- ske->sock->hostname, ske->sock->ip, version));
- return SILC_SKE_STATUS_BAD_VERSION;
- }
-
ske->sock->version = r_protocol_version;
return SILC_SKE_STATUS_OK;
silc_ske_check_version, context);
if (ctx->responder == TRUE) {
+ if (!ctx->packet) {
+ SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
+ silc_ske_map_status(status), ctx->sock->hostname,
+ ctx->sock->ip));
+
+ protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute(protocol, server->schedule, 0, 300000);
+ return;
+ }
+
/* Start the key exchange by processing the received security
properties packet from initiator. */
SILC_LOG_DEBUG(("Process security property list (KE)"));
SILC_LOG_DEBUG(("Send security property list reply (KE)"));
status = silc_ske_responder_phase_1(ctx->ske);
} else {
+ if (!ctx->packet) {
+ SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
+ silc_ske_map_status(status), ctx->sock->hostname,
+ ctx->sock->ip));
+
+ protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute(protocol, server->schedule, 0, 300000);
+ return;
+ }
+
/* Call Phase-1 function. This processes the Key Exchange Start
paylaod reply we just got from the responder. The callback
function will receive the processed payload where we will
* Phase 2
*/
if (ctx->responder == TRUE) {
+ if (!ctx->packet) {
+ SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
+ silc_ske_map_status(status), ctx->sock->hostname,
+ ctx->sock->ip));
+
+ protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute(protocol, server->schedule, 0, 300000);
+ return;
+ }
+
/* Process the received Key Exchange 1 Payload packet from
the initiator. This also creates our parts of the Diffie
Hellman algorithm. The silc_server_protocol_ke_continue
/* End the protocol on the next round */
protocol->state = SILC_PROTOCOL_STATE_END;
} else {
+ if (!ctx->packet) {
+ SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)",
+ silc_ske_map_status(status), ctx->sock->hostname,
+ ctx->sock->ip));
+
+ protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute(protocol, server->schedule, 0, 300000);
+ return;
+ }
+
/* Finish the protocol. This verifies the Key Exchange 2 payload
sent by responder. The silc_server_protocol_ke_continue will
be called after the public key has been verified. */
*/
/* Send abort notification */
- silc_ske_abort(ctx->ske, ctx->ske->status);
+ if (ctx->ske)
+ silc_ske_abort(ctx->ske, ctx->ske->status);
/* Unregister the timeout task since the protocol has ended.
This was the timeout task to be executed if the protocol is
SILC_LOG_INFO(("Performing authentication protocol for %s (%s)",
ctx->sock->hostname, ctx->sock->ip));
+ if (!ctx->packet) {
+ SILC_LOG_ERROR(("Bad authentication protocol request"));
+ protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute(protocol, server->schedule, 0, 300000);
+ return;
+ }
+
/* Parse the received authentication data packet. The received
payload is Connection Auth Payload. */
ret = silc_buffer_unformat(ctx->packet->buffer,
* using the SKE protocol.
*/
+ if (!ctx->packet) {
+ SILC_LOG_ERROR(("Error during Re-key, with %s (%s)",
+ ctx->sock->hostname, ctx->sock->ip));
+ protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute(protocol, server->schedule, 0, 300000);
+ return;
+ }
+
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), "
*/
/* Send the REKEY_DONE to indicate we will take new keys into use */
+ silc_server_packet_queue_purge(server, ctx->sock);
silc_server_packet_send(server, ctx->sock, SILC_PACKET_REKEY_DONE,
0, NULL, 0, FALSE);
key to the new key since all packets after this packet must
encrypted with the new key. */
silc_server_protocol_rekey_generate(server, ctx, TRUE);
+ silc_server_packet_queue_purge(server, ctx->sock);
/* The protocol ends in next stage. */
protocol->state = SILC_PROTOCOL_STATE_END;
/* Send the REKEY_DONE to indicate we will take new keys into use
now. */
+ silc_server_packet_queue_purge(server, ctx->sock);
silc_server_packet_send(server, ctx->sock, SILC_PACKET_REKEY_DONE,
0, NULL, 0, FALSE);
key to the new key since all packets after this packet must
encrypted with the new key. */
silc_server_protocol_rekey_generate(server, ctx, TRUE);
+ silc_server_packet_queue_purge(server, ctx->sock);
/* The protocol ends in next stage. */
protocol->state = SILC_PROTOCOL_STATE_END;
case 2:
/*
- * Second state, used only when oding re-key with PFS.
+ * Second state, used only when doing re-key with PFS.
*/
if (ctx->responder == TRUE) {
if (ctx->pfs == TRUE) {
/*
- * Send our KE packe to the initiator now that we've processed
+ * Send our KE packet to the initiator now that we've processed
* the initiator's KE packet.
*/
status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
/*
* The packet type must be KE packet
*/
+ if (!ctx->packet) {
+ SILC_LOG_ERROR(("Error during Re-key, with %s (%s)",
+ ctx->sock->hostname, ctx->sock->ip));
+ protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute(protocol, server->schedule, 0, 300000);
+ return;
+ }
+
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), "
/* Send the REKEY_DONE to indicate we will take new keys into use
now. */
+ silc_server_packet_queue_purge(server, ctx->sock);
silc_server_packet_send(server, ctx->sock, SILC_PACKET_REKEY_DONE,
0, NULL, 0, FALSE);
key to the new key since all packets after this packet must
encrypted with the new key. */
silc_server_protocol_rekey_generate_pfs(server, ctx, TRUE);
+ silc_server_packet_queue_purge(server, ctx->sock);
/* The protocol ends in next stage. */
protocol->state = SILC_PROTOCOL_STATE_END;
* End protocol
*/
+ if (!ctx->packet) {
+ SILC_LOG_ERROR(("Error during Re-key, with %s (%s)",
+ ctx->sock->hostname, ctx->sock->ip));
+ protocol->state = SILC_PROTOCOL_STATE_ERROR;
+ silc_protocol_execute(protocol, server->schedule, 0, 300000);
+ return;
+ }
+
if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
SILC_LOG_ERROR(("Error during Re-key (%s PFS): re-key state is "
"incorrect (received %d, expected %d packet), "
silc_server_protocol_rekey_generate_pfs(server, ctx, FALSE);
else
silc_server_protocol_rekey_generate(server, ctx, FALSE);
+ silc_server_packet_queue_purge(server, ctx->sock);
/* Assure that after calling final callback there cannot be pending
executions for this protocol anymore. This just unregisters any
* Error occured
*/
- if (ctx->pfs == TRUE)
+ if (ctx->pfs == TRUE && ctx->ske)
/* Send abort notification */
silc_ske_abort(ctx->ske, ctx->ske->status);