13 Commits

Author SHA1 Message Date
eric
f60e243a89 v0.10.13
Some checks failed
ci / test (macos-latest) (push) Has been cancelled
ci / test (ubuntu-latest) (push) Has been cancelled
ci / build-cli-cross (aarch64-unknown-linux-musl) (push) Has been cancelled
ci / build-cli-cross (arm-unknown-linux-musleabi) (push) Has been cancelled
ci / build-cli-cross (armv7-unknown-linux-musleabihf) (push) Has been cancelled
ci / build-cli-cross (i686-unknown-linux-musl) (push) Has been cancelled
ci / build-cli-cross (x86_64-pc-windows-gnu) (push) Has been cancelled
ci / build-cli-cross (x86_64-unknown-linux-musl) (push) Has been cancelled
ci / build-cli-macos (aarch64-apple-darwin) (push) Has been cancelled
ci / build-cli-macos (x86_64-apple-darwin) (push) Has been cancelled
ci / build-lib-apple (push) Has been cancelled
ci / build-lib-android (push) Has been cancelled
releases / build-cli-cross (aarch64-unknown-linux-musl) (push) Has been cancelled
releases / build-cli-cross (x86_64-pc-windows-gnu) (push) Has been cancelled
releases / build-cli-cross (x86_64-unknown-linux-musl) (push) Has been cancelled
releases / build-cli-macos (aarch64-apple-darwin) (push) Has been cancelled
releases / build-cli-macos (x86_64-apple-darwin) (push) Has been cancelled
releases / build-lib-apple (push) Has been cancelled
releases / build-lib-android (push) Has been cancelled
releases / create-release (push) Has been cancelled
releases / release-cli (aarch64-apple-darwin) (push) Has been cancelled
releases / release-cli (aarch64-unknown-linux-musl) (push) Has been cancelled
releases / release-cli (x86_64-apple-darwin) (push) Has been cancelled
releases / release-cli (x86_64-pc-windows-gnu) (push) Has been cancelled
releases / release-cli (x86_64-unknown-linux-musl) (push) Has been cancelled
releases / release-mobile-libs (push) Has been cancelled
2024-05-06 19:46:21 +08:00
eric
42c9d74676 Use ring as default crypto backend 2024-05-06 19:45:50 +08:00
eric
7a31f50c56 chore: fix cross build 2024-05-02 02:46:18 +08:00
eric
effac11504 Support aws-lc-rs crypto backend 2024-05-02 02:24:26 +08:00
eric
4ff8b1d102 chore: set deployment target for Apple platforms 2024-05-02 00:11:30 +08:00
eric
15777875c2 chore: update deps 2024-05-01 23:59:44 +08:00
eric
1dfe30bfdb chore: exit on command fail 2024-04-22 22:12:39 +08:00
eric
067c3ee0f5 chore: fix android build 2024-04-22 21:48:17 +08:00
eric
adcf157db3 fake_dns: fix fake IP allocation 2024-04-20 21:21:30 +08:00
eric
e2541dc594 net: return error instead of panic on receiving unexpected target 2024-04-20 21:06:44 +08:00
eric
9e06f37eb0 fake_dns: enlarge fake IP address pool 2024-04-20 20:35:11 +08:00
eric
06503e16c0 v0.10.12
Some checks failed
ci / test (macos-latest) (push) Has been cancelled
ci / test (ubuntu-latest) (push) Has been cancelled
ci / build-bin-cross (aarch64-unknown-linux-musl) (push) Has been cancelled
ci / build-bin-cross (arm-unknown-linux-musleabi) (push) Has been cancelled
ci / build-bin-cross (armv7-unknown-linux-musleabihf) (push) Has been cancelled
ci / build-bin-cross (i686-unknown-linux-musl) (push) Has been cancelled
ci / build-bin-cross (x86_64-pc-windows-gnu) (push) Has been cancelled
ci / build-bin-cross (x86_64-unknown-linux-musl) (push) Has been cancelled
ci / build-bin-local (macos-latest, x86_64-apple-darwin) (push) Has been cancelled
ci / build-apple (push) Has been cancelled
ci / build-android (push) Has been cancelled
releases / build-bin-cross (aarch64-unknown-linux-musl) (push) Has been cancelled
releases / build-bin-cross (x86_64-pc-windows-gnu) (push) Has been cancelled
releases / build-bin-cross (x86_64-unknown-linux-musl) (push) Has been cancelled
releases / build-bin-local (macos-latest, x86_64-apple-darwin) (push) Has been cancelled
releases / build-apple (push) Has been cancelled
releases / build-android (push) Has been cancelled
releases / create-release (push) Has been cancelled
releases / release-bin (aarch64-unknown-linux-musl) (push) Has been cancelled
releases / release-bin (x86_64-apple-darwin) (push) Has been cancelled
releases / release-bin (x86_64-pc-windows-gnu) (push) Has been cancelled
releases / release-bin (x86_64-unknown-linux-musl) (push) Has been cancelled
releases / release-mobile-libs (push) Has been cancelled
2024-04-18 16:47:38 +08:00
eric
2b3c4822ab chore: fix build script 2024-04-18 16:47:21 +08:00
26 changed files with 250 additions and 178 deletions

View File

@@ -25,7 +25,7 @@ jobs:
- name: test leaf
run: cargo test -p leaf
build-bin-cross:
build-cli-cross:
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -60,7 +60,7 @@ jobs:
run: |
export CFG_COMMIT_HASH=`git log --pretty=format:'%h' -n 1`
export CFG_COMMIT_DATE=`git log --format="%ci" -n 1`
./scripts/build_cross.sh ${{ matrix.target }}
cross build --release --target ${{ matrix.target }}
- name: rename and compress artifacts
if: ${{ matrix.target == 'x86_64-pc-windows-gnu' }}
@@ -86,14 +86,14 @@ jobs:
name: leaf-${{ matrix.target }}
path: leaf-${{ matrix.target }}
build-bin-local:
build-cli-macos:
runs-on: [macos-latest]
strategy:
fail-fast: false
matrix:
os: [macos-latest]
include:
- os: macos-latest
target: x86_64-apple-darwin
runs-on: ${{ matrix.os }}
target:
- aarch64-apple-darwin
- x86_64-apple-darwin
steps:
- name: checkout
uses: actions/checkout@v2
@@ -114,11 +114,15 @@ jobs:
run: |
brew install llvm protobuf
- name: install target
run: |
rustup target add ${{ matrix.target }}
- name: build
run: |
export CFG_COMMIT_HASH=`git log --pretty=format:'%h' -n 1`
export CFG_COMMIT_DATE=`git log --format="%ci" -n 1`
cargo build --release --target ${{ matrix.target }} -p leaf-bin
cargo build --release --target ${{ matrix.target }} -p leaf-cli
- name: rename and compress artifacts
run: |
@@ -130,7 +134,7 @@ jobs:
name: leaf-${{ matrix.target }}
path: leaf-${{ matrix.target }}
build-apple:
build-lib-apple:
runs-on: macos-latest
steps:
- name: checkout
@@ -163,7 +167,7 @@ jobs:
name: leaf.xcframework.zip
path: leaf.xcframework.zip
build-android:
build-lib-android:
runs-on: ubuntu-latest
steps:
- name: checkout

View File

@@ -6,7 +6,7 @@ on:
- v*
jobs:
build-bin-cross:
build-cli-cross:
runs-on: ubuntu-latest
strategy:
matrix:
@@ -37,7 +37,7 @@ jobs:
run: |
export CFG_COMMIT_HASH=`git log --pretty=format:'%h' -n 1`
export CFG_COMMIT_DATE=`git log --format="%ci" -n 1`
./scripts/build_cross.sh ${{ matrix.target }}
cross build --release --target ${{ matrix.target }}
- name: rename and compress artifacts
if: ${{ matrix.target == 'x86_64-pc-windows-gnu' }}
@@ -63,14 +63,14 @@ jobs:
name: leaf-${{ matrix.target }}
path: leaf-${{ matrix.target }}
build-bin-local:
build-cli-macos:
runs-on: [macos-latest]
strategy:
fail-fast: false
matrix:
os: [macos-latest]
include:
- os: macos-latest
target: x86_64-apple-darwin
runs-on: ${{ matrix.os }}
target:
- aarch64-apple-darwin
- x86_64-apple-darwin
steps:
- name: checkout
uses: actions/checkout@v2
@@ -87,11 +87,15 @@ jobs:
run: |
brew install llvm protobuf
- name: install target
run: |
rustup target add ${{ matrix.target }}
- name: build
run: |
export CFG_COMMIT_HASH=`git log --pretty=format:'%h' -n 1`
export CFG_COMMIT_DATE=`git log --format="%ci" -n 1`
cargo build --release --target ${{ matrix.target }} -p leaf-bin
cargo build --release --target ${{ matrix.target }} -p leaf-cli
- name: rename and compress artifacts
run: |
@@ -103,7 +107,7 @@ jobs:
name: leaf-${{ matrix.target }}
path: leaf-${{ matrix.target }}
build-apple:
build-lib-apple:
runs-on: macos-latest
steps:
- name: checkout
@@ -136,7 +140,7 @@ jobs:
name: leaf.xcframework.zip
path: leaf.xcframework.zip
build-android:
build-lib-android:
runs-on: ubuntu-latest
steps:
- name: checkout
@@ -182,7 +186,7 @@ jobs:
path: leaf-android-libs.zip
create-release:
needs: [build-bin-cross, build-bin-local, build-apple, build-android]
needs: [build-cli-cross, build-cli-macos, build-lib-apple, build-lib-android]
runs-on: macos-latest
steps:
- name: checkout
@@ -211,13 +215,14 @@ jobs:
name: upload_url.txt
path: ./upload_url.txt
release-bin:
release-cli:
needs: [create-release]
runs-on: macos-latest
strategy:
matrix:
target:
- x86_64-apple-darwin
- aarch64-apple-darwin
- x86_64-unknown-linux-musl
- aarch64-unknown-linux-musl
- x86_64-pc-windows-gnu

View File

@@ -1,4 +1,4 @@
.PHONY: local local-dev test proto-gen
.PHONY: cli cli-dev test proto-gen
CFG_COMMIT_HASH := $(shell git rev-parse HEAD | cut -c 1-7)
export CFG_COMMIT_HASH := $(CFG_COMMIT_HASH)

View File

@@ -83,7 +83,7 @@ Clone & Build:
```sh
git clone --recursive https://github.com/eycorsican/leaf.git
cd leaf
cargo build -p leaf-bin
cargo build -p leaf-cli
```
Run:

View File

@@ -1,6 +1,6 @@
[package]
name = "leaf-cli"
version = "0.10.11"
version = "0.10.13"
authors = ["eycorsican <eric.y.corsican@gmail.com>"]
edition = "2021"
@@ -9,13 +9,13 @@ name = "leaf"
path = "src/main.rs"
[features]
default = ["default-ring"]
default-ring = ["leaf/default-ring", "leaf/ctrlc", "auto-reload"]
default-openssl = ["leaf/default-openssl", "leaf/ctrlc", "auto-reload"]
auto-reload = ["leaf/auto-reload"]
default = [
"leaf/default-ring",
"leaf/outbound-quic",
"leaf/outbound-quic",
"leaf/ctrlc",
"leaf/auto-reload",
]
[dependencies]
leaf = { path = "../leaf", default-features = false, optional = true }

View File

@@ -34,7 +34,6 @@ struct Args {
config: String,
/// enables auto reloading when config file changes
#[cfg(feature = "auto-reload")]
#[argh(switch)]
auto_reload: bool,
@@ -123,7 +122,6 @@ fn main() {
if let Err(e) = leaf::util::run_with_options(
0,
args.config,
#[cfg(feature = "auto-reload")]
args.auto_reload,
!args.single_thread,
true,

View File

@@ -14,6 +14,10 @@ default = [
"default-ring",
]
default-aws-lc= [
"leaf/default-aws-lc",
]
default-ring = [
"leaf/default-ring",
]

View File

@@ -19,12 +19,19 @@ default-ring = [
"all-endpoints",
"ring-aead",
"rustls-tls",
# quinn supports only rustls as tls backend for now
"inbound-quic",
"outbound-quic",
"rustls-tls-ring",
"api",
"stat",
]
default-aws-lc = [
"all-configs",
"all-endpoints",
"aws-lc-aead",
"rustls-tls",
"rustls-tls-aws-lc",
"api",
"stat",
# "plugin",
]
default-openssl = [
@@ -34,6 +41,9 @@ default-openssl = [
"openssl-tls",
]
rustls-tls-aws-lc = ["tokio-rustls/aws_lc_rs"]
rustls-tls-ring = ["tokio-rustls/ring"]
# Grouping all features
all-configs = [
"config-conf",
@@ -74,6 +84,7 @@ all-endpoints = [
# Ring-related
ring-aead = ["ring"]
aws-lc-aead = ["aws-lc-rs"]
rustls-tls = ["tokio-rustls", "webpki-roots", "rustls-pemfile"]
# Openssl-related, for platforms not supported by ring, such as mips
@@ -99,7 +110,7 @@ outbound-static= []
outbound-tryall = []
outbound-chain = []
outbound-amux= ["tokio-util"]
outbound-quic = ["quinn", "rustls", "webpki-roots", "rustls-pemfile"]
outbound-quic = ["quinn", "rustls", "webpki-roots-old", "rustls-pemfile-old"]
outbound-select = ["directories"]
outbound-vmess = ["lz_fnv", "cfb-mode", "hmac", "aes", "sha3", "digest", "uuid", "md-5", "tokio-util", "byteorder"]
@@ -111,7 +122,7 @@ inbound-http = ["http"]
inbound-tun = ["tun", "netstack-lwip", "pnet_datalink"]
inbound-ws = ["tungstenite", "tokio-tungstenite", "url", "http"]
inbound-amux = ["tokio-util"]
inbound-quic = ["quinn", "rustls", "webpki-roots"]
inbound-quic = ["quinn", "rustls", "rustls-pemfile-old"]
inbound-tls = []
inbound-chain = []
inbound-cat = ["tokio/io-std"]
@@ -125,31 +136,31 @@ ctrlc = ["tokio/signal"]
[dependencies]
# Common
tokio = { version = "1", features = ["sync", "io-util", "net", "time", "rt", "rt-multi-thread"] }
protobuf = "=3.3.0"
protobuf = "=3.4.0"
thiserror = "1.0"
futures = "0.3"
async-trait = "0.1"
bytes = "1"
bytes = "1.6"
lazy_static = "1.4"
anyhow = "1.0"
rand = "0.8"
socket2 = "0.5"
async-recursion = "1.0"
async-recursion = "1.1"
# DNS
trust-dns-proto = { version = "0.23", default-features = false }
lru = "0.11"
lru = "0.12"
# Logging
tracing = "0.1"
tracing-appender = "0.2"
tracing-subscriber = "0.3"
chrono = "0.4"
colored = "2.0"
colored = "2.1"
# Router
maxminddb = { version = "0.23", features = ["mmap"] }
memmap2 = "0.8"
maxminddb = { version = "0.24", features = ["mmap"] }
memmap2 = "0.9"
cidr = "0.2"
# outbound-select
@@ -165,42 +176,44 @@ serde_derive = { version = "1.0", optional = true }
serde = { version = "1.0", optional = true }
# config-conf
regex = { version = "1", optional = true }
regex = { version = "1.10", optional = true }
# Openssl
openssl = { version = "0.10", features = ["vendored"], optional = true }
# Ring
ring = { version = "0.16", optional = true }
ring = { version = "0.17", optional = true }
aws-lc-rs = { version = "1.7", features = ["bindgen"], optional = true }
# TLS/rustls/QUIC
tokio-rustls = { version = "0.24", features = ["dangerous_configuration"], optional = true }
webpki-roots = { version = "0.25", optional = true }
rustls-pemfile = { version = "1.0", optional = true }
tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "tls12"], optional = true }
webpki-roots = { version = "0.26", optional = true }
webpki-roots-old = { package = "webpki-roots", version = "0.25", optional = true }
rustls-pemfile = { version = "2.1", optional = true }
rustls-pemfile-old = { package = "rustls-pemfile", version = "1.0", optional = true }
# TLS/openssl
openssl-probe = { version = "0.1", optional = true }
tokio-openssl = { version = "0.6", optional = true }
# WebSocket
tungstenite = { version = "0.20", default-features = false, optional = true }
tokio-tungstenite = { version = "0.20", optional = true }
tungstenite = { version = "0.21", default-features = false, optional = true }
tokio-tungstenite = { version = "0.21", optional = true }
# WebSocket
url = { version = "2.4", optional = true }
http = { version = "0.2", optional = true }
url = { version = "2.5", optional = true }
http = { version = "1.1", optional = true }
# SOCKS outbound
async-socks5 = { version = "0.5", optional = true }
async-socks5 = { version = "0.6", optional = true }
# Shadowsocks
hkdf = { version = "0.12", optional = true }
md-5 = { version = "0.10", optional = true }
sha-1 = { version = "0.10", optional = true }
percent-encoding = { version = "2", optional = true }
percent-encoding = { version = "2.3", optional = true }
# Obfs
base64 = { version = "0.21", optional = true }
base64 = { version = "0.22", optional = true }
memchr = { version = "2", optional = true }
# Trojan
@@ -239,7 +252,7 @@ jni = "0.21"
# TUN
[target.'cfg(any(target_os = "ios", target_os = "android", target_os = "macos", target_os = "linux"))'.dependencies]
tun = { git = "https://github.com/eycorsican/rust-tun.git", branch = "fork", features = ["async"], optional = true }
netstack-lwip = { git = "https://github.com/eycorsican/netstack-lwip.git", rev = "809a733", optional = true }
netstack-lwip = { git = "https://github.com/eycorsican/netstack-lwip.git", rev = "9c7f2e3", optional = true }
[target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies]
pnet_datalink = { version = "0.34", package = "pnet_datalink", optional = true }
@@ -250,11 +263,11 @@ libc = "0.2"
memchr = { version = "2" }
[dev-dependencies]
rcgen = "0.11"
rcgen = "0.13"
sha2 = "0.10"
tokio = { version = "1", features = ["fs", "sync", "io-util", "net", "time", "rt", "rt-multi-thread"] }
[build-dependencies]
cc = "1.0"
bindgen = "0.68"
protobuf-codegen = "=3.3.0"
bindgen = "0.69"
protobuf-codegen = "=3.4.0"

View File

@@ -32,7 +32,7 @@ fn generate_mobile_bindings() {
} else {
"".to_string()
})
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Unable to generate bindings");

View File

@@ -58,7 +58,7 @@ pub(self) struct FakeDnsImpl {
impl FakeDnsImpl {
pub(self) fn new(mode: FakeDnsMode) -> Self {
let min_cursor = Self::ip_to_u32(&Ipv4Addr::new(198, 18, 0, 0));
let max_cursor = Self::ip_to_u32(&Ipv4Addr::new(198, 18, 4, 255));
let max_cursor = Self::ip_to_u32(&Ipv4Addr::new(198, 18, 255, 255));
Self {
ip_to_domain: HashMap::new(),
domain_to_ip: HashMap::new(),
@@ -129,7 +129,7 @@ impl FakeDnsImpl {
_ => return Err(anyhow!("unexpected Ipv6 fake IP")),
}
} else {
let ip = self.allocate_ip(&domain);
let ip = self.allocate_ip(&domain)?;
debug!("allocate {} for {}", &ip, &domain);
ip
};
@@ -173,30 +173,34 @@ impl FakeDnsImpl {
ip >= self.min_cursor && ip <= self.max_cursor
}
fn allocate_ip(&mut self, domain: &str) -> Ipv4Addr {
fn allocate_ip(&mut self, domain: &str) -> Result<Ipv4Addr> {
if let Some(prev_domain) = self.ip_to_domain.insert(self.cursor, domain.to_owned()) {
// Remove the entry in the reverse map to make sure we won't have
// multiple domains point to a same IP.
self.domain_to_ip.remove(&prev_domain);
}
let ip = self.get_ip();
self.domain_to_ip.insert(domain.to_owned(), self.cursor);
self.cursor += 1;
ip
let ip = Self::u32_to_ip(self.cursor);
self.prepare_next_cursor()?;
Ok(ip)
}
fn get_ip(&mut self) -> Ipv4Addr {
if self.cursor > self.max_cursor {
self.cursor = self.min_cursor;
}
let ip = Self::u32_to_ip(self.cursor);
match ip.octets()[3] {
0 | 255 => {
self.cursor += 1;
self.get_ip()
// Make sure `self.cursor` is valid and can be used immediately for next fake IP.
fn prepare_next_cursor(&mut self) -> Result<()> {
for _ in 0..3 {
self.cursor += 1;
if self.cursor > self.max_cursor {
self.cursor = self.min_cursor;
}
// avoid network and broadcast addresses
match Self::u32_to_ip(self.cursor).octets()[3] {
0 | 255 => {
continue;
}
_ => return Ok(()),
}
_ => ip,
}
Err(anyhow!("unable to prepare next cursor"))
}
fn accept(&self, domain: &str) -> bool {

View File

@@ -1,5 +1,5 @@
// This file is generated by rust-protobuf 3.3.0. Do not edit
// .proto file is parsed by protoc 24.4
// This file is generated by rust-protobuf 3.4.0. Do not edit
// .proto file is parsed by protoc 26.1
// @generated
// https://github.com/rust-lang/rust-clippy/issues/702
@@ -24,7 +24,7 @@
/// Generated files are compatible only with the same version
/// of protobuf runtime.
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_3_0;
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_4_0;
// @@protoc_insertion_point(message:SelectorCache)
#[derive(PartialEq,Clone,Default,Debug)]

View File

@@ -204,8 +204,11 @@ pub mod aead {
}
}
#[cfg(feature = "ring-aead")]
#[cfg(any(feature = "aws-lc-aead", feature = "ring-aead"))]
pub mod aead {
#[cfg(feature = "aws-lc-aead")]
use aws_lc_rs::aead::{self, Aad, Algorithm, LessSafeKey, Nonce, UnboundKey};
#[cfg(feature = "ring-aead")]
use ring::aead::{self, Aad, Algorithm, LessSafeKey, Nonce, UnboundKey};
use super::*;
@@ -349,7 +352,11 @@ mod tests {
use super::*;
#[test]
#[cfg(any(feature = "ring-aead", feature = "openssl-aead"))]
#[cfg(any(
feature = "aws-lc-aead",
feature = "ring-aead",
feature = "openssl-aead"
))]
fn test_aead_enc_dec() {
struct ShadowsocksNonceSequence(Vec<u8>);

View File

@@ -1,5 +1,5 @@
// This file is generated by rust-protobuf 3.3.0. Do not edit
// .proto file is parsed by protoc 24.4
// This file is generated by rust-protobuf 3.4.0. Do not edit
// .proto file is parsed by protoc 26.1
// @generated
// https://github.com/rust-lang/rust-clippy/issues/702
@@ -24,7 +24,7 @@
/// Generated files are compatible only with the same version
/// of protobuf runtime.
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_3_0;
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_4_0;
// @@protoc_insertion_point(message:Domain)
#[derive(PartialEq,Clone,Default,Debug)]

View File

@@ -1,5 +1,5 @@
// This file is generated by rust-protobuf 3.3.0. Do not edit
// .proto file is parsed by protoc 24.4
// This file is generated by rust-protobuf 3.4.0. Do not edit
// .proto file is parsed by protoc 26.1
// @generated
// https://github.com/rust-lang/rust-clippy/issues/702
@@ -24,7 +24,7 @@
/// Generated files are compatible only with the same version
/// of protobuf runtime.
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_3_0;
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_4_0;
// @@protoc_insertion_point(message:Dns)
#[derive(PartialEq,Clone,Default,Debug)]

View File

@@ -59,8 +59,13 @@ pub struct StdOutboundDatagramSendHalf(Arc<UdpSocket>);
#[async_trait]
impl OutboundDatagramSendHalf for StdOutboundDatagramSendHalf {
async fn send_to(&mut self, buf: &[u8], target: &SocksAddr) -> io::Result<usize> {
// The type does not accept domain name.
self.0.send_to(buf, target.must_ip()).await
match target {
SocksAddr::Ip(a) => self.0.send_to(buf, a).await,
SocksAddr::Domain(domain, port) => Err(io::Error::new(
io::ErrorKind::Other,
format!("unexpected domain address {}:{}", domain, port),
)),
}
}
async fn close(&mut self) -> io::Result<()> {

View File

@@ -22,7 +22,7 @@ use std::os::windows::io::{AsRawSocket, AsSocket};
#[cfg(target_os = "android")]
use {
std::os::unix::io::RawFd, tokio::io::AsyncReadExt, tokio::io::AsyncWriteExt,
tokio::net::UnixStream,
tokio::net::UnixStream, tracing::trace,
};
use crate::{

View File

@@ -8,6 +8,7 @@ use async_trait::async_trait;
use futures::stream::Stream;
use futures::task::{Context, Poll};
use quinn::{RecvStream, SendStream};
use rustls_pemfile_old::{certs, ec_private_keys, pkcs8_private_keys, rsa_private_keys};
use tokio::sync::mpsc::{channel, Receiver, Sender};
use tracing::{debug, trace, warn};
@@ -61,7 +62,7 @@ impl Handler {
Some(Some(ext)) if ext == "der" => {
vec![rustls::Certificate(cert)]
}
_ => rustls_pemfile::certs(&mut &*cert)?
_ => certs(&mut &*cert)?
.into_iter()
.map(rustls::Certificate)
.collect(),
@@ -73,15 +74,15 @@ impl Handler {
{
Some(Some(ext)) if ext == "der" => rustls::PrivateKey(key),
_ => {
let pkcs8 = rustls_pemfile::pkcs8_private_keys(&mut &*key)?;
let pkcs8 = pkcs8_private_keys(&mut &*key)?;
match pkcs8.into_iter().next() {
Some(x) => rustls::PrivateKey(x),
None => {
let rsa = rustls_pemfile::rsa_private_keys(&mut &*key)?;
let rsa = rsa_private_keys(&mut &*key)?;
match rsa.into_iter().next() {
Some(x) => rustls::PrivateKey(x),
None => {
let rsa = rustls_pemfile::ec_private_keys(&mut &*key)?;
let rsa = ec_private_keys(&mut &*key)?;
match rsa.into_iter().next() {
Some(x) => rustls::PrivateKey(x),
None => {

View File

@@ -8,6 +8,7 @@ use anyhow::{anyhow, Result};
use async_trait::async_trait;
use futures::TryFutureExt;
use rustls::OwnedTrustAnchor;
use rustls_pemfile_old::certs;
use tokio::sync::RwLock;
use tracing::{debug, trace};
@@ -42,12 +43,11 @@ impl Manager {
roots.add(&rustls::Certificate(cert)).unwrap(); // FIXME
}
_ => {
let certs: Vec<rustls::Certificate> =
rustls_pemfile::certs(&mut &*cert)
.unwrap()
.into_iter()
.map(rustls::Certificate)
.collect();
let certs: Vec<rustls::Certificate> = certs(&mut &*cert)
.unwrap()
.into_iter()
.map(rustls::Certificate)
.collect();
for cert in certs {
roots.add(&cert).unwrap();
}
@@ -59,7 +59,7 @@ impl Manager {
}
}
} else {
roots.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
roots.add_trust_anchors(webpki_roots_old::TLS_SERVER_ROOTS.iter().map(|ta| {
OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,

View File

@@ -6,8 +6,11 @@ use anyhow::Result;
#[cfg(feature = "rustls-tls")]
use {
rustls_pemfile::{certs, pkcs8_private_keys, rsa_private_keys, ec_private_keys},
tokio_rustls::rustls::{Certificate, PrivateKey, ServerConfig},
rustls_pemfile::{certs, ec_private_keys, pkcs8_private_keys, rsa_private_keys},
tokio_rustls::rustls::{
pki_types::{CertificateDer, PrivateKeyDer},
ServerConfig,
},
tokio_rustls::TlsAcceptor,
};
@@ -19,23 +22,27 @@ pub struct Handler {
}
#[cfg(feature = "rustls-tls")]
fn load_certs(path: &Path) -> io::Result<Vec<Certificate>> {
certs(&mut BufReader::new(File::open(path)?))
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))
.map(|mut certs| certs.drain(..).map(Certificate).collect())
fn load_certs(path: &Path) -> io::Result<Vec<CertificateDer<'static>>> {
certs(&mut BufReader::new(File::open(path)?)).collect()
}
#[cfg(feature = "rustls-tls")]
fn load_keys(path: &Path) -> io::Result<Vec<PrivateKey>> {
let mut keys: Vec<PrivateKey> = pkcs8_private_keys(&mut BufReader::new(File::open(path)?))
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))
.map(|mut keys| keys.drain(..).map(PrivateKey).collect())?;
let mut keys2: Vec<PrivateKey> = rsa_private_keys(&mut BufReader::new(File::open(path)?))
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))
.map(|mut keys| keys.drain(..).map(PrivateKey).collect())?;
let mut keys3: Vec<PrivateKey> = ec_private_keys(&mut BufReader::new(File::open(path)?))
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))
.map(|mut keys| keys.drain(..).map(PrivateKey).collect())?;
fn load_keys(path: &Path) -> io::Result<Vec<PrivateKeyDer<'static>>> {
let mut keys = pkcs8_private_keys(&mut BufReader::new(File::open(path)?))
.into_iter()
.filter_map(|x| x.ok())
.map(Into::into)
.collect::<Vec<_>>();
let mut keys2 = rsa_private_keys(&mut BufReader::new(File::open(path)?))
.into_iter()
.filter_map(|x| x.ok())
.map(Into::into)
.collect::<Vec<_>>();
let mut keys3 = ec_private_keys(&mut BufReader::new(File::open(path)?))
.into_iter()
.filter_map(|x| x.ok())
.map(Into::into)
.collect::<Vec<_>>();
keys.append(&mut keys3);
keys.append(&mut keys2);
Ok(keys)
@@ -48,7 +55,6 @@ impl Handler {
let certs = load_certs(Path::new(&certificate))?;
let mut keys = load_keys(Path::new(&certificate_key))?;
let config = ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(certs, keys.remove(0))
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;

View File

@@ -11,7 +11,7 @@ use tracing::trace;
use {
std::sync::Arc,
tokio_rustls::{
rustls::{Certificate, ClientConfig, OwnedTrustAnchor, RootCertStore, ServerName},
rustls::{pki_types::ServerName, ClientConfig, RootCertStore},
TlsConnector,
},
};
@@ -28,26 +28,63 @@ use crate::{proxy::*, session::Session};
#[cfg(feature = "rustls-tls")]
mod dangerous {
use std::time::SystemTime;
use tokio_rustls::rustls::{
client::{ServerCertVerified, ServerCertVerifier},
Certificate, Error, ServerName,
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
pki_types::{CertificateDer, ServerName, UnixTime},
DigitallySignedStruct, Error, SignatureScheme,
};
#[derive(Debug)]
pub(super) struct NotVerified;
impl ServerCertVerifier for NotVerified {
fn verify_server_cert(
&self,
_end_entity: &Certificate,
_intermediates: &[Certificate],
_end_entity: &CertificateDer,
_intermediates: &[CertificateDer],
_server_name: &ServerName,
_scts: &mut dyn Iterator<Item = &[u8]>,
_ocsp_response: &[u8],
_now: SystemTime,
_now: UnixTime,
) -> core::result::Result<ServerCertVerified, Error> {
Ok(ServerCertVerified::assertion())
}
fn verify_tls12_signature(
&self,
_message: &[u8],
_cert: &CertificateDer<'_>,
_dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> {
Ok(HandshakeSignatureValid::assertion())
}
fn verify_tls13_signature(
&self,
_message: &[u8],
_cert: &CertificateDer<'_>,
_dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> {
Ok(HandshakeSignatureValid::assertion())
}
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
// Non-exhaustive, new variants can be added in the future.
vec![
SignatureScheme::RSA_PKCS1_SHA1,
SignatureScheme::ECDSA_SHA1_Legacy,
SignatureScheme::RSA_PKCS1_SHA256,
SignatureScheme::ECDSA_NISTP256_SHA256,
SignatureScheme::RSA_PKCS1_SHA384,
SignatureScheme::ECDSA_NISTP384_SHA384,
SignatureScheme::RSA_PKCS1_SHA512,
SignatureScheme::ECDSA_NISTP521_SHA512,
SignatureScheme::RSA_PSS_SHA256,
SignatureScheme::RSA_PSS_SHA384,
SignatureScheme::RSA_PSS_SHA512,
SignatureScheme::ED25519,
SignatureScheme::ED448,
]
}
}
}
@@ -68,27 +105,17 @@ impl Handler {
) -> Result<Self> {
#[cfg(feature = "rustls-tls")]
{
let mut root_cert_store = RootCertStore::empty();
let mut roots = RootCertStore::empty();
if let Some(cert) = certificate {
let mut pem = BufReader::new(File::open(cert)?);
let certs = rustls_pemfile::certs(&mut pem)?;
for cert in certs.into_iter().map(Certificate) {
root_cert_store.add(&cert)?;
for cert in rustls_pemfile::certs(&mut pem) {
roots.add(cert?)?;
}
} else {
root_cert_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(
|ta| {
OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
},
));
roots.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
}
let mut config = ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_cert_store)
.with_root_certificates(roots)
.with_no_client_auth();
if insecure {
let mut dangerous_config = config.dangerous();
@@ -160,7 +187,7 @@ impl OutboundStreamHandler for Handler {
)
})?;
let tls_stream = connector
.connect(domain, stream)
.connect(domain.to_owned(), stream)
.map_err(|e| {
io::Error::new(
io::ErrorKind::InvalidInput,

View File

@@ -189,11 +189,12 @@ fn test_quic_trojan() {
let mut path = std::env::current_exe().unwrap();
path.pop();
let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
std::fs::write(&path.join("key.der"), &cert.serialize_private_key_der()).unwrap();
std::fs::write(&path.join("cert.der"), &cert.serialize_der().unwrap()).unwrap();
std::fs::write(&path.join("key.pem"), &cert.serialize_private_key_pem()).unwrap();
std::fs::write(&path.join("cert.pem"), &cert.serialize_pem().unwrap()).unwrap();
let rcgen::CertifiedKey { cert, key_pair } =
rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
std::fs::write(&path.join("key.der"), &key_pair.serialize_der()).unwrap();
std::fs::write(&path.join("cert.der"), &cert.der().to_vec()).unwrap();
std::fs::write(&path.join("key.pem"), &key_pair.serialize_pem()).unwrap();
std::fs::write(&path.join("cert.pem"), &cert.pem()).unwrap();
let configs = vec![config1.to_string(), config2.to_string()];
common::test_configs(configs.clone(), "127.0.0.1", 1086);

View File

@@ -176,11 +176,12 @@ fn test_tls_trojan() {
let mut path = std::env::current_exe().unwrap();
path.pop();
let cert = rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
std::fs::write(&path.join("key.der"), &cert.serialize_private_key_der()).unwrap();
std::fs::write(&path.join("cert.der"), &cert.serialize_der().unwrap()).unwrap();
std::fs::write(&path.join("key.pem"), &cert.serialize_private_key_pem()).unwrap();
std::fs::write(&path.join("cert.pem"), &cert.serialize_pem().unwrap()).unwrap();
let rcgen::CertifiedKey { cert, key_pair } =
rcgen::generate_simple_self_signed(vec!["localhost".into()]).unwrap();
std::fs::write(&path.join("key.der"), &key_pair.serialize_der()).unwrap();
std::fs::write(&path.join("cert.der"), &cert.der().to_vec()).unwrap();
std::fs::write(&path.join("key.pem"), &key_pair.serialize_pem()).unwrap();
std::fs::write(&path.join("cert.pem"), &cert.pem()).unwrap();
let configs = vec![config1.to_string(), config2.to_string()];
common::test_configs(configs, "127.0.0.1", 1086);
let configs = vec![config3.to_string(), config4.to_string()];

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env sh
set -x
set -ex
name=leaf
package=leaf-ffi
@@ -24,7 +24,9 @@ fi
BASE=`dirname "$0"`
HOST_OS=`uname -s | tr "[:upper:]" "[:lower:]"`
HOST_ARCH=`uname -m | tr "[:upper:]" "[:lower:]"`
# HOST_ARCH=`uname -m | tr "[:upper:]" "[:lower:]"`
HOST_ARCH=x86_64
export PATH="$NDK_HOME/toolchains/llvm/prebuilt/$HOST_OS-$HOST_ARCH/bin/":$PATH

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env sh
set -x
set -ex
mode=release
release_flag=--release
@@ -17,17 +17,20 @@ if [ "$1" = "debug" ]; then
release_flag=
fi
export IPHONEOS_DEPLOYMENT_TARGET=10.0
export MACOSX_DEPLOYMENT_TARGET=10.12
# Build for all desired targets
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
rustup target add aarch64-apple-ios
rustup target add x86_64-apple-ios
rustup target add aarch64-apple-ios-sim
cargo build -p $package $release_flag --no-default-features --features "default-openssl outbound-quic" --target x86_64-apple-darwin
cargo build -p $package $release_flag --no-default-features --features "default-openssl outbound-quic" --target aarch64-apple-darwin
cargo build -p $package $release_flag --no-default-features --features "default-openssl outbound-quic" --target aarch64-apple-ios
cargo build -p $package $release_flag --no-default-features --features "default-openssl outbound-quic" --target x86_64-apple-ios
cargo build -p $package $release_flag --no-default-features --features "default-ring outbound-quic" --target aarch64-apple-ios-sim
cargo build -p $package $release_flag --no-default-features --features "default-aws-lc outbound-quic" --target x86_64-apple-darwin
cargo build -p $package $release_flag --no-default-features --features "default-aws-lc outbound-quic" --target aarch64-apple-darwin
cargo build -p $package $release_flag --no-default-features --features "default-aws-lc outbound-quic" --target aarch64-apple-ios
cargo build -p $package $release_flag --no-default-features --features "default-aws-lc outbound-quic" --target x86_64-apple-ios
cargo build -p $package $release_flag --no-default-features --features "default-aws-lc outbound-quic" --target aarch64-apple-ios-sim
cargo install --force cbindgen

View File

@@ -1,9 +0,0 @@
#!/usr/bin/env bash
target=$1
if [[ "$target" == *"mips"* ]]; then
cross build --release --target $target --manifest-path leaf-bin/Cargo.toml --no-default-features --features "default-openssl"
else
cross build --release --target $target --manifest-path leaf-bin/Cargo.toml --no-default-features --features "default-ring"
fi

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env sh
set -x
set -ex
touch leaf/build.rs
PROTO_GEN=1 cargo build -p leaf