· 9 years ago · Sep 17, 2016, 04:18 AM
1use sodiumoxide::crypto::box_::{SecretKey, PublicKey};
2use typemap::TypeMap;
3use std::sync::{Arc, RwLock};
4
5use llsd::frames::{Frame, FrameKind};
6use llsd::session::server::Session;
7use llsd::session::Sendable;
8use llsd::sessionstore::SessionStore;
9use llsd::authenticator::Authenticator;
10use errors::{AWResult, AWErrorKind};
11use system::{Handler, ServiceHub};
12
13pub type Response = Vec<u8>;
14
15
16pub struct AngelSystem<S: SessionStore, A: Authenticator, H: Handler> {
17 sessions: S,
18 authenticator: A,
19 public_key: PublicKey,
20 secret_key: SecretKey,
21
22 services: ServiceHub,
23 handler: Arc<H>
24}
25
26impl <S: SessionStore, A: Authenticator, H: Handler> Clone for AngelSystem<S,A,H>{
27 fn clone(&self) -> AngelSystem<S,A,H> {
28 AngelSystem {
29 sessions: self.sessions.clone(),
30 authenticator: self.authenticator.clone(),
31 public_key: self.public_key,
32 secret_key: self.secret_key.clone(),
33 services: self.services.clone(),
34 handler: self.handler.clone()
35 }
36 }
37}
38
39impl <S: SessionStore, A: Authenticator, H: Handler> AngelSystem<S,A,H>{
40 pub fn new(store: S, authenticator: A, pk: PublicKey, sk: SecretKey, handler: H) -> AngelSystem<S,A,H> {
41 AngelSystem {
42 sessions: store,
43 authenticator: authenticator,
44 public_key: pk,
45 secret_key: sk,
46 services: Arc::new(RwLock::new(TypeMap::new())),
47 handler: Arc::new(handler)
48 }
49 }
50
51 pub fn process(&self, req: Frame) -> AWResult<Frame> {
52 match req.kind {
53 FrameKind::Hello => self.process_hello(&req),
54 FrameKind::Initiate => self.process_initiate(&req),
55 FrameKind::Message => self.process_message(&req),
56 _ => unimplemented!()
57 }
58 }
59
60 fn process_hello(&self, frame: &Frame) -> AWResult<Frame> {
61 // Verify it's a new session
62 if let Some(_) = self.sessions.find_by_pk(&frame.id) {
63 fail!(AWErrorKind::IncorrectState);
64 }
65 let session = Session::new(frame.id);
66
67 // If inserting session failed - bail out early.
68 if let None = self.sessions.insert(session) {
69 fail!(AWErrorKind::ServerFault);
70 }
71
72 if let Some(session_lock) = self.sessions.find_by_pk(&frame.id) {
73 let session_guard = session_lock.write();
74 if let Ok(mut session) = session_guard {
75 match session.make_welcome(frame, &self.secret_key) {
76 Ok(frame) => return Ok(frame),
77 Err(e) => fail!(AWErrorKind::HandshakeFailed(Some(e)))
78 }
79 }
80 } else {
81 fail!(AWErrorKind::HandshakeFailed(None))
82 }
83 fail!(AWErrorKind::ServerFault);
84 }
85
86 // TODO: Rewrite this madness
87 fn process_initiate(&self, frame: &Frame) -> AWResult<Frame> {
88 match self.sessions.find_by_pk(&frame.id) {
89 None => fail!(AWErrorKind::IncorrectState),
90 Some(session_lock) => {
91 let session_guard = session_lock.write();
92 if let Ok(mut session) = session_guard {
93 match session.validate_initiate(frame) {
94 None => fail!(AWErrorKind::HandshakeFailed(None)),
95 Some(key) => {
96 if !self.authenticator.is_valid(&key) {
97 fail!(AWErrorKind::HandshakeFailed(None));
98 }
99 match session.make_ready(frame, &key) {
100 Ok(res) => Ok(res),
101 Err(err) => fail!(AWErrorKind::HandshakeFailed(Some(err)))
102 }
103 }
104 }
105 } else { // Failed to aquire write lock for a session.
106 fail!(AWErrorKind::ServerFault);
107 }
108 }
109 }
110 }
111
112 fn process_message(&self, frame: &Frame) -> AWResult<Frame> {
113 let session_lock = match self.sessions.find_by_pk(&frame.id) {
114 None => fail!(AWErrorKind::IncorrectState),
115 Some(session_lock) => session_lock,
116 };
117 let req = {
118 let session = match session_lock.write() {
119 Err(_) => fail!(AWErrorKind::ServerFault),
120 Ok(session) => session,
121 };
122 match session.read_msg(frame) {
123 None => fail!(AWErrorKind::CannotDecrypt),
124 Some(req) => req.to_vec(),
125 }
126 };
127 // this is going to take Arc<RWLock<Session>> as argument.
128 let res = try!(self.handler.handle(self.services.clone(), req.to_vec()));
129 let session = match session_lock.read() {
130 Err(_) => fail!(AWErrorKind::ServerFault),
131 Ok(session) => session,
132 };
133 session.make_message(&res).map_err(|_| ::std::convert::From::from(AWErrorKind::BadFrame))
134 }
135}