When a key exchange times out, the SKE can be freed before the user
responds. Switch the SKE callbacks to obtain their own reference to the
object to prevent this.
static void silc_ske_completion(SilcSKE ske)
{
/* Call the completion callback */
static void silc_ske_completion(SilcSKE ske)
{
/* Call the completion callback */
- if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
+ if (!ske->aborted && ske->callbacks->completed) {
if (ske->status != SILC_SKE_STATUS_OK)
ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
ske->callbacks->context);
if (ske->status != SILC_SKE_STATUS_OK)
ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
ske->callbacks->context);
void *destructor_context)
{
SilcSKE ske = fsm_context;
void *destructor_context)
{
SilcSKE ske = fsm_context;
- ske->running = FALSE;
- if (ske->freed)
void silc_ske_free(SilcSKE ske)
{
void silc_ske_free(SilcSKE ske)
{
- SILC_LOG_DEBUG(("Freeing Key Exchange object"));
-
- if (ske->running) {
- ske->freed = TRUE;
+ SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu", ske, ske->aborted, ske->refcnt));
if (ske->aborted) {
/* If already aborted, destroy the session immediately */
if (ske->aborted) {
/* If already aborted, destroy the session immediately */
silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
silc_fsm_continue_sync(&ske->fsm);
}
silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
silc_fsm_continue_sync(&ske->fsm);
}
ske->refcnt--;
if (ske->refcnt > 0)
ske->refcnt--;
if (ske->refcnt > 0)
silc_free(ske->hash);
silc_free(ske->callbacks);
silc_free(ske->hash);
silc_free(ske->callbacks);
- memset(ske, 'F', sizeof(*ske));
+ memset(ske, 0xdd, sizeof(*ske));
SilcSKEParams params,
SilcSKEStartPayload start_payload)
{
SilcSKEParams params,
SilcSKEStartPayload start_payload)
{
- SILC_LOG_DEBUG(("Start SKE as initiator"));
+ SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; start_payload=%p", ske, stream, params, start_payload));
if (!ske || !stream || !params || !params->version)
return NULL;
if (!ske || !stream || !params || !params->version)
return NULL;
ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
ske->start_payload = start_payload;
ske->version = params->version;
ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
ske->start_payload = start_payload;
ske->version = params->version;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
ske->version = params->version;
if (!ske->version)
return NULL;
ske->version = params->version;
if (!ske->version)
return NULL;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
ske->rekey = rekey;
ske->responder = FALSE;
ske->rekey = rekey;
ske->responder = FALSE;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
ske->rekey = rekey;
ske->responder = TRUE;
ske->rekey = rekey;
ske->responder = TRUE;
ske->rekeying = TRUE;
ske->packet = packet;
ske->rekeying = TRUE;
ske->packet = packet;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
/* Link to packet stream to get key exchange packets */
ske->stream = stream;
SilcUInt16 refcnt; /* Reference counter */
unsigned int aborted : 1; /* Set when SKE aborted */
SilcUInt16 refcnt; /* Reference counter */
unsigned int aborted : 1; /* Set when SKE aborted */
- unsigned int freed : 1; /* Set when freed during session */
unsigned int responder : 1; /* Set when we are responder side */
unsigned int responder : 1; /* Set when we are responder side */
- unsigned int running : 1; /* Set when SKE is running */
unsigned int rekeying : 1; /* Set when rekeying */
};
unsigned int rekeying : 1; /* Set when rekeying */
};