aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeerserverDE <himbeerserverde@gmail.com>2023-07-29 16:35:02 +0200
committerHimbeerserverDE <himbeerserverde@gmail.com>2023-07-29 16:35:02 +0200
commit7a9f1dcf7a829c7df48e7853f68e5179dfd556a1 (patch)
treef7b27cdf7a10a44c2226c6060921460699dc8bc3
parent7d5dcfcaa92eefdbc8dea5ed5a2ae5d58de78d92 (diff)
implement chap authentication
ppproperly limitation: only md5 is supported for now, but code was written with extensibility in mind
-rw-r--r--Cargo.lock9
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs77
3 files changed, 84 insertions, 3 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 520ba3a..e83bdd4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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",
diff --git a/Cargo.toml b/Cargo.toml
index b4cd3a5..d5bac76 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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(())
+ }
+ }
+}