From 88ad75398c3ec03665062d8e69556d7e372d5b9b Mon Sep 17 00:00:00 2001 From: Richard Whitehouse Date: Sun, 29 Oct 2017 13:59:31 +0000 Subject: [PATCH] Support Authorization header --- src/codec.rs | 3 ++- src/parser.rs | 72 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/types.rs | 31 ++++++++++++++++++++++ 3 files changed, 103 insertions(+), 3 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index 0c12300..a30485d 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -429,7 +429,8 @@ mod tests { "MESSAGE sip:test.com \ SIP/2.0\r\nAccept:text/plain\r\nAccept-Encoding:*\r\nAccept-Language:\ en-gb\r\nAlert-Info:\r\nAllow:\ - MESSAGE\r\nAuthentication-Info:qop=auth\r\nVia: localhost\r\n\r\n") + MESSAGE\r\nAuthentication-Info:qop=auth\r\nAuthorization:Digest \ + username=\"Alice\"\r\nVia: localhost\r\n\r\n") }); let finished = request.and_then(|(socket, _request)| { diff --git a/src/parser.rs b/src/parser.rs index 4d6330c..4c8c031 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -13,7 +13,7 @@ use types::{PathSegment, HostPort, Host, Hostname, UriParameter, UriHeader, UriH Scheme, Method, Transport, UserParam, Version, RequestLine, StatusLine, TopLine, Header, MediaType, MediaFullType, MediaParameter, MediaRange, GenericParam, AcceptParam, AcceptRange, Coding, Encoding, LanguageRange, Language, AlertParam, Qop, - AuthenticationInfo}; + AuthenticationInfo, AuthParam, Algorithm, DigestResponse, Credentials}; fn is_mark(c: u8) -> bool { c == b'-' || c == b'_' || c == b'.' || c == b'!' || c == b'~' || c == b'*' || c == b'\'' || @@ -634,6 +634,73 @@ named!(authentication_info_header>, preceded!( tag!(b","), ainfo))); +named!(username>, preceded!( + tag!(b"username="), + quoted_string)); + +named!(realm>, preceded!( + tag!(b"realm="), + quoted_string)); + +named!(nonce>, preceded!( + tag!(b"nonce="), + quoted_string)); + +named!(digest_uri>, preceded!( + tag!(b"digest_uri="), + quoted_string)); + +named!(dresponse>, preceded!( + tag!(b"response="), + response_digest)); + +named!(algorithm, alt!( + tag!("MD5") => { |_| Algorithm::MD5 } | + tag!("MD5-sess") => { |_| Algorithm::MD5_sess } | + token => { |t| Algorithm::Token(t) } +)); + +named!(opaque>, preceded!( + tag!(b"opaque="), + quoted_string)); + +named!(auth_param, separated_pair!( + token, + tag!(b"="), + alt!( + token | + quoted_string))); + +named!(digest_response>, many1!(alt!( + username => { |u| DigestResponse::Username(u) } | + realm => { |r| DigestResponse::Realm(r) } | + nonce => { |n| DigestResponse::Nonce(n) } | + digest_uri => { |d| DigestResponse::DigestUri(d) } | + dresponse => { |d| DigestResponse::Response(d) } | + algorithm => { |a| DigestResponse::Algorithm(a) } | + cnonce => { |c| DigestResponse::Cnonce(c) } | + opaque => { |o| DigestResponse::Opaque(o) } | + message_qop => { |m| DigestResponse::MessageQop(m) } | + nonce_count => { |n| DigestResponse::NonceCount(n) } | + auth_param => { |(k, v)| DigestResponse::AuthParam(k, v) }))); + +named!(other_response<(Vec, Vec)>, separated_pair!( + token, + tag!(b" "), + separated_nonempty_list!( + tag!(b","), + auth_param))); + +named!(credentials, alt!( + preceded!( + tag!(b"Digest "), + digest_response) => { |d| Credentials::Digest(d) } | + other_response => { |(s,p)| Credentials::Other(s, p) })); + +named!(authorization_header, preceded!( + tag!(b"Authorization:"), + credentials)); + named!(pub header
, alt!( // RFC 3261 Headers accept_header => { |a| Header::Accept(a) } | @@ -641,5 +708,6 @@ named!(pub header
, alt!( accept_language_header => { |a| Header::AcceptLanguage(a) } | alert_info_header => { |a| Header::AlertInfo(a) } | allow_header => { |a| Header::Allow(a) } | - authentication_info_header => { |a| Header::AuthenticationInfo(a) } + authentication_info_header => { |a| Header::AuthenticationInfo(a) } | + authorization_header => { |a| Header::Authorization(a) } )); diff --git a/src/types.rs b/src/types.rs index 3920bc8..e0e2cf1 100644 --- a/src/types.rs +++ b/src/types.rs @@ -201,6 +201,36 @@ pub enum AuthenticationInfo { NonceCount(Vec), } +pub type AuthParam = (Vec, Vec); + +#[derive(Debug)] +pub enum Algorithm { + MD5, + MD5_sess, + Token(Vec), +} + +#[derive(Debug)] +pub enum DigestResponse { + Username(Vec), + Realm(Vec), + Nonce(Vec), + DigestUri(Vec), + Response(Vec), + Algorithm(Algorithm), + Cnonce(Vec), + Opaque(Vec), + MessageQop(Qop), + NonceCount(Vec), + AuthParam(Vec, Vec), +} + +#[derive(Debug)] +pub enum Credentials { + Digest(Vec), + Other(Vec, Vec), +} + #[derive(Debug)] pub enum Header { Accept(Vec), @@ -209,6 +239,7 @@ pub enum Header { AlertInfo(Vec), Allow(Vec), AuthenticationInfo(Vec), + Authorization(Credentials), From(Uri), To(Uri), Extension { name: String, value: String }, -- 2.34.1