mirror of
https://github.com/cubixle/radius-rs.git
synced 2026-04-30 18:08:46 +01:00
fmt
This commit is contained in:
+48
-26
@@ -2,7 +2,7 @@ use std::convert::TryInto;
|
|||||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc, TimeZone};
|
use chrono::{DateTime, TimeZone, Utc};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Attribute(pub(crate) Vec<u8>);
|
pub struct Attribute(pub(crate) Vec<u8>);
|
||||||
@@ -28,9 +28,16 @@ impl Attribute {
|
|||||||
Attribute(v.octets().to_vec())
|
Attribute(v.octets().to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_user_password(plain_text: &[u8], secret: &[u8], request_authenticator: &[u8]) -> Result<Self, String> {
|
pub fn from_user_password(
|
||||||
|
plain_text: &[u8],
|
||||||
|
secret: &[u8],
|
||||||
|
request_authenticator: &[u8],
|
||||||
|
) -> Result<Self, String> {
|
||||||
if plain_text.len() > 128 {
|
if plain_text.len() > 128 {
|
||||||
return Err("the length of plain_text has to be within 128, but the given value is longer".to_owned());
|
return Err(
|
||||||
|
"the length of plain_text has to be within 128, but the given value is longer"
|
||||||
|
.to_owned(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if secret.is_empty() {
|
if secret.is_empty() {
|
||||||
@@ -38,7 +45,10 @@ impl Attribute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if request_authenticator.len() != 16 {
|
if request_authenticator.len() != 16 {
|
||||||
return Err("request_authenticator has to have 16-bytes payload, but the given value doesn't".to_owned());
|
return Err(
|
||||||
|
"request_authenticator has to have 16-bytes payload, but the given value doesn't"
|
||||||
|
.to_owned(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut enc: Vec<u8> = Vec::new();
|
let mut enc: Vec<u8> = Vec::new();
|
||||||
@@ -60,7 +70,8 @@ impl Attribute {
|
|||||||
enc.extend(digest.to_vec());
|
enc.extend(digest.to_vec());
|
||||||
|
|
||||||
let mut j = 0;
|
let mut j = 0;
|
||||||
for b in &plain_text[i..i + 16] { // TODO this has to be 16 bounds, is this correct?
|
for b in &plain_text[i..i + 16] {
|
||||||
|
// TODO this has to be 16 bounds, is this correct?
|
||||||
enc[i + j] ^= b;
|
enc[i + j] ^= b;
|
||||||
j += 1;
|
j += 1;
|
||||||
}
|
}
|
||||||
@@ -122,7 +133,11 @@ impl Attribute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_user_password(&self, secret: &[u8], request_authenticator: &[u8]) -> Result<Vec<u8>, String> {
|
pub fn to_user_password(
|
||||||
|
&self,
|
||||||
|
secret: &[u8],
|
||||||
|
request_authenticator: &[u8],
|
||||||
|
) -> Result<Vec<u8>, String> {
|
||||||
if self.0.len() < 16 || self.0.len() > 128 {
|
if self.0.len() < 16 || self.0.len() > 128 {
|
||||||
return Err(format!("invalid attribute length {}", self.0.len()));
|
return Err(format!("invalid attribute length {}", self.0.len()));
|
||||||
}
|
}
|
||||||
@@ -132,7 +147,10 @@ impl Attribute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if request_authenticator.len() != 16 {
|
if request_authenticator.len() != 16 {
|
||||||
return Err("request_authenticator has to have 16-bytes payload, but the given value doesn't".to_owned());
|
return Err(
|
||||||
|
"request_authenticator has to have 16-bytes payload, but the given value doesn't"
|
||||||
|
.to_owned(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut dec: Vec<u8> = Vec::new();
|
let mut dec: Vec<u8> = Vec::new();
|
||||||
@@ -158,7 +176,8 @@ impl Attribute {
|
|||||||
dec.extend(digest.to_vec());
|
dec.extend(digest.to_vec());
|
||||||
|
|
||||||
let mut j = 0;
|
let mut j = 0;
|
||||||
for b in &self.0[i..i + 16] { // TODO this has to be 16 bounds, is this correct?
|
for b in &self.0[i..i + 16] {
|
||||||
|
// TODO this has to be 16 bounds, is this correct?
|
||||||
dec[i + j] ^= b;
|
dec[i + j] ^= b;
|
||||||
if dec[i + j] == 0 && maybe_first_zero_byte_idx.is_none() {
|
if dec[i + j] == 0 && maybe_first_zero_byte_idx.is_none() {
|
||||||
maybe_first_zero_byte_idx = Option::Some(i + j)
|
maybe_first_zero_byte_idx = Option::Some(i + j)
|
||||||
@@ -171,7 +190,7 @@ impl Attribute {
|
|||||||
|
|
||||||
match maybe_first_zero_byte_idx {
|
match maybe_first_zero_byte_idx {
|
||||||
None => Ok(dec),
|
None => Ok(dec),
|
||||||
Some(idx) => Ok(dec[..idx].to_vec())
|
Some(idx) => Ok(dec[..idx].to_vec()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +223,10 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn it_should_convert_attribute_to_string() -> Result<(), FromUtf8Error> {
|
fn it_should_convert_attribute_to_string() -> Result<(), FromUtf8Error> {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Attribute(vec![0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64]).to_string()?,
|
Attribute(vec![
|
||||||
|
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64
|
||||||
|
])
|
||||||
|
.to_string()?,
|
||||||
"Hello, World"
|
"Hello, World"
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -214,21 +236,17 @@ mod tests {
|
|||||||
fn it_should_convert_ipv4() -> Result<(), String> {
|
fn it_should_convert_ipv4() -> Result<(), String> {
|
||||||
let given_ipv4 = Ipv4Addr::new(192, 0, 2, 1);
|
let given_ipv4 = Ipv4Addr::new(192, 0, 2, 1);
|
||||||
let ipv4_attr = Attribute::from_ipv4(&given_ipv4);
|
let ipv4_attr = Attribute::from_ipv4(&given_ipv4);
|
||||||
assert_eq!(
|
assert_eq!(ipv4_attr.to_ipv4()?, given_ipv4,);
|
||||||
ipv4_attr.to_ipv4()?,
|
|
||||||
given_ipv4,
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_should_convert_ipv6() -> Result<(), String> {
|
fn it_should_convert_ipv6() -> Result<(), String> {
|
||||||
let given_ipv6 = Ipv6Addr::new(0x2001, 0x0db8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001);
|
let given_ipv6 = Ipv6Addr::new(
|
||||||
let ipv6_attr = Attribute::from_ipv6(&given_ipv6);
|
0x2001, 0x0db8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
|
||||||
assert_eq!(
|
|
||||||
ipv6_attr.to_ipv6()?,
|
|
||||||
given_ipv6,
|
|
||||||
);
|
);
|
||||||
|
let ipv6_attr = Attribute::from_ipv6(&given_ipv6);
|
||||||
|
assert_eq!(ipv6_attr.to_ipv6()?, given_ipv6,);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,14 +255,21 @@ mod tests {
|
|||||||
let plain_text = b"texttexttexttexttexttexttexttext".to_vec();
|
let plain_text = b"texttexttexttexttexttexttexttext".to_vec();
|
||||||
let secret = b"secret".to_vec();
|
let secret = b"secret".to_vec();
|
||||||
let request_authenticator = b"0123456789abcdef".to_vec();
|
let request_authenticator = b"0123456789abcdef".to_vec();
|
||||||
let user_password_attr_result = Attribute::from_user_password(&plain_text, &secret, &request_authenticator);
|
let user_password_attr_result =
|
||||||
|
Attribute::from_user_password(&plain_text, &secret, &request_authenticator);
|
||||||
let user_password_attr = user_password_attr_result.unwrap();
|
let user_password_attr = user_password_attr_result.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
user_password_attr.0,
|
user_password_attr.0,
|
||||||
vec![0xb7, 0xb0, 0xcb, 0x5d, 0x4f, 0x96, 0xd4, 0x75, 0x1c, 0xea, 0x3a, 0xb6, 0xf, 0xc, 0xea, 0xa5, 0xc9, 0x22, 0xac, 0x26, 0x28, 0x23, 0x93, 0xef, 0x19, 0x67, 0xcc, 0xeb, 0x9d, 0x33, 0xd7, 0x46],
|
vec![
|
||||||
|
0xb7, 0xb0, 0xcb, 0x5d, 0x4f, 0x96, 0xd4, 0x75, 0x1c, 0xea, 0x3a, 0xb6, 0xf, 0xc,
|
||||||
|
0xea, 0xa5, 0xc9, 0x22, 0xac, 0x26, 0x28, 0x23, 0x93, 0xef, 0x19, 0x67, 0xcc, 0xeb,
|
||||||
|
0x9d, 0x33, 0xd7, 0x46
|
||||||
|
],
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
user_password_attr.to_user_password(&secret, &request_authenticator).unwrap(),
|
user_password_attr
|
||||||
|
.to_user_password(&secret, &request_authenticator)
|
||||||
|
.unwrap(),
|
||||||
plain_text,
|
plain_text,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -253,10 +278,7 @@ mod tests {
|
|||||||
fn it_should_convert_date() -> Result<(), String> {
|
fn it_should_convert_date() -> Result<(), String> {
|
||||||
let now = Utc::now();
|
let now = Utc::now();
|
||||||
let attr = Attribute::from_date(&now);
|
let attr = Attribute::from_date(&now);
|
||||||
assert_eq!(
|
assert_eq!(attr.to_date()?.timestamp(), now.timestamp(),);
|
||||||
attr.to_date()?.timestamp(),
|
|
||||||
now.timestamp(),
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -44,10 +44,7 @@ impl Attributes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, typ: Type, attribute: Attribute) {
|
pub fn add(&mut self, typ: Type, attribute: Attribute) {
|
||||||
self.0.push(AVP {
|
self.0.push(AVP { typ, attribute })
|
||||||
typ,
|
|
||||||
attribute,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attributes_encoded_len(&self) -> Result<u16, String> {
|
pub fn attributes_encoded_len(&self) -> Result<u16, String> {
|
||||||
|
|||||||
+21
-8
@@ -3,7 +3,10 @@ use std::net::SocketAddr;
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::UdpSocket;
|
||||||
|
|
||||||
use crate::client::ClientError::{FailedConnection, FailedParsingUDPResponse, FailedRadiusPacketEncoding, FailedReceivingResponse, FailedSendingPacket, FailedUdpSocketBinding};
|
use crate::client::ClientError::{
|
||||||
|
FailedConnection, FailedParsingUDPResponse, FailedRadiusPacketEncoding,
|
||||||
|
FailedReceivingResponse, FailedSendingPacket, FailedUdpSocketBinding,
|
||||||
|
};
|
||||||
use crate::packet::Packet;
|
use crate::packet::Packet;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@@ -27,14 +30,19 @@ pub struct Client {}
|
|||||||
impl Client {
|
impl Client {
|
||||||
const MAX_DATAGRAM_SIZE: usize = 65507;
|
const MAX_DATAGRAM_SIZE: usize = 65507;
|
||||||
|
|
||||||
pub async fn send_packet(remote_addr: &SocketAddr, request_packet: &Packet) -> Result<Packet, ClientError> {
|
pub async fn send_packet(
|
||||||
|
remote_addr: &SocketAddr,
|
||||||
|
request_packet: &Packet,
|
||||||
|
) -> Result<Packet, ClientError> {
|
||||||
// TODO retransmission
|
// TODO retransmission
|
||||||
|
|
||||||
let local_addr: SocketAddr = if remote_addr.is_ipv4() {
|
let local_addr: SocketAddr = if remote_addr.is_ipv4() {
|
||||||
"0.0.0.0:0"
|
"0.0.0.0:0"
|
||||||
} else {
|
} else {
|
||||||
"[::]:0"
|
"[::]:0"
|
||||||
}.parse().unwrap();
|
}
|
||||||
|
.parse()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let conn = match UdpSocket::bind(local_addr).await {
|
let conn = match UdpSocket::bind(local_addr).await {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
@@ -42,28 +50,33 @@ impl Client {
|
|||||||
};
|
};
|
||||||
match conn.connect(remote_addr).await {
|
match conn.connect(remote_addr).await {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => return Err(FailedConnection(remote_addr.to_string(), e.to_string()))
|
Err(e) => return Err(FailedConnection(remote_addr.to_string(), e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let request_data = match request_packet.encode() {
|
let request_data = match request_packet.encode() {
|
||||||
Ok(encoded) => encoded,
|
Ok(encoded) => encoded,
|
||||||
Err(e) => return Err(FailedRadiusPacketEncoding(e))
|
Err(e) => return Err(FailedRadiusPacketEncoding(e)),
|
||||||
};
|
};
|
||||||
|
|
||||||
match conn.send(request_data.as_slice()).await {
|
match conn.send(request_data.as_slice()).await {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => return Err(FailedSendingPacket(remote_addr.to_string(), e.to_string()))
|
Err(e) => return Err(FailedSendingPacket(remote_addr.to_string(), e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut buf = vec![0; Self::MAX_DATAGRAM_SIZE];
|
let mut buf = vec![0; Self::MAX_DATAGRAM_SIZE];
|
||||||
let len = match conn.recv(&mut buf).await {
|
let len = match conn.recv(&mut buf).await {
|
||||||
Ok(len) => len,
|
Ok(len) => len,
|
||||||
Err(e) => return Err(FailedReceivingResponse(remote_addr.to_string(), e.to_string()))
|
Err(e) => {
|
||||||
|
return Err(FailedReceivingResponse(
|
||||||
|
remote_addr.to_string(),
|
||||||
|
e.to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match Packet::parse(&buf[..len].to_vec(), request_packet.get_secret()) {
|
match Packet::parse(&buf[..len].to_vec(), request_packet.get_secret()) {
|
||||||
Ok(response_packet) => Ok(response_packet),
|
Ok(response_packet) => Ok(response_packet),
|
||||||
Err(e) => Err(FailedParsingUDPResponse(e))
|
Err(e) => Err(FailedParsingUDPResponse(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ impl Code {
|
|||||||
pub fn from(value: u8) -> Self {
|
pub fn from(value: u8) -> Self {
|
||||||
match Code::try_from(value) {
|
match Code::try_from(value) {
|
||||||
Ok(code) => code,
|
Ok(code) => code,
|
||||||
Err(_) => Code::Invalid
|
Err(_) => Code::Invalid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -1,12 +1,12 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
pub mod code;
|
|
||||||
pub mod attribute;
|
pub mod attribute;
|
||||||
pub mod attributes;
|
pub mod attributes;
|
||||||
pub mod packet;
|
|
||||||
pub mod server;
|
|
||||||
pub mod secret_provider;
|
|
||||||
pub mod request_handler;
|
|
||||||
pub mod request;
|
|
||||||
pub mod client;
|
pub mod client;
|
||||||
|
pub mod code;
|
||||||
|
pub mod packet;
|
||||||
|
pub mod request;
|
||||||
|
pub mod request_handler;
|
||||||
|
pub mod secret_provider;
|
||||||
|
pub mod server;
|
||||||
|
|||||||
+46
-26
@@ -33,7 +33,8 @@ impl Packet {
|
|||||||
self.identifier
|
self.identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_secret(&self) -> &Vec<u8> { // TODO
|
pub fn get_secret(&self) -> &Vec<u8> {
|
||||||
|
// TODO
|
||||||
&self.secret
|
&self.secret
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,14 +83,23 @@ impl Packet {
|
|||||||
|
|
||||||
match self.code {
|
match self.code {
|
||||||
Code::AccessRequest | Code::StatusServer => Ok(bs),
|
Code::AccessRequest | Code::StatusServer => Ok(bs),
|
||||||
Code::AccessAccept | Code::AccessReject | Code::AccountingRequest | Code::AccessChallenge | Code::DisconnectRequest | Code::DisconnectACK | Code::DisconnectNAK | Code::CoARequest | Code::CoAACK | Code::CoANAK => {
|
Code::AccessAccept
|
||||||
|
| Code::AccessReject
|
||||||
|
| Code::AccountingRequest
|
||||||
|
| Code::AccessChallenge
|
||||||
|
| Code::DisconnectRequest
|
||||||
|
| Code::DisconnectACK
|
||||||
|
| Code::DisconnectNAK
|
||||||
|
| Code::CoARequest
|
||||||
|
| Code::CoAACK
|
||||||
|
| Code::CoANAK => {
|
||||||
// TODO length checking
|
// TODO length checking
|
||||||
let mut buf: Vec<u8> = bs[..4].to_vec();
|
let mut buf: Vec<u8> = bs[..4].to_vec();
|
||||||
match self.code {
|
match self.code {
|
||||||
Code::AccountingRequest | Code::DisconnectRequest | Code::CoARequest => {
|
Code::AccountingRequest | Code::DisconnectRequest | Code::CoARequest => {
|
||||||
buf.extend(vec![
|
buf.extend(vec![
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -100,14 +110,14 @@ impl Packet {
|
|||||||
buf.extend(&self.secret);
|
buf.extend(&self.secret);
|
||||||
Ok(md5::compute(buf).to_vec())
|
Ok(md5::compute(buf).to_vec())
|
||||||
}
|
}
|
||||||
_ => Err("unknown packet code".to_owned())
|
_ => Err("unknown packet code".to_owned()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn marshal_binary(&self) -> Result<Vec<u8>, String> {
|
pub fn marshal_binary(&self) -> Result<Vec<u8>, String> {
|
||||||
let attributes_len = match self.attributes.attributes_encoded_len() {
|
let attributes_len = match self.attributes.attributes_encoded_len() {
|
||||||
Ok(attributes_len) => attributes_len,
|
Ok(attributes_len) => attributes_len,
|
||||||
Err(e) => return Err(e)
|
Err(e) => return Err(e),
|
||||||
};
|
};
|
||||||
|
|
||||||
let size = 20 + attributes_len;
|
let size = 20 + attributes_len;
|
||||||
@@ -128,12 +138,17 @@ impl Packet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
md5::compute([
|
md5::compute(
|
||||||
&response[..4],
|
[
|
||||||
&request[4..20],
|
&response[..4],
|
||||||
&response[20..], // TODO length
|
&request[4..20],
|
||||||
&secret,
|
&response[20..], // TODO length
|
||||||
].concat()).to_vec().eq(&response[4..20].to_vec())
|
&secret,
|
||||||
|
]
|
||||||
|
.concat(),
|
||||||
|
)
|
||||||
|
.to_vec()
|
||||||
|
.eq(&response[4..20].to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_authentic_request(request: &[u8], secret: &[u8]) -> bool {
|
pub fn is_authentic_request(request: &[u8], secret: &[u8]) -> bool {
|
||||||
@@ -144,17 +159,22 @@ impl Packet {
|
|||||||
match Code::from(request[0]) {
|
match Code::from(request[0]) {
|
||||||
Code::AccessRequest | Code::StatusServer => true,
|
Code::AccessRequest | Code::StatusServer => true,
|
||||||
Code::AccountingRequest | Code::DisconnectRequest | Code::CoARequest => {
|
Code::AccountingRequest | Code::DisconnectRequest | Code::CoARequest => {
|
||||||
md5::compute([
|
md5::compute(
|
||||||
&request[..4],
|
[
|
||||||
&[
|
&request[..4],
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
&[
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
],
|
0x00, 0x00, 0x00, 0x00,
|
||||||
&request[20..], // TODO length
|
],
|
||||||
&secret,
|
&request[20..], // TODO length
|
||||||
].concat()).to_vec().eq(&request[4..20].to_vec())
|
&secret,
|
||||||
|
]
|
||||||
|
.concat(),
|
||||||
|
)
|
||||||
|
.to_vec()
|
||||||
|
.eq(&request[4..20].to_vec())
|
||||||
}
|
}
|
||||||
_ => false
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,10 +190,10 @@ mod tests {
|
|||||||
|
|
||||||
let secret: Vec<u8> = "xyzzy5461".as_bytes().to_vec();
|
let secret: Vec<u8> = "xyzzy5461".as_bytes().to_vec();
|
||||||
let request: Vec<u8> = vec![
|
let request: Vec<u8> = vec![
|
||||||
0x01, 0x00, 0x00, 0x38, 0x0f, 0x40, 0x3f, 0x94, 0x73, 0x97, 0x80, 0x57, 0xbd, 0x83, 0xd5, 0xcb,
|
0x01, 0x00, 0x00, 0x38, 0x0f, 0x40, 0x3f, 0x94, 0x73, 0x97, 0x80, 0x57, 0xbd, 0x83,
|
||||||
0x98, 0xf4, 0x22, 0x7a, 0x01, 0x06, 0x6e, 0x65, 0x6d, 0x6f, 0x02, 0x12, 0x0d, 0xbe, 0x70, 0x8d,
|
0xd5, 0xcb, 0x98, 0xf4, 0x22, 0x7a, 0x01, 0x06, 0x6e, 0x65, 0x6d, 0x6f, 0x02, 0x12,
|
||||||
0x93, 0xd4, 0x13, 0xce, 0x31, 0x96, 0xe4, 0x3f, 0x78, 0x2a, 0x0a, 0xee, 0x04, 0x06, 0xc0, 0xa8,
|
0x0d, 0xbe, 0x70, 0x8d, 0x93, 0xd4, 0x13, 0xce, 0x31, 0x96, 0xe4, 0x3f, 0x78, 0x2a,
|
||||||
0x01, 0x10, 0x05, 0x06, 0x00, 0x00, 0x00, 0x03,
|
0x0a, 0xee, 0x04, 0x06, 0xc0, 0xa8, 0x01, 0x10, 0x05, 0x06, 0x00, 0x00, 0x00, 0x03,
|
||||||
];
|
];
|
||||||
|
|
||||||
let packet = Packet::parse(&request, &secret)?;
|
let packet = Packet::parse(&request, &secret)?;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use thiserror::Error;
|
|||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum SecretProviderError {
|
pub enum SecretProviderError {
|
||||||
#[error("failed to fetch a secret value => `{0}`")]
|
#[error("failed to fetch a secret value => `{0}`")]
|
||||||
FailedFetching(String)
|
FailedFetching(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SecretProvider: 'static + Sync + Send {
|
pub trait SecretProvider: 'static + Sync + Send {
|
||||||
|
|||||||
+18
-6
@@ -64,7 +64,10 @@ impl Server {
|
|||||||
let local_addr = match conn.local_addr() {
|
let local_addr = match conn.local_addr() {
|
||||||
Ok(addr) => addr,
|
Ok(addr) => addr,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("failed to get a local address from from a connection; {}", e);
|
error!(
|
||||||
|
"failed to get a local address from from a connection; {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -81,7 +84,8 @@ impl Server {
|
|||||||
request_handler,
|
request_handler,
|
||||||
secret_provider,
|
secret_provider,
|
||||||
skip_authenticity_validation,
|
skip_authenticity_validation,
|
||||||
).await;
|
)
|
||||||
|
.await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,7 +103,10 @@ impl Server {
|
|||||||
let secret: Vec<u8> = match secret_provider.fetch_secret(remote_addr) {
|
let secret: Vec<u8> = match secret_provider.fetch_secret(remote_addr) {
|
||||||
Ok(secret) => secret,
|
Ok(secret) => secret,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("failed to fetch secret binary vector from the secret provider; {}", e);
|
error!(
|
||||||
|
"failed to fetch secret binary vector from the secret provider; {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -116,7 +123,10 @@ impl Server {
|
|||||||
let packet = match Packet::parse(request_data, &secret) {
|
let packet = match Packet::parse(request_data, &secret) {
|
||||||
Ok(packet) => packet,
|
Ok(packet) => packet,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("failed to parse given request data to pack into the RADIUS packet; {}", e);
|
error!(
|
||||||
|
"failed to parse given request data to pack into the RADIUS packet; {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
debug!("failed request data => {:?}", request_data);
|
debug!("failed request data => {:?}", request_data);
|
||||||
// TODO error handler?
|
// TODO error handler?
|
||||||
return;
|
return;
|
||||||
@@ -137,7 +147,10 @@ impl Server {
|
|||||||
undergoing_requests.insert(key);
|
undergoing_requests.insert(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
request_handler.handle_radius_request(conn.borrow(), &Request::new(local_addr, remote_addr, packet));
|
request_handler.handle_radius_request(
|
||||||
|
conn.borrow(),
|
||||||
|
&Request::new(local_addr, remote_addr, packet),
|
||||||
|
);
|
||||||
|
|
||||||
let mut undergoing_requests = undergoing_requests_lock.write().unwrap();
|
let mut undergoing_requests = undergoing_requests_lock.write().unwrap();
|
||||||
undergoing_requests.remove(&key_for_remove);
|
undergoing_requests.remove(&key_for_remove);
|
||||||
@@ -149,4 +162,3 @@ struct RequestKey {
|
|||||||
ip: String,
|
ip: String,
|
||||||
identifier: u8,
|
identifier: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user