From c34a8b7116a2a6c94602a258e4ddbffe45492a4e Mon Sep 17 00:00:00 2001 From: Richard Whitehouse Date: Sun, 29 Oct 2017 20:06:30 +0000 Subject: [PATCH] Support Proxy-Authenticate header --- src/codec.rs | 3 ++- src/parser.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/types.rs | 34 +++++++++++++++++++++++++++++----- 3 files changed, 79 insertions(+), 8 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index 31f9a49..4b292a8 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -440,7 +440,8 @@ mod tests { com>\r\nExpires:30\r\nFrom:sip:+12125551212@server.phone2net.com;\ tag=887s\r\nIn-Reply-To:70710@saturn.bell-tel.com,17320@saturn.\ bell-tel.com\r\nMax-Forwards:32\r\nMIME-Version:2.0\r\nMin-Expires:\ - 30\r\nOrganization:Foobar\r\nPriority:normal\r\nVia: localhost\r\n\r\n") + 30\r\nOrganization:Foobar\r\nPriority:normal\r\nProxy-Authenticate:\ + Digest realm=\"atlanta.com\"\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 59aed8e..ac051a7 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -16,7 +16,8 @@ use types::{PathSegment, HostPort, Host, Hostname, UriParameter, UriHeader, UriH Language, AlertParam, Qop, AuthenticationInfo, AuthParam, Algorithm, DigestResponse, Credentials, CallId, Purpose, InfoParam, Info, NameAddr, ContactParam, Target, Contact, DispositionType, Handling, DispositionParam, ContentCoding, Day, Month, Date, - Time, DateTime, ErrorUri, FromParam, From, Priority}; + Time, DateTime, ErrorUri, FromParam, From, Priority, Domain, DigestChallenge, + Challenge}; fn is_mark(c: u8) -> bool { c == b'-' || c == b'_' || c == b'.' || c == b'!' || c == b'~' || c == b'*' || c == b'\'' || @@ -988,6 +989,50 @@ named!(priority_header, preceded!( tag!(b"non-urgent") => { |_| Priority::NonUrgent } | token => { |t| Priority::Other(t) }))); +named!(domain>, delimited!( + tag!(b"domain=\""), + separated_nonempty_list!( + tag!(" "), + alt!( + absolute_uri => { |u| Domain::Uri(u) } | + abs_path => { |p| Domain::Path(p) } + )), + tag!(b"\""))); + +named!(boolean, alt!( + tag!(b"true") => { |_| true } | + tag!(b"false") => { |_| false })); + +named!(stale, preceded!( + tag!(b"stale="), + boolean)); + +named!(qop_options>, delimited!( + tag!(b"qop=\""), + separated_nonempty_list!( + tag!(b","), + qop_value), + tag!(b"\""))); + +named!(digest_challenge>, many1!(alt!( + realm => { |r| DigestChallenge::Realm(r) } | + domain => { |d| DigestChallenge::Domain(d) } | + nonce => { |n| DigestChallenge::Nonce(n) } | + opaque => { |o| DigestChallenge::Opaque(o) } | + stale => { |s| DigestChallenge::Stale(s) } | + qop_options => { |q| DigestChallenge::QopOptions(q) } | + auth_param => { |(k, v)| DigestChallenge::AuthParam(k, v) }))); + +use self::other_response as other_challenge; + +named!(challenge, alt!( + preceded!(tag!(b"Digest "), digest_challenge) => { |d| Challenge::Digest(d) } | + other_challenge => { |(s, p)| Challenge::Other(s, p) })); + +named!(proxy_authenticate_header, preceded!( + tag!(b"Proxy-Authenticate:"), + challenge)); + named!(pub header
, alt!( // RFC 3261 Headers accept_header => { |a| Header::Accept(a) } | @@ -1015,5 +1060,6 @@ named!(pub header
, alt!( mime_version_header => { |(m, v)| Header::MimeVersion(m, v) } | min_expires_header => { |m| Header::MinExpires(m) } | organization_header => { |o| Header::Organization(o) } | - priority_header => { |p| Header::Priority(p) } + priority_header => { |p| Header::Priority(p) } | + proxy_authenticate_header => { |p| Header::ProxyAuthenticate(p) } )); diff --git a/src/types.rs b/src/types.rs index 6a546d2..6a48c4a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -343,11 +343,34 @@ pub type From = (Target, Vec); #[derive(Debug)] pub enum Priority { - Emergency, - Urgent, - Normal, - NonUrgent, - Other(Vec) + Emergency, + Urgent, + Normal, + NonUrgent, + Other(Vec), +} + +#[derive(Debug)] +pub enum Domain { + Uri(AbsoluteUri), + Path(AbsolutePath), +} + +#[derive(Debug)] +pub enum DigestChallenge { + Realm(Vec), + Domain(Vec), + Nonce(Vec), + Opaque(Vec), + Stale(bool), + QopOptions(Vec), + AuthParam(Vec, Vec), +} + +#[derive(Debug)] +pub enum Challenge { + Digest(Vec), + Other(Vec, Vec), } #[derive(Debug)] @@ -378,6 +401,7 @@ pub enum Header { MinExpires(u32), Organization(Vec), Priority(Priority), + ProxyAuthenticate(Challenge), To(Uri), Extension { name: String, value: String }, } -- 2.34.1