Exemplo n.º 1
0
void server1_read(SshStream stream)
{
  int ret;
  unsigned char buf[1024];

  for (;;)
    {
      ret = ssh_stream_read(stream, buf, sizeof(buf));
      if (ret < 0)
	return;
      if (ret == 0)
	{
	  if (read_count != send_count)
	    ssh_fatal("server1_read eof received, read_count %ld send_count %ld",
		  read_count, send_count);
	  break;
	}
      if (memcmp(buf, ssh_buffer_ptr(&expect_buffer), ret) != 0)
	ssh_fatal("server1_read data does not match");
      ssh_buffer_consume(&expect_buffer, ret);
      read_count += ret;
    }
  /* All data has been received. */
  ssh_stream_destroy(stream);
  exited1 = 1;
}
Exemplo n.º 2
0
int ssh_pipe_stream_read(void *context, unsigned char *buf, size_t size)
{
    SshPipeStream pipes = (SshPipeStream)context;
    int len;

    len = ssh_stream_read(pipes->stdio_stream, buf, size);

    /* Convert the return status to EOF if the child has already
       exited.  Note that we'll want to keep reading as long as
       there is data available before returning the EOF, as the
       SIGCHLD handler might be called before all data is read. */
    if (len < 0 && pipes->status_returned)
    {
        ssh_debug("ssh_pipe_stream_read: faking eof after sigchld");
        len = 0;
    }
    else if (len == 0 && !pipes->status_returned)
    {
        /* We got real EOF, but the SIGCHLD handler hasn't been called yet.
           Do not return EOF quite yet; we fake it to no data available.
           When SIGCHLD is delivered, the callback will be called
           and it will call this again; at that time we'll return EOF.
           This is to ensure that a valid exit status is available after
           we return EOF. */
        len = -1;
    }
    return len;
}
Exemplo n.º 3
0
Arquivo: t-tr.c Projeto: AnthraX1/rk
SshBuffer *handler_input_cross(Handler c)
{
  int len;
  unsigned char *cp;
  SshBuffer *packet;
  
  packet = c->incoming;
  if (packet == NULL)
    {
      /* No partial packet already received; initialize for receiving packet
         header. */
      packet = ssh_buffer_allocate();
      c->incoming = packet;
      c->incoming_offset = 0;
      c->incoming_len = 4;
      ssh_buffer_append_space(packet, &cp, c->incoming_len);
    }

keep_reading:
  /* Keep reading until either entire header or entire packet received
     (determined by incoming_len).  Space has already been allocated
     in the buffer. */
  while (c->incoming_offset < c->incoming_len)
    {
      len = c->incoming_len - c->incoming_offset;
      cp = ssh_buffer_ptr(packet);
      cp += c->incoming_offset;
      len = ssh_stream_read(c->stream, cp, len);
      if (len < 0)
        return NULL;
      if (len == 0)
        ssh_fatal("%s: handler_input_cross: received unexpected eof", c->side);
      c->incoming_offset += len;
    }

  /* If this was the header received, read the rest of the packet if there
     is non-zero length payload. */
  if (c->incoming_len == 4 && c->incoming_offset == 4)
    {
      cp = ssh_buffer_ptr(packet);
      c->incoming_len = 4 + SSH_GET_32BIT(cp);
      if (c->incoming_len > 4)
        {
          ssh_buffer_append_space(packet, &cp, c->incoming_len - 4);
          goto keep_reading;
        }
    }

  /* The entire packet has been received.  Return it. */
  c->incoming = NULL;
  cp = ssh_buffer_ptr(packet);

  return packet;
}
Exemplo n.º 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");
        }
    }
}
Exemplo n.º 5
0
void connect1_done(SshStream stream, void *context)
{
  unsigned char buf[100];

  if (context != (void *)3)
    ssh_fatal("connect1 bad context");
  if (!stream)
    ssh_fatal("connection failed");

  if (ssh_stream_read(stream, buf, sizeof(buf)) >= 0)
    ssh_fatal("connect1 read should have failed");
  
  ssh_stream_get_stats(stream, &stats);
  ssh_stream_set_callback(stream, connect1_callback, (void *)stream);
}
Exemplo n.º 6
0
void copy_reader(SshStreamNotification op, void *context)
{
  unsigned char *buf;
  int len;

  if (op != SSH_STREAM_INPUT_AVAILABLE)
    return;

  buf = ssh_xmalloc(T_STREAMPAIR_BIG_BUF_LEN);

  for (;;)
    {
      len = ssh_stream_read(ts2, buf, T_STREAMPAIR_BIG_BUF_LEN);
      if (len == 0)
        {
          ssh_stream_destroy(ts2);
          ts2 = NULL;
          destroy_count++;
          ssh_xfree(buf);
          return; /* EOF received */
        }
      if (len < 0)
        {
          ssh_xfree(buf);
          return;
        }
      ssh_buffer_append(received_data, buf, len);
      if (break_test && ssh_rand() % 10 == 0)
        {
          ssh_stream_destroy(ts2);
          ts2 = NULL;
          destroy_count++;
          ssh_xfree(buf);
          return;
        }
      if (!reader_sent_eof && ssh_rand() % 10 == 0)
        {
          ssh_stream_output_eof(ts2);
          reader_sent_eof = TRUE;
        }
    }
  /*NOTREACHED*/
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
Boolean ssh_packet_wrapper_input(SshPacketWrapper down)
{
  size_t data_to_read, data_read;
  int ret;
  unsigned char *ptr;
  SshPacketType type;
  Boolean return_value = FALSE;

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

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

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

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

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

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

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

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

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

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

      return_value = TRUE;
    }
  /*NOTREACHED*/
}
Exemplo n.º 9
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;
    }
}
Exemplo n.º 10
0
Arquivo: t-tr.c Projeto: AnthraX1/rk
Boolean handler_input(Handler c)
{
  SshBuffer *packet;
  char *cp, *cp2;
  int len;
  unsigned char byte;
  Boolean wake_up_output = FALSE;

  for (;; c->script++)
    {
#ifdef DEBUG
      ssh_debug("%s: handler_input: %s", c->side, opnames[c->script->op]);
#endif
      switch (c->script->op)
        {
        case OP_EXPECT_SERVICE_REQUEST:
          packet = handler_input_expect_cross(c,
                                              SSH_CROSS_SERVICE_REQUEST);
          if (!packet)
            return FALSE;
          cp = buffer_get_uint32_string(packet, NULL);
          if (strcmp(cp, c->script->arg) != 0)
            ssh_fatal("%s: handler_input: service request mismatch: %s vs %s",
                  c->side, c->script->arg, cp);
          ssh_xfree(cp);
          ssh_buffer_free(packet);
          break;

        case OP_EXPECT_DISCONNECT:
          packet = handler_input_expect_cross(c, SSH_CROSS_DISCONNECT);
          if (!packet)
            return FALSE;
          (void)buffer_get_boolean(packet);
          (void)buffer_get_int(packet);
          cp = buffer_get_uint32_string(packet, NULL);
          ssh_xfree(buffer_get_uint32_string(packet, NULL)); /* lang. tag */
          if (strcmp(cp, c->script->arg) != 0)
            ssh_fatal("%s: handler_input: disconnect mismatch: %s vs %s",
                  c->side, c->script->arg, cp);
          ssh_xfree(cp);
          ssh_buffer_free(packet);
          break;
          
        case OP_EXPECT_EOF:
          len = ssh_stream_read(c->stream, &byte, 1);
          if (len < 0)
            return FALSE;
          if (len != 0)
            ssh_fatal("%s: handler_input: EOF expected, received 0x%0x",
                  c->side, byte);
          break;
          
        case OP_EXPECT_STARTUP:
          packet = handler_input_expect_cross(c, SSH_CROSS_STARTUP);
          if (!packet)
            return FALSE;
          ssh_buffer_free(packet);
          break;
          
        case OP_EXPECT_ALGORITHMS:
          packet = handler_input_expect_cross(c, SSH_CROSS_ALGORITHMS);
          if (!packet)
            return FALSE;
          ssh_buffer_free(packet);
          break;

        case OP_EXPECT_PACKET:
          packet = handler_input_expect_packet(c, atoi(c->script->arg));
          if (!packet)
            return FALSE;
          ssh_buffer_free(packet);
          break;
          
        case OP_EXPECT_TEST_STREAM:
          while (c->stream_offset < ssh_buffer_len(&testdata))
            {
              packet = handler_input_expect_packet(c, atoi(c->script->arg));
              if (!packet)
                return FALSE;
              cp = ssh_buffer_ptr(packet);
              cp2 = ssh_buffer_ptr(&testdata);
              if (memcmp(cp, cp2 + c->stream_offset, ssh_buffer_len(packet)) != 0)
                ssh_fatal("%s: handler_input: TEST_STREAM compare fail offset %d",
                      c->side, c->stream_offset);
              c->stream_offset += ssh_buffer_len(packet);
              ssh_buffer_free(packet);
            }
          c->stream_offset = 0;
          break;
          
        case OP_SEND_SERVICE_ACCEPT:
        case OP_SEND_REKEY_REQUEST:
        case OP_SEND_PACKET:
        case OP_SEND_TEST_STREAM:
        case OP_SEND_DISCONNECT:
        case OP_SEND_EOF:
          wake_up_output = TRUE;
          goto out;

        case OP_END:
          return FALSE;

        default:
          ssh_fatal("%s: handler_input: unknown op %d",
                c->side, (int)c->script->op);
        }
    }
out:
  c->input_blocked = TRUE;
  return wake_up_output;
}
Exemplo n.º 11
0
/* This function reads complete payload from the HTTP stream described
   at the context argument (also the thread running this session is
   identified b the context's upper context), and calls the input
   processing thread when done. This gets called when the CA replies
   to the clients message or poll. */
static void
pkix_http_stream_callback(SshStreamNotification not, void *context)
{
  int i;
  size_t len;
  SshUInt8 type_or_version;
  unsigned char input[256], *data;
  PkixHttpReadContext c = (PkixHttpReadContext)context;
  SshFSMThread thread = (SshFSMThread) c->upper_context;
  SshPkiThreadData tdata = ssh_fsm_get_tdata(thread);
  SshPkiGlobalData gdata = ssh_fsm_get_gdata(thread);

  while (TRUE)
    {
      i = ssh_stream_read(c->http_stream, input, sizeof(input));
      if (i == 0)
        {
          if ((len = ssh_buffer_len(c->input)) > 5)
            {
              data = ssh_buffer_ptr(c->input);
              len = SSH_GET_32BIT(data);
              type_or_version = data[4];

              if (type_or_version < 10)
                {
                  tdata->input_version = SSH_PKI_VERSION_0;
                  tdata->input_flags = 0;
                  tdata->input_type = type_or_version;
                  tdata->input_len = len - 1;
                  tdata->input = ssh_memdup(data + 5, tdata->input_len);
                }
              else
                {
                  if (type_or_version == 10)
                    {
                      data += 4; /* skip to end of length */
                      tdata->input_version = SSH_PKI_VERSION_1;
                      tdata->input_len = len - 3;
                      tdata->input_flags = data[1];
                      tdata->input_type  = data[2];
                      data += 3;
                      tdata->input = ssh_memdup(data, tdata->input_len);
                    }
                  else
                    {
                      tdata->input_version = type_or_version;
                      tdata->input_type = SSH_PKI_MSG_ERRORREP;
                    }
                }

              if (tdata->input == NULL)
                tdata->input_type = SSH_PKI_MSG_ERRORREP;

              ssh_buffer_free(c->input);
              ssh_stream_destroy(c->http_stream);
              ssh_fsm_continue(gdata->input_thread);
              ssh_free(c);
              return;
            }
          else
            {
            error:
              tdata->input_type = SSH_PKI_MSG_ERRORREP;
              ssh_fsm_set_next(thread, pkix_aborted);
              ssh_fsm_continue(gdata->input_thread);
              ssh_stream_destroy(c->http_stream);
              ssh_buffer_free(c->input);
              ssh_free(c);
              return;
            }
        }
      else if (i < 0)
        {
          return;
        }
      else
        {
          if (ssh_buffer_append(c->input, input, i) != SSH_BUFFER_OK)
            {
              goto error;
            }
        }

    }
}