Example #1
0
int ssh_pipe_stream_write(void *context, const unsigned char *buf,
                          size_t size)
{
    SshPipeStream pipes = (SshPipeStream)context;

    return ssh_stream_write(pipes->stdio_stream, buf, size);
}
Example #2
0
File: t-tr.c Project: 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;
}
Example #3
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);
}
Example #4
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");
        }
    }
}
Example #5
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);
}
Example #6
0
void disconnect_test()
{
  SshStream server;
  SshStream s1, s2;
  unsigned char buf[8192];
  int len, i;
  
  ssh_stream_pair_create(&s1, &s2);

  /* Initialize server side. */
  server = ssh_transport_server_wrap(s1, random_state, TEST_VERSION, NULL,
                                     hostkey, serverkey,
                                     hostkey_blob, hostkey_blob_len,
                                     NULL, NULL);

  ssh_event_loop_run();
  
  if (random() % 5 == 0)
    len = 0;
  else
    len = random() % sizeof(buf);
  for (i = 0; i < len; i++)
    {
      buf[i] = random();
      if (buf[i] < 32 && buf[i] != '\n' && buf[i] != '\r')
        buf[i] = 'X';
    }

  ssh_stream_write(s2, buf, len);

  ssh_event_loop_run();

  ssh_stream_destroy(s2);

  ssh_event_loop_run();

  ssh_stream_destroy(server);

  ssh_event_loop_run();
}
Example #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;
}
Example #8
0
void t_tcpc_stream_callback(SshStreamNotification        notification,
                            void*                                 context)
{
  t_tcpc_context  pcontext = context;
  char                    buf[4096];
  int                             i;

  SSH_TRACE(SSH_D_MY, ("%s", "t_tcpc_stream_callback"));

  switch (notification)
    {
    case SSH_STREAM_INPUT_AVAILABLE:
      SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_INPUT_AVAILABLE"));
      while ((i = ssh_stream_read(pcontext->pstream,
                                  buf,
                                  4096)) > 0)
        {
          buf[i] = 0;
          SSH_TRACE(SSH_D_MY, ("read: %s", buf));

          if (pcontext->phost_name_or_address)
            {
              ssh_buffer_append(pcontext->pbuffer,
                                buf,
                                i);
              t_tcpc_stream_callback(SSH_STREAM_CAN_OUTPUT,
                                     pcontext);
            }
          else
            {
              SSH_TRACE(SSH_D_MY, ("output: %s", buf));
            }
        }
      break;
    case SSH_STREAM_CAN_OUTPUT:
      SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_CAN_OUTPUT"));
      if (ssh_buffer_len(pcontext->pbuffer) > 0)
        {
          i = ssh_stream_write(pcontext->pstream,
                               ssh_buffer_ptr(pcontext->pbuffer),
                               ssh_buffer_len(pcontext->pbuffer));

          if (i > 0)
            {
              ssh_buffer_consume(pcontext->pbuffer,
                                 i);
            }
        }
      break;
    case SSH_STREAM_DISCONNECTED:
      SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_DISCONNECTED"));
#if 0
      /* BUG BUG BUG */
      ssh_stream_destroy(pcontext->pstream);
#endif /* 0 */
      ssh_event_loop_abort();
      break;
    default:
      SSH_NOTREACHED;
      break;
    }
}
Example #9
0
int ssh_packet_impl_write(void *context, const unsigned char *buf,
                          size_t size)
{
  SshPacketImpl up = (SshPacketImpl)context;
  size_t offset, payload_len, len;
  unsigned char *ucp;

  /* If shortcircuiting, direct the write down. */
  if (up->shortcircuit_stream)
    {
      SSH_ASSERT(ssh_buffer_len(&up->incoming) == 0);
      return ssh_stream_write(up->shortcircuit_stream, buf, size);
    }

  offset = 0;

normal:
  while (up->can_receive && !up->incoming_eof && offset < size &&
         !up->shortcircuit_stream)
    {
      /* If already processing a partial packet, continue it now. */
      if (ssh_buffer_len(&up->incoming) > 0)
        goto partial;

      /* If only partial packet available, do special proccessing. */
      if (size - offset < 4)
        goto partial;  /* Need partial packet processing. */
      payload_len = SSH_GET_32BIT(buf + offset);
      if (payload_len < 1)
        goto partial;

      if (size - offset < 4 + payload_len)
        goto partial;  /* Need partial packet processing. */

      /* The entire packet is available; pass it to the callback. */
      if (up->received_packet)
        (*up->received_packet)((SshPacketType)buf[offset + 4],
                               buf + offset + 5, payload_len - 1, up->context);
      offset += 4 + payload_len;
    }
  /* We cannot take more data now.  If we processed some data, return
     the number of bytes processed. */
  if (offset > 0)
    return offset;

  /* We couldn't take any data.  Remember that we have returned error to
     the writer and must call the callback later. */
  up->up_write_blocked = TRUE;
  return -1;

partial:
  /* Process partial packet.  First we read its header. */
  len = ssh_buffer_len(&up->incoming);
  if (len < 4)
    {
      len = 4 - len;
      if (size - offset < len)
        len = size - offset;
      if (ssh_buffer_append(&up->incoming, buf + offset, len)
          != SSH_BUFFER_OK)
        {
          (*up->received_eof)(up->context);
          return 0;
        }

      offset += len;
    }
  if (ssh_buffer_len(&up->incoming) < 4)
    return offset;

  /* Get the length of the packet. */
  ucp = ssh_buffer_ptr(&up->incoming);
  payload_len = SSH_GET_32BIT(ucp);
  if (payload_len < 1)
    {
      /* Received an invalid packet with length = 0, even though we should
         always have at least the packet type. */
      (*up->received_eof)(up->context);
      return 0;
    }

  /* Add remaining data in the packet to the buffer. */
  len = 4 + payload_len - ssh_buffer_len(&up->incoming);
  if (len > size - offset)
    len = size - offset;
  if (ssh_buffer_append(&up->incoming, buf + offset, len)
      != SSH_BUFFER_OK)
    {
      (*up->received_eof)(up->context);
      return 0;
    }
  offset += len;

  /* If some data still not available, return. */
  if (ssh_buffer_len(&up->incoming) < 4 + payload_len)
    return offset;

  /* The entire packet is now in buffer. */
  ucp = ssh_buffer_ptr(&up->incoming);
  if (up->received_packet)
    (*up->received_packet)((SshPacketType)ucp[4], ucp + 5,
                           payload_len - 1,
                           up->context);

  /* Clear the incoming partial packet buffer and resume normal processing. */
  ssh_buffer_clear(&up->incoming);
  goto normal;
}