Esempio n. 1
0
File: t-tr.c Progetto: AnthraX1/rk
void handler_send_cross(Handler c, unsigned int cross_type,
                        const unsigned char *payload, size_t len)
{
  unsigned char header[5];

  SSH_PUT_32BIT(header, len + 1);
  header[4] = cross_type;
  ssh_buffer_append(&c->outgoing, header, 5);
  ssh_buffer_append(&c->outgoing, payload, len);
}
Esempio n. 2
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;
}
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
void
ssh_eap_build_and_send_request(SshEap eap, SshUInt8 type,
                               const SshUInt8 *ptr, unsigned long len)
{
  SshBuffer pkt;

  pkt = ssh_eap_create_request(eap, (SshUInt16)len, type);

  if (pkt == NULL)
    {
      ssh_eap_fatal(eap, NULL,
                    "Out of memory. Can not send request.");
      return;
    }

  if (len != 0 && ptr != NULL)
    {
      if (ssh_buffer_append(pkt, ptr, len) != SSH_BUFFER_OK)
        {
	  ssh_buffer_free(pkt);
          ssh_eap_fatal(eap, NULL,
                        "Out of memory. Can not send request.");
          return;
        }
    }

  /* Send packet */

  ssh_eap_protocol_send_request(NULL, eap, pkt);
}
Esempio n. 5
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. 6
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);
}
static int
ssh_appgw_http_marshal_int(SshBuffer buf, int i)
{
  SshUInt32 hi;

  SSH_PUT_32BIT(&hi,i);
  if (ssh_buffer_append(buf,(unsigned char*)&hi,4) == SSH_BUFFER_ERROR)
    return 0;
  return 1;
}
Esempio n. 8
0
void ssh_buffer_append_cstrs(SshBuffer *buffer, ...)
{
  va_list ap;
  char *str;

  va_start(ap, buffer);

  while ((str = va_arg(ap, char *)) != NULL)
    ssh_buffer_append(buffer, (unsigned char *) str, strlen(str));

  va_end(ap);
}
static int
ssh_appgw_http_marshal_data(SshBuffer buf, const unsigned char *str,
                            size_t len)
{
  SshUInt32 i;

  if (str == NULL)
    {
      SSH_PUT_32BIT(&i,0);
      if (ssh_buffer_append(buf, (unsigned char *)&i, 4) == SSH_BUFFER_ERROR)
        return 0;
    }
  else
    {
      SSH_PUT_32BIT(&i,len);
      if (ssh_buffer_append(buf, (unsigned char*)&i, 4) == SSH_BUFFER_ERROR)
        return 0;

      if (ssh_buffer_append(buf, (unsigned char *)str,len) == SSH_BUFFER_ERROR)
        return 0;
    }
  return 1;
}
Esempio n. 10
0
void
ssh_eap_build_and_send_reply(SshEap eap, SshUInt8 type,
                             const SshUInt8 *ptr, SshUInt16 len)
{
  SshBuffer pkt;

  /* Only send replies to requests */

  SSH_ASSERT(eap->id_isinit == 1);

  pkt = ssh_buffer_allocate();

  if (pkt == NULL)
    {
      ssh_eap_fatal(eap, NULL,
                    "Out of memory. Can not send reply.");
      return;
    }

  if (!ssh_eap_packet_build_hdr_with_type(pkt,
					  SSH_EAP_CODE_REPLY,
					  eap->id,
					  len,
					  type))
    {
      ssh_buffer_free(pkt);
      ssh_eap_fatal(eap, NULL,
                    "Out of memory. Can not send reply.");
      return;
    }

  if (len != 0 && ptr != NULL)
    {
      if (ssh_buffer_append(pkt, ptr, len) != SSH_BUFFER_OK)
        {
	  ssh_buffer_free(pkt);
          ssh_eap_fatal(eap, NULL, "Out of memory. Can not send reply.");
          return;
        }
    }

  /* Ok. let's transmit this packet */

  ssh_eap_remember_packet(eap, pkt);
  ssh_eap_send_packet(eap, pkt);
}
Esempio n. 11
0
void create_testdata(void)
{
  int len, i;
  unsigned char ch;

  if (testdata)
    ssh_buffer_clear(testdata);
  else
    testdata = ssh_buffer_allocate();

  len = ssh_rand() % 100000;
  for (i = 0; i < len; i++)
    {
      ch = (unsigned char)(ssh_rand() % 256);
      ssh_buffer_append(testdata, &ch, 1);
    }
}
Esempio n. 12
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*/
}
Esempio n. 13
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. 14
0
void t_tcpc_timeout_callback(void *context)
{
  t_tcpc_context  pcontext = context;

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

  if (! pcontext || !pcontext->pdata)
    return;

  ssh_buffer_append(pcontext->pbuffer,
                    pcontext->pdata,
                    strlen(pcontext->pdata));

  t_tcpc_stream_callback(SSH_STREAM_CAN_OUTPUT,
                         pcontext);

  ssh_xregister_timeout(pcontext->timeout,
                        0,
                        t_tcpc_timeout_callback,
                        pcontext);
}
Esempio n. 15
0
void
ssh_audit_syslog_cb(SshAuditEvent event, SshUInt32 argc, 
		    SshAuditArgument argv, void *context)
{
  SshAuditSyslogContext ctx = (SshAuditSyslogContext) context;

  ssh_buffer_clear(&ctx->buffer);

  if (!ssh_audit_format(&ctx->buffer, ctx->format, event, argc, argv))
    {
    error:
      SSH_DEBUG(SSH_D_ERROR, ("Could not format event into a string"));
      return;
    }

  if (ssh_buffer_append(&ctx->buffer, (unsigned char *) "\0", 1)
      != SSH_BUFFER_OK)
    goto error;

  ssh_log_event(ctx->facility, ctx->severity, "%s",
                (char *) ssh_buffer_ptr(&ctx->buffer));
}
SshTlsTransStatus ssh_tls_trans_write_change_cipher(SshTlsProtocolState s)
{
  ssh_tls_start_building(s, SSH_TLS_CTYPE_CHANGE_CIPHER);

  if (ssh_buffer_append(s->outgoing_raw_data, (unsigned char *)"\001", 1)
      == SSH_BUFFER_OK)
    s->built_len++;
  else
    return SSH_TLS_TRANS_FAILED;

  /* Must flush so that the coming change does not affect
     this packet. */
  ssh_tls_flush(s);

#ifdef SSH_IPSEC_HWACCEL_SUPPORT_TLS
  /* Wait outgoing crypto operations to complete */
  if (s->conn.outgoing.ops_pending)
    {
      s->outgoing_all_complete_cb = ssh_tls_write_change_cipher_finish;
      s->kex.state = SSH_TLS_KEX_WAIT_OUT_CRYPTO_COMPLETION;
      s->kex.next_state = s->conf.is_server ?
        SSH_TLS_KEX_SEND_S_FINISHED:SSH_TLS_KEX_SEND_C_FINISHED;
      s->kex.alert = 0;
      s->kex.alert_text = NULL;
      ssh_tls_async_freeze(s);
      return SSH_TLS_TRANS_OK;
    }
#endif /* SSH_IPSEC_HWACCEL_SUPPORT_TLS */

  /* Now change cipher context. */
  if (!ssh_tls_change_cipher_context(s, TRUE))
    return SSH_TLS_TRANS_FAILED;

  if (s->conf.is_server)
    s->kex.state = SSH_TLS_KEX_SEND_S_FINISHED;
  else
    s->kex.state = SSH_TLS_KEX_SEND_C_FINISHED;
  return SSH_TLS_TRANS_OK;
}
Esempio n. 17
0
static void
ssh_eap_md5_server_begin(SshEapProtocol protocol, SshEap eap)
{
  unsigned long name_len;
  SshEapMd5State state;
  SshEapMd5Params params;
  SshUInt8 rndbyte;
  SshBuffer pkt;
  int i;

  state = ssh_eap_protocol_get_state(protocol);
  params = ssh_eap_protocol_get_params(protocol);

  if (state == NULL)
    {
      SSH_DEBUG(SSH_D_ERROR,
                ("eap md5 state not initialized. "
                 "can not begin authentication"));
      return;
    }

  /* Parse parameters for defaults and free any "old" state */

  if (params == NULL)
    {
      /* Do not leak too much information regarding the state of the PRNG,
         but make a sufficiently difficult (256 bits) challenge. */
      state->challenge_length = 32;
      name_len = 0;
    }
  else
    {
      state->challenge_length = params->challenge_length;
      name_len = params->name_length;
    }

  if (state->challenge_length > 255)
    state->challenge_length = 255;

  SSH_ASSERT(state->challenge_length > 0);

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

  /* Build packet */

  pkt = ssh_eap_create_request(eap,
                               (SshUInt16)(1 + state->challenge_length
                                           + name_len),
                               protocol->impl->id);

  if (pkt == NULL)
    {
      ssh_eap_fatal(eap, protocol,
                    "Out of memory. Could not create request");
      return;
    }

  SSH_ASSERT(state->challenge_length < 256);

  rndbyte = (SshUInt8)state->challenge_length;

  if (ssh_buffer_append(pkt, &rndbyte, 1) != SSH_BUFFER_OK)
    {
      ssh_buffer_free(pkt);
      ssh_eap_fatal(eap, protocol,
                    "Out of memory. Could not create request");
      return;
    }

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

  if (state->challenge_buffer == NULL)
    {
      ssh_buffer_free(pkt);
      ssh_eap_fatal(eap, protocol,
                    "Out of memory. Could not create challenge");
      return;
    }


  for (i = 0; i < state->challenge_length; i++)
    {
      rndbyte = (SshUInt8)ssh_random_get_byte();
      state->challenge_buffer[i] = rndbyte;
      if (ssh_buffer_append(pkt, &rndbyte, 1) != SSH_BUFFER_OK)
        {
          ssh_buffer_free(pkt);
          ssh_free(state->challenge_buffer);
          state->challenge_buffer = NULL;
          ssh_eap_fatal(eap, protocol,
                        "Out of memory. Could not create request");
          return;
        }
    }

  if (name_len > 0)
    {
      SSH_ASSERT(params != NULL && params->name_buffer != NULL);

      if (ssh_buffer_append(pkt, params->name_buffer, name_len))
        {
          ssh_buffer_free(pkt);
          ssh_free(state->challenge_buffer);
          state->challenge_buffer = NULL;
          ssh_eap_fatal(eap, protocol,
                        "Out of memory. Could not create request");
          return;
        }
    }

  state->response_id = ssh_eap_packet_get_identifier(pkt);

  SSH_DEBUG(SSH_D_MIDOK,("sending eap md5 authentication request"));
  ssh_eap_protocol_send_request(protocol, eap, pkt);
}
Esempio n. 18
0
File: t-tr.c Progetto: AnthraX1/rk
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;
}
Esempio n. 19
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;
}
Esempio n. 20
0
static void
ssh_eap_md5_client_recv_token(SshEapProtocol protocol,
                              SshEap eap,
                              SshBuffer buf)
{
  SshEapMd5State state;
  SshEapMd5Params params;
  SshBuffer pkt = NULL;
  SshUInt8 b;
  SshHash hash = NULL;
  SshCryptoStatus status;
  unsigned long len;
  unsigned long name_len;
  unsigned long secret_len;
  SshUInt8 *secret_ptr;
  SshEapToken t;
  SshUInt8 hashbuf[32];

  if (ssh_eap_get_token_type_from_buf(buf) != SSH_EAP_TOKEN_SHARED_SECRET)
    {
      ssh_eap_discard_token(eap, protocol, buf, ("unexpected token type"));
      return;
    }

  t = (SshEapToken)ssh_buffer_ptr(buf);
  if (t == NULL)
    {
      ssh_eap_discard_token(eap, protocol, buf, ("invalid token"));
      return;
    }

  secret_ptr = ssh_eap_get_token_secret_ptr(t);
  secret_len = ssh_eap_get_token_secret_len(t);

  SSH_ASSERT(secret_ptr != NULL || secret_len == 0);

  state = ssh_eap_protocol_get_state(protocol);
  params = ssh_eap_protocol_get_params(protocol);

  status = SSH_CRYPTO_UNSUPPORTED;
  name_len = 0;

  if (params != NULL && params->name_buffer != NULL)
    {
      name_len = params->name_length;
    }

  if (state->challenge_buffer == NULL)
    {
      ssh_eap_discard_token(eap, protocol, buf,
                            "EAP MD5 state lacks authenticator challenge");
      goto fail_auth;
    }

  status = ssh_hash_allocate("md5", &hash);

  if (status != SSH_CRYPTO_OK)
    {
      ssh_eap_discard_token(eap, protocol, buf,
                            "failed to initialize MD5 function");
      goto fail_auth;
    }

  len = ssh_hash_digest_length(ssh_hash_name(hash));

  if (len > 32)
    {
      ssh_eap_fatal(eap, protocol,
                    "MD5 output of unexpected size");
      goto fail_auth;
    }

  pkt = ssh_eap_create_reply(eap,
                             (SshUInt16)(1 + len + name_len),
                             protocol->impl->id);

  if (pkt == NULL)
    {
      ssh_eap_fatal(eap, protocol,
                    "Out of memory. Could not allocate reply packet.");
      goto fail_auth;
    }

  b = (SshUInt8)(len & 0xFF);

  if (ssh_buffer_append(pkt,&b,1) != SSH_BUFFER_OK)
    {
      ssh_eap_fatal(eap, protocol,
                    "Out of memory. Could not build reply packet.");
      goto fail_auth;
    }

  ssh_hash_reset(hash);
  ssh_hash_update(hash, &state->response_id, 1);
  ssh_hash_update(hash, secret_ptr, secret_len);
  ssh_hash_update(hash, state->challenge_buffer, state->challenge_length);
  ssh_hash_final(hash, hashbuf);

  if (ssh_buffer_append(pkt, hashbuf, len) != SSH_BUFFER_OK)
    {
      ssh_eap_fatal(eap, protocol,
                    "Out of memory. Could not build reply packet.");
      goto fail_auth;
    }

  if (name_len > 0)
    {
      if (ssh_buffer_append(pkt, params->name_buffer, name_len)
          != SSH_BUFFER_OK)
        {
          ssh_eap_fatal(eap, protocol,
                        "Out of memory. Could not build reply packet.");
          goto fail_auth;
        }
    }

  ssh_eap_protocol_send_response(protocol, eap, pkt);
  pkt = NULL;

  ssh_eap_protocol_auth_ok(protocol, eap, SSH_EAP_SIGNAL_NONE, NULL);

 fail_auth:
  if (pkt != NULL)
    ssh_buffer_free(pkt);
  if (hash != NULL)
    ssh_hash_free(hash);

  ssh_eap_md5_reset(protocol,eap);
}
Esempio n. 21
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;
}
Esempio n. 22
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;
            }
        }

    }
}
Esempio n. 23
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;
    }
}
Esempio n. 24
0
static void
filter_html(SshBuffer to, SshBuffer from, Boolean eof_seen, void *context)
{
  ProxyRequest *req = context;
  unsigned char *cp;
  size_t len;
  size_t i;

 restart:

  cp = ssh_buffer_ptr(from);
  len = ssh_buffer_len(from);

  for (i = 0; i < len; i++)
    {
      switch (req->state)
        {
        case FILTER_TEXT:
          if (cp[i] == '<')
            {
              ssh_buffer_append(to, cp, i);
              ssh_buffer_consume(from, i);

              len = ssh_buffer_len(from);
              cp = ssh_buffer_ptr(from);

              /* Is the end of the tag seen? */
              for (i = 0; i < len; i++)
                if (cp[i] == '>')
                  {
                    i++;
                    break;
                  }

              if (i >= len && !eof_seen)
                /* No, need more data. */
                return;

              /* Yes, it is seen. */

              if (i > 4 && strncasecmp(cp, "<img", 4) == 0)
                {
                  char *url = parse_img_src(cp, i);
                  ssh_buffer_append_cstrs(to,
                                          "<a href=\"http://amme.ssh.fi:8080",
                                          "/catch?url=", url, "\">*</a>",
                                          NULL);
                }

              ssh_buffer_append(to, cp, i);
              ssh_buffer_consume(from, i);

              goto restart;
            }
          else if (cp[i] == '&')
            req->state = FILTER_ENTITY;
          break;

        case FILTER_ENTITY:
          if (cp[i] == ';')
            req->state = FILTER_TEXT;
          break;
        }
    }

  ssh_buffer_append(to, ssh_buffer_ptr(from), ssh_buffer_len(from));
  ssh_buffer_clear(from);
}
Esempio n. 25
0
static void
copy_data(SshBuffer to, SshBuffer from, Boolean eof_seen, void *context)
{
  ssh_buffer_append(to, ssh_buffer_ptr(from), ssh_buffer_len(from));
  ssh_buffer_clear(from);
}
Esempio n. 26
0
int ssh_tls_stream_write(void *context, const unsigned char *buf, size_t size)
{
  int iv_len = 0; /*CBCATT, TLS1.1: need space for storing random IV*/

  SshTlsProtocolState s = (SshTlsProtocolState)context;

  SSH_DEBUG(7, ("The upper layer wants to write max. %d bytes of data.",
                size));

  /* If this assert fails it is an application error. */
  SSH_ASSERT(!(s->flags & SSH_TLS_FLAG_OUTPUT_EOF));

  if (SSH_TLS_IS_FAILED_STATUS(s->status))
    {
      SSH_DEBUG(7, ("Do not accept more application data as the "
                    "protocol is being shut down."));
      return 0;
    }

  if (s->flags & SSH_TLS_FLAG_STREAM_WRITE_CLOSED)
    {
      SSH_DEBUG(7, ("The underlying stream does not accept data any more, "
                    "thus return zero."));
      return 0;
    }

  if (!(s->flags & SSH_TLS_FLAG_INITIAL_KEX_DONE))
    {
      SSH_DEBUG(7, ("Do not accept application data yet as the initial "
                    "key exchange has not been finished."));

      /* We need to notify the application when the KEX has been finished. */
      s->flags |= SSH_TLS_FLAG_GIVE_WRITE_NOTIFY;
      return -1;
    }

  if (s->kex.state != SSH_TLS_KEX_CLEAR)
    {
      SSH_DEBUG(7, ("Do not send application data now as a key exchange "
                    "is in progress."));

      /* We need to notify the application when the KEX has been finished. */
      s->flags |= SSH_TLS_FLAG_GIVE_WRITE_NOTIFY;
      return -1;
    }

  if ((s->conn.outgoing.cipher) && !s->conn.outgoing.is_stream_cipher 
		  && SSH_TLS_VER_TLS1_1 == ssh_tls_version(s)) 
    {
      iv_len = s->conn.outgoing.block_length;
      SSH_DEBUG(6, ("Adjusting for CBCATT random IV size %d", iv_len));
    }

  /* Check that we do not create a too long packet. */
  if (s->built_len == 0)
    {
      if (size > SSH_TLS_MAX_RECORD_LENGTH - iv_len) 
        size = SSH_TLS_MAX_RECORD_LENGTH - iv_len;
    }
  else
    {
      if (size + s->built_len >
          SSH_TLS_MAX_RECORD_LENGTH + SSH_TLS_HEADER_SIZE - iv_len)
        size = (SSH_TLS_MAX_RECORD_LENGTH + SSH_TLS_HEADER_SIZE) -
          s->built_len - iv_len;
    }

#ifdef SSH_IPSEC_HWACCEL_SUPPORT_TLS
  {
    int bytes = ssh_tls_appstream_can_write_bytes(s);

    if (bytes < size)
      size = bytes;
#else
  {
    long l = ssh_buffer_len(s->outgoing_raw_data);

    if (size + l > s->conf.max_buffered_data)
      {
        if (l > s->conf.max_buffered_data)
          size = 0;
        else
          size = s->conf.max_buffered_data - l;
      }
#endif /* SSH_IPSEC_HWACCEL_SUPPORT_TLS */

    if (size == 0)
      {
        SSH_DEBUG(7, ("Cannot fit more data into the outgoing data buffer"));
        s->flags |= SSH_TLS_FLAG_GIVE_WRITE_NOTIFY;
        return -1;
      }
  }

  if (s->conf.flags & SSH_TLS_FIX_IV_LEAK)
    {
      ssh_tls_start_building(s, SSH_TLS_CTYPE_APPDATA);
      ssh_tls_flush(s);
    }
  ssh_tls_start_building(s, SSH_TLS_CTYPE_APPDATA);

  if (ssh_buffer_append(s->outgoing_raw_data, buf, size) == SSH_BUFFER_OK)
    {
      s->built_len += size;
      s->stats.app_bytes_got += size;
    }
  else
    {
      SSH_DEBUG(7, ("The send buffer can not fit any more data "
                    "thus return zero."));
      return 0;
    }

  trigger_rekey_if_needed(s);

  /* Check for a long packet that could be sent immediately.  This
     covers also those maximum-length packets that have been
     `truncated' above. */
  if (s->built_len > SSH_TLS_MAX_RECORD_LENGTH / 2)
    {
      SSH_DEBUG(6, ("Long packet, flush immediately."));
      ssh_tls_flush(s);
    }

  return size;
}

void ssh_tls_stream_output_eof(void *context)
{
  SshTlsProtocolState s = (SshTlsProtocolState)context;

  SSH_DEBUG(7, ("Got output eof from the upper layer."));

  s->flags |= SSH_TLS_FLAG_OUTPUT_EOF;
}
Esempio n. 27
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;
}
Esempio n. 28
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 */
}