Esempio n. 1
0
/*
 * Test the behavior of ssh_buffer_prepend_data
 */
static void *thread_buffer_prepend(void *threadid)
{
    ssh_buffer buffer = NULL;
    uint32_t v;

    /* Unused */
    (void) threadid;

    /* Setup */
    buffer = ssh_buffer_new();
    if (buffer == NULL) {
        pthread_exit((void *)-1);
    }
    ssh_buffer_set_secure(buffer);

    ssh_buffer_add_data(buffer, "abcdef", 6);
    ssh_buffer_prepend_data(buffer, "xyz", 3);
    assert_int_equal(ssh_buffer_get_len(buffer), 9);
    assert_memory_equal(ssh_buffer_get(buffer),  "xyzabcdef", 9);

    /* Now remove 4 bytes and see if we can replace them */
    ssh_buffer_get_u32(buffer, &v);
    assert_int_equal(ssh_buffer_get_len(buffer), 5);
    assert_memory_equal(ssh_buffer_get(buffer), "bcdef", 5);

    ssh_buffer_prepend_data(buffer, "aris", 4);
    assert_int_equal(ssh_buffer_get_len(buffer), 9);
    assert_memory_equal(ssh_buffer_get(buffer), "arisbcdef", 9);

    /* same thing but we add 5 bytes now */
    ssh_buffer_get_u32(buffer, &v);
    assert_int_equal(ssh_buffer_get_len(buffer), 5);
    assert_memory_equal(ssh_buffer_get(buffer), "bcdef", 5);

    ssh_buffer_prepend_data(buffer, "12345", 5);
    assert_int_equal(ssh_buffer_get_len(buffer), 10);
    assert_memory_equal(ssh_buffer_get(buffer), "12345bcdef", 10);

    /* Teardown */
    SSH_BUFFER_FREE(buffer);
    pthread_exit(NULL);
}
Esempio n. 2
0
int ssh_packet_send1(ssh_session session) {
  unsigned int blocksize = (session->current_crypto ?
      session->current_crypto->out_cipher->blocksize : 8);
  uint32_t currentlen = ssh_buffer_get_len(session->out_buffer) + sizeof(uint32_t);
  char padstring[32] = {0};
  int rc = SSH_ERROR;
  uint32_t finallen;
  uint32_t crc;
  uint8_t padding;

  SSH_LOG(SSH_LOG_PACKET,"Sending a %d bytes long packet",currentlen);

/* TODO FIXME
#ifdef WITH_ZLIB
  if (session->current_crypto && session->current_crypto->do_compress_out) {
    if (compress_buffer(session, session->out_buffer) < 0) {
      goto error;
    }
    currentlen = ssh_buffer_get_len(session->out_buffer);
  }
#endif
*/
  padding = blocksize - (currentlen % blocksize);
  if (session->current_crypto) {
    ssh_get_random(padstring, padding, 0);
  } else {
    memset(padstring, 0, padding);
  }

  finallen = htonl(currentlen);
  SSH_LOG(SSH_LOG_PACKET,
      "%d bytes after comp + %d padding bytes = %d bytes packet",
      currentlen, padding, ntohl(finallen));

  if (ssh_buffer_prepend_data(session->out_buffer, &padstring, padding) < 0) {
    goto error;
  }
  if (ssh_buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) {
    goto error;
  }

  crc = ssh_crc32((char *)ssh_buffer_get(session->out_buffer) + sizeof(uint32_t),
      ssh_buffer_get_len(session->out_buffer) - sizeof(uint32_t));

  if (ssh_buffer_add_u32(session->out_buffer, ntohl(crc)) < 0) {
    goto error;
  }

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("Clear packet", ssh_buffer_get(session->out_buffer),
      ssh_buffer_get_len(session->out_buffer));
#endif

  /* session->out_buffer should have more than sizeof(uint32_t) bytes
     in it as required for ssh_packet_encrypt */
  ssh_packet_encrypt(session, (unsigned char *)ssh_buffer_get(session->out_buffer) + sizeof(uint32_t),
      ssh_buffer_get_len(session->out_buffer) - sizeof(uint32_t));

#ifdef DEBUG_CRYPTO
  ssh_print_hexa("encrypted packet",ssh_buffer_get(session->out_buffer),
      ssh_buffer_get_len(session->out_buffer));
#endif
  rc=ssh_socket_write(session->socket, ssh_buffer_get(session->out_buffer),
      ssh_buffer_get_len(session->out_buffer));
  if(rc== SSH_ERROR) {
    goto error;
  }

  session->send_seq++;

  if (ssh_buffer_reinit(session->out_buffer) < 0) {
    rc = SSH_ERROR;
  }
error:

  return rc;     /* SSH_OK, AGAIN or ERROR */
}
Esempio n. 3
0
static int packet_send2(ssh_session session) {
  unsigned int blocksize = (session->current_crypto ?
      session->current_crypto->out_cipher->blocksize : 8);
  unsigned int lenfield_blocksize = (session->current_crypto ?
      session->current_crypto->out_cipher->lenfield_blocksize : 0);
  enum ssh_hmac_e hmac_type = (session->current_crypto ?
      session->current_crypto->out_hmac : session->next_crypto->out_hmac);
  uint32_t currentlen = ssh_buffer_get_len(session->out_buffer);
  unsigned char *hmac = NULL;
  char padstring[32] = { 0 };
  int rc = SSH_ERROR;
  uint32_t finallen,payloadsize,compsize;
  uint8_t padding;
  ssh_buffer header_buffer = ssh_buffer_new();

  payloadsize = currentlen;
#ifdef WITH_ZLIB
  if (session->current_crypto
      && session->current_crypto->do_compress_out
      && ssh_buffer_get_len(session->out_buffer)) {
    if (compress_buffer(session,session->out_buffer) < 0) {
      goto error;
    }
    currentlen = ssh_buffer_get_len(session->out_buffer);
  }
#endif /* WITH_ZLIB */
  compsize = currentlen;
  /* compressed payload + packet len (4) + padding len (1) */
  /* totallen - lenfield_blocksize must be equal to 0 (mod blocksize) */
  padding = (blocksize - ((blocksize - lenfield_blocksize + currentlen + 5) % blocksize));
  if(padding < 4) {
    padding += blocksize;
  }

  if (session->current_crypto != NULL) {
      int ok;

      ok = ssh_get_random(padstring, padding, 0);
      if (!ok) {
          ssh_set_error(session, SSH_FATAL, "PRNG error");
          goto error;
      }
  }

  if (header_buffer == NULL){
    ssh_set_error_oom(session);
    goto error;
  }
  finallen = currentlen + padding + 1;
  rc = ssh_buffer_pack(header_buffer, "db", finallen, padding);
  if (rc == SSH_ERROR){
    goto error;
  }

  rc = ssh_buffer_prepend_data(session->out_buffer,
                               ssh_buffer_get(header_buffer),
                               ssh_buffer_get_len(header_buffer));
  if (rc < 0) {
    goto error;
  }
  rc = ssh_buffer_add_data(session->out_buffer, padstring, padding);
  if (rc < 0) {
    goto error;
  }
#ifdef WITH_PCAP
  if (session->pcap_ctx) {
      ssh_pcap_context_write(session->pcap_ctx,
                             SSH_PCAP_DIR_OUT,
                             ssh_buffer_get(session->out_buffer),
                             ssh_buffer_get_len(session->out_buffer),
                             ssh_buffer_get_len(session->out_buffer));
  }
#endif
  hmac = ssh_packet_encrypt(session, ssh_buffer_get(session->out_buffer),
      ssh_buffer_get_len(session->out_buffer));
  if (hmac) {
    rc = ssh_buffer_add_data(session->out_buffer, hmac, hmac_digest_len(hmac_type));
    if (rc < 0) {
      goto error;
    }
  }

  rc = ssh_packet_write(session);
  session->send_seq++;
  if (session->raw_counter != NULL) {
      session->raw_counter->out_bytes += payloadsize;
      session->raw_counter->out_packets++;
  }

  SSH_LOG(SSH_LOG_PACKET,
          "packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]",
          finallen, padding, compsize, payloadsize);
  if (ssh_buffer_reinit(session->out_buffer) < 0) {
    rc = SSH_ERROR;
  }
error:
  if (header_buffer != NULL) {
      ssh_buffer_free(header_buffer);
  }
  return rc; /* SSH_OK, AGAIN or ERROR */
}
Esempio n. 4
0
static int packet_send2(ssh_session session) {
  unsigned int blocksize = (session->current_crypto ?
      session->current_crypto->out_cipher->blocksize : 8);
  enum ssh_hmac_e hmac_type = (session->current_crypto ?
      session->current_crypto->out_hmac : session->next_crypto->out_hmac);
  uint32_t currentlen = ssh_buffer_get_len(session->out_buffer);
  unsigned char *hmac = NULL;
  char padstring[32] = { 0 };
  int rc = SSH_ERROR;
  uint32_t finallen,payloadsize,compsize;
  uint8_t padding;

  uint8_t header[sizeof(padding) + sizeof(finallen)] = { 0 };

  payloadsize = currentlen;
#ifdef WITH_ZLIB
  if (session->current_crypto
      && session->current_crypto->do_compress_out
      && ssh_buffer_get_len(session->out_buffer)) {
    if (compress_buffer(session,session->out_buffer) < 0) {
      goto error;
    }
    currentlen = ssh_buffer_get_len(session->out_buffer);
  }
#endif /* WITH_ZLIB */
  compsize = currentlen;
  padding = (blocksize - ((currentlen +5) % blocksize));
  if(padding < 4) {
    padding += blocksize;
  }

  if (session->current_crypto) {
    ssh_get_random(padstring, padding, 0);
  }

  finallen = htonl(currentlen + padding + 1);

  memcpy(&header[0], &finallen, sizeof(finallen));
  header[sizeof(finallen)] = padding;
  rc = ssh_buffer_prepend_data(session->out_buffer, &header, sizeof(header));
  if (rc < 0) {
    goto error;
  }
  rc = ssh_buffer_add_data(session->out_buffer, padstring, padding);
  if (rc < 0) {
    goto error;
  }
#ifdef WITH_PCAP
  if(session->pcap_ctx){
  	ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT,
  			ssh_buffer_get(session->out_buffer),ssh_buffer_get_len(session->out_buffer)
  			,ssh_buffer_get_len(session->out_buffer));
  }
#endif
  hmac = ssh_packet_encrypt(session, ssh_buffer_get(session->out_buffer),
      ssh_buffer_get_len(session->out_buffer));
  if (hmac) {
    rc = ssh_buffer_add_data(session->out_buffer, hmac, hmac_digest_len(hmac_type));
    if (rc < 0) {
      goto error;
    }
  }

  rc = ssh_packet_write(session);
  session->send_seq++;
  if (session->raw_counter != NULL) {
      session->raw_counter->out_bytes += payloadsize;
      session->raw_counter->out_packets++;
  }

  SSH_LOG(SSH_LOG_PACKET,
          "packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]",
          ntohl(finallen), padding, compsize, payloadsize);
  if (ssh_buffer_reinit(session->out_buffer) < 0) {
    rc = SSH_ERROR;
  }
error:

  return rc; /* SSH_OK, AGAIN or ERROR */
}