Skip to content

Commit

Permalink
tests(pcap): fix support for older tshark versions
Browse files Browse the repository at this point in the history
  • Loading branch information
lrstewart committed Aug 30, 2024
1 parent 9cdbea8 commit c750a30
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
9 changes: 8 additions & 1 deletion tests/pcap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@ publish = false

[features]
default = []
ja4 = [] # Older versions of tshark do not support JA4
# tshark >= 3.7.0 is required for JA3 support
# JA3 support was added to earlier versions, but did not correctly ignore grease values.
# See https://github.com/wireshark/wireshark/commit/03afef0a566ed649ead587fb4c02fc2d8539f3b7
ja3 = []
# tshark >= 4.2.0 is required for JA4 support
# See https://gitlab.com/wireshark/wireshark/-/issues/19370
ja4 = []
download = [] # Download additional pcaps from a list of configured urls

[build-dependencies]
anyhow = "1.0.86"
bytes = "1.7.1"
hex = "0.4.3"
reqwest = { version = "0.12.7", features = ["blocking"] }
semver = "1.0.23"

[dependencies]
anyhow = "1.0.86"
Expand Down
38 changes: 38 additions & 0 deletions tests/pcap/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
use anyhow::*;
use bytes::Buf;
use bytes::Bytes;
use semver::Version;
use semver::VersionReq;
use std::collections::HashMap;
use std::fs::File;
use std::io::copy;
use std::path::Path;
use std::process::Command;
use std::thread;
use std::time::Duration;

Expand Down Expand Up @@ -101,7 +104,42 @@ fn download(url: &str) -> Result<Bytes> {
bail!("Unable to download: {}", url);
}

fn assert_tshark_version() -> Result<()> {
let output = Command::new("tshark").args(["--version"]).output();
let version = output.ok().and_then(|output| {
let message = std::str::from_utf8(&output.stdout).ok();
message.and_then(|msg| msg.split_whitespace().find_map(|s| Version::parse(s).ok()))
});

let ja3_req = VersionReq::parse(">= 3.7.0")?;
let ja4_req = VersionReq::parse(">= 4.2.0")?;
if let Some(version) = version {
println!("tshark version: {:?}", version);
if cfg!(feature = "ja3") {
assert!(
ja3_req.matches(&version),
"tshark {} required for ja3, {} found",
ja3_req,
version
);
}
if cfg!(feature = "ja4") {
assert!(
ja4_req.matches(&version),
"tshark {} required for ja4, {} found",
ja4_req,
version
);
}
} else {
println!("cargo:warning=Unable to determine tshark version");
}
Ok(())
}

fn main() -> Result<()> {
assert_tshark_version()?;

let out_dir = std::env::var("OUT_DIR")?;
let download_path = Path::new(&out_dir).join("downloaded_pcaps");

Expand Down
7 changes: 7 additions & 0 deletions tests/pcap/src/handshake_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ impl Builder {
// We currently don't support QUIC
let filter = filter + " && !quic";

// We currently don't support SSLv2.
// Newer versions of tshark automatically filter out SSLv2 by marking
// SSLv2 handshake messages as "tls.ssl2" rather than just "tls".
// To support SSLv2, we'd need to search for both "tls" and "tls.ssl2".
// Instead, let's just explicitly ignore SSLv2 for now.
let filter = filter + " && tls.record.version != 0x0002";

// tshark associates a LOT of metadata with each packet. Filtering that
// metadata (like by using `metadata_whitelist`) significantly improves
// both performance and memory usage.
Expand Down
7 changes: 5 additions & 2 deletions tests/pcap/tests/s2n_client_hellos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use anyhow::*;
use pcap::all_pcaps;
use pcap::client_hello::ClientHello as PcapHello;
use pcap::handshake_message::Builder;
use s2n_tls::client_hello::{ClientHello as S2NHello, FingerprintType};
use s2n_tls::client_hello::ClientHello as S2NHello;

fn get_s2n_hello(pcap_hello: &PcapHello) -> Result<Box<S2NHello>> {
let bytes = pcap_hello.message().bytes();
Expand Down Expand Up @@ -42,9 +42,12 @@ fn parsing() -> Result<()> {
test_all_client_hellos(|_, _| Ok(()))
}

#[cfg(feature = "ja3")]
#[test]
#[allow(deprecated)]
fn ja3_fingerprints() -> Result<()> {
use s2n_tls::client_hello::FingerprintType;

test_all_client_hellos(|pcap_hello, s2n_hello| {
let mut s2n_ja3_hash = Vec::new();
s2n_hello
Expand All @@ -68,7 +71,7 @@ fn ja3_fingerprints() -> Result<()> {
fn ja4_fingerprints() -> Result<()> {
use s2n_tls::fingerprint;

let mut builder = fingerprint::Builder::new(FingerprintType::JA4)?;
let mut builder = fingerprint::Builder::new(fingerprint::FingerprintType::JA4)?;

test_all_client_hellos(|pcap_hello, s2n_hello| {
let mut fingerprint = builder.build(&s2n_hello)?;
Expand Down

0 comments on commit c750a30

Please sign in to comment.