예제 #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
static Boolean
pkix_client_srv_close(SshPkiThreadData tdata)
{
  if (tdata->wrapper)
    {
      ssh_packet_wrapper_destroy(tdata->wrapper);
      tdata->wrapper = NULL;
    }
  return TRUE;
}
예제 #3
0
static void
pkix_tcp_receive_eof(void *context)
{
  SshFSMThread thread = (SshFSMThread)context;
  SshPkiThreadData tdata = ssh_fsm_get_tdata(thread);

  ssh_packet_wrapper_destroy(tdata->wrapper);
  tdata->wrapper = NULL;
  SSH_DEBUG(SSH_D_HIGHOK, ("Received EOF from CA for thread %p", thread));
}
예제 #4
0
/* Callback, which notifies that packetstream has received EOF from
   the other side. */
void auth_hostbased_received_eof(void *context)
{
  SshClientHostbasedAuth state = (SshClientHostbasedAuth) context;
  
  SSH_TRACE(0, ("received EOF from ssh-signer2."));
  
  ssh_packet_wrapper_send_eof(state->wrapper);
  ssh_packet_wrapper_destroy(state->wrapper);
  state->wrapper = NULL;

  *(state->state_placeholder) = NULL;
  
  /* Send failure message up, and return. */
  (*state->completion)(SSH_AUTH_CLIENT_FAIL, state->user, NULL,
                       state->completion_context);
}
예제 #5
0
파일: ssh-signer2.c 프로젝트: hnuxgp/rk
void signer_free_context(SshSigner signer)
{
    static Boolean destroyed = FALSE;

    if (destroyed)
        return;

    destroyed = TRUE;

    SSH_DEBUG(3, ("Destroying SshSigner-struct..."));
    ssh_packet_wrapper_destroy(signer->wrapper);
    ssh_xfree(signer->packet_payload);
    ssh_random_free(signer->random_state);
    ssh_config_free(signer->config);
    ssh_user_free(signer->effective_user_data, FALSE);
    ssh_xfree(signer);
    SSH_DEBUG(3, ("done."));
}
예제 #6
0
Boolean ssh_packet_wrapper_input(SshPacketWrapper down)
{
  size_t data_to_read, data_read;
  int ret;
  unsigned char *ptr;
  SshPacketType type;
  Boolean return_value = FALSE;

  for (;;)
    {
      /* If we cannot receive, return immediately. */
      if (!down->can_receive || down->incoming_eof || down->destroy_pending ||
          down->shortcircuit_up_stream != NULL)
        return return_value;

      /* Get length of data read so far. */
      data_read = ssh_buffer_len(&down->incoming);

      /* Add enough space to buffer for reading either header or
         entire packet.  This also sets `ptr' to point to the place
         where data should be read, and `data_to_read' to the number
         of bytes that should be there after reading (should read
         data_to_read - data_read bytes). */
      if (data_read < 4)
        {
          /* Packet header not yet in buffer.  Read only header. */
          data_to_read = 4;
          ssh_buffer_append_space(&down->incoming, &ptr, 4 - data_read);
        }
      else
        {
          /* Packet header already in buffer. */
          ptr = ssh_buffer_ptr(&down->incoming);
          data_to_read = 4 + SSH_GET_32BIT(ptr);
          if (data_to_read > 100000000L)
            ssh_fatal("ssh_packet_wrapper_input: "
                      "invalid packet received: len %ld",
                      (long)data_to_read);
          SSH_ASSERT(data_to_read > data_read);
          ssh_buffer_append_space(&down->incoming, &ptr,
                                  data_to_read - data_read);
        }

      /* Keep reading until entire packet read, or no more data available. */
      while (data_read < data_to_read)
        {
          /* Try to read the remaining bytes. */
          ptr = (unsigned char *)ssh_buffer_ptr(&down->incoming) + data_read;
          ret = ssh_stream_read(down->stream, ptr, data_to_read - data_read);
          if (ret < 0)
            {
              /* No more data available at this time.  Remove
                 allocated but unread space from end of buffer. */
              ssh_buffer_consume_end(&down->incoming,
                                     data_to_read - data_read);
              return return_value;
            }

          if (ret == 0)
            {
              /* EOF received. */
              ssh_buffer_consume_end(&down->incoming,
                                     data_to_read - data_read);
              down->incoming_eof = TRUE;

              /* Pass the EOF to the application callback. */
              down->cannot_destroy = TRUE;
              if (down->received_eof)
                (*down->received_eof)(down->context);
              down->cannot_destroy = FALSE;
              if (down->destroy_requested)
                {
                  ssh_packet_wrapper_destroy(down);
                  return FALSE;
                }
              return TRUE;
            }

          if (data_read < 4 && data_read + ret >= 4)
            {
              /* Header has now been fully received.  Prepare to receive rest
                 of packet. */
              data_read += ret;
              ptr = ssh_buffer_ptr(&down->incoming);
              data_to_read = 4 + SSH_GET_32BIT(ptr);
              if (data_to_read > 100000000L)
                ssh_fatal("ssh_packet_wrapper_input: "
                          "invalid packet received: len %ld",
                          (long)data_to_read);
              if (data_to_read > data_read)
                ssh_buffer_append_space(&down->incoming, &ptr,
                                    data_to_read - data_read);
            }
          else
            data_read += ret;
        }

      /* An entire packet has been received. */
      SSH_ASSERT(ssh_buffer_len(&down->incoming) == data_to_read);

      /* Get packet type. */
      ptr = ssh_buffer_ptr(&down->incoming);
      type = (SshPacketType)ptr[4];

      /* Call the application callback if set. */
      down->cannot_destroy = TRUE;
      if (down->received_packet)
        (*down->received_packet)(type, ptr + 5, data_to_read - 5,
                                 down->context);
      down->cannot_destroy = FALSE;
      if (down->destroy_requested)
        {
          ssh_packet_wrapper_destroy(down);
          return FALSE;
        }
      ssh_buffer_clear(&down->incoming);

      return_value = TRUE;
    }
  /*NOTREACHED*/
}
예제 #7
0
Boolean ssh_packet_wrapper_output(SshPacketWrapper down)
{
  int len;
  Boolean return_value = FALSE;

  /* Loop while we have data to output.  When all data has been sent,
     we check whether we need to send EOF. */
  while (ssh_buffer_len(&down->outgoing) > 0)
    {
      /* Write as much data as possible. */
      len = ssh_stream_write(down->stream, ssh_buffer_ptr(&down->outgoing),
                             ssh_buffer_len(&down->outgoing));
      if (len < 0)
        return return_value;  /* Cannot write more now. */
      if (len == 0)
        {
          /* EOF on output; will not be able to write any more. */
          down->outgoing_eof = TRUE;
          ssh_buffer_clear(&down->outgoing);
          return TRUE;
        }

      /* Consume written data. */
      ssh_buffer_consume(&down->outgoing, len);

      /* We've done something, so return TRUE. */
      return_value = TRUE;
    }

  /* All output has drained.  There is no more buffered data. */
  if (down->send_blocked)
    {
      down->cannot_destroy = TRUE;
      if (down->can_send)
        (*down->can_send)(down->context);
      down->cannot_destroy = FALSE;
      if (down->destroy_requested)
        {
          ssh_packet_wrapper_destroy(down);
          return FALSE;
        }
      down->send_blocked = FALSE;
    }

  /* If we should send EOF after output has drained, do it now. */
  if (down->outgoing_eof)
    ssh_stream_output_eof(down->stream);

  /* If we get here and the stream is shortcircuited, that means we had
     output data to drain before shortcircuiting. */
  if (down->shortcircuit_up_stream && !down->shortcircuited)
    {
      down->shortcircuited = TRUE;
      ssh_packet_impl_shortcircuit_now(down->shortcircuit_up_stream,
                                       down->stream);
    }

  /* If there's a destroy pending (that is, waiting for buffers to drain),
     do the destroy now. */
  if (down->destroy_pending)
    {
      /* Destroy the context now.  This also closes the stream. */
      ssh_packet_wrapper_destroy_now(down);

      /* Return FALSE to ensure that the loop in ssh_packet_wrapper_callback
         exits without looking at the context again. */
      return FALSE;
    }

  return return_value;
}
예제 #8
0
/* Callback, which is used to notify that our packetstream has a
   packet for us.*/
void auth_hostbased_received_packet(SshPacketType type,
                                    const unsigned char *packet,
                                    size_t packet_len,
                                    void *context)
{
  SshBuffer *b;

  SshClientHostbasedAuth state = (SshClientHostbasedAuth) context;
  
  switch(type)
    {
    case SSH_AUTH_HOSTBASED_PACKET:
      SSH_TRACE(2, ("ssh-signer returned SSH_AUTH_HOSTBASED_PACKET "\
                    "(this is an error)"));
      /* signer shouldn't send this to us, so this is an error.*/
      /* XXX */
      break;
    case SSH_AUTH_HOSTBASED_SIGNATURE:
      SSH_TRACE(2, ("ssh-signer returned SSH_AUTH_HOSTBASED_SIGNATURE"));
      /* We've got a signature. */
      b = ssh_buffer_allocate();


      /* Destroy wrapper (and signer) */
      ssh_packet_wrapper_send_eof(state->wrapper);
      ssh_packet_wrapper_destroy(state->wrapper);
      state->wrapper = NULL;
      
      ssh_encode_buffer(b,
                        /* public key algorithm (string) */
                        SSH_FORMAT_UINT32_STR,
                        state->pubkey_algorithm,
                        strlen(state->pubkey_algorithm),
                        /* public key (string) */
                        SSH_FORMAT_UINT32_STR, state->pubkeyblob,
                        state->pubkeyblob_len,
                        /* client host name (FQDN, string) */
                        SSH_FORMAT_UINT32_STR, state->local_host_name,
                        strlen(state->local_host_name),
                        /* user name at client side */
                        SSH_FORMAT_UINT32_STR, state->local_user_name,
                        strlen(state->local_user_name),
                        /* signature */
                        SSH_FORMAT_DATA, packet, packet_len,
                        SSH_FORMAT_END);

      /* Detach the state structure from the state_placeholder. */
      *state->state_placeholder = NULL;
  
      /* Call the authentication method completion procedure. */
      (*state->completion)(SSH_AUTH_CLIENT_SEND, state->user, b,
                           state->completion_context);

      /* Free the buffer */
      ssh_buffer_free(b);

      /* XXX Free the state. */

      break;
    case SSH_AUTH_HOSTBASED_ERROR:
      /* Destroy wrapper (and signer) */
      ssh_packet_wrapper_send_eof(state->wrapper);
      ssh_packet_wrapper_destroy(state->wrapper);
      state->wrapper = NULL;

      SSH_TRACE(0, ("ssh-signer returned SSH_AUTH_HOSTBASED_ERROR"));
      /* Send failure message to server, and return. */
      (*state->completion)(SSH_AUTH_CLIENT_FAIL, state->user, NULL,
                           state->completion_context);
      break;
    }
}