Skip to content

Commit

Permalink
fwd proxy working 🥳
Browse files Browse the repository at this point in the history
  • Loading branch information
jmwample committed Mar 26, 2024
1 parent 91d3eb3 commit 2984bf8
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 130 deletions.
2 changes: 1 addition & 1 deletion crates/obfs4/src/bin/fwd/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ fn init_logging_recvr(unsafe_logging: bool, level_str: &str) -> Result<safelog::
#[tokio::main]
async fn main() -> Result<()> {
let args = Args::parse();
obfs4::dev::print_dev_args();
// obfs4::dev::print_dev_args();

// launch tracing subscriber with filter level
let _guard = init_logging_recvr(args.unsafe_logging, &args.log_level)?;
Expand Down
6 changes: 5 additions & 1 deletion crates/obfs4/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub mod dev {

pub const CLIENT_ARGS: &str =
"cert=AAAAAAAAAAAAAAAAAAAAAAAAAADTSFvsGKxNFPBcGdOCBSgpEtJInG9zCYZezBPVBuBWag;iat-mode=0";
pub const SERVER_ARGS: &str = "drbg-seed=abcdefabcdefabcdefabcdef;iat-mode=0;node-id=00112233445566778899;private-key=0123456789abcdeffedcba9876543210";
pub const SERVER_ARGS: &str = "drbg-seed=0a0b0c0d0e0f0a0b0c0d0e0f0a0b0c0d0e0f0a0b0c0d0e0f;node-id=0000000000000000000000000000000000000000;private-key=3031323334353637383961626364656666656463626139383736353433323130;iat-mode=0";

pub fn print_dev_args() {
let static_secret = StaticSecret::from(*DEV_PRIV_KEY);
Expand All @@ -45,6 +45,8 @@ pub mod dev {
client_args.insert(CERT_ARG.into(), vec![sk.pk.to_string()]);
client_args.insert(IAT_ARG.into(), vec!["0".into()]);
println!("{}", client_args.encode_smethod_args());
println!("{}", hex::encode(sk.pk.pk.as_bytes()));
println!("{}", hex::encode(DEV_PRIV_KEY));
}

#[test]
Expand All @@ -56,5 +58,7 @@ pub mod dev {
let mut builder = ClientBuilder::default();
<ClientBuilder as ptrs::ClientBuilderByTypeInst<TcpStream>>::options(&mut builder, &args)
.unwrap();

// print_dev_args()
}
}
11 changes: 11 additions & 0 deletions crates/obfs4/src/obfs4/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ impl std::str::FromStr for IAT {
}
}

impl std::fmt::Display for IAT {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
IAT::Off => write!(f, "0")?,
IAT::Enabled => write!(f, "1")?,
IAT::Paranoid => write!(f, "2")?,
}
Ok(())
}
}

impl MaybeTimeout {
pub(crate) fn duration(&self) -> Option<Duration> {
match self {
Expand Down
83 changes: 25 additions & 58 deletions crates/obfs4/src/obfs4/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub struct ServerBuilder {
pub statefile_path: Option<String>,
pub(crate) identity_keys: Obfs4NtorSecretKey,
pub(crate) handshake_timeout: MaybeTimeout,
// pub(crate) drbg: Drbg, // TODO: build in DRBG
}

impl Default for ServerBuilder {
Expand All @@ -59,40 +60,40 @@ impl Default for ServerBuilder {
impl ServerBuilder {
/// 64 byte combined representation of an x25519 public key, private key
/// combination.
pub fn node_keys(mut self, keys: [u8; KEY_LENGTH * 2]) -> Self {
pub fn node_keys(&mut self, keys: [u8; KEY_LENGTH * 2]) -> &Self {
let sk: [u8; KEY_LENGTH] = keys[..KEY_LENGTH].try_into().unwrap();
let pk: [u8; KEY_LENGTH] = keys[KEY_LENGTH..].try_into().unwrap();
self.identity_keys.sk = sk.into();
self.identity_keys.pk.pk = (&self.identity_keys.sk).into();
self
}

pub fn statefile_path(mut self, path: &str) -> Self {
pub fn statefile_path(&mut self, path: &str) -> &Self {
self.statefile_path = Some(path.into());
self
}

pub fn node_id(mut self, id: [u8; NODE_ID_LENGTH]) -> Self {
pub fn node_id(&mut self, id: [u8; NODE_ID_LENGTH]) -> &Self {
self.identity_keys.pk.id = id.into();
self
}

pub fn iat_mode(mut self, iat: IAT) -> Self {
pub fn iat_mode(&mut self, iat: IAT) -> &Self {
self.iat_mode = iat;
self
}

pub fn with_handshake_timeout(mut self, d: Duration) -> Self {
pub fn with_handshake_timeout(&mut self, d: Duration) -> &Self {
self.handshake_timeout = MaybeTimeout::Length(d);
self
}

pub fn with_handshake_deadline(mut self, deadline: Instant) -> Self {
pub fn with_handshake_deadline(&mut self, deadline: Instant) -> &Self {
self.handshake_timeout = MaybeTimeout::Fixed(deadline);
self
}

pub fn fail_fast(mut self) -> Self {
pub fn fail_fast(&mut self) -> &Self {
self.handshake_timeout = MaybeTimeout::Unset;
self
}
Expand All @@ -114,20 +115,25 @@ impl ServerBuilder {
Ok(())
}

fn parse_state(statedir: Option<impl AsRef<str>>, args: Args) -> Result<RequiredServerState> {
let mut required_args = args.clone();
pub(crate) fn parse_state(
statedir: Option<impl AsRef<str>>,
args: &Args,
) -> Result<RequiredServerState> {
if statedir.is_none() {
return RequiredServerState::try_from(args);
}

// if the provided arguments do not satisfy all required arguments, we
// attempt to parse the server state from json IFF a statedir path was
// provided. Otherwise this method just fails.
if let Err(e) = Self::validate_args(&args) {
match statedir {
Some(p) => Self::server_state_from_file(p, &mut required_args)?,
None => return Err(e),
let mut required_args = args.clone();
match RequiredServerState::try_from(args) {
Ok(state) => Ok(state),
Err(e) => {
Self::server_state_from_file(statedir.unwrap(), &mut required_args)?;
RequiredServerState::try_from(&required_args)
}
}

RequiredServerState::try_from(&required_args)
}

fn server_state_from_file(statedir: impl AsRef<str>, args: &mut Args) -> Result<()> {
Expand Down Expand Up @@ -182,10 +188,10 @@ impl JsonServerState {
}
}

struct RequiredServerState {
private_key: Obfs4NtorSecretKey,
drbg_seed: drbg::Drbg,
iat_mode: IAT,
pub(crate) struct RequiredServerState {
pub(crate) private_key: Obfs4NtorSecretKey,
pub(crate) drbg_seed: drbg::Drbg,
pub(crate) iat_mode: IAT,
}

impl TryFrom<&Args> for RequiredServerState {
Expand Down Expand Up @@ -370,42 +376,3 @@ mod tests {
Ok(())
}
}

/*
// unused fns for ServerBuilder
/// TODO: Implement server from statefile
pub fn from_statefile(location: &str) -> Result<Self> {
let identity_keys = Obfs4NtorSecretKey {
sk: [0_u8; KEY_LENGTH].into(),
pk: Obfs4NtorPublicKey {
pk: [0_u8; KEY_LENGTH].into(),
id: [0_u8; NODE_ID_LENGTH].into(),
},
};
Ok(Self {
iat_mode: IAT::Off,
identity_keys,
statefile_path: Some(location.into()),
handshake_timeout: MaybeTimeout::Default_,
})
}
/// TODO: parse server params form str vec
pub fn from_params(param_strs: Vec<impl AsRef<[u8]>>) -> Result<Self> {
let identity_keys = Obfs4NtorSecretKey {
sk: [0_u8; KEY_LENGTH].into(),
pk: Obfs4NtorPublicKey {
pk: [0_u8; KEY_LENGTH].into(),
id: [0_u8; NODE_ID_LENGTH].into(),
},
};
Ok(Self {
iat_mode: IAT::Off,
identity_keys,
statefile_path: None,
handshake_timeout: MaybeTimeout::Default_,
})
}
*/
21 changes: 20 additions & 1 deletion crates/obfs4/src/pt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,20 @@ where

/// Pluggable transport attempts to parse and validate options from a string,
/// typically using ['parse_smethod_args'].
fn options(&mut self, _opts: &Args) -> Result<&mut Self, Self::Error> {
fn options(&mut self, opts: &Args) -> Result<&mut Self, Self::Error> {
// TODO: pass on opts

let state = Self::parse_state(None::<&str>, opts)?;
self.identity_keys = state.private_key;
self.iat_mode(state.iat_mode);
// self.drbg = state.drbg_seed; // TODO apply seed from args to server

trace!(
"node_pubkey: {}, node_id: {}, iat: {}",
hex::encode(self.identity_keys.pk.pk.as_bytes()),
hex::encode(self.identity_keys.pk.id.as_bytes()),
self.iat_mode,
);
Ok(self)
}

Expand Down Expand Up @@ -164,6 +177,12 @@ where
self.with_node_pubkey(server_materials.0)
.with_node_id(server_materials.1)
.with_iat_mode(iat_mode);
trace!(
"node_pubkey: {}, node_id: {}, iat: {}",
hex::encode(self.station_pubkey),
hex::encode(self.station_id),
iat_mode
);

Ok(self)
}
Expand Down
Loading

0 comments on commit 2984bf8

Please sign in to comment.