diff options
author | metamuffin <metamuffin@disroot.org> | 2024-07-06 15:43:45 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-07-06 15:43:45 +0200 |
commit | 7177367ae41a5e2d6ed401f60ee1455812dd8ffb (patch) | |
tree | 75c89835d03e1a1ccd4e8c930c95310f757b2b3a /src/transaction | |
parent | 5dd0fafce20ed37fdc97dc96539391ebdebffaff (diff) | |
download | sip-rs-7177367ae41a5e2d6ed401f60ee1455812dd8ffb.tar sip-rs-7177367ae41a5e2d6ed401f60ee1455812dd8ffb.tar.bz2 sip-rs-7177367ae41a5e2d6ed401f60ee1455812dd8ffb.tar.zst |
phone is ringing
Diffstat (limited to 'src/transaction')
-rw-r--r-- | src/transaction/auth.rs | 51 | ||||
-rw-r--r-- | src/transaction/mod.rs | 23 |
2 files changed, 73 insertions, 1 deletions
diff --git a/src/transaction/auth.rs b/src/transaction/auth.rs new file mode 100644 index 0000000..f64bb4b --- /dev/null +++ b/src/transaction/auth.rs @@ -0,0 +1,51 @@ +use crate::encoding::{ + headers::{Authorization, WWWAuthenticate}, + method::Method, + request::Request, + response::Response, + uri::Uri, +}; +use anyhow::Result; + +impl Authorization { + pub fn construct( + request: &Request, + failed_response: &Response, + username: &str, + password: &str, + ) -> Result<Authorization> { + let challenge = failed_response.headers.get::<WWWAuthenticate>().unwrap()?; + + Ok(Authorization { + response: response_digest( + username.to_string(), + challenge.realm.clone(), + password.to_string(), + request.method, + challenge.nonce.clone(), + request.uri.clone(), + ), + nonce: challenge.nonce, + realm: challenge.realm, + uri: request.uri.content.clone(), + username: username.to_string(), + }) + } +} + +fn response_digest( + username: String, + realm: String, + password: String, + method: Method, + nonce: String, + uri: Uri, +) -> String { + let h = |s: String| hex::encode(md5::compute(s.as_bytes()).0); + let kd = |secret, data| h(format!("{secret}:{data}")); + + let a1 = format!("{username}:{realm}:{password}"); + let a2 = format!("{method}:{uri}"); + let response_digest = kd(h(a1), format!("{nonce}:{}", h(a2))); + return response_digest; +} diff --git a/src/transaction/mod.rs b/src/transaction/mod.rs index 3be9544..601b134 100644 --- a/src/transaction/mod.rs +++ b/src/transaction/mod.rs @@ -1,5 +1,12 @@ +pub mod auth; + use crate::{ - encoding::{headers::CSeq, request::Request, response::Response, Message}, + encoding::{ + headers::{CSeq, CallID}, + request::Request, + response::Response, + Message, + }, transport::Transport, }; use anyhow::{anyhow, Result}; @@ -48,6 +55,20 @@ impl<T: Transport> TransactionUser<T> { } } } + pub async fn respond(&self, req: &Request, mut resp: Response) -> Result<()> { + resp.headers.insert( + req.headers + .get::<CSeq>() + .ok_or(anyhow!("cseq is mandatory"))??, + ); + resp.headers.insert( + req.headers + .get::<CallID>() + .ok_or(anyhow!("call-id is mandatory"))??, + ); + self.transport.send(Message::Response(resp)).await?; + Ok(()) + } pub async fn transact(&self, mut request: Request) -> Result<mpsc::Receiver<Response>> { let seq = self.sequence.fetch_add(1, Ordering::Relaxed); |