Example #1
0
int sftp_service_handle(struct ssh2_packet *pkt) {
  int res;
  char *service = NULL;

  res = read_service_req(pkt, &service);
  if (res < 0) {
    destroy_pool(pkt->pool);
    SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE, NULL);
  }

  destroy_pool(pkt->pool);

  pkt = sftp_ssh2_packet_create(service_pool);
  res = write_service_accept(pkt, service);
  if (res < 0) {
    destroy_pool(pkt->pool);
    return -1;
  }

  res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
  if (res < 0) {
    destroy_pool(pkt->pool);
    return -1;
  }

  destroy_pool(pkt->pool);
  return 0;
}
Example #2
0
int sftp_mac_read_data(struct ssh2_packet *pkt) {
  struct sftp_mac *mac;
  HMAC_CTX *mac_ctx;

  mac = &(read_macs[read_mac_idx]);
  mac_ctx = &(read_ctxs[read_mac_idx]);

  if (mac->key) {
    unsigned char *mac_data;
    char *buf, *ptr;
    uint32_t buflen, bufsz = (sizeof(uint32_t) * 2) + pkt->packet_len,
      mac_len = 0;

    mac_data = pcalloc(pkt->pool, EVP_MAX_MD_SIZE);

    buflen = bufsz;
    ptr = buf = sftp_msg_getbuf(pkt->pool, bufsz);

    sftp_msg_write_int(&buf, &buflen, pkt->seqno);
    sftp_msg_write_int(&buf, &buflen, pkt->packet_len);
    sftp_msg_write_byte(&buf, &buflen, pkt->padding_len);
    sftp_msg_write_data(&buf, &buflen, pkt->payload, pkt->payload_len, FALSE);
    sftp_msg_write_data(&buf, &buflen, pkt->padding, pkt->padding_len, FALSE);

#if OPENSSL_VERSION_NUMBER > 0x000907000L
# if OPENSSL_VERSION_NUMBER >= 0x10000001L
    if (HMAC_Init_ex(mac_ctx, NULL, 0, NULL, NULL) != 1) {
      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
        "error resetting HMAC context: %s", sftp_crypto_get_errors());
      errno = EPERM;
      return -1;
    }
# else
    HMAC_Init_ex(mac_ctx, NULL, 0, NULL, NULL);
# endif /* OpenSSL-1.0.0 and later */

#else
    HMAC_Init(mac_ctx, NULL, 0, NULL);
#endif /* OpenSSL-0.9.7 and later */

#if OPENSSL_VERSION_NUMBER >= 0x10000001L
    if (HMAC_Update(mac_ctx, (unsigned char *) ptr, (bufsz - buflen)) != 1) {
      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
        "error adding %lu bytes of data to  HMAC context: %s",
        (unsigned long) (bufsz - buflen), sftp_crypto_get_errors());
      errno = EPERM;
      return -1;
    }

    if (HMAC_Final(mac_ctx, mac_data, &mac_len) != 1) {
      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
        "error finalizing HMAC context: %s", sftp_crypto_get_errors());
      errno = EPERM;
      return -1;
    }
#else
    HMAC_Update(mac_ctx, (unsigned char *) ptr, (bufsz - buflen));
    HMAC_Final(mac_ctx, mac_data, &mac_len);
#endif /* OpenSSL-1.0.0 and later */

    if (mac_len == 0) {
      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
        "error computing MAC using %s: %s", mac->algo,
        sftp_crypto_get_errors());
      SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_MAC_ERROR, NULL);
    }

    if (mac->mac_len != 0) {
      mac_len = mac->mac_len;
    }

    if (mac_len != pkt->mac_len) {
      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
        "expected %u MAC len from client, got %lu", mac_len,
        (unsigned long) pkt->mac_len);
      SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_MAC_ERROR, NULL);
    }

    if (memcmp(mac_data, pkt->mac, mac_len) != 0) {
      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
        "MAC from client differs from expected MAC using %s", mac->algo);

#ifdef SFTP_DEBUG_PACKET
{
      unsigned int i;
      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
        "client MAC (len %lu):", (unsigned long) pkt->mac_len);
      for (i = 0; i < mac_len;) {
        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
          "  %02x%02x %02x%02x %02x%02x %02x%02x",
          ((unsigned char *) pkt->mac)[i], ((unsigned char *) pkt->mac)[i+1],
          ((unsigned char *) pkt->mac)[i+2], ((unsigned char *) pkt->mac)[i+3],
          ((unsigned char *) pkt->mac)[i+4], ((unsigned char *) pkt->mac)[i+5],
          ((unsigned char *) pkt->mac)[i+6], ((unsigned char *) pkt->mac)[i+7]);
        i += 8;
      }

      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
        "server MAC (len %lu):", (unsigned long) mac_len);
      for (i = 0; i < mac_len;) {
        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
          "  %02x%02x %02x%02x %02x%02x %02x%02x",
          ((unsigned char *) mac)[i], ((unsigned char *) mac)[i+1],
          ((unsigned char *) mac)[i+2], ((unsigned char *) mac)[i+3],
          ((unsigned char *) mac)[i+4], ((unsigned char *) mac)[i+5],
          ((unsigned char *) mac)[i+6], ((unsigned char *) mac)[i+7]);
        i += 8;
      }
}
#endif

      SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_MAC_ERROR, NULL);
    }

    return 0;
  }

  return 0;
}