all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Jarno Malmari <jarno@malmari.fi>
To: emacs-devel@gnu.org
Cc: larsi@gnus.org
Subject: [PATCH 2/2] Initial implementation for HTTP Digest qop for url
Date: Sun, 13 Nov 2016 00:03:14 +0200	[thread overview]
Message-ID: <1478988194-7761-3-git-send-email-jarno@malmari.fi> (raw)
In-Reply-To: <1478988194-7761-1-git-send-email-jarno@malmari.fi>

Some servers have dropped backward compatibility with HTTP Digest
Authentication without "qop". The Quality Of Protection scheme is
partially implemented:
* only one supported qop, qop=auth
* only one supported algorithm, algorithm=md5
* nonce count remains always as 1, no replays
---
 lisp/url/url-auth.el            | 59 ++++++++++++++++++++++++++++++++++++-----
 test/lisp/url/url-auth-tests.el | 31 +++++++++++++---------
 2 files changed, 72 insertions(+), 18 deletions(-)

diff --git a/lisp/url/url-auth.el b/lisp/url/url-auth.el
index 52b2244..a48e511 100644
--- a/lisp/url/url-auth.el
+++ b/lisp/url/url-auth.el
@@ -131,8 +131,8 @@ url-basic-auth
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Digest authorization code
 ;;; ------------------------
-;;; This implements the DIGEST authorization type.  See the internet draft
-;;; ftp://ds.internic.net/internet-drafts/draft-ietf-http-digest-aa-01.txt
+;;; This implements the DIGEST authorization type.  See RFC 2617
+;;; https://www.ietf.org/rfc/rfc2617.txt
 ;;; for the complete documentation on this type.
 ;;;
 ;;; This is very secure
@@ -167,6 +167,15 @@ url-digest-auth-make-request-digest
 Inputs for this are the hash strings HA1, HA2, and NONCE."
   (url-digest-auth-kd (url-digest-auth-colonjoin nonce ha2) ha1))
 
+(defsubst url-digest-auth-make-request-digest-qop (qop ha1 ha2 nonce nc cnonce)
+  "Construct the request-digest with qop as described in RFC 2617.
+QOP describes the \"quality of protection\" and algorithm to use.
+HA1, HA2, and NONCE, NC, and CNONCE are string values, described
+in RFC 2617. It's worth noting that HA2 already depends on value
+of QOP."
+  (url-digest-auth-kd (url-digest-auth-colonjoin
+                       nonce nc cnonce qop ha2) ha1))
+
 (defsubst url-digest-auth-directory-id (url realm)
   "Make an identifier to use for server keys.
 The identifier is made either from URL's path or REALM."
@@ -177,6 +186,21 @@ url-digest-auth-server-id
 The identifier is made from URL's host and port."
   (format "%s:%d" (url-host url) (url-port url)))
 
+(defun url-digest-auth-make-cnonce ()
+  "Compute a new unique client nonce value."
+  (base64-encode-string
+   (apply 'format "%016x%04x%04x%05x%05x" (random) (current-time)) t))
+
+(defun url-digest-auth-nonce-count (nonce)
+  "The number requests sent to server with the given NONCE.
+This count includes the request we're preparing here.
+
+Currently, this is not implemented and will always return 1.
+
+Value returned is in string format with leading zeroes, such as
+\"00000001\"."
+  (format "%08x" 1))
+
 (defun url-digest-auth-name-value-string (pairs)
   "Concatenate name-value pairs in association list PAIRS.
 
@@ -281,12 +305,20 @@ url-digest-auth-build-response
 and contents of alist ATTRS.
 
 ATTRS is expected to contain at least the server's \"nonce\"
-value.  It also might contain the optional \"opaque\" value."
+value.  It also might contain the optional \"opaque\" value.
+Newer implementations conforming to RFC 2617 should also contain
+qop (Quality Of Protection) and related attributes.
+
+Restrictions on Quality of Protection scheme: The qop value
+\"auth-int\" or algorithm any other than \"MD5\" are not
+implemented."
+
   (when key
     (let ((user (nth 1 key))
           (ha1 (nth 2 key))
           (ha2 (nth 3 key))
           (digest-uri (url-filename url))
+          (qop (cdr-safe (assoc "qop" attrs)))
           (nonce (cdr-safe (assoc "nonce" attrs)))
           (opaque (cdr-safe (assoc "opaque" attrs))))
 
@@ -296,9 +328,24 @@ url-digest-auth-build-response
         (append (list (cons 'username user)
                       (cons 'realm realm)
                       (cons 'nonce nonce)
-                      (cons 'uri digest-uri)
-                      (cons 'response (url-digest-auth-make-request-digest
-                                       ha1 ha2 nonce)))
+                      (cons 'uri digest-uri))
+
+                (cond
+                 ((null qop)
+                  (list (cons 'response (url-digest-auth-make-request-digest
+                                         ha1 ha2 nonce))))
+                 ((string= qop "auth")
+                  (let ((nc (url-digest-auth-nonce-count nonce))
+                        (cnonce (url-digest-auth-make-cnonce)))
+                    (list (cons 'qop qop)
+                          (cons 'nc nc)
+                          (cons 'cnonce cnonce)
+                          (cons 'response
+                                (url-digest-auth-make-request-digest-qop
+                                 qop ha1 ha2 nonce nc cnonce)))))
+                 (t (message "Quality of protection \"%s\" is not implemented." qop)
+                    nil))
+
 
                 (if opaque (list (cons 'opaque opaque)))))))))
 
diff --git a/test/lisp/url/url-auth-tests.el b/test/lisp/url/url-auth-tests.el
index 3d3132b..58f60c4 100644
--- a/test/lisp/url/url-auth-tests.el
+++ b/test/lisp/url/url-auth-tests.el
@@ -104,14 +104,23 @@ url-auth-test-challenges
                      (plist-get row :expected-ha2)))))
 
 (ert-deftest url-auth-test-digest-request-digest ()
-  "Check digest response value when not supporting `qop'."
+  "Check digest response value."
   (dolist (row url-auth-test-challenges)
-    (should (string= (url-digest-auth-make-request-digest
-                      ;; HA1 and HA2 already tested
-                      (plist-get row :expected-ha1)
-                      (plist-get row :expected-ha2)
-                      (plist-get row :nonce))
-                     (plist-get row :expected-response)))))
+    (should (string= (plist-get row :expected-response)
+                     (if (plist-member row :qop)
+                         (url-digest-auth-make-request-digest-qop
+                          (plist-get row :qop)
+                          ;; HA1 and HA2 already tested
+                          (plist-get row :expected-ha1)
+                          (plist-get row :expected-ha2)
+                          (plist-get row :nonce)
+                          (plist-get row :nc)
+                          (plist-get row :cnonce))
+                       (url-digest-auth-make-request-digest
+                        ;; HA1 and HA2 already tested
+                        (plist-get row :expected-ha1)
+                        (plist-get row :expected-ha2)
+                        (plist-get row :nonce)))))))
 
 (ert-deftest url-auth-test-digest-create-key ()
   "Check user credentials in their hashed form."
@@ -259,14 +268,12 @@ url-auth-test-challenges
           (progn
             ;; We don't know these, just check that they exists.
             (should (string-match-p ".*response=\".*?\".*" auth))
-            ;; url-digest-auth doesn't return these AFAICS.
-;;;            (should (string-match-p ".*nc=\".*?\".*" auth))
-;;;            (should (string-match-p ".*cnonce=\".*?\".*" auth))
-            )
+            (should (string-match-p ".*nc=\".*?\".*" auth))
+            (should (string-match-p ".*cnonce=\".*?\".*" auth)))
         (should (string-match ".*response=\"\\(.*?\\)\".*" auth))
         (should (string= (match-string 1 auth)
                          (plist-get challenge :expected-response))))
-      )))
+        )))
 
 (ert-deftest url-auth-test-digest-auth-opaque ()
   "Check that `opaque' value is added to result when presented by
-- 
2.7.0.25.gfc10eb5




  parent reply	other threads:[~2016-11-12 22:03 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-09 12:25 url-digest-auth QOP implementation Jarno Malmari
2015-05-10 17:10 ` Lars Magne Ingebrigtsen
2015-05-11 19:17   ` Patches for qop=auth implementation for url-digest-auth Jarno Malmari
2015-05-11 19:17     ` [PATCH 1/3] Test for url-auth Jarno Malmari
2015-05-11 19:17     ` [PATCH 2/3] Refactor digest authentication in url-auth Jarno Malmari
2015-05-11 19:17     ` [PATCH 3/3] Initial implementation for HTTP Digest qop for url Jarno Malmari
2015-05-18 15:47     ` Patches for qop=auth implementation for url-digest-auth Lars Magne Ingebrigtsen
2015-05-26 17:13       ` Jarno Malmari
2015-08-08  8:14       ` Jarno Malmari
2015-08-30 11:52         ` Lars Magne Ingebrigtsen
2015-08-30 16:17           ` [PATCH 1/3] Test for url-auth Jarno Malmari
2015-08-30 16:17             ` [PATCH 2/3] Refactor digest authentication in url-auth Jarno Malmari
2015-08-30 16:17             ` [PATCH 3/3] Initial implementation for HTTP Digest qop for url Jarno Malmari
2016-02-07  5:35             ` [PATCH 1/3] Test for url-auth Lars Ingebrigtsen
2016-02-07 15:57               ` Eli Zaretskii
2016-02-08  4:57             ` Lars Ingebrigtsen
2016-02-08  5:29               ` Lars Ingebrigtsen
2016-09-08 19:51                 ` Jarno Malmari
2016-09-08 19:51                   ` [PATCH 1/3] Revert parts of url-auth test Jarno Malmari
2016-09-08 19:51                   ` [PATCH 2/3] Refactor digest authentication in url-auth Jarno Malmari
2016-09-08 19:51                   ` [PATCH 3/3] Initial implementation for HTTP Digest qop for url Jarno Malmari
2016-11-12 22:03                   ` [PATCH 1/3] Test for url-auth Jarno Malmari
2016-11-12 22:03                     ` [PATCH 1/2] Refactor digest authentication in url-auth Jarno Malmari
2016-11-12 22:03                     ` Jarno Malmari [this message]
2016-11-13 11:36                     ` [PATCH 1/3] Test for url-auth Jarno Malmari
2016-11-13 11:36                       ` [PATCH 1/2] Refactor digest authentication in url-auth Jarno Malmari
2016-11-13 15:53                         ` Eli Zaretskii
2016-11-13 21:57                           ` Jarno Malmari
2016-11-14  3:42                             ` Eli Zaretskii
2016-11-14  4:34                               ` Yuri Khan
2016-11-14 15:28                                 ` Eli Zaretskii
2017-02-14 21:12                                 ` Jarno Malmari
2017-02-14 21:12                                   ` [PATCH 1/2] " Jarno Malmari
2017-02-14 21:12                                   ` [PATCH 2/2] Initial implementation for HTTP Digest qop for url Jarno Malmari
2017-02-18 11:11                                   ` Refactor digest authentication in url-auth Eli Zaretskii
2017-02-25  8:54                                     ` Eli Zaretskii
2017-03-05 15:54                                       ` Jarno Malmari
2017-03-05 16:06                                         ` Eli Zaretskii
2017-03-11 10:08                                         ` Eli Zaretskii
2017-03-25 16:08                                           ` Eli Zaretskii
2017-03-27 19:47                                           ` Jarno Malmari
2017-03-27 19:47                                             ` [PATCH 1/2] " Jarno Malmari
2017-03-27 19:47                                             ` [PATCH 2/2] Initial implementation for HTTP Digest qop for url Jarno Malmari
2017-04-01  6:24                                             ` Refactor digest authentication in url-auth Eli Zaretskii
2016-11-13 11:36                       ` [PATCH 2/2] Initial implementation for HTTP Digest qop for url Jarno Malmari

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1478988194-7761-3-git-send-email-jarno@malmari.fi \
    --to=jarno@malmari.fi \
    --cc=emacs-devel@gnu.org \
    --cc=larsi@gnus.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.