radius_rust/server/
server.rs1use crate::protocol::host::Host;
5use crate::protocol::radius_packet::{ RadiusAttribute, RadiusMsgType, RadiusPacket, TypeCode };
6use crate::protocol::dictionary::Dictionary;
7use crate::protocol::error::RadiusError;
8
9use md5::{ Digest, Md5 };
10
11
12#[derive(Debug)]
13pub struct Server {
15 host: Host,
16 allowed_hosts: Vec<String>,
17 server: String,
18 secret: String,
19 retries: u16,
20 timeout: u16,
21}
22
23impl Server {
24 pub fn with_dictionary(dictionary: Dictionary) -> Server {
29 let host = Host::with_dictionary(dictionary);
30
31 Server {
32 host,
33 allowed_hosts: Vec::new(),
34 server: String::from(""),
35 secret: String::from(""),
36 retries: 1,
37 timeout: 2,
38 }
39 }
40
41 pub fn set_server(mut self, server: String) -> Server {
45 self.server = server;
46 self
47 }
48
49 pub fn set_secret(mut self, secret: String) -> Server {
53 self.secret = secret;
54 self
55 }
56
57 pub fn set_allowed_hosts(mut self, allowed_hosts: Vec<String>) -> Server {
61 self.allowed_hosts = allowed_hosts;
62 self
63 }
64
65 pub fn set_port(mut self, msg_type: RadiusMsgType, port: u16) -> Server {
69 self.host.set_port(msg_type, port);
70 self
71 }
72
73 pub fn set_retries(mut self, retries: u16) -> Server {
77 self.retries = retries;
78 self
79 }
80
81 pub fn set_timeout(mut self, timeout: u16) -> Server {
85 self.timeout = timeout;
86 self
87 }
88 pub fn port(&self, code: &TypeCode) -> Option<u16> {
92 self.host.port(code)
93 }
94
95 pub fn server(&self) -> &str {
97 &self.server
98 }
99
100 pub fn retries(&self) -> u16 {
102 self.retries
103 }
104
105 pub fn timeout(&self) -> u16 {
107 self.timeout
108 }
109
110 pub fn allowed_hosts(&self) -> &[String] {
112 &self.allowed_hosts
113 }
114
115 pub fn create_attribute_by_name(&self, attribute_name: &str, value: Vec<u8>) -> Result<RadiusAttribute, RadiusError> {
119 self.host.create_attribute_by_name(attribute_name, value)
120 }
121
122 pub fn create_attribute_by_id(&self, attribute_id: u8, value: Vec<u8>) -> Result<RadiusAttribute, RadiusError> {
126 self.host.create_attribute_by_id(attribute_id, value)
127 }
128
129 pub fn create_reply_packet(&self, reply_code: TypeCode, attributes: Vec<RadiusAttribute>, request: &mut [u8]) -> RadiusPacket {
133 let mut reply_packet = RadiusPacket::initialise_packet(reply_code);
134 reply_packet.set_attributes(attributes);
135
136 reply_packet.override_id(request[1]);
138
139 let authenticator = self.create_reply_authenticator(&reply_packet.to_bytes(), &request[4..20]);
140 reply_packet.override_authenticator(authenticator);
141
142 reply_packet
143 }
144
145 fn create_reply_authenticator(&self, raw_reply_packet: &[u8], request_authenticator: &[u8]) -> Vec<u8> {
146 let mut md5_hasher = Md5::new();
148
149 md5_hasher.update(&raw_reply_packet[0..4]); md5_hasher.update(&request_authenticator); md5_hasher.update(&raw_reply_packet[20..]); md5_hasher.update(&self.secret.as_bytes()); md5_hasher.finalize().to_vec()
156 }
157
158 pub fn verify_request(&self, request: &[u8]) -> Result<(), RadiusError> {
163 match RadiusPacket::initialise_packet_from_bytes(&self.host.dictionary(), request) {
164 Err(err) => Err(err),
165 _ => Ok(())
166 }
167 }
168
169 pub fn verify_request_attributes(&self, request: &[u8]) -> Result<(), RadiusError> {
174 self.host.verify_packet_attributes(&request)
175 }
176
177 pub fn initialise_packet_from_bytes(&self, request: &[u8]) -> Result<RadiusPacket, RadiusError> {
182 self.host.initialise_packet_from_bytes(request)
183 }
184
185 pub fn host_allowed(&self, remote_host: &std::net::SocketAddr) -> bool {
188 let remote_host_name = remote_host.to_string();
189 let remote_host_name: Vec<&str> = remote_host_name.split(':').collect();
190
191 self.allowed_hosts.iter().any(|host| host==remote_host_name[0])
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use super::*;
198
199 #[test]
200 fn test_add_allowed_hosts_and_add_request_handler() {
201 let dictionary = Dictionary::from_file("./dict_examples/integration_dict").unwrap();
202 let server = Server::with_dictionary(dictionary)
203 .set_server(String::from("0.0.0.0"))
204 .set_secret(String::from("secret"))
205 .set_allowed_hosts(vec![String::from("127.0.0.1")]);
206
207 assert_eq!(server.allowed_hosts().len(), 1);
208 }
209}