Esempio n. 1
0
void decode_case_int(SshEncodingFormat fmt, unsigned int value)
{
  SshUInt16 lv16;
  SshUInt32 lv32;
  size_t bytes;

  bytes = ssh_buffer_len(buffer);
  if (bytes != ssh_decode_array(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer),
                                      fmt, NULL, SSH_FORMAT_END))
    ssh_fatal("decode_case_int: NULL decode bad len");
  if (fmt == SSH_FORMAT_UINT32)
    {
      if (bytes != ssh_decode_buffer(buffer, fmt, &lv32, SSH_FORMAT_END))
	ssh_fatal("decode_case_int: bad returned len");
      if (lv32 != value)
	ssh_fatal("decode_case_int: bad value");
    }
  else if (fmt == SSH_FORMAT_UINT16)
    {
      if (bytes != ssh_decode_buffer(buffer, fmt, &lv16, SSH_FORMAT_END))
	ssh_fatal("decode_case_int: bad returned len");
      if (lv16 != value)
	ssh_fatal("decode_case_int: bad value");
    }
  else
    ssh_fatal("Unknown fmt");
  if (ssh_buffer_len(buffer) > 0)
    ssh_fatal("decode_case_int: data left");
}
Esempio n. 2
0
size_t ssh_packet_encode_va(SshBuffer *buffer,
                            SshPacketType type,
                            va_list ap)
{
  size_t payload_size, original_len;
  unsigned char *p;

  /* Save the original length so we can later find where the packet header
     starts. */
  original_len = ssh_buffer_len(buffer);

  /* Construct the packet header with dummy length. */
  ssh_encode_buffer(buffer,
                    SSH_FORMAT_UINT32, (SshUInt32) 0,
                    SSH_FORMAT_CHAR, (unsigned int)type,
                    SSH_FORMAT_END);

  /* Encode the packet payload. */
  payload_size = ssh_encode_va(buffer, ap);

  /* Update the packet header to contain the correct payload size. */
  p = ssh_buffer_ptr(buffer);
  p += original_len;
  SSH_PUT_32BIT(p, payload_size + 1);
  
  /* Return the total number of bytes added to the buffer. */
  return ssh_buffer_len(buffer) - original_len;
}
Esempio n. 3
0
void ssh_packet_wrapper_send_encode_va(SshPacketWrapper down,
                                       SshPacketType type,
                                       va_list va)
{
  /* Format the packet in a separate buffer. */
  ssh_buffer_clear(&down->outgoing_packet);
  ssh_packet_encode_va(&down->outgoing_packet, type, va);

  /* Check that we don't overflow maximum buffer size.  Drop the packet
     if we would. */
  if (ssh_buffer_len(&down->outgoing) +
      ssh_buffer_len(&down->outgoing_packet) >= BUFFER_MAX_SIZE)
    {
      ssh_debug("ssh_packet_wrapper_send_encode_va: flow control problems; "
                "outgoing packet dropped.");
      return;
    }

  /* Append the packet to the outgoing buffer. */
  ssh_buffer_append(&down->outgoing, ssh_buffer_ptr(&down->outgoing_packet),
                    ssh_buffer_len(&down->outgoing_packet));

  /* Reset the callback to ensure that our callback gets called. */
  ssh_stream_set_callback(down->stream, ssh_packet_wrapper_callback,
                          (void *)down);
}
Esempio n. 4
0
static void
ssh_eap_md5_client_recv_msg(SshEapProtocol protocol,
                            SshEap eap,
                            SshBuffer buf)
{
  SshEapMd5State state;
  unsigned char *ucp = NULL;

  state = ssh_eap_protocol_get_state(protocol);

  if (state == NULL)
    {
      ssh_eap_discard_packet(eap, protocol, buf,
                             "EAP MD5 state uninitialized");
      return;
    }

  if (state->challenge_buffer != NULL)
    {
      ssh_free(state->challenge_buffer);
      state->challenge_buffer =  NULL;
    }

  ucp = ssh_buffer_ptr(buf);

  if (ucp == NULL || (ssh_buffer_len(buf) < 6))
    {
      ssh_eap_discard_packet(eap, protocol, buf,
                             "packet length incorrect for EAP MD5 packet");
      return;
    }

  state->challenge_length = ucp[5];

  /* Note that RFC 1994 requires the challenge to be at least one octet */

  if (state->challenge_length == 0
      || (state->challenge_length + 6) > ssh_buffer_len(buf))
    {
      ssh_eap_discard_packet(eap, protocol, buf,
                             "EAP MD5 incorrect challenge length");
      return;
    }

  state->challenge_buffer = ssh_malloc(state->challenge_length);

  if (state->challenge_buffer == NULL)
    {
      ssh_eap_fatal(eap, protocol,
                    "Could not allocate buffer for challenge");
      return;
    }

  memcpy(state->challenge_buffer, ucp + 6, state->challenge_length);

  state->response_id = ssh_eap_packet_get_identifier(buf);

  ssh_eap_protocol_request_token(eap, protocol->impl->id,
                                 SSH_EAP_TOKEN_SHARED_SECRET);
}
Esempio n. 5
0
File: t-tr.c Progetto: AnthraX1/rk
Boolean handler_output_outgoing(Handler c)
{
  int len;
#ifdef DEBUG
  ssh_debug("handler_output_outgoing");
#endif
#ifdef DUMP_PACKETS
  buffer_dump(&c->outgoing); 
#endif
 

  while (ssh_buffer_len(&c->outgoing) > 0)
    {
      len = ssh_buffer_len(&c->outgoing);
      len = ssh_stream_write(c->stream, ssh_buffer_ptr(&c->outgoing), len);
      if (len == 0)
        ssh_fatal("%s: handler_output: error writing to stream", c->side);
      if (len < 0)
        return FALSE;
      ssh_buffer_consume(&c->outgoing, len);
    }

  if (c->outgoing_eof)
    ssh_stream_output_eof(c->stream);

  return TRUE;
}
Esempio n. 6
0
void ssh_channel_open_ssh1_agent_connected(SshStream stream,
                                          void *context)
{
  SshAgentConnection a = (SshAgentConnection)context;
  SshBuffer buffer;
  unsigned char *cp;

  if (stream == NULL)
    {
      SSH_DEBUG(1, ("Connecting to the real agent failed."));
      (*a->completion)(SSH_OPEN_CONNECT_FAILED,
                       NULL, FALSE, FALSE, 0, NULL, 0, NULL, NULL, NULL,
                       a->context);
      ssh_xfree(a);
      return;
    }

  SSH_DEBUG(5, ("connection to real agent established"));

  /* Increment the number of channels. */
  ssh_common_new_channel(a->common);

  if (a->common->config->ssh_agent_compat == SSH_AGENT_COMPAT_SSH2)
    {
      /* We are required to send a FORWARDING_NOTIFY to the agent to inform it
         that the connection is actually forwarded.  Format that packet now. */
      ssh_buffer_init(&buffer);
      ssh_encode_buffer(&buffer,
                        SSH_FORMAT_DATA, "1234", (size_t)4,
                        SSH_FORMAT_CHAR,
                        (unsigned int) SSH_AGENT_FORWARDING_NOTICE,
                        SSH_FORMAT_UINT32_STR,
                        a->common->server_host_name,
                        strlen(a->common->server_host_name),
                        SSH_FORMAT_UINT32_STR,
                        a->common->remote_ip, strlen(a->common->remote_ip),
                        SSH_FORMAT_UINT32,
                        (SshUInt32) atol(a->common->remote_port),
                        SSH_FORMAT_END);
      cp = ssh_buffer_ptr(&buffer);
      SSH_PUT_32BIT(cp, ssh_buffer_len(&buffer) - 4);

      /* Write the buffer to the channel.  This is a kludge; this assumes that
         we can always write this much to the internal buffers. */
      if (ssh_stream_write(stream, ssh_buffer_ptr(&buffer),
                           ssh_buffer_len(&buffer)) !=
          ssh_buffer_len(&buffer))
        ssh_fatal("ssh_channel_open_agent_connected: kludge failed");
      ssh_buffer_uninit(&buffer);
    }

  /* Create the channel. */
  (*a->completion)(SSH_OPEN_OK, stream, TRUE, TRUE, AGENT_WINDOW_SIZE, NULL, 0,
                   NULL, ssh_channel_ssh1_agent_connection_destroy,
                   (void *)a->common, a->context);
  ssh_xfree(a);
}
Esempio n. 7
0
Boolean
ssh2_key_blob_encode(unsigned long magic,
                     const char *subject, const char *comment,
                     const unsigned char *key, size_t keylen,
                     unsigned char **encoded, size_t *encoded_len)
{
  SshBufferStruct buffer;
  char *base64;
  unsigned int key_index;

  /* Translate to index. */
  switch (magic)
    {
    case SSH_KEY_MAGIC_PUBLIC:            key_index = 0; break;
    case SSH_KEY_MAGIC_PRIVATE:           key_index = 1; break;
    case SSH_KEY_MAGIC_PRIVATE_ENCRYPTED: key_index = 2; break;
    default:                                             return FALSE;
    }

  ssh_buffer_init(&buffer);

  /* Add the head for the key. */
  ssh_key_blob_dump_line_str(&buffer,
                             ssh2_pk_format_name_list[key_index].head);
  ssh_key_blob_dump_lf(&buffer);

  /* Handle key words. */
  if (subject)
    {
      ssh_key_blob_dump_line_str(&buffer, "Subject: ");
      ssh_key_blob_dump_line_str(&buffer, subject);
      ssh_key_blob_dump_lf(&buffer);
    }

  if (comment)
    {
      ssh_key_blob_dump_line_str(&buffer, "Comment: ");
      ssh_key_blob_dump_quoted_str(&buffer, 9, comment);
      ssh_key_blob_dump_lf(&buffer);
    }

  /* Now add the base64 formatted stuff. */
  base64 = (char *)ssh_buf_to_base64(key, keylen);
  ssh_key_blob_dump_str(&buffer, base64);
  ssh_key_blob_dump_lf(&buffer);
  ssh_xfree(base64);

  /* Add the tail for the key. */
  ssh_key_blob_dump_line_str(&buffer,
                             ssh2_pk_format_name_list[key_index].tail);
  ssh_key_blob_dump_lf(&buffer);

  *encoded_len = ssh_buffer_len(&buffer);
  *encoded = ssh_xmemdup(ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer));
  ssh_buffer_uninit(&buffer);
  return TRUE;
}
Esempio n. 8
0
static void
ssh_eap_md5_server_recv_msg(SshEapProtocol protocol,
                            SshEap eap,
                            SshBuffer buf)
{
  SshEapMd5State state;
  unsigned char *ucp = NULL;

  state = ssh_eap_protocol_get_state(protocol);

  if (state == NULL)
    {
      ssh_eap_discard_packet(eap, protocol, buf,
                             "eap md5 auth state not initialized");
      return;
    }
  ucp = ssh_buffer_ptr(buf);

  if (ucp == NULL || (ssh_buffer_len(buf) < 6))
    {
      ssh_eap_discard_packet(eap, protocol, buf,
                             "packet too short to be eap md5 response");
      return;
    }

  state->response_length = ucp[5] & 0xFF;

  if (state->response_length < 1
      || (state->response_length + 6) > ssh_buffer_len(buf))
    {
      ssh_eap_discard_packet(eap, protocol, buf,
                             "invalid ressponse value length");
      return;
    }

  SSH_ASSERT(state->response_buffer == NULL);

  state->response_buffer = ssh_malloc(state->response_length);

  if (state->response_buffer == NULL)
    {
      ssh_eap_fatal(eap, protocol,
                    "Could not cache challenge response. Out of memory");
      return;
    }

  memcpy(state->response_buffer, ucp + 6, state->response_length);

  ssh_eap_protocol_request_token(eap, protocol->impl->id,
                                 SSH_EAP_TOKEN_SHARED_SECRET);
}
Esempio n. 9
0
/* Handle the parsing of the single line string. */
static size_t
ssh_key_blob_get_line(const unsigned char *buf, size_t len,
                      char **string)
{
  size_t i, step, keep;
  SshBufferStruct buffer;

  ssh_buffer_init(&buffer);
  for (i = 0, step = 0, keep = 0; i < len; i++)
    {
      switch (buf[i])
        {
        case '\n':
          /* End. */
          step = i;
          goto end;
        case ' ':
        case '\t':
        case '\r':
          if (ssh_buffer_len(&buffer) == 0)
            {
              keep = 0;
              break;
            }
          keep = 1;
          break;
        default:
          if (keep)
            {
              ssh_xbuffer_append(&buffer, (const unsigned char *)" ", 1);
              keep = 0;
            }
          ssh_xbuffer_append(&buffer, &buf[i], 1);
          break;
        }
    }

end:

  /* Make a string. */
  *string = ssh_xmalloc(ssh_buffer_len(&buffer) + 1);
  memcpy(*string, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer));
  (*string)[ssh_buffer_len(&buffer)] = '\0';

  ssh_buffer_uninit(&buffer);

  return step;
}
Esempio n. 10
0
static int
ssh_appgw_http_unmarshal_string(SshBuffer buf, unsigned char **ptr)
{
  int len;

  *ptr = NULL;

  if (ssh_appgw_http_unmarshal_int(buf, &len) == 0)
    return 0;

  if (len == 0)
    return 1;

  if (ssh_buffer_len(buf) < len)
    return 0;

  *ptr = ssh_malloc(len+1);
  if (ptr == NULL)
    return 0;

  memcpy(*ptr,ssh_buffer_ptr(buf),len);
  (*ptr)[len] = '\0';
  ssh_buffer_consume(buf,len);
  return 1;

}
Esempio n. 11
0
void decode_case_char(SshEncodingFormat fmt, unsigned char value)
{
  unsigned int ch;
  size_t bytes;

  bytes = ssh_buffer_len(buffer);
  if (bytes != ssh_decode_array(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer),
                                      fmt, NULL, SSH_FORMAT_END))
    ssh_fatal("decode_case_char: NULL decode bad len");
  if (bytes != ssh_decode_buffer(buffer, fmt, &ch, SSH_FORMAT_END))
    ssh_fatal("decode_case_char: bad returned len");
  if (ch != value)
    ssh_fatal("decode_case_char: bad value");
  if (ssh_buffer_len(buffer) > 0)
    ssh_fatal("decode_case_char: data left");
}
Esempio n. 12
0
void decode_case_bool(SshEncodingFormat fmt, Boolean value)
{
  Boolean boo;
  size_t bytes;

  bytes = ssh_buffer_len(buffer);
  if (bytes != ssh_decode_array(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer),
                                      fmt, NULL, SSH_FORMAT_END))
    ssh_fatal("decode_case_bool: NULL decode bad len");
  if (bytes != ssh_decode_buffer(buffer, fmt, &boo, SSH_FORMAT_END))
    ssh_fatal("decode_case_bool: bad returned len");
  if (boo != value)
    ssh_fatal("decode_case_bool: bad value");
  if (ssh_buffer_len(buffer) > 0)
    ssh_fatal("decode_case_bool: data left");
}
Esempio n. 13
0
void connect1_write(SshStream stream)
{
  int len;
  while (ssh_buffer_len(&send_buffer) > 0)
    {
      len = ssh_buffer_len(&send_buffer);
      len = ssh_stream_write(stream, ssh_buffer_ptr(&send_buffer), len);
      if (len < 0)
	return;
      if (len == 0)
	ssh_fatal("connect1_write failed");
      ssh_buffer_consume(&send_buffer, len);
    }
  ssh_stream_output_eof(stream);
  ssh_stream_destroy(stream);
}
Esempio n. 14
0
void encode_case(const char *name, const char *expect,
                 size_t expect_len, ...)
{
  size_t len, i, bytes;
  unsigned char ch, *cp;
  va_list va;

  ssh_buffer_clear(buffer);
  len = rand() % 100;
  ch = rand();
  for (i = 0; i < len; i++)
    ssh_buffer_append(buffer, &ch, 1);

  va_start(va, expect_len);
  bytes = ssh_encode_buffer_va(buffer, va);

  if (bytes != expect_len || ssh_buffer_len(buffer) != len + expect_len)
    ssh_fatal("test_encode: %s: unexpected length %d vs. %d",
              name, bytes, len + expect_len);
  cp = ssh_buffer_ptr(buffer);
  if (memcmp(expect, cp + len, expect_len) != 0)
    ssh_fatal("test_encode: %s: mismatch", name);

  for (i = 0; i < len; i++)
    if (cp[i] != ch)
      ssh_fatal("test_encode: %s: beginning corrupted", name);
  ssh_buffer_consume(buffer, len);
}
Esempio n. 15
0
/*
 * Parse reply method. This doesn't do anything with SOCKS4.
 */
SocksError ssh_socks_client_parse_method(SshBuffer buffer,
                                         SocksInfo *socksinfo)
{
  size_t ret = 0L, len;
  unsigned int version, method;
  unsigned char *data;

  data = ssh_buffer_ptr(buffer);
  len = ssh_buffer_len(buffer);

  if (len < 1)
    return SSH_SOCKS_TRY_AGAIN;

  version = *data;
  if (version == 0)
    version = 4;

  if (version == 4)
    return SSH_SOCKS_SUCCESS;

  if (len < 2)
    return SSH_SOCKS_TRY_AGAIN;

  ret = ssh_decode_buffer(buffer,
                          SSH_DECODE_CHAR(&version),
                          SSH_DECODE_CHAR(&method),
                          SSH_FORMAT_END);
  if (ret == 0)
    {
      SSH_DEBUG(2, ("Decoding method buffer failed."));
      return SSH_SOCKS_ERROR_PROTOCOL_ERROR;
    }
  if (method != SSH_SOCKS5_AUTH_METHOD_NO_AUTH_REQD)
    {
      SSH_DEBUG(2, ("Server sent method 0x%x.", method));
      if (method == SSH_SOCKS5_AUTH_METHOD_NO_ACCEPTABLE)
        {
          SSH_DEBUG(2, ("Server doesn't allow use without some authentication "
                        "(we don't implement any methods)."));
        }
      else
        {
          SSH_DEBUG(2, ("Server sent method that we don't support."));
          return SSH_SOCKS_ERROR_PROTOCOL_ERROR;
        }
      return SSH_SOCKS_FAILED_AUTH;
    }
  if (socksinfo)
    {
      *socksinfo = ssh_calloc(1, sizeof(**socksinfo));
      if (*socksinfo == NULL)
        {
          SSH_DEBUG(2, ("Couldn't allocate SshSocksInfo."));
          return SSH_SOCKS_ERROR_INVALID_ARGUMENT;
        }
      (*socksinfo)->socks_version_number = version;
    }
  return SSH_SOCKS_SUCCESS;
}
Esempio n. 16
0
void copy_data_test(SshStream s1, SshStream s2)
{
  ts1 = s1;
  ts2 = s2;

  create_testdata();
  if (received_data)
    ssh_buffer_clear(received_data);
  else
    received_data = ssh_buffer_allocate();
  test_data_index = 0;
  destroy_count = 0;
  reader_sent_eof = FALSE;

  ssh_stream_set_callback(s1, copy_writer, NULL);
  ssh_stream_set_callback(s2, copy_reader, NULL);

  ssh_event_loop_run();
  if (destroy_count != 2 || ts1 != NULL || ts2 != NULL)
    ssh_fatal("copy_data_test: one stream not destroyed");
  if (ssh_buffer_len(received_data) > ssh_buffer_len(testdata))
    ssh_fatal("copy_data_test: received more data than sent");
  if (break_test)
    ssh_buffer_consume_end(testdata,
                           ssh_buffer_len(testdata)
                           - ssh_buffer_len(received_data));
  if (ssh_buffer_len(testdata) != ssh_buffer_len(received_data))
    ssh_fatal("copy_data_test: data lens differ");
  if (memcmp(ssh_buffer_ptr(testdata), ssh_buffer_ptr(received_data),
             ssh_buffer_len(testdata)) != 0)
    ssh_fatal("copy_data_test: received data differs");
}
Esempio n. 17
0
void test_functions_parse_compound(SshBuffer buffer, ...)
{
  va_list va;

  va_start(va, buffer);
  if (ssh_decode_array_va(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer), va)
      != 4)
    ssh_fatal("test_functions_parse_compound error");
}
Esempio n. 18
0
void decode_case_data(SshEncodingFormat fmt,
                      const char *value, size_t valuelen)
{
  char buf[1024];
  size_t bytes;

  SSH_ASSERT(valuelen < sizeof(buf));
  bytes = ssh_buffer_len(buffer);
  if (bytes != ssh_decode_array(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer),
                                      fmt, NULL, valuelen, SSH_FORMAT_END))
    ssh_fatal("decode_case_data: NULL decode bad len");
  if (bytes != ssh_decode_buffer(buffer, fmt, buf, valuelen,
                                       SSH_FORMAT_END))
    ssh_fatal("decode_case_data: bad returned len");
  if (memcmp(buf, value, valuelen) != 0)
    ssh_fatal("decode_case_data: bad value");
  if (ssh_buffer_len(buffer) > 0)
    ssh_fatal("decode_case_data: data left");
}
Esempio n. 19
0
void decode_case_str(SshEncodingFormat fmt, const char *value, size_t valuelen)
{
  unsigned char *cp;
  size_t len, bytes;

  bytes = ssh_buffer_len(buffer);
  if (bytes != ssh_decode_array(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer),
                                      fmt, NULL, NULL, SSH_FORMAT_END))
    ssh_fatal("decode_case_str: NULL decode bad len");
  if (bytes != ssh_decode_buffer(buffer, fmt, &cp, &len, SSH_FORMAT_END))
    ssh_fatal("decode_case_str: bad returned len");
  if (len != valuelen || memcmp(cp, value, len) != 0)
    ssh_fatal("decode_case_str: bad cmp");
  if (ssh_buffer_len(buffer) > 0)
    ssh_fatal("decode_case_str: data left");
  if (cp[len] != 0)
    ssh_fatal("decode_case_str: not null terminated");
  ssh_xfree(cp);
}
Esempio n. 20
0
void ssh_packet_impl_send_encode_va(SshStream up_stream,
                                    SshPacketType type,
                                    va_list va)
{
  SshPacketImpl up;

  /* Verify that it is a SshPacketImpl stream. */
  if (ssh_stream_get_methods(up_stream) != &ssh_packet_impl_methods)
    ssh_fatal("ssh_packet_impl_can_receive: not a SshPacketImpl stream");
  /* Get the internal context. */
  up = (SshPacketImpl)ssh_stream_get_context(up_stream);

  /* Format the packet in a separate buffer. */
  ssh_buffer_clear(&up->outgoing_packet);
  ssh_packet_encode_va(&up->outgoing_packet, type, va);

  /* Check that we don't overflow maximum buffer size.  Drop the
     packet if we would. */
  if (ssh_buffer_len(&up->outgoing) + ssh_buffer_len(&up->outgoing_packet) >=
      BUFFER_MAX_SIZE)
    {
      ssh_debug("ssh_packet_impl_send_encode_va: "
                "flow control problems; outgoing packet dropped.");
      return;
    }

  /* Append the packet to the outgoing buffer. */
  if (ssh_buffer_append(&up->outgoing,
                        ssh_buffer_ptr(&up->outgoing_packet),
                        ssh_buffer_len(&up->outgoing_packet)) != SSH_BUFFER_OK)
    {
      return;
    }

  /* Restart reads by upper level. */
  ssh_packet_impl_restart_input(up);

  /* Sanity check that we didn't exceed max buffer size. */
  if (ssh_buffer_len(&up->outgoing) > BUFFER_MAX_SIZE)
    ssh_debug("ssh_packet_impl_send: buffer max size exceeded: size %ld",
              (long)ssh_buffer_len(&up->outgoing));
}
Esempio n. 21
0
void ssh_packet_wrapper_send_eof(SshPacketWrapper down)
{
  /* If EOF already sent, return immediately. */
  if (down->outgoing_eof)
    return;

  /* Otherwise, send EOF now. */
  down->outgoing_eof = TRUE;
  if (ssh_buffer_len(&down->outgoing) == 0)
    ssh_stream_output_eof(down->stream);
}
Esempio n. 22
0
void ssh_packet_shortcircuit(SshStream packet_stream,
                             SshPacketWrapper wrapper)
{
  /* Mark that the stream is shortcircuited. */
  wrapper->shortcircuited = FALSE;
  wrapper->shortcircuit_up_stream = packet_stream;

#if 0 /* the packet is still in wrapper->incoming when we call the callback */
  /* Sanity check: there must not be data in incoming buffer. */
  if (ssh_buffer_len(&wrapper->incoming) != 0)
    ssh_fatal("ssh_packet_shortcircuit: incoming data in buffer; not set in packet callback");
#endif /* 0 */

  /* If there is no data to drain, shortcircuit output now. */
  if (ssh_buffer_len(&wrapper->outgoing) == 0)
    {
      wrapper->shortcircuited = TRUE;
      ssh_packet_impl_shortcircuit_now(wrapper->shortcircuit_up_stream,
                                       wrapper->stream);
    }
}
Esempio n. 23
0
static int
ssh_appgw_http_unmarshal_int(SshBuffer buf, int *result)
{
  if (ssh_buffer_len(buf) < 4)
    {
      *result = 0;
      return 0;
    }

  *result = (int)(SSH_GET_32BIT(ssh_buffer_ptr(buf)));
  ssh_buffer_consume(buf,4);
  return 1;
}
Esempio n. 24
0
Boolean ssh_packet_wrapper_can_send(SshPacketWrapper down)
{
  Boolean status;

  status = ssh_buffer_len(&down->outgoing) <
    BUFFER_MAX_SIZE - ALLOW_AFTER_BUFFER_FULL;

  /* If no more can be sent, mark that sending is blocked.  This will
     trigger a callback when data can again be sent. */
  if (!status)
    down->send_blocked = TRUE;

  return status;
}
Esempio n. 25
0
int ssh_packet_impl_read(void *context, unsigned char *buf, size_t size)
{
  SshPacketImpl up = (SshPacketImpl)context;
  size_t len;

  /* Compute the number of bytes we can transmit. */
  len = ssh_buffer_len(&up->outgoing);
  if (len > size)
    len = size;

  /* Return immediately if no data available. */
  if (len == 0)
    {
      /* If shortcircuiting, pass it to the shortcircuit stream. */
      if (up->shortcircuit_stream)
        return ssh_stream_read(up->shortcircuit_stream, buf, size);

      /* Return EOF or "no more data available yet". */
      if (up->outgoing_eof)
        return 0;
      else
        {
          up->up_read_blocked = TRUE;
          return -1;
        }
    }

  /* Move data to the caller's buffer. */
  memcpy(buf, ssh_buffer_ptr(&up->outgoing), len);
  ssh_buffer_consume(&up->outgoing, len);

  /* Wake up the sender if appropriate. */
  if (ssh_buffer_len(&up->outgoing) == 0)
    ssh_packet_impl_restart_send(up);

  return len;
}
Esempio n. 26
0
void copy_writer(SshStreamNotification op, void *context)
{
  int len;
  int len2;
  unsigned char buf[100];

  if (op != SSH_STREAM_CAN_OUTPUT)
    return;

  for (;;)
    {
      len = ssh_buffer_len(testdata) - test_data_index;
      len2 = ssh_rand() % 100000;
      if (len <= 0)
        {
          if (ssh_rand() % 2 == 0)
            ssh_stream_output_eof(ts1);
          ssh_stream_destroy(ts1);
          ts1 = NULL;
          destroy_count++;
          return;
        }
      if (len > len2)
        len = len2;
      len = ssh_stream_write(ts1, (unsigned char *)ssh_buffer_ptr(testdata) +
                             test_data_index, len);
      if (len == 0)
        {
          if (ssh_rand() % 2 == 0)
            ssh_stream_output_eof(ts1);
          ssh_stream_destroy(ts1);
          ts1 = NULL;
          destroy_count++;
          return; /* Eof while writing. */
        }
      if (len < 0)
        return; /* Cannot write more at this time */
      test_data_index += len;

      if (ssh_rand() % 5 == 0)
        {
          len = ssh_stream_read(ts1, buf, sizeof(buf));
          if (len == 0 && !reader_sent_eof)
            ssh_fatal("copy_writer: read returned EOF when not sent");
          if (len > 0)
            ssh_fatal("copy_writer: read > 0");
        }
    }
}
Esempio n. 27
0
/*
 * Parse methods array. This doesn't do anything with SOCKS4.
 */
SocksError ssh_socks_server_parse_methods(SshBuffer buffer,
                                          SocksInfo *socksinfo)
{
  size_t ret = 0L, len;
  unsigned int version, num_methods;
  unsigned char *data;

  data = ssh_buffer_ptr(buffer);
  len = ssh_buffer_len(buffer);

  if (len < 1)
    return SSH_SOCKS_TRY_AGAIN;

  version = *data;

  if (version == 4)
    goto return_success;

  if (len < 2)
    return SSH_SOCKS_TRY_AGAIN;

  ret = ssh_decode_array(data, len,
                         SSH_DECODE_CHAR(&version),
                         SSH_DECODE_CHAR(&num_methods),
                         SSH_FORMAT_END);
  if (ret == 0)
    {
      SSH_DEBUG(2, ("Decoding methods buffer failed."));
      return SSH_SOCKS_ERROR_PROTOCOL_ERROR;
    }
  if (len < num_methods + 2)
    return SSH_SOCKS_TRY_AGAIN;

  ssh_buffer_consume(buffer, num_methods + 2);

 return_success:
  if (socksinfo)
    {
      *socksinfo = ssh_calloc(1, sizeof(**socksinfo));
      if (*socksinfo == NULL)
        {
          SSH_DEBUG(2, ("Couldn't allocate SshSocksInfo."));
          return SSH_SOCKS_ERROR_INVALID_ARGUMENT;
        }
      (*socksinfo)->socks_version_number = version;
    }
  return SSH_SOCKS_SUCCESS;
}
Esempio n. 28
0
void test_encode(void)
{
  encode_case("uint32_str 0", "\0\0\0\0", 4,
              SSH_ENCODE_UINT32_STR(NULL, 0), SSH_FORMAT_END);
  decode_case_str(SSH_FORMAT_UINT32_STR, "", 0);
  encode_case("uint32_str 0", "\0\0\0\0", 4,
              SSH_ENCODE_UINT32_SSTR("ABC", 0), SSH_FORMAT_END);
  decode_case_str(SSH_FORMAT_UINT32_STR, "", 0);
  encode_case("uint32_str 5", "\0\0\0\5ABCDE", 9,
              SSH_ENCODE_UINT32_SSTR("ABCDEFGHIJK", 5), SSH_FORMAT_END);
  decode_case_str(SSH_FORMAT_UINT32_STR, "ABCDE", 5);

  encode_case("uint32 0x12345678", "\22\64\126\170", 4,
              SSH_ENCODE_UINT32(0x12345678), SSH_FORMAT_END);
  decode_case_int(SSH_FORMAT_UINT32, (SshUInt32) 0x12345678);

  encode_case("uint16 0x1234", "\22\64", 2,
              SSH_ENCODE_UINT16(0x1234), SSH_FORMAT_END);
  decode_case_int(SSH_FORMAT_UINT16, (SshUInt16) 0x1234);

  encode_case("boolean FALSE", "\0", 1,
              SSH_ENCODE_BOOLEAN(FALSE), SSH_FORMAT_END);
  decode_case_bool(SSH_FORMAT_BOOLEAN, FALSE);
  encode_case("boolean TRUE", "\1", 1,
              SSH_ENCODE_BOOLEAN(TRUE), SSH_FORMAT_END);
  decode_case_bool(SSH_FORMAT_BOOLEAN, TRUE);
  encode_case("boolean 0xff", "\1", 1,
              SSH_ENCODE_BOOLEAN(0xff), SSH_FORMAT_END);
  decode_case_bool(SSH_FORMAT_BOOLEAN, TRUE);



  encode_case("char 0x12", "\22", 1,
              SSH_ENCODE_CHAR(0x12), SSH_FORMAT_END);
  decode_case_char(SSH_FORMAT_CHAR, (unsigned int) 0x12);
  encode_case("char 0xee", "\356", 1,
              SSH_ENCODE_CHAR(0xee), SSH_FORMAT_END);
  decode_case_char(SSH_FORMAT_CHAR, (unsigned int) 0xee);
  encode_case("data foo\\0bar", "foo\0bar", 7,
              SSH_ENCODE_DATA("foo\0bar", 7), SSH_FORMAT_END);
  decode_case_data(SSH_FORMAT_DATA, "foo\0bar", 7);
  encode_case("nothing", "", 0, SSH_FORMAT_END);
  if (ssh_buffer_len(buffer) != 0)
    ssh_fatal("``nothing'' encoded to non-empty");
}
Esempio n. 29
0
static int
cm_debug_renderer_return(SshBuffer buffer, unsigned char *buf, int len)
{
  int l = ssh_buffer_len(buffer);

  if (l > len)
    {
      ssh_ustrncpy(buf, ssh_buffer_ptr(buffer), len - 1);
      ssh_buffer_uninit(buffer);
      return len + 1;
    }
  else
    {
      ssh_ustrncpy(buf, ssh_buffer_ptr(buffer), l);
      ssh_buffer_uninit(buffer);
      return l;
    }
}
Esempio n. 30
0
/* 
 * Inserts specified event into log file specified in context.
 * event parameter specifies the audited event. Each element after event 
 * must start with a SshAuditformat type followed by arguments of the 
 * appropriate type, and the list must end with SSH_AUDIT_ARGUMENT_END.
 */
void ssh_audit_event(SshAuditContext context, SshAuditEvent event, ...)
{
  size_t bytes;
  va_list ap;
  SshBuffer *audit_info, *formated_str;
  char *audit_time;

  if (context == NULL) return;

  if ((event < 0) || (event > SSH_AUDIT_MAX_VALUE)) return;
  /* Check if given event is allowed */
  if (!context->ssh_audit_event_allowed[(int)event]) return;

  /* Initialize a buffer for output string */
  audit_info = ssh_buffer_allocate();

  /* Start constructing string which will be inserted into audit log.*/
  /* Start with inserting the name of the event.*/
  /* then date and time */
  audit_time = ssh_time_string(ssh_time());
  ssh_buffer_append_cstrs(audit_info, 
                          ssh_find_keyword_name(ssh_audit_event_title, 
                                                (int)event),
                          ": ", audit_time, ": ", 
                          NULL); 
  ssh_xfree(audit_time);

  /* Handle the variable list*/
  va_start(ap, event);
  formated_str = ssh_format_audit_string(ap);
  va_end(ap);

  /* Insert given parameters into string*/
  ssh_buffer_append(audit_info, 
                    ssh_buffer_ptr(formated_str),
                    ssh_buffer_len(formated_str));
  ssh_buffer_append(audit_info, (unsigned char *) "\0", 1);

  /* Output the log message*/
  ssh_send_log_message(context, ssh_buffer_ptr(audit_info));

  ssh_buffer_free(formated_str);
  ssh_buffer_free(audit_info);
}