Пример #1
0
static void
pkix_tcp_kill_input(SshFSMThread thread)
{
  SshPkiThreadData tdata = ssh_fsm_get_tdata(thread);
  SshPkiGlobalData gdata = ssh_fsm_get_gdata(thread);

  SSH_DEBUG(SSH_D_HIGHOK,
            ("Deleting wrapper and timeouts for thread %p conn=%p",
             thread, tdata->http));

  ssh_cancel_timeouts(pkix_timeout_handler, (void *)thread);
  tdata->timeout_set = FALSE;
  if (tdata->wrapper)
    {
      ssh_packet_wrapper_destroy(tdata->wrapper);
      tdata->wrapper = NULL;
    }
  if (tdata->http)
    {
      ssh_http_client_uninit(tdata->http);
      tdata->http = NULL;
    }
  if (gdata->input_thread)
    {
      ssh_fsm_kill_thread(gdata->input_thread);
      gdata->input_thread = NULL;
    }
}
Пример #2
0
void
ssh_eap_cancel_auth_timeout(SshEap eap)
{
  SSH_ASSERT(eap != NULL);

  eap->auth_timeout_active = 0;
  ssh_cancel_timeouts(ssh_eap_auth_timeout_cb, eap);
}
Пример #3
0
void ssh_server_destroy(SshServer server)
{
  /* Cancel grace timeout. */
  ssh_cancel_timeouts(ssh_login_grace_time_exceeded, SSH_ALL_CONTEXTS);
  ssh_common_destroy(server->common);
  ssh_xfree(server->compat_flags);
  ssh_server_authentication_uninitialize(server->methods);
  memset(server, 'F', sizeof(*server));
  ssh_xfree(server);
}
Пример #4
0
void
ssh_eap_cancel_resend_timeout(SshEap eap)
{
#ifdef SSHDIST_RADIUS
  eap->radius_session_timeout = 0;
#endif /* SSHDIST_RADIUS */
  eap->num_retransmit = 0;
  eap->retransmit_timer_active = 0;
  ssh_cancel_timeouts(ssh_eap_resend_timeout_cb, eap);
}
Пример #5
0
void signer_received_eof(void *context)
{
    SshSigner signer = (SshSigner)context;

    /* Cancel self-destruct. */
    ssh_cancel_timeouts(signer_destroy_timeout, SSH_ALL_CONTEXTS);

    SSH_TRACE(0, ("EOF received from packetstream. Exiting."));

    signer_free_context(signer);

    exit(0);
}
Пример #6
0
void check_for_threads(void *context)
{
  D(("Checking for threads, number of threads = %d\n", threads));
  if (threads == 0)
    {
      D(("No more threads, uninitilizing threaded timeouts\n"));
      ssh_threaded_timeouts_uninit();
      ssh_cancel_timeouts(SSH_ALL_CALLBACKS, SSH_ALL_CONTEXTS);
      return;
    }
  D(("Still some threads running, reinserting timeout\n"));
  ssh_xregister_timeout(0, 1000000, check_for_threads, NULL);
  return;
}
Пример #7
0
void ssh_packet_impl_destroy(void *context)
{
  SshPacketImpl up = (SshPacketImpl)context;

  /* Call the destroy callback. */
  if (up->destroy)
    (*up->destroy)(up->context);

  /* Cancel pending callbacks. */
  ssh_cancel_timeouts(ssh_packet_impl_signal_output_proc, (void *)up);
  ssh_cancel_timeouts(ssh_packet_impl_signal_input_proc, (void *)up);
  ssh_cancel_timeouts(ssh_packet_impl_signal_send_proc, (void *)up);

  /* Uninitialize the buffers. */
  ssh_buffer_uninit(&up->outgoing);
  ssh_buffer_uninit(&up->outgoing_packet);
  ssh_buffer_uninit(&up->incoming);

  /* Fill the context with garbage so that accesses after freeing are more
     reliably trapped.  This eases debugging. */
  memset(up, 'F', sizeof(*up));
  ssh_xfree(up);
}
Пример #8
0
/* Connection aborted out */
void ssh_tcp_connect_aborted(void *context)
{
    ConnectContext c = (ConnectContext) context;

    if (c->handle)
    {
        ssh_operation_abort(c->handle);
        c->handle = NULL;
    }
    /* Make sure we don't receive timeouts or call the user callback after
       we have been aborted. */
    c->user_callback = NULL_FNPTR;
    ssh_cancel_timeouts(tcp_connect_time_out, c);
    ssh_fsm_set_next(c->thread, tcp_connect_abort);
    ssh_fsm_continue(c->thread);
}
Пример #9
0
void ssh_pipe_stream_destroy(void *context)
{
    SshPipeStream pipes = (SshPipeStream)context;

    ssh_debug("ssh_pipe_stream_destroy");

    /* Cancel any pending input notification callbacks for this pipe. */
    ssh_cancel_timeouts(ssh_pipe_sigchld_do_callback, (void *)pipes);

    /* Unregister the sigchld handler for the stream. */
    ssh_sigchld_unregister(pipes->pid);

    /* Destroy the stream going to the master side. */
    ssh_stream_destroy(pipes->stdio_stream);

    /* Free our own data structures. */
    memset(pipes, 'F', sizeof(*pipes));
    ssh_xfree(pipes);
}
Пример #10
0
void ssh_stream_fd_destroy(void *context)
{
  SshFdStream sdata = (SshFdStream)context;

  /* Mark it as destroyed. */
  assert(!sdata->destroyed);
  sdata->destroyed = TRUE;
  sdata->callback = NULL;

  /* Unregister the descriptors from the event loop. */
  if (sdata->readfd >= 0)
    ssh_io_unregister_fd(sdata->readfd, sdata->keep_nonblocking);
  if (sdata->readfd != sdata->writefd && sdata->writefd >= 0)
    ssh_io_unregister_fd(sdata->writefd, sdata->keep_nonblocking);

  /* Close the file descriptors if appropriate. */
  if (sdata->close_on_destroy)
    {
      if (sdata->readfd >= 0)
	close(sdata->readfd);
      if (sdata->readfd != sdata->writefd && sdata->writefd >= 0)
	close(sdata->writefd);
      sdata->writefd = -1;
      sdata->readfd = -1;
    }

  /* Cancel any pending timeouts for us. */
  ssh_cancel_timeouts(SSH_ALL_CALLBACKS, (void *)sdata);

  /* If this is called from a callback, delay actually freeing the context
     until we have returned from the callback.  The destroyed flag was set
     above, and will be tested after the callback has returned. */
  if (sdata->in_callback)
    return;
  
  /* Destroy the context.  We first fill it with garbage to ease debugging. */
  memset(sdata, 'F', sizeof(*sdata));
  ssh_xfree(sdata);
}
Пример #11
0
/* Destroy decaying counter */
void ssh_decay_counter_delete(SshDecayCounter counter)
{
  SSH_DEBUG(SSH_D_HIGHSTART, ("Destroying decay counter"));
  ssh_cancel_timeouts(ssh_decay_counter_timer, counter);
  ssh_free(counter);
}
Пример #12
0
void *func1(void *context)
{
  unsigned long val, xval = 0;
  unsigned char tmp[128];
  size_t rd = 0, r;
  size_t reason, result;
  int res;

#ifdef DEBUG_OUTPUT
  if (logging)
    out = fopen(DEBUG_OUTPUT, "w");
#endif /* DEBUG_OUTPUT */

  /* Read end, close write */
  /* close(testpipe[1]); */

  if (!blocking)
    ssh_debug_set_non_blocking(testpipe[0]);

  D(("In thread 1, Locking mutex 1\n"));
  ssh_mutex_lock(mutex1);
  ssh_mutex_lock(mutex1_start);
  ssh_mutex_unlock(mutex1_start);

  D(("R: In thread 1, Activating self-destruction\n"));
  ssh_xregister_threaded_timeout(0, 5000000, kill_thread_1, thread1);

  D(("R: In thread 1, starting\n"));
  r = FORMATLEN + 1;

  for (;;)
    {
      errno = 0;
      res = read(testpipe[0], tmp + rd, r - rd);

      if (res > 0)
        tmp[res + rd] = (char)0;

#ifdef DEBUG_INPUT
      if (logging)
        fprintf(out, "res: %d, err: %d, data: \"%s\"\n",
                res, errno, linearise(tmp + rd));
#endif /* DEBUG_INPUT */

      if (res == 0 && errno == 0)
        break;

      if (res > 0)
        {
          rd +=res;

          if (rd == FORMATLEN + 1)
            {
              rd = 0;
              val = atol(tmp);
              tmp[0] = (char)0;

              if (val != xval + 1)
                {
                  if (firsterror < 2)
                    {
                      D(("R: expected (prev %ld) %ld - %ld received\n",
                         xval, xval + 1, val));
                      if (firsterror == 1)
                        firsterror += 1;
                    }
                  retval += 1;
                }
              else
                {
                  xval = val;
                  received += 1;
                  if ((val % reportinterval) == 0)
                    D(("R: %0*ld\n", FORMATLEN, val));
                }

              if (val == iterations)
                {
                  D(("R: === END === yeah baby!\n"));
                  break;
                }
            }
        }

      if (errno != 0)
        {
          if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN)
            {
              D(("R: read: %d, error: %d (%s)\n",
                 res, errno, strerror(errno)));
              break;
            }
#ifdef DEBUG_OUTPUT
          if (logging)
            fprintf(out, "Entering select(), stream empty\n");
#endif /* DEBUG_OUTPUT */
          D(("R: Entering select(), current value: '%ld', err:%d (%s)\n",
             val, errno, strerror(errno)));
          do
            {
              result = ssh_debug_wait_fd_readable(testpipe[0], 0, &reason);
            } while (result == -1 && reason == EINTR);
        }
    }

#ifdef DEBUG_OUTPUT
  if (logging && out)
    {
      fclose(out);
      out = NULL;
    }
#endif /* DEBUG_OUTPUT */

  D(("R: In thread 1, All done, inserting thread wait timeout, thread = %p\n",
     thread1));
  ssh_xregister_threaded_timeout(0, 0, call_wait_thread, thread1);

  D(("R: In thread 1, Unlocking mutex 1\n"));
  ssh_mutex_unlock(mutex1);

  D(("R: In thread 1, De-activating self-destruction\n"));
  ssh_cancel_timeouts(kill_thread_1, SSH_ALL_CONTEXTS);

  D(("R: In thread 1, Exiting now\n"));
  close(testpipe[0]);

  return NULL;
}
Пример #13
0
/* Import given buffer to the IKE Server given in the argument. Returns the IKE
   SA negotiation or NULL in case of error. The data that was parsed
   successfully is consumed from the buffer in any case. If there is extra data
   after the complete packet then it is left to the buffer. */
SshIkeNegotiation ssh_ike_sa_import(SshBuffer buffer,
                                    SshIkeServerContext server)
{
  unsigned char initiator_cookie[SSH_IKE_COOKIE_LENGTH];
  unsigned char responder_cookie[SSH_IKE_COOKIE_LENGTH];
  unsigned char *auc, *buc, *cuc, *duc;
  SshUInt32 a32, b32, c32, d32;
  SshUInt64 a64, b64, c64, d64;
  SshIkePMPhaseI pm_info;
  SshIkeNegotiation neg;
  SshIkeSA sa;
  size_t len;
  long l;
  SshADTHandle h;
  SshCryptoStatus cret;
  SshTime t;
  SshUInt16 local_port;

  sa = NULL;
  pm_info = NULL;
  neg = NULL;
  auc = NULL;
  buc = NULL;
  cuc = NULL;
  duc = NULL;

  SSH_DEBUG(5, ("Start"));

  len = ssh_decode_buffer
    (buffer,
     /* Magic number */
     SSH_DECODE_UINT32(&a32),
     /* Version number */
     SSH_DECODE_UINT32(&b32),
     /* Cookies, initiator, responder */
     SSH_DECODE_DATA(initiator_cookie, SSH_IKE_COOKIE_LENGTH),
     SSH_DECODE_DATA(responder_cookie, SSH_IKE_COOKIE_LENGTH),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode magic, version, cookies"));
      goto error;
    }
  if (a32 != SSH_IKE_EXPORT_MAGIC1)
    {
      SSH_DEBUG(3, ("Invalid magic 0x%08x vs 0x%08x", (int) a32,
                    SSH_IKE_EXPORT_MAGIC1));
      goto error;
    }
  if (b32 != SSH_IKE_EXPORT_VERSION)
    {
      SSH_DEBUG(3, ("Invalid version 0x%08x vs 0x%08x", (int) b32,
                    SSH_IKE_EXPORT_VERSION));
      goto error;
    }

  h = ssh_adt_get_handle_to_equal(server->isakmp_context->
                                  isakmp_cookie_mapping, initiator_cookie);
  if (h != SSH_ADT_INVALID)
    {
      SSH_DEBUG(3, ("Duplicate initiator cookie"));
      goto error;
    }

  sa = ike_sa_allocate(server, initiator_cookie, responder_cookie);
  if (sa == NULL)
    {
      SSH_DEBUG(3, ("ike_sa_allocate_half return error"));
      goto error;
    }

  len = ssh_decode_buffer
    (buffer,
     /* Local ip, port. */
     SSH_DECODE_UINT32_STR(&auc, NULL),
     SSH_DECODE_UINT32_STR(&buc, NULL),
     /* Remote ip, port. */
     SSH_DECODE_UINT32_STR(&cuc, NULL),
     SSH_DECODE_UINT32_STR(&duc, NULL),
     /* IKE exchange version. */
     SSH_DECODE_UINT32(&a32),
     SSH_DECODE_UINT32(&b32),
     /* IKE exchange type. */
     SSH_DECODE_UINT32(&c32),
     /* Was this the initiator for the original exchange? */
     SSH_DECODE_UINT32(&d32),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode ip, port, version, exchage type, init"));
      goto error;
    }
  if (!ike_init_isakmp_sa(sa, auc, buc, cuc, duc, a32, b32, c32, d32, FALSE))
    {
      SSH_DEBUG(3, ("Could not init isakmp sa"));
      goto error;
    }
  ssh_free(auc);
  ssh_free(buc);
  ssh_free(cuc);
  ssh_free(duc);
  auc = NULL;
  buc = NULL;
  cuc = NULL;
  duc = NULL;

  neg = sa->isakmp_negotiation;
  pm_info = neg->ike_pm_info;

  /* Initialize */
  sa->phase_1_done = 1;
  neg->notification_state = SSH_IKE_NOTIFICATION_STATE_ALREADY_SENT;
  ike_free_negotiation_isakmp(neg);


  /* Set NAT-T status. */
  local_port = ssh_uatoi(sa->isakmp_negotiation->ike_pm_info->local_port);
  if (local_port != server->normal_local_port)
    sa->use_natt = 1;

  /* I think we should count this as SA */
  server->statistics->current_ike_sas++;
  server->statistics->total_ike_sas++;
  if (neg->ike_pm_info->this_end_is_initiator)
    {
      server->statistics->current_ike_sas_initiated++;
      server->statistics->total_ike_sas_initiated++;
    }
  else
    {
      server->statistics->current_ike_sas_responded++;
      server->statistics->total_ike_sas_responded++;
    }

  len = ssh_decode_buffer
    (buffer,
     /* Byte count and byte limit. */
     SSH_DECODE_UINT64(&a64),
     SSH_DECODE_UINT64(&b64),
     /* Created time and laste use time */
     SSH_DECODE_UINT64(&c64),
     SSH_DECODE_UINT64(&d64),
     /* Encryption, hash, prf algorithm names. */
     SSH_DECODE_UINT32_STR(&auc, NULL),
     SSH_DECODE_UINT32_STR(&buc, NULL),
     SSH_DECODE_UINT32_STR(&cuc, NULL),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode byte count limit, times, alg names"));
      goto error;
    }
  sa->byte_count = (unsigned long) a64;
  sa->kbyte_limit = (unsigned long) b64;
  sa->created_time = (SshTime) c64;
  sa->last_use_time = (SshTime) d64;

  l = ssh_find_keyword_number(ssh_ike_encryption_algorithms, ssh_csstr(auc));
  if (l == -1)
    {
      if (ssh_usstrcmp(auc, "cast128-12-cbc") == 0)
        sa->encryption_algorithm_name = ssh_custr("cast128-12-cbc");
      else
        {
          SSH_DEBUG(3, ("Unknown cipher %s", auc));
          goto error;
        }
    }
  else
    {
      sa->encryption_algorithm_name =
        ssh_custr(ssh_find_keyword_name(ssh_ike_encryption_algorithms, l));
      SSH_ASSERT(sa->encryption_algorithm_name != NULL);
    }

  l = ssh_find_keyword_number(ssh_ike_hash_algorithms, ssh_csstr(buc));
  if (l == -1)
    {
      SSH_DEBUG(3, ("Unknown hash %s", buc));
      goto error;
    }
  else
    {
      sa->hash_algorithm_name =
        ssh_custr(ssh_find_keyword_name(ssh_ike_hash_algorithms, l));
      SSH_ASSERT(sa->hash_algorithm_name != NULL);
    }

  l = ssh_find_keyword_number(ssh_ike_hmac_prf_algorithms, ssh_csstr(cuc));
  if (l == -1)
    {
      SSH_DEBUG(3, ("Unknown prf %s", cuc));
      goto error;
    }
  else
    {
      sa->prf_algorithm_name =
        ssh_custr(ssh_find_keyword_name(ssh_ike_hmac_prf_algorithms, l));
      SSH_ASSERT(sa->prf_algorithm_name != NULL);
    }

  ssh_free(auc);
  ssh_free(buc);
  ssh_free(cuc);
  ssh_free(duc);
  auc = NULL;
  buc = NULL;
  cuc = NULL;
  duc = NULL;

  len = ssh_decode_buffer
    (buffer,
     /* Cipher key. */
     SSH_DECODE_UINT32_STR(&sa->cipher_key, &sa->cipher_key_len),
     /* Cipher IV. */
     SSH_DECODE_UINT32_STR(&sa->cipher_iv, &sa->cipher_iv_len),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode cipher key, iv"));
      goto error;
    }

  len = ssh_decode_buffer
    (buffer,
     /* Keying material, Diffie-Hellman. */
     SSH_DECODE_UINT32_STR(&sa->skeyid.dh, &sa->skeyid.dh_size),
     /* Keying material, SKEYID mac. */
     SSH_DECODE_UINT32_STR(&sa->skeyid.skeyid, &sa->skeyid.skeyid_size),
     /* Keying material, SKEYID_d mac. */
     SSH_DECODE_UINT32_STR(&sa->skeyid.skeyid_d, &sa->skeyid.skeyid_d_size),
     /* Keying material, SKEYID_a mac. */
     SSH_DECODE_UINT32_STR(&sa->skeyid.skeyid_a, &sa->skeyid.skeyid_a_size),
     /* Keying material, SKEYID_e mac. */
     SSH_DECODE_UINT32_STR(&sa->skeyid.skeyid_e, &sa->skeyid.skeyid_e_size),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode skeyid"));
      goto error;
    }
  sa->skeyid.initialized = TRUE;

  cret = ssh_mac_allocate(ssh_csstr(sa->prf_algorithm_name),
                          sa->skeyid.skeyid,
                          sa->skeyid.skeyid_size,
                          &sa->skeyid.skeyid_mac);
  if (cret != SSH_CRYPTO_OK)
    {
      SSH_DEBUG(3, ("ssh_mac_allocate failed: %.200s",
                    ssh_crypto_status_message(cret)));
      goto error;
    }

  cret = ssh_mac_allocate(ssh_csstr(sa->prf_algorithm_name),
                          sa->skeyid.skeyid_a,
                          sa->skeyid.skeyid_a_size,
                          &sa->skeyid.skeyid_a_mac);
  if (cret != SSH_CRYPTO_OK)
    {
      SSH_DEBUG(3, ("ssh_mac_allocate failed: %.200s",
                    ssh_crypto_status_message(cret)));
      goto error;
    }
  cret = ssh_mac_allocate(ssh_csstr(sa->prf_algorithm_name),
                          sa->skeyid.skeyid_e,
                          sa->skeyid.skeyid_e_size,
                          &sa->skeyid.skeyid_e_mac);
  if (cret != SSH_CRYPTO_OK)
    {
      SSH_DEBUG(3, ("ssh_mac_allocate failed: %.200s",
                    ssh_crypto_status_message(cret)));
      goto error;
    }

  len = ssh_decode_buffer
    (buffer,
     /* Retry defaults. */
     SSH_DECODE_UINT32(&sa->retry_limit),
     SSH_DECODE_UINT32(&sa->retry_timer),
     SSH_DECODE_UINT32(&sa->retry_timer_usec),
     SSH_DECODE_UINT32(&sa->retry_timer_max),
     SSH_DECODE_UINT32(&sa->retry_timer_max_usec),
     SSH_DECODE_UINT32(&sa->expire_timer),
     SSH_DECODE_UINT32(&sa->expire_timer_usec),
     /* Statistics. */
     SSH_DECODE_UINT32(&sa->statistics.packets_in),
     SSH_DECODE_UINT32(&sa->statistics.packets_out),
     SSH_DECODE_UINT32(&sa->statistics.octects_in),
     SSH_DECODE_UINT32(&sa->statistics.octects_out),
     SSH_DECODE_UINT32(&sa->statistics.created_suites),
     SSH_DECODE_UINT32(&sa->statistics.deleted_suites),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode retry, expire timers and stats"));
      goto error;
    }

  len = ssh_decode_buffer
    (buffer,
     /* IKE SA negotiation information. */
     SSH_DECODE_UINT32(&a32),
     SSH_DECODE_UINT32(&b32),





     SSH_DECODE_UINT32(&c32),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode ike sa info and private group cnt"));
      goto error;
    }
  neg->exchange_type = a32;
  /* The b32 used to be authe_method_type, but as it was duplicate for the
     value in pm_info, we ignore it now. */
  if (c32 != 0)
    {
      ssh_warning("Remote end sent packet including private groups. "
                  "This end does not support transferring of them. "
                  "Private groups ignored");
    }
  len = ssh_decode_buffer
    (buffer,
     /* Private groups as UINT32_STRING. */ 



     SSH_DECODE_UINT32_STR(NULL, NULL),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode private groups info"));
      goto error;
    }

  if (!ssh_ike_sa_import_id(buffer, &pm_info->local_id,
                            &pm_info->local_id_txt))
    {
      SSH_DEBUG(3, ("Could not decode local id"));
      goto error;
    }
  if (!ssh_ike_sa_import_id(buffer, &pm_info->remote_id,
                            &pm_info->remote_id_txt))
    {
      SSH_DEBUG(3, ("Could not decode remote id"));
      goto error;
    }

  len = ssh_decode_buffer
    (buffer,
     /* Authentication type. */
     SSH_DECODE_UINT32(&a32),
     SSH_DECODE_UINT32(&b32),
     /* Start and expire times. */
     SSH_DECODE_UINT64(&a64),
     SSH_DECODE_UINT64(&b64),
     /* None of the policy manager filled data is copied, this include
        auth_data, auth_data_len, own_auth_data, own_auth_data_len,
        public_key, number_of_certificates, number_of_allocated_certificates,
        certificates, certificate_lens, certificate_encodings,
        policy_manager_data, pm. */
     SSH_DECODE_UINT32(&c32),
     /* Magic number */
     SSH_DECODE_UINT32(&d32),
     SSH_FORMAT_END);
  if (len == 0)
    {
      SSH_DEBUG(3, ("Could not decode pm info and magic2"));
      goto error;
    }
  pm_info->auth_method_type = a32;
  pm_info->auth_method = b32;
  pm_info->sa_start_time = (SshTime) a64;
  pm_info->sa_expire_time = (SshTime) b64;
  pm_info->doi = c32;
  if (d32 != SSH_IKE_EXPORT_MAGIC2)
    {
      SSH_DEBUG(3, ("Invalid magic2 0x%08x vs 0x%08x", (int) d32,
                    SSH_IKE_EXPORT_MAGIC2));
      goto error;
    }

  ssh_cancel_timeouts(SSH_ALL_CALLBACKS, neg);
  /* Insert expire timer allowing the sa to exists for a while (for
     bootstrap) */
  t = ssh_time();
  if (t < pm_info->sa_expire_time)
    t = pm_info->sa_expire_time - t;
  else
    t = 0;

  t = (t < 30) ? 30 : t;
  ssh_xregister_timeout((SshUInt32) t, 0,
                       ike_call_ike_remove_isakmp_sa,
                       neg);
  return neg;
 error:
  if (sa != NULL)
    {
      if (sa->isakmp_negotiation == NULL)
        {
          ike_sa_delete(server->isakmp_context, sa);
          ssh_free(sa);
        }
      else
        ike_delete_negotiation(sa->isakmp_negotiation);
    }
  ssh_free(auc);
  ssh_free(buc);
  ssh_free(cuc);
  ssh_free(duc);
  return NULL;
}