Exemple #1
0
int main(int ac, char **av)
{
  int i, j;
  int pass;
  unsigned char buf[1024];

  snprintf(lpath1, sizeof (lpath1), "/tmp/lstr1.%x", (unsigned)random());
  snprintf(lpath2, sizeof (lpath2), "/tmp/lstr2.%x", (unsigned)random());
  
  printf("Doing %d iterations of localstream test:", PASSES);

  for (pass = 0; pass < PASSES; pass++)
    {
      printf(" %d", pass);
      fflush(stdout);

      ssh_buffer_init(&send_buffer);
      ssh_buffer_init(&expect_buffer);
      
      for (i = 0; i < 100; i++)
	{
	  for (j = 0; j < sizeof(buf); j++)
	    buf[j] = random();
	  ssh_buffer_append(&send_buffer, buf, sizeof(buf));
	  ssh_buffer_append(&expect_buffer, buf, sizeof(buf));
	  send_count += sizeof(buf);
	}

      ssh_event_loop_initialize();

      remove(lpath1);
      listener1 = ssh_local_make_listener(lpath1, 
					  listener1_callback,
					  (void *)4);
      if (!listener1) {
	  ssh_fatal("cannot create listener1");
      }

      ssh_local_connect(lpath1, connect1_done, (void *)3);

      ssh_event_loop_run();

      ssh_event_loop_uninitialize();

      ssh_buffer_uninit(&send_buffer);
      ssh_buffer_uninit(&expect_buffer);
      
    }
  printf("\n");
  
  return 0;
}
SshStream ssh_packet_impl_create(SshPacketReceiveProc received_packet,
                                 SshPacketEofProc received_eof,
                                 SshPacketCanSendProc can_send,
                                 SshPacketImplDestroyProc destroy,
                                 void *context)
{
  SshPacketImpl up;
  SshStream stream;

  /* Allocate and initialize the context. */
  if ((up = ssh_calloc(1, sizeof(*up))) == NULL)
    return NULL;

  ssh_buffer_init(&up->incoming);
  ssh_buffer_init(&up->outgoing);
  ssh_buffer_init(&up->outgoing_packet);
  up->can_receive = FALSE;
  up->incoming_eof = FALSE;
  up->outgoing_eof = FALSE;
  up->up_write_blocked = FALSE;
  up->up_read_blocked = FALSE;
  up->send_blocked = TRUE; /* Cause a callback immediately. */

  /* Save the callback functions. */
  up->received_packet = received_packet;
  up->received_eof = received_eof;
  up->can_send = can_send;
  up->destroy = destroy;
  up->context = context;

  up->up_callback = NULL_FNPTR;
  up->up_context = NULL;

  /* Cause the send callback to be called if non-NULL.  Note that it isn't
     called until from the bottom of the event loop. */
  ssh_packet_impl_restart_send(up);

  /* Wrap it into a stream. */
  stream = ssh_stream_create(&ssh_packet_impl_methods, (void *)up);

  if (stream == NULL)
    ssh_fatal("Insufficient memory to create packet stream object!");

  /* Enable receives. */
  ssh_packet_impl_can_receive(stream, TRUE);

  return stream;
}
Exemple #3
0
SshBuffer *ssh_buffer_allocate()
{
  SshBuffer *buffer = ssh_xmalloc(sizeof(*buffer));
  ssh_buffer_init(buffer);
  buffer->dynamic = TRUE;
  return buffer;
}
Exemple #4
0
int
ssh_cm_render_state(unsigned char *buf, int len, int precision, void *datum)
{
  SshCMSearchState state = *(unsigned int *)((void *)&datum);
  int i;
  const char *name;
  SshBufferStruct buffer;

  ssh_buffer_init(&buffer);
  ssh_buffer_append_str(&buffer, "\nsearch-state = \n{\n");
  if (state == 0)
    ssh_buffer_append_str(&buffer, "  nil\n");
  else
    {
      for (i = 0; i < 32; i++)
        {
          if (state & (1 << i))
            {
              name =
                ssh_find_keyword_name(ssh_cm_debug_state_strs, (1 << i));
              ssh_buffer_append_cstrs(&buffer, "  ", name, "\n", NULL);
            }
        }
    }
  ssh_buffer_append_str(&buffer, "}\n");
  return cm_debug_renderer_return(&buffer, buf, len);
}
Exemple #5
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);
}
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;
}
/* Initialize an already allocated file buffer */
void ssh_file_buffer_init(SshFileBuffer buf)
{
  SSH_ASSERT(buf != NULL);
  buf->attached_as_fileptr = FALSE;
  buf->f = NULL;
  buf->read_callback = NULL_FNPTR;
  buf->read_context = NULL;
  ssh_buffer_init(&(buf->buf));
  return;
}
Exemple #8
0
int
ssh_cm_render_crl(unsigned char *buf, int len, int precision, void *datum)
{
  SshX509Crl crl = datum;
  char *name;
  SshBerTimeStruct this_update, next_update;
  SshBufferStruct buffer;

  if (crl)
    {
      ssh_buffer_init(&buffer);

      ssh_buffer_append_str(&buffer, "\ncrl = { \n");
      if (!ssh_x509_crl_get_issuer_name(crl, &name))
        {
          ssh_buffer_append_str(&buffer, "  missing-issuer-name\n");
        }
      else
        {
          ssh_buffer_append_cstrs(&buffer,
                                  "  issuer-name = <", name, ">\n", NULL);
          ssh_free(name);
        }

      if (!ssh_x509_crl_get_update_times(crl, &this_update, &next_update))
        {
          ssh_buffer_append_str(&buffer, "  missing-update-times\n");
        }
      else
        {
          if (ssh_ber_time_available(&this_update))
            {
              ssh_ber_time_to_string(&this_update, &name);
              ssh_buffer_append_cstrs(&buffer,
                                      "  this-update = ", name, "\n", NULL);
              ssh_free(name);
            }
          if (ssh_ber_time_available(&next_update))
            {
              ssh_ber_time_to_string(&next_update, &name);
              ssh_buffer_append_cstrs(&buffer,
                                      "  next-update = ", name, "\n", NULL);
              ssh_free(name);
            }
        }

      /* Finished. */
      ssh_buffer_append_str(&buffer, "}\n");
      return cm_debug_renderer_return(&buffer, buf, len);
    }
  return 0;
}
Exemple #9
0
SshPacketWrapper ssh_packet_wrap(SshStream down_stream,
                                 SshPacketReceiveProc received_packet,
                                 SshPacketEofProc received_eof,
                                 SshPacketCanSendProc can_send,
                                 void *context)
{
  SshPacketWrapper down;

  down = ssh_xcalloc(1, sizeof(*down));
  down->stream = down_stream;
  ssh_buffer_init(&down->incoming);
  ssh_buffer_init(&down->outgoing);
  ssh_buffer_init(&down->outgoing_packet);
  down->incoming_eof = FALSE;
  down->outgoing_eof = FALSE;
  down->send_blocked = TRUE;
  down->can_receive = FALSE;
  down->destroy_pending = FALSE;
  down->cannot_destroy = FALSE;
  down->destroy_requested = FALSE;
  down->shortcircuited = FALSE;

  /* Save the callback functions. */
  down->received_packet = received_packet;
  down->received_eof = received_eof;
  down->can_send = can_send;
  down->context = context;

  /* Set callback for the downward stream.  Note that this will also cause
     can_send to be called from the output callback. */
  ssh_stream_set_callback(down->stream, ssh_packet_wrapper_callback,
                          (void *)down);

  /* Enable receives. */
  ssh_packet_wrapper_can_receive(down, TRUE);

  return down;
}
Exemple #10
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;
}
Exemple #11
0
int
ssh_cm_render_mp(unsigned char *buf, int len, int precision, void *datum)
{
  SshMPInteger mpint;
  char *tmp;
  SshBufferStruct buffer;

  mpint = datum;
  if ((tmp = ssh_mprz_get_str(mpint, 10)) != NULL)
    {
      ssh_buffer_init(&buffer);
      ssh_buffer_append_str(&buffer, tmp);
      ssh_free(tmp);
      return cm_debug_renderer_return(&buffer, buf, len);
    }
  return 0;
}
SshAuditSyslogContext
ssh_audit_syslog_create(SshLogFacility facility, SshLogSeverity severity,
			SshAuditFormatType format)
{
  SshAuditSyslogContext ctx;

  ctx = ssh_calloc(1, sizeof(*ctx));
  if (ctx == NULL)
    return NULL;

  ctx->facility = facility;
  ctx->severity = severity;
  ctx->format = format;

  ssh_buffer_init(&ctx->buffer);

  return ctx;
}
Exemple #13
0
void ssh_channel_start_remote_tcp_forward(SshCommon common,
                                          const char *address_to_bind,
                                          const char *port,
                                          const char *connect_to_host,
                                          const char *connect_to_port,
                                          void (*completion)(Boolean ok,
                                                             void *context),
                                          void *context)
{
  SshRemoteTcpForward fwd;
  SshBuffer buffer;
  SshChannelTypeTcpForward ct;

  SSH_DEBUG(5, ("requesting remote forwarding for port %s", port));

  ct = ssh_channel_ftcp_ct(common);
  
  /* Create a context for the forwarding. */
  fwd = ssh_xcalloc(1, sizeof(*fwd));
  fwd->common = common;
  fwd->address_to_bind = ssh_xstrdup(address_to_bind);
  fwd->port = ssh_xstrdup(port);
  fwd->connect_to_host = ssh_xstrdup(connect_to_host);
  fwd->connect_to_port = ssh_xstrdup(connect_to_port);

  /* Add it to the list of remote forwardings. */
  fwd->next = ct->remote_forwards;
  ct->remote_forwards = fwd;

  /* Send a forwarding request to the remote side. */
  ssh_buffer_init(&buffer);
  ssh_encode_buffer(&buffer,
                    SSH_FORMAT_UINT32_STR,
                      address_to_bind, strlen(address_to_bind),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(port),
                    SSH_FORMAT_END);
  ssh_conn_send_global_request(common->conn, "tcpip-forward",
                               ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer),
                               completion, context);
  ssh_buffer_uninit(&buffer);
}
Exemple #14
0
void ssh_channel_dtcp_open_to_remote(SshCommon common, SshStream stream,
                                     const char *connect_to_host,
                                     const char *connect_to_port,
                                     const char *originator_ip,
                                     const char *originator_port)
{
  SshBuffer buffer;

  SSH_DEBUG(5, ("opening direct TCP/IP connection to %s:%s originator %s:%s",
                connect_to_host, connect_to_port,
                originator_ip, originator_port));

  /* Register that we have a new channel. */
  ssh_common_new_channel(common);

  /* Format the channel open request in a buffer. */
  ssh_buffer_init(&buffer);
  ssh_encode_buffer(&buffer,
                    SSH_FORMAT_UINT32_STR,
                      connect_to_host, strlen(connect_to_host),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(connect_to_port),
                    SSH_FORMAT_UINT32_STR,
                      originator_ip, strlen(originator_ip),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(originator_port),
                    SSH_FORMAT_END);
  
  /* Send the channel open request. */
  ssh_conn_send_channel_open(common->conn, "direct-tcpip",
                             stream, TRUE, FALSE, SSH_TCPIP_WINDOW,
                             SSH_TCPIP_PACKET_SIZE,
                             ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer),
                             NULL, 
                             ssh_channel_tcp_connection_destroy,
                             (void *)common, NULL, NULL);

  ssh_buffer_uninit(&buffer);
}
Exemple #15
0
/* Handle the quoted string parsing. */
size_t
ssh_key_blob_get_string(const unsigned char *buf, size_t len,
                        char **string)
{
  unsigned int quoting, ret_quoting;
  SshBufferStruct buffer;
  size_t step, i, j;

  ssh_buffer_init(&buffer);
  for (i = 0, step = 0, quoting = 0, ret_quoting = 0; i < len; i++)
    {
      switch (quoting)
        {
        case 0:
          switch (buf[i])
            {
            case ' ':
            case '\n':
            case '\r':
            case '\t':
              /* Skip! */
              break;
            case '\"': /* " */
              quoting = 2;
              ret_quoting = 0;
              break;
            default:
              /* End! */
              step = i;
              goto end;
            }
          break;
        case 1:
          if (buf[i] == '\n')
            {
              for (j = 0; isspace(buf[i + j]) && i + j < len;
                   j++)
                ;
              i = i + j - 1;
            }
          quoting = ret_quoting;
          ret_quoting = 0;
          break;
        case 2:
          switch (buf[i])
            {
            case '\\':
              quoting = 1;
              ret_quoting = 2;
              break;
            case '\"': /* " */
              quoting = 0;
              ret_quoting = 0;
              break;
            default:
              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;
}
Exemple #16
0
int main(int ac, char **av)
{
  unsigned int pass, i;
  SshBuffer buffer, buffer2;
  SocksInfo socksinfo, socksreturn;
  SocksError ret;

  ssh_buffer_init(&buffer);
  ssh_buffer_init(&buffer2);
  for(pass = 0; pass < 20000; pass++)
    {
      ssh_buffer_clear(&buffer);
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 4;
      socksinfo->command_code = (pass & 1) + 1;
      socksinfo->ip =
	ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) /
				   sizeof(ip_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) /
				     sizeof(port_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_client_generate_open(&buffer, socksinfo) !=
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_client_generate_open fails");
      if (pass & 1)
	{
	  unsigned char *p;
	  unsigned int len;
	  
	  ssh_buffer_clear(&buffer2);
	  p = ssh_buffer_ptr(&buffer);
	  len = ssh_buffer_len(&buffer);
	  /* Give partial buffer */
	  for(i = 0; i + 1 < len; i++)
	    {
	      ssh_buffer_append(&buffer2, p + i, 1);
	      if (ssh_socks_server_parse_open(&buffer2, &socksreturn) !=
		  SSH_SOCKS_TRY_AGAIN)
		ssh_fatal("ssh_socks_server_parse_open fails in partial data (should return try_again)");
	    }
	  ssh_buffer_append(&buffer2, p + i, 1);
	  if (ssh_socks_server_parse_open(&buffer2, &socksreturn) !=
	      SSH_SOCKS_SUCCESS)
	    ssh_fatal("ssh_socks_server_parse_open fails for partial data (should return success)");
          if (ssh_buffer_len(&buffer2) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      else
	{
	  if (ssh_socks_server_parse_open(&buffer, &socksreturn) !=
	      SSH_SOCKS_SUCCESS)
	    ssh_fatal("ssh_socks_server_parse_open fails for partial data (should return success)");
          if (ssh_buffer_len(&buffer) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      if (socksinfo->socks_version_number != socksreturn->socks_version_number)
	ssh_fatal("socks_version_numbers differ request");
      if (socksinfo->command_code != socksreturn->command_code)
	ssh_fatal("command_codes differ request");
      if (strcmp(socksinfo->ip, socksreturn->ip) != 0)
	ssh_fatal("ip numbers differ request");
      if (strcmp(socksinfo->port, socksreturn->port) != 0)
	ssh_fatal("port numbers differ request");
      if (strcmp(socksinfo->username, socksreturn->username) != 0)
	ssh_fatal("usernames differ request");
      ssh_socks_free(&socksreturn);
      ssh_socks_free(&socksinfo);
      
      ssh_buffer_clear(&buffer);
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 0;
      socksinfo->command_code = (pass % 4) + 90;
      socksinfo->ip =
	ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) /
				   sizeof(ip_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) /
				     sizeof(port_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_server_generate_reply(&buffer, socksinfo) !=
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_server_generate_reply fails");
      if (pass & 1)
	{
	  unsigned char *p;
	  unsigned int len;
	  
	  ssh_buffer_clear(&buffer2);
	  p = ssh_buffer_ptr(&buffer);
	  len = ssh_buffer_len(&buffer);
	  /* Give partial buffer */
	  for(i = 0; i + 1 < len; i++)
	    {
	      ssh_buffer_append(&buffer2, p + i, 1);
	      if (ssh_socks_client_parse_reply(&buffer2, &socksreturn) !=
		  SSH_SOCKS_TRY_AGAIN)
		ssh_fatal("ssh_socks_server_parse_open fails in partial data (should return try_again)");
	    }
	  ssh_buffer_append(&buffer2, p + i, 1);
	  ret = ssh_socks_client_parse_reply(&buffer2, &socksreturn);
	  if (((pass % 4) == 0 && ret != SSH_SOCKS_SUCCESS) ||
	      ((pass % 4) == 1 && ret != SSH_SOCKS_FAILED_REQUEST) ||
	      ((pass % 4) == 2 && ret != SSH_SOCKS_FAILED_IDENTD) ||
	      ((pass % 4) == 3 && ret != SSH_SOCKS_FAILED_USERNAME))
	    ssh_fatal("ssh_socks_client_parse_reply fails for partial data");
          if (ret == SSH_SOCKS_SUCCESS && ssh_buffer_len(&buffer2) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      else
	{
	  ret = ssh_socks_client_parse_reply(&buffer, &socksreturn);
	  if (((pass % 4) == 0 && ret != SSH_SOCKS_SUCCESS) ||
	      ((pass % 4) == 1 && ret != SSH_SOCKS_FAILED_REQUEST) ||
	      ((pass % 4) == 2 && ret != SSH_SOCKS_FAILED_IDENTD) ||
	      ((pass % 4) == 3 && ret != SSH_SOCKS_FAILED_USERNAME))
	    ssh_fatal("ssh_socks_client_parse_reply fails");
          if (ret == SSH_SOCKS_SUCCESS && ssh_buffer_len(&buffer) != 0)
	    ssh_fatal("Junk left to buffer after server_parse_open");
	}
      if (ret == SSH_SOCKS_SUCCESS)
	{
	  if (socksinfo->socks_version_number !=
	      socksreturn->socks_version_number)
	    ssh_fatal("socks_version_numbers differ reply");
	  if (socksinfo->command_code != socksreturn->command_code)
	    ssh_fatal("command_codes differ reply");
	  if (strcmp(socksinfo->ip, socksreturn->ip) != 0)
	    ssh_fatal("ip numbers differ reply");
	  if (strcmp(socksinfo->port, socksreturn->port) != 0)
	    ssh_fatal("port numbers differ reply");
	  ssh_socks_free(&socksreturn);
	}
      ssh_socks_free(&socksinfo);
    }
  
  ssh_buffer_clear(&buffer);
  
  for(pass = 0;
      pass < (sizeof(ip_invalid_numbers) / sizeof(ip_invalid_numbers[0]));
      pass++)
    {
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 4;
      socksinfo->command_code = (pass & 1) + 1;
      socksinfo->ip =
	ssh_xstrdup(ip_invalid_numbers[pass % (sizeof(ip_invalid_numbers) /
					   sizeof(ip_invalid_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) /
				     sizeof(port_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_client_generate_open(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_client_generate_open success (should fail, ip)");
      socksinfo->socks_version_number = 0;
      socksinfo->command_code = (pass % 4) + 90;
      if (ssh_socks_server_generate_reply(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_server_generate_reply success (should fail, ip)");
      ssh_socks_free(&socksinfo);
    }
  for(pass = 0;
      pass < (sizeof(port_invalid_numbers) / sizeof(port_invalid_numbers[0]));
      pass++)
    {
      socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec));
      socksinfo->socks_version_number = 4;
      socksinfo->command_code = (pass & 1) + 1;
      socksinfo->ip =
	ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) /
				   sizeof(ip_numbers[0]))]);
      socksinfo->port =
	ssh_xstrdup(port_invalid_numbers[pass % (sizeof(port_invalid_numbers) /
					     sizeof(port_invalid_numbers[0]))]);
      socksinfo->username =
	ssh_xstrdup(usernames[pass % (sizeof(usernames) /
				  sizeof(usernames[0]))]);
      if (ssh_socks_client_generate_open(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_client_generate_open success (should fail, port)");
      socksinfo->command_code = (pass % 4) + 90;
      socksinfo->socks_version_number = 0;
      if (ssh_socks_server_generate_reply(&buffer, socksinfo) ==
	  SSH_SOCKS_SUCCESS)
	ssh_fatal("ssh_socks_server_generate_reply success (should fail, port)");
      ssh_socks_free(&socksinfo);
    }
  if (ssh_buffer_len(&buffer) != 0)
    ssh_fatal("some of the failed ssh_socks_*_generate_* function wrote something to buffer, size != 0");
  ssh_buffer_uninit(&buffer);
  ssh_buffer_uninit(&buffer2);
  return 0;
}
void
ssh_virtual_adapter_configure(SshInterceptor interceptor,
			      SshInterceptorIfnum adapter_ifnum,
			      SshVirtualAdapterState adapter_state,
			      SshUInt32 num_addresses,
			      SshIpAddr addresses,
			      SshVirtualAdapterParams params,
			      SshVirtualAdapterStatusCB callback,
			      void *context)
{
  SshInterceptorVirtualAdapter va;
  SshInterceptorVirtualAdapterOp op;
  SshBufferStruct ip_buffer;
  unsigned char *param_ptr;
  size_t param_len;
  SshUInt32 i;
  SshVirtualAdapterError error = SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR;
  SshIpAddrStruct undefined_ip;

  ssh_buffer_init(&ip_buffer);

  /* Assert that this virtual adapter exists. */
  ssh_mutex_lock(interceptor->mutex);
  for (va = interceptor->virtual_adapters; va; va = va->next)
    if (va->adapter_ifnum == adapter_ifnum)
      break;
  ssh_mutex_unlock(interceptor->mutex);
  SSH_ASSERT(va != NULL);

  /* Encode "clear all addresses" as one undefined address. */
  if (num_addresses == 0 && addresses != NULL)
    {
      SSH_IP_UNDEFINE(&undefined_ip);
      addresses = &undefined_ip;      
      num_addresses = 1;
    }
  
  /* Encode IP addresses. */
  for (i = 0; i < num_addresses; i++)
    {
      if (!ssh_encode_ipaddr_buffer(&ip_buffer, &addresses[i]))
	{
	  error = SSH_VIRTUAL_ADAPTER_ERROR_ADDRESS_FAILURE;
	  goto error;
	}
    }

  /* Encode params. */
  param_ptr = NULL;
  param_len = 0;
  if (params)
    {      
      if (!ssh_virtual_adapter_param_encode(params, &param_ptr, &param_len))
	{
	  error = SSH_VIRTUAL_ADAPTER_ERROR_ADDRESS_FAILURE;
	  goto error;
	}
    }

  /* Initialize an operation handle. */
  op = alloc_virtual_adapter_op(interceptor);
  op->status_cb = callback;
  op->context = context;

  SSH_DEBUG(SSH_D_NICETOKNOW, 
	    ("sending configure request for virtual adapter %d to forwarder.",
	     (int) adapter_ifnum));

  /* Send a message to the kernel forwarder module. */
  ssh_usermode_interceptor_send_encode(
                  interceptor,
                  SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_CONFIGURE,
                  SSH_FORMAT_UINT32, op->id,
		  SSH_FORMAT_UINT32, adapter_ifnum,
		  SSH_FORMAT_UINT32, adapter_state,
		  SSH_FORMAT_UINT32, num_addresses,
                  SSH_FORMAT_UINT32_STR, 
		  ssh_buffer_ptr(&ip_buffer), ssh_buffer_len(&ip_buffer),
                  SSH_FORMAT_UINT32_STR, param_ptr, param_len,
                  SSH_FORMAT_END);

  op->handle = ssh_operation_register(virtual_adapter_operation_abort, op);
  ssh_buffer_uninit(&ip_buffer);
  ssh_free(param_ptr);
  return;

 error:
  ssh_buffer_uninit(&ip_buffer);
  ssh_free(param_ptr);

  (*callback)(error, adapter_ifnum, NULL, SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
	      NULL, context);
}
Exemple #18
0
Boolean ssh_pgp_read_packet(SshFileBuffer *filebuf, SshPgpPacket *packet)
{
  unsigned char type_id;
  int packet_type;
  int i;
  size_t l;
  Boolean fr;
  Boolean partial_body;
  SshPgpPacket newpacket;
  SshBuffer partial_buf;
  Boolean partial_buf_init;

  partial_buf_init = FALSE;

  do {
    fr = ssh_file_buffer_expand(filebuf, 1);
    if (fr == FALSE)
      goto failed;
    type_id = *(ssh_buffer_ptr(&(filebuf->buf)));
    ssh_buffer_consume(&(filebuf->buf), 1);
    
    SSH_DEBUG(5, ("type_id = %d\n", type_id));

    if (type_id & 0x40) 
      {
        /* New packet header format */
        SSH_DEBUG(5, ("New packet header format\n"));
        if (partial_buf_init == FALSE)
          packet_type = type_id & 0x7f;
        fr = ssh_file_buffer_expand(filebuf, 1);
        if (fr == FALSE)
          goto failed;
        l = *(ssh_buffer_ptr(&(filebuf->buf)));
        ssh_buffer_consume(&(filebuf->buf), 1);
        if ((l >= 192) && (l <= 223))
          {
            partial_body = FALSE;
            fr = ssh_file_buffer_expand(filebuf, 1);
            if (fr == FALSE)
              goto failed;
            l = (((l - 192) << 8) + 
                 ((size_t)(*(ssh_buffer_ptr(&(filebuf->buf))))) +
                 192);
            ssh_buffer_consume(&(filebuf->buf), 1);
          }
        else if ((l >= 224) && (l <= 254))
          {
            partial_body = TRUE;
            fr = ssh_file_buffer_expand(filebuf, 1);
            if (fr == FALSE)
              goto failed;
            l = ((size_t)1) << ((*(ssh_buffer_ptr(&(filebuf->buf)))) & 0x1f);
            ssh_buffer_consume(&(filebuf->buf), 1);
            if (partial_buf_init == FALSE)
              {
                ssh_buffer_init(&partial_buf);
                partial_buf_init = TRUE;
              }
          }
        else if (l == 255)
          {
            partial_body = FALSE;
            l = 0;
            fr = ssh_file_buffer_expand(filebuf, 4);
            if (fr == FALSE)
              goto failed;
            for (i = 0; i < 4; i++)
              {
                l = (l << 8) + (*(ssh_buffer_ptr(&(filebuf->buf))));
                ssh_buffer_consume(&(filebuf->buf), 1);
              }
          }
        else
          {
            partial_body = FALSE;
          }
      }
    else
      {
        size_t ll;

        /* Old packet header format */
        SSH_DEBUG(5, ("Old packet header format\n"));
        partial_body = FALSE;
        if (partial_buf_init == FALSE)
          packet_type = (type_id & 0x7c) >> 2;
        ll = ((int)1) << (type_id & 0x03);
        fr = ssh_file_buffer_expand(filebuf, (int)ll);
        if (fr == FALSE)
          goto failed;
        l = 0;
        for (i = 0; i < ll; i++) {
          l = (l << 8) + (*(ssh_buffer_ptr(&(filebuf->buf))));
          ssh_buffer_consume(&(filebuf->buf), 1);
        }
      }

    if ((l < 1) || (l > 0x4000)) /* XXX */
      goto failed; 

    fr = ssh_file_buffer_expand(filebuf, l);
    if (fr == FALSE)
      goto failed;
    if (partial_body == FALSE)
      {
        if (packet != NULL) 
          {
            newpacket = ssh_xmalloc(sizeof (struct SshPgpPacketRec));
            newpacket->type = packet_type;
            if (partial_buf_init)
              {
                newpacket->len = l + ssh_buffer_len(&partial_buf);
                newpacket->data = ssh_xmalloc(newpacket->len);
                memcpy(newpacket->data, 
                       ssh_buffer_ptr(&partial_buf),
                       ssh_buffer_len(&partial_buf));
                memcpy(&(newpacket->data[ssh_buffer_len(&partial_buf)]), 
                       ssh_buffer_ptr(&(filebuf->buf)), 
                       l);
                ssh_buffer_uninit(&partial_buf);
                partial_buf_init = FALSE;
              }
            else
              {
                newpacket->len = l;
                newpacket->data = ssh_xmalloc(l);
                memcpy(newpacket->data, ssh_buffer_ptr(&(filebuf->buf)), l);
              }
            *packet = newpacket;
            ssh_buffer_consume(&(filebuf->buf), l);
          }
      }
    else
      {
        ssh_buffer_append(&partial_buf, ssh_buffer_ptr(&(filebuf->buf)), l);
        ssh_buffer_consume(&(filebuf->buf), l);
      }
  } while (partial_body == TRUE);

  return TRUE;

 failed:
  if (partial_buf_init == TRUE)
    ssh_buffer_uninit(&partial_buf);
  return FALSE;
}
Exemple #19
0
int main(int ac, char **av)
{
  char port[100];
  int i;
  TestCase *testcase;
  int pass;
  SshTime time_now;

  time_now = ssh_time();
  srandom(time_now);

  for (pass = 0; pass < PASSES; pass++)
    {
#ifdef DEBUG
      ssh_debug("pass %d", pass);
#endif
      random_state = ssh_random_allocate();

      /* randomize it a bit */
      ssh_random_add_noise(random_state, &time_now, sizeof(time_now));

      ssh_buffer_init(&testdata);
      for (i = 0; i < 100000; i++)
        buffer_put_char(&testdata, ssh_random_get_byte(random_state));

      ssh_event_loop_initialize();

      for (i = 0; tests[i].name; i++)
        {
          testcase = &tests[i];
          end_of_script_count = 0;

#ifdef DEBUG      
          ssh_debug("Running test %s", testcase->name);
#endif
          
          snprintf(port, sizeof(port), "%d", (int)(35000 + random() % 1000));
#ifdef DEBUG
          ssh_debug("Making listener, port %s...", port);
#endif
          listener = ssh_tcp_make_listener("127.0.0.1", port,
                                              listener_callback,
                                              (void *)testcase);
          if (!listener)
            ssh_fatal("making listener failed");
#ifdef DEBUG      
          ssh_debug("Making connect...");
#endif
          ssh_tcp_connect_with_socks("127.0.0.1", port, NULL, 2,
                             connect_callback, (void *)testcase);

#ifdef DEBUG      
          ssh_debug("Event loop running...");
#endif 
          ssh_event_loop_run();
#ifdef DEBUG
          ssh_debug("Event loop exited...");
#endif
          if (end_of_script_count != 2)
            ssh_fatal("end_of_script_count %d, script end not reached.",
                  end_of_script_count);
          /* Listener was destroyed in callback. */
        }
  
      ssh_event_loop_uninitialize();
      ssh_buffer_uninit(&testdata);
      ssh_random_free(random_state);
    }
#ifdef DEBUG
  ssh_debug("Exiting...");
#endif
  return 0;
}
Exemple #20
0
void ssh_decode_tty_flags(int fd, unsigned char *buf, size_t buf_len)
{
  SshBuffer buffer;
  
#ifdef USING_TERMIOS
  struct termios tio;
#endif /* USING_TERMIOS */
#ifdef USING_SGTTY
  struct sgttyb tio;
  struct tchars tiotc;
  struct ltchars tioltc;
  int tiolm;
#ifdef TIOCGSTAT
  struct tstatus tiots;
#endif /* TIOCGSTAT */
#endif
  int opcode, baud;

  if (!isatty(fd))
    {
      SSH_TRACE(2, ("Not a tty. (fd = %d)", fd));
      return;
    }

  if (buf_len == 0)
    return;
  
  SSH_DEBUG_HEXDUMP(5, ("received tty-flags buffer"), buf, buf_len);

  ssh_buffer_init(&buffer);

  ssh_buffer_append(&buffer, buf, buf_len);
  
  /* Get old attributes for the terminal.  We will modify these flags. 
     I am hoping that if there are any machine-specific modes, they will
     initially have reasonable values. */
#ifdef USING_TERMIOS
  if (tcgetattr(fd, &tio) < 0)
    return;
#endif /* USING_TERMIOS */
#ifdef USING_SGTTY
  if (ioctl(fd, TIOCGETP, &tio) < 0)
    return;
  if (ioctl(fd, TIOCGETC, &tiotc) < 0)
    return;
  if (ioctl(fd, TIOCLGET, &tiolm) < 0)
    return;
  if (ioctl(fd, TIOCGLTC, &tioltc) < 0)
    return;
#ifdef TIOCGSTAT
  if (ioctl(fd, TIOCGSTAT, &tiots) < 0)
    return;
#endif /* TIOCGSTAT */
#endif /* USING_SGTTY */

  for (;;)
    {
      ssh_decode_buffer(&buffer,
                    SSH_FORMAT_CHAR, &opcode,
                    SSH_FORMAT_END);
      
      switch(opcode)
        {
        case TTY_OP_END:
          goto set;

        case TTY_OP_ISPEED:
          baud = GET_UINT32();
          if (cfsetispeed(&tio, baud_to_speed(baud)) < 0)
            ssh_warning("cfsetispeed failed for %d", baud);
          break;

        case TTY_OP_OSPEED:
          baud = GET_UINT32();
          if (cfsetospeed(&tio, baud_to_speed(baud)) < 0)
            ssh_warning("cfsetospeed failed for %d", baud);
          break;

#ifdef USING_TERMIOS
#define TTYCHAR(NAME, OP)                               \
        case OP:                                        \
          tio.c_cc[NAME] = GET_UINT32();                \
          break;
#define TTYMODE(NAME, FIELD, OP)                        \
        case OP:                                        \
          if (GET_UINT32())                     \
            tio.FIELD |= NAME;                          \
          else                                          \
            tio.FIELD &= ~NAME;                         \
          break;
#define SGTTYCHAR(NAME, OP)
#define SGTTYMODE(NAME, FIELD, OP)
#define SGTTYMODEN(NAME, FIELD, OP)
#endif /* USING_TERMIOS */

#ifdef USING_SGTTY
#define TTYCHAR(NAME, OP)
#define TTYMODE(NAME, FIELD, OP)
#define SGTTYCHAR(NAME, OP)                             \
        case OP:                                        \
          NAME = GET_UINT32();                  \
          break;
#define SGTTYMODE(NAME, FIELD, OP)                      \
        case OP:                                        \
          if (GET_UINT32())                     \
            FIELD |= NAME;                              \
          else                                          \
            FIELD &= ~NAME;                             \
          break;
#define SGTTYMODEN(NAME, FIELD, OP)                     \
        case OP:                                        \
          if (GET_UINT32())                     \
            FIELD &= ~NAME;                             \
          else                                          \
            FIELD |= NAME;                              \
          break;
#endif /* USING_SGTTY */

#include "sshttyflagsi.h"

#undef TTYCHAR
#undef TTYMODE
#undef SGTTYCHAR
#undef SGTTYMODE
#undef SGTTYMODEN

        default:
          SSH_TRACE(1, ("Ignoring unsupported tty mode opcode %d (0x%x)",
                        opcode, opcode));
          /* Opcodes 0 to 160 are defined to have a uint32 argument. */
          if (opcode >= 0 && opcode < 160)
            {
              (void)GET_UINT32();
              break;
            }
          /* It is a truly undefined opcode (160 to 255).  We have no idea
             about its arguments.  So we must stop parsing.  Note that some
             data may be left in the packet; hopefully there is nothing more
             coming after the mode data. */
          ssh_warning("ssh_decode_tty_flags: unknown opcode %d", opcode);
          goto set;
        }
    }

 set:
  /* Set the new modes for the terminal. */
#ifdef USING_TERMIOS
  if (tcsetattr(fd, TCSANOW, &tio) < 0)
    ssh_warning("Setting tty modes failed: %.100s", strerror(errno));
#endif /* USING_TERMIOS */
#ifdef USING_SGTTY
  /* termio's ECHOE is really both LCRTBS and LCRTERA -
     so wire them together */
  if (tiolm & LCRTERA)
    tiolm |= LCRTBS;
  if (ioctl(fd, TIOCSETP, &tio) < 0
      || ioctl(fd, TIOCSETC, &tiotc) < 0
      || ioctl(fd, TIOCLSET, &tiolm) < 0
      || ioctl(fd, TIOCSLTC, &tioltc) < 0
#ifdef TIOCSSTAT
      || ioctl(fd, TIOCSSTAT, &tiots) < 0
#endif /* TIOCSSTAT */
     ) 
    ssh_warning("Setting tty modes failed: %.100s", strerror(errno));
#endif /* USING_SGTTY */
}
Exemple #21
0
void ssh_channel_ftcp_incoming_connection(SshIpError error, SshStream stream,
                                          void *context)
{
  SshRemoteTcpForward fwd = (SshRemoteTcpForward)context;
  char ip[20], port[20];
  SshBuffer buffer;

  SSH_DEBUG(5, ("connection to forwarded TCP/IP port"));
  
  /* We should only receive new connection notifications. */
  if (error != SSH_IP_NEW_CONNECTION)
    ssh_fatal("ssh_channel_ftcp_incoming_connection: error %d", (int)error);

  /* Get remote ip address and port. */
  if (!ssh_tcp_get_remote_address(stream, ip, sizeof(ip)))
    strcpy(ip, "UNKNOWN");
  if (!ssh_tcp_get_remote_port(stream, port, sizeof(port)))
    strcpy(port, "UNKNOWN");

  SSH_TRACE(0, ("Connection to forwarded port %s from %s:%s",
                fwd->port, ip, port));
  ssh_log_event(fwd->common->config->log_facility,
                SSH_LOG_INFORMATIONAL,
                "Connection to forwarded port %s from %s:%s",
                fwd->port, fwd->common->remote_host, port);

  /* XXXXXXXX */
#ifdef HAVE_LIBWRAP
  {
    struct request_info req;
    struct servent *serv;
    char fwdportname[32];
    void *old_handler;
    
    old_handler = signal(SIGCHLD, SIG_DFL);

    /* try to find port's name in /etc/services */
    serv = getservbyport(atoi(fwd->port), "tcp");
    if (serv == NULL)
      {
        /* not found (or faulty getservbyport) -
           use the number as a name */
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%s", fwd->port);
      }
    else
      {
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%.20s",
                 serv->s_name);
      }
    /* fill req struct with port name and fd number */
    request_init(&req, RQ_DAEMON, fwdportname,
                 RQ_FILE, ssh_stream_fd_get_readfd(stream), NULL);
    fromhost(&req);
    if (!hosts_access(&req))
      {
        ssh_conn_send_debug(fwd->common->conn, TRUE,
                            "Fwd connection from %.500s to local port " \
                            "%s refused by tcp_wrappers.",
                            eval_client(&req), fwdportname);
        ssh_stream_destroy(stream);
        signal(SIGCHLD, old_handler);
    
        return;
      }
    signal(SIGCHLD, old_handler);
        
    ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL,
                  "Remote fwd connect from %.500s to local port %s",
                  eval_client(&req), fwdportname);
  }
#endif /* HAVE_LIBWRAP */

  /* Register that we have an open channel. */
  ssh_common_new_channel(fwd->common);
  
  /* Send a request to open a channel and connect it to the given port. */
  ssh_buffer_init(&buffer);
  ssh_encode_buffer(&buffer,
                    SSH_FORMAT_UINT32_STR,
                    fwd->address_to_bind, strlen(fwd->address_to_bind),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(fwd->port),
                    SSH_FORMAT_UINT32_STR, ip, strlen(ip),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(port),
                    SSH_FORMAT_END);
  ssh_conn_send_channel_open(fwd->common->conn, "forwarded-tcpip",
                             stream, TRUE, FALSE, SSH_TCPIP_WINDOW,
                             SSH_TCPIP_PACKET_SIZE,
                             ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer),
                             NULL,
                             ssh_channel_tcp_connection_destroy,
                             (void *)fwd->common, NULL, NULL);
  ssh_buffer_uninit(&buffer);
}  
Exemple #22
0
int
ssh_cm_render_certificate(unsigned char *buf, int len,
			  int precision, void *datum)
{

  SshX509Certificate cert = datum;
  char *name;
  unsigned char *t;
  SshX509Name names;
  SshMPIntegerStruct mp;
  SshBerTimeStruct not_before, not_after;
  SshBufferStruct buffer;
  SshX509OidList oid_list;
  const SshOidStruct *oids;
  Boolean critical;
  SshStr str;
  size_t l, kid_len;
  SshPublicKey pub;
  unsigned char *kid;

  if (cert)
    {
      ssh_buffer_init(&buffer);
      ssh_buffer_append_str(&buffer, "\ncertificate = { \n");

      /* Add the serial number. */
      ssh_mprz_init(&mp);
      if (ssh_x509_cert_get_serial_number(cert, &mp) == FALSE)
        {
          ssh_buffer_append_str(&buffer, "  missing-serial-number\n");
        }
      else
        {
	  if ((t = (unsigned char *) ssh_mprz_get_str(&mp, 10)) != NULL)
	    {
	      ssh_buffer_append_cstrs(&buffer,
				      "  serial-number = ", t, "\n", NULL);
	      ssh_mprz_clear(&mp);
	      ssh_free(t);
	    }
	  else
	    {
	      ssh_mprz_clear(&mp);
	      ssh_buffer_uninit(&buffer);
	      return -1;
	    }
	}

      /* Add suitable names. */
      ssh_x509_name_reset(cert->subject_name);
      if (!ssh_x509_cert_get_subject_name_str(cert, &str))
        {
          ssh_buffer_append_str(&buffer, "  missing-subject-name\n");
        }
      else
        {
          SshStr latin1 = ssh_str_charset_convert(str,
						  SSH_CHARSET_ISO_8859_1);

          name = (char *)ssh_str_get(latin1, &l);
          ssh_buffer_append_cstrs(&buffer,
                                  "  subject-name = <", name, ">\n", NULL);
          ssh_str_free(latin1);
          ssh_free(name);
          ssh_str_free(str);
        }
      ssh_x509_name_reset(cert->issuer_name);
      if (!ssh_x509_cert_get_issuer_name(cert, &name))
        {
          ssh_buffer_append_str(&buffer, "  missing-issuer-name\n");
        }
      else
        {
          ssh_buffer_append_cstrs(&buffer,
                                  "  issuer-name = <", name, ">\n", NULL);
          ssh_free(name);
        }

      /* Validity period. */
      if (!ssh_x509_cert_get_validity(cert, &not_before, &not_after))
        {
          ssh_buffer_append_str(&buffer, "  missing-validity-period\n");
        }
      else
        {
	  if ((t = ssh_malloc(64)) != NULL)
	    {
	      if (ssh_ber_time_available(&not_before))
		{
		  ssh_snprintf(t, 64,
			       "%@", ssh_ber_time_render, &not_before);
		  ssh_buffer_append_cstrs(&buffer,
					  "  not-before = ", t, "\n", NULL);
		}
	      if (ssh_ber_time_available(&not_after))
		{
		  ssh_snprintf(t, 64,
			       "%@", ssh_ber_time_render, &not_after);
		  ssh_buffer_append_cstrs(&buffer,
					  "  not-after = ", t, "\n", NULL);
		}
	      ssh_free(t);
	    }
        }

      if (ssh_x509_cert_get_subject_key_id(cert, &kid, &kid_len, &critical))
        {
          unsigned char *fingerprint;

          if ((fingerprint = (unsigned char *)
               ssh_fingerprint(kid, kid_len,  SSH_FINGERPRINT_HEX_UPPER))
              != NULL)
            ssh_buffer_append_cstrs(&buffer,
                                    "  subject-kid = ",
                                    fingerprint, "\n", NULL);
          ssh_free(fingerprint);
        }
      if (ssh_x509_cert_get_public_key(cert, &pub))
        {
          unsigned char *key_digest;
          size_t digest_len;

          if (ssh_cm_key_kid_create(pub, FALSE, &key_digest, &digest_len))
            {
              unsigned char *fingerprint;

              fingerprint =
		(unsigned char *)ssh_fingerprint(key_digest,
						 digest_len,
						 SSH_FINGERPRINT_HEX_UPPER);
              if (fingerprint)
                {
                  ssh_buffer_append_cstrs(&buffer,
                                          "  pubkey-hash = ",
                                          ssh_sstr(fingerprint), "\n", NULL);

                }
              ssh_free(fingerprint);
              ssh_free(key_digest);
            }
          ssh_public_key_free(pub);
        }

      /* Some alternate names. */
      if (ssh_x509_cert_get_subject_alternative_names(cert, &names, &critical))
        {
          ssh_x509_name_reset(names);
          ssh_buffer_append_str(&buffer, "  subject-alt-names = { \n");
          ssh_cm_names_dump(&buffer, names);
          ssh_buffer_append_str(&buffer, "  }\n");
        }

      if (ssh_x509_cert_get_issuer_alternative_names(cert, &names, &critical))
        {
          ssh_x509_name_reset(names);
          ssh_buffer_append_str(&buffer, "  issuer-alt-names = { \n");
          ssh_cm_names_dump(&buffer, names);
          ssh_buffer_append_str(&buffer, "  }\n");
        }

      if (ssh_x509_cert_get_ext_key_usage(cert, &oid_list, &critical))
        {
          ssh_buffer_append_str(&buffer, "  extended-key-usage = { \n");
          while (oid_list != NULL)
            {
              oids = ssh_oid_find_by_oid_of_type(ssh_custr(oid_list->oid),
                                                 SSH_OID_EXT_KEY_USAGE);
              if (oids == NULL)
                ssh_buffer_append_cstrs(&buffer,
                                        "    (", oid_list->oid, ")\n",
                                        NULL);
              else
                ssh_buffer_append_cstrs(&buffer,
                                        "    ", oids->std_name,
                                        " (", oid_list->oid, ")\n",
                                        NULL);
              oid_list = oid_list->next;
            }
          ssh_buffer_append_str(&buffer, "  }\n");
        }
      ssh_buffer_append_str(&buffer, "}\n");

      return cm_debug_renderer_return(&buffer, buf, len);
    }
  return 0;
}
Exemple #23
0
Boolean handler_output(Handler c)
{
  SshBuffer buffer;
  unsigned int len;
  const unsigned char *cp;
  Boolean wake_up_input = FALSE;
  
  for (;; c->script++)
    {
#ifdef DEBUG
      ssh_debug("%s: handler_output: %s", c->side, opnames[c->script->op]);
#endif
      switch (c->script->op)
        {
        case OP_EXPECT_SERVICE_REQUEST:
        case OP_EXPECT_DISCONNECT:
        case OP_EXPECT_EOF:
        case OP_EXPECT_STARTUP:
        case OP_EXPECT_ALGORITHMS:
        case OP_EXPECT_PACKET:
        case OP_EXPECT_TEST_STREAM:
          wake_up_input = TRUE;
          goto out;
          
        case OP_SEND_SERVICE_ACCEPT:
          handler_send_cross(c, SSH_CROSS_SERVICE_ACCEPT, NULL, 0);
          break;
          
        case OP_SEND_REKEY_REQUEST:
          ssh_buffer_init(&buffer);
          store_delimited_strings(&buffer, c->script->arg);
          handler_send_cross(c, SSH_CROSS_REKEY_REQUEST,
                             ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer));
          ssh_buffer_uninit(&buffer);
          break;
          
        case OP_SEND_PACKET:
          ssh_buffer_init(&buffer);
          buffer_put_char(&buffer, atoi(c->script->arg));
          handler_send_cross(c, SSH_CROSS_PACKET,
                             ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer));
          ssh_buffer_uninit(&buffer);
          break;

        case OP_SEND_TEST_STREAM:
          while (c->stream_offset < ssh_buffer_len(&testdata))
            {
              if (ssh_buffer_len(&c->outgoing) >
                  XMALLOC_MAX_SIZE - SSH_MAX_PAYLOAD_LENGTH - 5000 ||
                  ssh_buffer_len(&c->outgoing) > 50000 - SSH_MAX_PAYLOAD_LENGTH)
                if (!handler_output_outgoing(c))
                  goto out;
              len = random() % (SSH_MAX_PAYLOAD_LENGTH - 3);
              if (len > ssh_buffer_len(&testdata) - c->stream_offset)
                len = ssh_buffer_len(&testdata) - c->stream_offset;
              ssh_buffer_init(&buffer);
              buffer_put_char(&buffer, atoi(c->script->arg));
              cp = ssh_buffer_ptr(&testdata);
              ssh_buffer_append(&buffer, cp + c->stream_offset, len);
              c->stream_offset += len;
              handler_send_cross(c, SSH_CROSS_PACKET,
                                 ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer));
              ssh_buffer_uninit(&buffer);
            }
          c->stream_offset = 0;
          break;

        case OP_SEND_DISCONNECT:
          ssh_buffer_init(&buffer);
          buffer_put_boolean(&buffer, TRUE);
          buffer_put_int(&buffer, SSH_DISCONNECT_BY_APPLICATION);
          buffer_put_uint32_string(&buffer, c->script->arg,
                                    strlen(c->script->arg));
          buffer_put_uint32_string(&buffer, "", 0);
          handler_send_cross(c, SSH_CROSS_DISCONNECT,
                             ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer));
          ssh_buffer_uninit(&buffer);
          break;

        case OP_SEND_EOF:
          c->outgoing_eof = TRUE;
          break;
          
        case OP_END:
          goto out;

        default:
          ssh_fatal("%s: handler_output: unknown op %d",
                c->side, (int)c->script->op);
        }
    }

out:
  c->output_blocked = handler_output_outgoing(c);
  return wake_up_input;
}
Exemple #24
0
/* Encodes terminal modes for the terminal referenced by fd in a
   portable manner, and appends the modes to a buffer being
   constructed. Stores constructed buffers len to buf_len. This call
   always succeeds, but if an error happens during encoding, buf will
   be empty and buf_len will be 0 */
void ssh_encode_tty_flags(int fd, unsigned char **buf, size_t *buf_len)
     /*void tty_make_modes(int fd)*/
{
  SshBuffer buffer;  
#ifdef USING_TERMIOS
  struct termios tio;
#endif
#ifdef USING_SGTTY
  struct sgttyb tio;
  struct tchars tiotc;
  struct ltchars tioltc;
  int tiolm;
#ifdef TIOCGSTAT
  struct tstatus tiots;
#endif /* TIOCGSTAT */
#endif /* USING_SGTTY */
  int baud;

  if (!isatty(fd))
    {
      SSH_TRACE(2, ("Not a tty. (fd = %d)", fd));
      *buf = ssh_xstrdup("");
      *buf_len = 0;
      return;
    }
  
  ssh_buffer_init(&buffer);

  /* Get the modes. */
#ifdef USING_TERMIOS
  if (tcgetattr(fd, &tio) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("tcgetattr: %.100s", strerror(errno));
      goto error;
    }
#endif /* USING_TERMIOS */
#ifdef USING_SGTTY
  if (ioctl(fd, TIOCGETP, &tio) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGETP, ...): %.100s", strerror(errno));
      goto error;
    }
  if (ioctl(fd, TIOCGETC, &tiotc) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGETC, ...): %.100s", strerror(errno));
      goto error;
    }
  if (ioctl(fd, TIOCLGET, &tiolm) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCLGET, ...): %.100s", strerror(errno));
      goto error;
    }
  if (ioctl(fd, TIOCGLTC, &tioltc) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGLTC, ...): %.100s", strerror(errno));
      goto error;
    }
#ifdef TIOCGSTAT
  if (ioctl(fd, TIOCGSTAT, &tiots) < 0) 
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGSTAT, ...): %.100s", strerror(errno));
      goto error;
    }
#endif /* TIOCGSTAT */
  /* termio's ECHOE is really both LCRTBS and LCRTERA - so wire them
     together */
  if (tiolm & LCRTBS)
    tiolm |= LCRTERA;
#endif /* USING_SGTTY */

  /* Store input and output baud rates. */
  baud = speed_to_baud(cfgetospeed(&tio));
  PUT_CHAR(TTY_OP_OSPEED);
  PUT_UINT32(baud);
  baud = speed_to_baud(cfgetispeed(&tio));
  PUT_CHAR(TTY_OP_ISPEED);
  PUT_UINT32(baud);

  /* Store values of mode flags. */
#ifdef USING_TERMIOS
#define TTYCHAR(NAME, OP) \
  PUT_CHAR(OP); PUT_UINT32(tio.c_cc[NAME]);
#define TTYMODE(NAME, FIELD, OP) \
  PUT_CHAR(OP); PUT_UINT32((tio.FIELD & NAME) != 0);
#define SGTTYCHAR(NAME, OP)
#define SGTTYMODE(NAME, FIELD, OP)
#define SGTTYMODEN(NAME, FIELD, OP)
#endif /* USING_TERMIOS */

#ifdef USING_SGTTY
#define TTYCHAR(NAME, OP)
#define TTYMODE(NAME, FIELD, OP)
#define SGTTYCHAR(NAME, OP) \
  PUT_CHAR(OP); PUT_UINT32(NAME);
#define SGTTYMODE(NAME, FIELD, OP) \
  PUT_CHAR(OP); PUT_UINT32((FIELD & NAME) != 0);
#define SGTTYMODEN(NAME, FIELD, OP) \
  PUT_CHAR(OP); PUT_UINT32((FIELD & NAME) == 0);
#endif /* USING_SGTTY */

#include "sshttyflagsi.h"

#undef TTYCHAR
#undef TTYMODE
#undef SGTTYCHAR
#undef SGTTYMODE
#undef SGTTYMODEN

  /* Mark end of mode data. */
  PUT_CHAR(TTY_OP_END);

  *buf_len = ssh_buffer_len(&buffer);
  *buf = ssh_xmemdup(ssh_buffer_ptr(&buffer), *buf_len);
  ssh_buffer_uninit(&buffer);

  SSH_DEBUG_HEXDUMP(5, ("encoded tty-flags buffer"), *buf, *buf_len);
  
  return;

 error:
  ssh_buffer_uninit(&buffer);
  *buf = ssh_xstrdup("");
  *buf_len = 0;
}