% 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 \file{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 \file{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 \file{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} ::. \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}