% This LaTeX document was generated using the LaTeX backend of PlDoc,
% The SWI-Prolog documentation system



\subsection{library(http/http_digest): HTTP Digest authentication}

\label{sec:httpdigest}

\begin{tags}
    \tag{See also}
\url{https://tools.ietf.org/html/rfc2617}
\end{tags}

This library implements HTTP \textit{Digest Authentication} as per RFC2617.
Unlike \textit{Basic Authentication}, digest authentication is based on
challenge-reponse and therefore does not need to send the password over
the (insecure) connection. In addition, it provides a count mechanism
that ensure that old credentials cannot be reused, which prevents
attackers from using old credentials with a new request. Digest
authentication have the following advantages and disadvantages:

\begin{itemize}
    \item Advantages

\begin{shortlist}
    \item Authentication without exchanging the password
    \item No re-use of authentication data
\end{shortlist}

    \item Disadvantages

\begin{itemize}
    \item An extra round trip is needed for the first authentication
    \item Server-side storage of the password is the MD5 hash of the
user, \textit{realm} and password. As MD5 hashes are quick to
compute, one needs strong passwords. This fixed algorithm
also allows for \textit{rainbow table} attacks, although their
value is limited because you need to precompute the rainbow
table for every server (\textit{realm}) and user.
    \item The connection is sensitive to man-in-the-middle attack,
where the attacker can both change the request and response.
    \item Both client and server need to keep an administration of
issued \textit{nonce} values and associated \textit{nonce count} values.
\end{itemize}
\end{itemize}

And, of course, the connection itself remains insecure. Digest based
authentication is a viable alternative if HTTPS is not a good option and
security of the data itself is not an issue.

This library acts as plugin for \verb$library(http/http_dispatch)$, where the
registered handler (\predref{http_handler}{3}) can be given the option below to
initiate digest authentication.

\begin{shortlist}
    \item \verb$authentication(digest(PasswdFile, Realm))$
\end{shortlist}

Above, \arg{PasswdFile} is a file containing lines of the from below, where
PasswordHash is computed using \predref{http_digest_password_hash}{4}. See also
\verb$library(http/http_authenticate)$, \predref{http_read_passwd_file}{2} and
\predref{http_write_passwd_file}{2}.

\begin{code}
User ":" PasswordHash (":" Extra)*
\end{code}

This library also hooks into \verb$library(http/http_open)$ if the option
\verb$authorization(digest(User, Password))$ is given.\vspace{0.7cm}

\begin{description}
    \dcg{http_digest_challenge}{2}{+Realm, +Options}
Generate the content for a 401 \verb$WWW-Authenticate: Digest$
header field.

    \predicate[det]{http_parse_digest_challenge}{2}{+Challenge, -Fields}
Parse the value of an HTTP \verb$WWW-Authenticate$ header into
a list of Name(Value) terms.

    \predicate{http_digest_response}{5}{+Challenge, +User, +Password, -Reply, +Options}
Formulate a reply to a digest authentication request. \arg{Options}:

\begin{description}
    \termitem{path}{+Path}
The request URI send along with the authentication. Defaults
to \verb$/$
    \termitem{method}{+Method}
The HTTP method. Defaults to \verb$'GET'$
    \termitem{nc}{+Integer}
The nonce-count as an integer. This is formatted as an
8 hex-digit string.
\end{description}

\begin{arguments}
\arg{Challenge} & is a list Name(Value), normally from
\predref{http_parse_digest_challenge}{2}. Must contain
\const{realm} and \const{nonce}. Optionally contains
\const{opaque}. \\
\arg{User} & is the user we want to authenticated \\
\arg{Password} & is the user's password \\
\arg{Options} & provides additional options \\
\end{arguments}

    \predicate[det]{http_digest_password_hash}{4}{+User, +Realm, +Password, -Hash}
Compute the password hash for the HTTP password file. Note that
the HTTP digest mechanism does allow us to use a seeded expensive
arbitrary hash function. Instead, the hash is defined as the MD5
of the following components:

\begin{code}
<user>:<realm>:<password>.
\end{code}

The inexpensive MD5 algorithm makes the hash sensitive to brute
force attacks while the lack of seeding make the hashes sensitive
for \textit{rainbow table} attacks, although the value is somewhat limited
because the \textit{realm} and \textit{user} are part of the hash.

\qpredicate[multifile]{http}{authenticate}{3}{+Digest, +Request, -Fields}Plugin for \verb$library(http_dispatch)$ to perform basic HTTP
authentication. Note that we keep the authentication details
cached to avoid a `nonce-replay' error in the case that the
application tries to verify multiple times.

This predicate throws \verb$http_reply(authorise(digest(Digest)))$

\begin{arguments}
\arg{Digest} & is a term \verb$digest(File, Realm, Options)$ \\
\arg{Request} & is the HTTP request \\
\arg{Fields} & describes the authenticated user with the option
\verb$user(User)$ and with the option \verb$user_details(Fields)$ if
the password file contains additional fields after the
user and password. \\
\end{arguments}

\qpredicate[semidet,multifile]{http}{authenticate_client}{2}{+URL, +Action}This hooks is called by \predref{http_open}{3} with the following \arg{Action}
value:

\begin{description}
    \termitem{send_auth_header}{+AuthData, +Out, +Options}
Called when sending the initial request. \arg{AuthData} contains
the value for the \predref{http_open}{3} option \verb$authorization(AuthData)$
and \arg{Out} is a stream on which to write additional HTTP headers.
    \termitem{auth_reponse}{+Headers, +OptionsIn, -Options}
Called if the server replies with a 401 code, challenging the
client. Our implementation adds a
\verb$request_header(authorization=Digest)$ header to \arg{Options}, causing
\predref{http_open}{3} to retry the request with the additional option.
\end{description}
\end{description}

