feat: complete wgcloak v1 transports
This commit is contained in:
1 parent
49ec9d8c33
commit
cedab4910e
47 files changed
+2849
-400
No files matched your search
@@ -0,0 +1,2 @@
|
||||
/target/
|
||||
/Cargo.lock
|
||||
@@ -0,0 +1,40 @@
|
||||
[package]
|
||||
name = "wgcloak-fuzz"
|
||||
version = "0.0.0"
|
||||
publish = false
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata]
|
||||
cargo-fuzz = true
|
||||
|
||||
[dependencies]
|
||||
libfuzzer-sys = "0.4"
|
||||
wgcloak = { path = ".." }
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_direct_packet"
|
||||
path = "fuzz_targets/fuzz_direct_packet.rs"
|
||||
test = false
|
||||
doc = false
|
||||
bench = false
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_tls_frame"
|
||||
path = "fuzz_targets/fuzz_tls_frame.rs"
|
||||
test = false
|
||||
doc = false
|
||||
bench = false
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_http3_parser"
|
||||
path = "fuzz_targets/fuzz_http3_parser.rs"
|
||||
test = false
|
||||
doc = false
|
||||
bench = false
|
||||
|
||||
[[bin]]
|
||||
name = "fuzz_config_toml"
|
||||
path = "fuzz_targets/fuzz_config_toml.rs"
|
||||
test = false
|
||||
doc = false
|
||||
bench = false
|
||||
@@ -0,0 +1 @@
|
||||
[[client
|
||||
@@ -0,0 +1,4 @@
|
||||
[client]
|
||||
server = "127.0.0.1:51820"
|
||||
id = "fuzz"
|
||||
secret = "ZmFrZQ=="
|
||||
@@ -0,0 +1 @@
|
||||
\x01\x10\x00\xff
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
\x2a\x20
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
\xff\xff
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#![no_main]
|
||||
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
use wgcloak::config::Config;
|
||||
|
||||
const MAX_INPUT: usize = 64 * 1024;
|
||||
|
||||
fuzz_target!(|input: &[u8]| {
|
||||
let input = &input[..input.len().min(MAX_INPUT)];
|
||||
// Parsing only: Config::from_str never reads secret files. Validation is
|
||||
// intentionally not called because it may resolve file-backed secrets.
|
||||
if let Ok(text) = std::str::from_utf8(input) {
|
||||
let _ = Config::from_str(text);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
#![no_main]
|
||||
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
use wgcloak::protocol::direct::parse_packet_bounded;
|
||||
|
||||
const MAX_INPUT: usize = 64 * 1024;
|
||||
const MAX_DATA_PAYLOAD: usize = 16 * 1024;
|
||||
|
||||
fuzz_target!(|input: &[u8]| {
|
||||
// Keep the harness itself bounded even if the engine is configured with a
|
||||
// larger input size. The parser performs structural checks before copying
|
||||
// DATA payloads.
|
||||
let input = &input[..input.len().min(MAX_INPUT)];
|
||||
let _ = parse_packet_bounded(input, MAX_DATA_PAYLOAD);
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
#![no_main]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
use wgcloak::transport::http3::{
|
||||
decode_auth_challenge, decode_capsule, decode_http_datagram, is_auth_accept,
|
||||
verify_auth_response, AuthChallenge,
|
||||
};
|
||||
|
||||
const MAX_INPUT: usize = 64 * 1024;
|
||||
const MAX_DATAGRAM: usize = 16 * 1024;
|
||||
|
||||
fuzz_target!(|input: &[u8]| {
|
||||
let input = &input[..input.len().min(MAX_INPUT)];
|
||||
// All of these are in-memory parsers. decode_http_datagram bounds the
|
||||
// copied payload, while the capsule/auth parsers only copy this bounded
|
||||
// input or fixed-size fields.
|
||||
let _ = decode_http_datagram(input, 0, MAX_DATAGRAM);
|
||||
let _ = decode_capsule(input);
|
||||
let _ = decode_auth_challenge(input);
|
||||
let _ = is_auth_accept(input);
|
||||
let challenge = AuthChallenge { bytes: [0; 32] };
|
||||
let clients = HashMap::new();
|
||||
let _ = verify_auth_response(&challenge, input, &clients);
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
#![no_main]
|
||||
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
use wgcloak::transport::tls_tcp::FrameCodec;
|
||||
|
||||
const MAX_INPUT: usize = 64 * 1024;
|
||||
const MAX_FRAME: usize = 16 * 1024;
|
||||
const CHUNK: usize = 97;
|
||||
|
||||
fuzz_target!(|input: &[u8]| {
|
||||
let input = &input[..input.len().min(MAX_INPUT)];
|
||||
let Ok(mut codec) = FrameCodec::new(MAX_FRAME) else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Feed deliberately uneven chunks so header/payload state transitions are
|
||||
// exercised independently of TCP read boundaries.
|
||||
for chunk in input.chunks(CHUNK) {
|
||||
if codec.feed(chunk).is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let _ = codec.finish();
|
||||
});
|
||||
Reference in new issue
Block a user