mirror of
https://github.com/cubixle/radius-rs.git
synced 2026-04-30 17:38:42 +01:00
Support to generate user-password attribute
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
gen:
|
gen:
|
||||||
|
cat /dev/null > $(PWD)/src/rfc2865.rs
|
||||||
cargo run --bin code_gen $(PWD)/dicts/dictionary.rfc2865 $(PWD)/src/rfc2865.rs
|
cargo run --bin code_gen $(PWD)/dicts/dictionary.rfc2865 $(PWD)/src/rfc2865.rs
|
||||||
cargo fmt
|
cargo fmt
|
||||||
|
|||||||
+51
-7
@@ -26,9 +26,10 @@ struct RadiusValue {
|
|||||||
typ: u16,
|
typ: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum RadiusAttributeValueType {
|
enum RadiusAttributeValueType {
|
||||||
STRING,
|
STRING,
|
||||||
|
USER_PASSWORD,
|
||||||
OCTETS,
|
OCTETS,
|
||||||
IPADDR,
|
IPADDR,
|
||||||
INTEGER,
|
INTEGER,
|
||||||
@@ -40,6 +41,7 @@ impl FromStr for RadiusAttributeValueType {
|
|||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s.to_uppercase().as_str() {
|
match s.to_uppercase().as_str() {
|
||||||
"STRING" => Ok(RadiusAttributeValueType::STRING),
|
"STRING" => Ok(RadiusAttributeValueType::STRING),
|
||||||
|
"USER_PASSWORD" => Ok(RadiusAttributeValueType::USER_PASSWORD),
|
||||||
"OCTETS" => Ok(RadiusAttributeValueType::OCTETS),
|
"OCTETS" => Ok(RadiusAttributeValueType::OCTETS),
|
||||||
"IPADDR" => Ok(RadiusAttributeValueType::IPADDR),
|
"IPADDR" => Ok(RadiusAttributeValueType::IPADDR),
|
||||||
"INTEGER" => Ok(RadiusAttributeValueType::INTEGER),
|
"INTEGER" => Ok(RadiusAttributeValueType::INTEGER),
|
||||||
@@ -120,6 +122,7 @@ fn generate_attributes_code(w: &mut BufWriter<File>, attrs: &[RadiusAttribute])
|
|||||||
fn generate_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) {
|
fn generate_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) {
|
||||||
match attr.value_type {
|
match attr.value_type {
|
||||||
RadiusAttributeValueType::STRING => generate_string_attribute_code(w, attr),
|
RadiusAttributeValueType::STRING => generate_string_attribute_code(w, attr),
|
||||||
|
RadiusAttributeValueType::USER_PASSWORD => generate_user_password_attribute_code(w, attr),
|
||||||
RadiusAttributeValueType::OCTETS => generate_octets_attribute_code(w, attr),
|
RadiusAttributeValueType::OCTETS => generate_octets_attribute_code(w, attr),
|
||||||
RadiusAttributeValueType::IPADDR => generate_ipaddr_attribute_code(w, attr),
|
RadiusAttributeValueType::IPADDR => generate_ipaddr_attribute_code(w, attr),
|
||||||
RadiusAttributeValueType::INTEGER => generate_integer_attribute_code(w, attr),
|
RadiusAttributeValueType::INTEGER => generate_integer_attribute_code(w, attr),
|
||||||
@@ -159,6 +162,39 @@ pub fn lookup_all_{method_identifier}(packet: &Packet) -> Vec<&Attribute> {{
|
|||||||
w.write_all(code.as_bytes()).unwrap();
|
w.write_all(code.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_user_password_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) {
|
||||||
|
let attr_name = attr.name.clone();
|
||||||
|
|
||||||
|
let type_identifier = format!("{}_TYPE", attr_name.to_screaming_snake_case());
|
||||||
|
let type_calling = format!("Self::{}", type_identifier);
|
||||||
|
|
||||||
|
let code = format!(
|
||||||
|
"pub const {type_identifier}: AVPType = {type_value};
|
||||||
|
pub fn add_{method_identifier}(packet: &mut Packet, value: &[u8]) -> Result<(), String> {{
|
||||||
|
let attr = Attribute::from_user_password(value, packet.get_secret(), packet.get_authenticator())?;
|
||||||
|
packet.add({type_calling}, &attr);
|
||||||
|
Ok(())
|
||||||
|
}}
|
||||||
|
pub fn delete_{method_identifier}(packet: &mut Packet) {{
|
||||||
|
packet.delete({type_calling});
|
||||||
|
}}
|
||||||
|
pub fn lookup_{method_identifier}(packet: &Packet) -> Option<&Attribute> {{
|
||||||
|
packet.lookup({type_calling})
|
||||||
|
}}
|
||||||
|
pub fn lookup_all_{method_identifier}(packet: &Packet) -> Vec<&Attribute> {{
|
||||||
|
packet.lookup_all({type_calling})
|
||||||
|
}}
|
||||||
|
|
||||||
|
",
|
||||||
|
method_identifier = attr_name.to_snake_case(),
|
||||||
|
type_identifier = type_identifier,
|
||||||
|
type_calling = type_calling,
|
||||||
|
type_value = attr.typ,
|
||||||
|
);
|
||||||
|
|
||||||
|
w.write_all(code.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
fn generate_octets_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) {}
|
fn generate_octets_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) {}
|
||||||
|
|
||||||
fn generate_ipaddr_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) {}
|
fn generate_ipaddr_attribute_code(w: &mut BufWriter<File>, attr: &RadiusAttribute) {}
|
||||||
@@ -194,19 +230,27 @@ fn parse_dict_file(dict_file_path: &Path) -> Result<DictParsed, String> {
|
|||||||
match kind {
|
match kind {
|
||||||
ATTRIBUTE_KIND => {
|
ATTRIBUTE_KIND => {
|
||||||
let type_descriptions = items[3].split(' ').collect::<Vec<&str>>();
|
let type_descriptions = items[3].split(' ').collect::<Vec<&str>>();
|
||||||
|
|
||||||
|
let is_encrypt = if type_descriptions.len() >= 2 {
|
||||||
|
type_descriptions[1] == "encrypt=1" // FIXME: ad-hoc!!!
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
let typ = match RadiusAttributeValueType::from_str(type_descriptions[0]) {
|
let typ = match RadiusAttributeValueType::from_str(type_descriptions[0]) {
|
||||||
Ok(t) => t,
|
Ok(t) => {
|
||||||
|
if t == RadiusAttributeValueType::STRING && is_encrypt {
|
||||||
|
RadiusAttributeValueType::USER_PASSWORD
|
||||||
|
} else {
|
||||||
|
t
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return Err(
|
return Err(
|
||||||
format!("invalid type has come => {}", type_descriptions[0]).to_owned()
|
format!("invalid type has come => {}", type_descriptions[0]).to_owned()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let is_encrypt = if type_descriptions.len() >= 2 {
|
|
||||||
type_descriptions[1] == "encrypt=1" // FIXME: ad-hoc!!!
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
radius_attributes.push(RadiusAttribute {
|
radius_attributes.push(RadiusAttribute {
|
||||||
name: items[1].to_string(),
|
name: items[1].to_string(),
|
||||||
|
|||||||
+4
-1
@@ -35,10 +35,13 @@ impl Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_secret(&self) -> &Vec<u8> {
|
pub fn get_secret(&self) -> &Vec<u8> {
|
||||||
// TODO
|
|
||||||
&self.secret
|
&self.secret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_authenticator(&self) -> &Vec<u8> {
|
||||||
|
&self.get_authenticator()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse(bs: &[u8], secret: &[u8]) -> Result<Self, String> {
|
pub fn parse(bs: &[u8], secret: &[u8]) -> Result<Self, String> {
|
||||||
if bs.len() < 20 {
|
if bs.len() < 20 {
|
||||||
return Err("radius packet doesn't have enough length of bytes; that has to be at least 20 bytes".to_owned());
|
return Err("radius packet doesn't have enough length of bytes; that has to be at least 20 bytes".to_owned());
|
||||||
|
|||||||
+4
-2
@@ -22,9 +22,11 @@ impl RFC2865 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const USER_PASSWORD_TYPE: AVPType = 2;
|
pub const USER_PASSWORD_TYPE: AVPType = 2;
|
||||||
pub fn add_user_password(packet: &mut Packet, value: &str) {
|
pub fn add_user_password(packet: &mut Packet, value: &[u8]) -> Result<(), String> {
|
||||||
let attr = Attribute::from_string(value);
|
let attr =
|
||||||
|
Attribute::from_user_password(value, packet.get_secret(), packet.get_authenticator())?;
|
||||||
packet.add(Self::USER_PASSWORD_TYPE, &attr);
|
packet.add(Self::USER_PASSWORD_TYPE, &attr);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn delete_user_password(packet: &mut Packet) {
|
pub fn delete_user_password(packet: &mut Packet) {
|
||||||
packet.delete(Self::USER_PASSWORD_TYPE);
|
packet.delete(Self::USER_PASSWORD_TYPE);
|
||||||
|
|||||||
Reference in New Issue
Block a user