diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-07-29 16:35:02 +0200 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-07-29 16:35:02 +0200 |
commit | 7a9f1dcf7a829c7df48e7853f68e5179dfd556a1 (patch) | |
tree | f7b27cdf7a10a44c2226c6060921460699dc8bc3 | |
parent | 7d5dcfcaa92eefdbc8dea5ed5a2ae5d58de78d92 (diff) |
implement chap authentication
ppproperly limitation: only md5 is supported for now, but code was written with extensibility in mind
-rw-r--r-- | Cargo.lock | 9 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 77 |
3 files changed, 84 insertions, 3 deletions
@@ -430,6 +430,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -619,7 +625,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "ppproperly" version = "0.1.0" -source = "git+https://github.com/rsdsl/ppproperly.git#63edb1e3c35a6001c4dc0dd67806c920a5676f5e" +source = "git+https://github.com/rsdsl/ppproperly.git#d41dcb2599f5160b5158a9e9f0bcd786b2236784" dependencies = [ "bitfield", "ppproperly_macros", @@ -767,6 +773,7 @@ name = "rsdsl_pppoe2" version = "0.1.0" dependencies = [ "libc", + "md5", "ppproperly", "rand", "rsdsl_netlinkd", @@ -7,6 +7,7 @@ edition = "2021" [dependencies] libc = "0.2.147" +md5 = "0.7.0" ppproperly = { git = "https://github.com/rsdsl/ppproperly.git", version = "0.1.0" } rand = "0.8.5" rsdsl_netlinkd = { git = "https://github.com/rsdsl/netlinkd.git", version = "0.3.2" } diff --git a/src/main.rs b/src/main.rs index d896873..ac71a9c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,8 @@ use std::thread; use std::time::Duration; use ppproperly::{ - AuthProto, Deserialize, LcpData, LcpOpt, LcpPkt, MacAddr, PapData, PapPkt, PppData, PppPkt, - PppoeData, PppoePkt, PppoeVal, Serialize, + AuthProto, ChapAlgorithm, ChapData, ChapPkt, Deserialize, LcpData, LcpOpt, LcpPkt, MacAddr, + PapData, PapPkt, PppData, PppPkt, PppoeData, PppoePkt, PppoeVal, Serialize, }; use rsdsl_netlinkd::link; use rsdsl_pppoe2::{Ppp, Pppoe, Result}; @@ -441,6 +441,7 @@ fn recv_session(ctl: File, state: Arc<Mutex<Ppp>>) -> Result<()> { match ppp.data { PppData::Lcp(lcp) => handle_lcp(lcp, &mut ctl_w, state.clone(), &mut magic)?, PppData::Pap(pap) => handle_pap(pap, state.clone())?, + PppData::Chap(chap) => handle_chap(chap, &mut ctl_w, state.clone())?, _ => println!(" <- unhandled ppp {:?}", ppp), } } @@ -774,3 +775,75 @@ fn handle_pap(pap: PapPkt, state: Arc<Mutex<Ppp>>) -> Result<()> { } } } + +fn handle_chap(chap: ChapPkt, ctl_w: &mut BufWriter<File>, state: Arc<Mutex<Ppp>>) -> Result<()> { + let algorithm = match *state.lock().expect("ppp state mutex is poisoned") { + Ppp::Auth(Some(AuthProto::Chap(algo)), ..) => algo, + _ => { + println!(" <- unexpected chap"); + return Ok(()); + } + }; + + match chap.data { + ChapData::Challenge(chap_challenge) => { + let mut hash_input = Vec::new(); + + hash_input.push(chap.identifier); + hash_input.extend_from_slice(PASSWORD.as_bytes()); + hash_input.extend_from_slice(&chap_challenge.value); + + let challenge_hash = match algorithm { + ChapAlgorithm::Md5 => *md5::compute(hash_input), + }; + + PppPkt::new_chap(ChapPkt::new_response( + chap.identifier, + challenge_hash.to_vec(), + USERNAME.into(), + )) + .serialize(ctl_w)?; + ctl_w.flush()?; + + println!( + " <- chap challenge {}, name: {}, value: {:?}", + chap.identifier, chap_challenge.name, chap_challenge.value + ); + println!( + " -> chap response {}, name: {}, value: {:?}", + chap.identifier, USERNAME, challenge_hash + ); + + Ok(()) + } + ChapData::Response(chap_response) => { + // We never ask the peer to authenticate itself + // so a Response will always be unexpected. + + println!( + " <- unexpected chap response {}, name: {}, value: {:?}", + chap.identifier, chap_response.name, chap_response.value + ); + Ok(()) + } + ChapData::Success(chap_success) => { + *state.lock().expect("ppp state mutex is poisoned") = Ppp::Active; + + println!( + " <- chap success {}, message: {}", + chap.identifier, chap_success.message + ); + Ok(()) + } + ChapData::Failure(chap_failure) => { + // The peer should terminate the session + // which is already handled by LCP. + + println!( + " <- chap failure {}, reason: {}", + chap.identifier, chap_failure.message + ); + Ok(()) + } + } +} |