Support to generate user-password attribute

This commit is contained in:
moznion
2020-11-25 01:04:05 +09:00
parent 84943f10eb
commit 5d5d1dbf68
4 changed files with 60 additions and 10 deletions

View File

@@ -1,3 +1,4 @@
gen:
cat /dev/null > $(PWD)/src/rfc2865.rs
cargo run --bin code_gen $(PWD)/dicts/dictionary.rfc2865 $(PWD)/src/rfc2865.rs
cargo fmt

View File

@@ -26,9 +26,10 @@ struct RadiusValue {
typ: u16,
}
#[derive(Debug)]
#[derive(Debug, PartialEq)]
enum RadiusAttributeValueType {
STRING,
USER_PASSWORD,
OCTETS,
IPADDR,
INTEGER,
@@ -40,6 +41,7 @@ impl FromStr for RadiusAttributeValueType {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_uppercase().as_str() {
"STRING" => Ok(RadiusAttributeValueType::STRING),
"USER_PASSWORD" => Ok(RadiusAttributeValueType::USER_PASSWORD),
"OCTETS" => Ok(RadiusAttributeValueType::OCTETS),
"IPADDR" => Ok(RadiusAttributeValueType::IPADDR),
"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) {
match attr.value_type {
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::IPADDR => generate_ipaddr_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();
}
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_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 {
ATTRIBUTE_KIND => {
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]) {
Ok(t) => t,
Ok(t) => {
if t == RadiusAttributeValueType::STRING && is_encrypt {
RadiusAttributeValueType::USER_PASSWORD
} else {
t
}
}
Err(_) => {
return Err(
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 {
name: items[1].to_string(),

View File

@@ -35,10 +35,13 @@ impl Packet {
}
pub fn get_secret(&self) -> &Vec<u8> {
// TODO
&self.secret
}
pub fn get_authenticator(&self) -> &Vec<u8> {
&self.get_authenticator()
}
pub fn parse(bs: &[u8], secret: &[u8]) -> Result<Self, String> {
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());

View File

@@ -22,9 +22,11 @@ impl RFC2865 {
}
pub const USER_PASSWORD_TYPE: AVPType = 2;
pub fn add_user_password(packet: &mut Packet, value: &str) {
let attr = Attribute::from_string(value);
pub fn add_user_password(packet: &mut Packet, value: &[u8]) -> Result<(), String> {
let attr =
Attribute::from_user_password(value, packet.get_secret(), packet.get_authenticator())?;
packet.add(Self::USER_PASSWORD_TYPE, &attr);
Ok(())
}
pub fn delete_user_password(packet: &mut Packet) {
packet.delete(Self::USER_PASSWORD_TYPE);