Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / jigsaw / src / org / w3c / jigsaw / acl / DigestQopAuthPrincipal.java
diff --git a/JMCR-Stable/real-world application/jigsaw/src/org/w3c/jigsaw/acl/DigestQopAuthPrincipal.java b/JMCR-Stable/real-world application/jigsaw/src/org/w3c/jigsaw/acl/DigestQopAuthPrincipal.java
new file mode 100644 (file)
index 0000000..e92db90
--- /dev/null
@@ -0,0 +1,173 @@
+// DigestAuthPrincipal.java\r
+// $Id: DigestQopAuthPrincipal.java,v 1.1 2010/06/15 12:22:07 smhuang Exp $\r
+// (c) COPYRIGHT MIT, INRIA and Keio, 1999.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigsaw.acl;\r
+\r
+import java.io.UnsupportedEncodingException;\r
+import java.security.Principal;\r
+import java.security.MessageDigest;\r
+import java.security.NoSuchAlgorithmException;\r
+\r
+import org.w3c.jigsaw.http.Request;\r
+import org.w3c.www.http.HttpCredential;\r
+import org.w3c.util.StringUtils;\r
+\r
+/**\r
+ * @version $Revision: 1.1 $\r
+ * @author  Benoît Mahé (bmahe@w3.org)\r
+ */\r
+public class DigestQopAuthPrincipal extends DigestAuthPrincipal  {\r
+\r
+    String dac_opaque    = null;\r
+    String dac_cnonce    = null;\r
+    String dac_nc        = null;\r
+    String dac_qop       = null;\r
+\r
+    /**\r
+     * Check that the challenge matches with the provided nonce\r
+     * @return true if it matches\r
+     */\r
+    private boolean checkDigest2617(String username, String realm , \r
+                                   String password, String nonce) {\r
+       // check if the user knows the right passwd\r
+       String a1, a2, ha1, ha2;\r
+       // "auth" case\r
+       StringBuffer sb = new StringBuffer(256);\r
+       // a1 = unq(username-value) ":" unq(realm-value) ":" passwd\r
+       sb.append(username).append(':').append(realm);\r
+       sb.append(':').append(password);\r
+       a1 = sb.toString();\r
+       // A2       = Method ":" digest-uri-value\r
+       sb = new StringBuffer(256);\r
+       sb.append(dac_method).append(':').append(dac_uri);\r
+       a2 = sb.toString();\r
+       MessageDigest md = null;\r
+       try {\r
+           md = MessageDigest.getInstance(this.algo);\r
+       } catch (NoSuchAlgorithmException algex) {\r
+           // fatal error, can't authenticate\r
+           return false;\r
+       }\r
+       try {\r
+           md.update(a1.getBytes("ISO-8859-1"));\r
+           ha1 = StringUtils.toHexString(md.digest());\r
+           md.reset();\r
+           md.update(a2.getBytes("ISO-8859-1"));\r
+           ha2 = StringUtils.toHexString(md.digest());\r
+           md.reset();\r
+           String kd, hkd;\r
+           // KD( H(A1), unq(nonce-value) ":" nc-value ":" unq(cnonce-value)\r
+           // ":" unq(qop-value)" ":" H(A2) )\r
+           sb = new StringBuffer(256);\r
+           sb.append(ha1).append(':').append(dac_nonce).append(':');\r
+           sb.append(dac_nc).append(':').append(dac_cnonce).append(':');\r
+           sb.append(dac_qop).append(':').append(ha2);\r
+           kd = sb.toString();\r
+           md.update(kd.getBytes("ISO-8859-1"));\r
+           hkd = StringUtils.toHexString(md.digest());\r
+           return hkd.equals(dac_response);\r
+       } catch (Exception ex) {\r
+           // in case iso-8859-1 is not known...\r
+       }\r
+       return false;\r
+    }\r
+    \r
+\r
+    public boolean equals(Object another) {\r
+       if (no_user)\r
+           return false;\r
+       if (another instanceof AclPrincipal) {\r
+           AclPrincipal aclp = (AclPrincipal) another;\r
+           String username   = aclp.getName();\r
+           String realm      = aclp.getRealm();\r
+           String passwd     = aclp.getPassword();\r
+           \r
+           if (!dac_user.equals(username))\r
+               return false;\r
+           if (!dac_realm.equals(realm))\r
+               return false;\r
+           if (dac_algorithm != null && !dac_algorithm.equals(this.algo))\r
+               return false;\r
+           // are we using the current nonce?\r
+           if (!dac_nonce.equals(this.nonce)) {\r
+               // no, is it the old one?\r
+               if (dac_nonce.equals(this.old_nonce)) {\r
+                   // yes, does it matches?\r
+                   if (checkDigest2617(username, realm, passwd, old_nonce)) {\r
+                       // it doesn't mean that we are validating an old nonce\r
+                       // but it is a trick, allowing two nonces at the same\r
+                       // time to populate "AuthenticationInfo" with the\r
+                       // next nonce.\r
+                       stale = true;\r
+                       return true;\r
+                   }\r
+               } else {\r
+                   // reject but mark as atale if auth is ok with nonce.\r
+                   if (checkDigest2617(username, realm, passwd, dac_nonce)) {\r
+                       System.out.println("** stale!");\r
+                       stale = true;\r
+                   }\r
+               }\r
+               return false;\r
+           }\r
+           return checkDigest2617(username, realm, passwd, nonce);\r
+       } else if (another instanceof DigestQopAuthPrincipal) {\r
+           return false;\r
+       }\r
+       return false;\r
+    }\r
+\r
+    public DigestQopAuthPrincipal(Request request, \r
+                                 String nonce, \r
+                                 String old_nonce,\r
+                                 String algo)\r
+       throws InvalidAuthException\r
+    {\r
+       super(request, algo);\r
+       this.request = request;\r
+       HttpCredential credential = (request.isProxy()\r
+                                    ? request.getProxyAuthorization()\r
+                                    : request.getAuthorization());\r
+       if ((credential == null) ||\r
+           ( ! credential.getScheme().equalsIgnoreCase("Digest"))) {\r
+           no_user = true;\r
+       } else {\r
+           no_user        = false;\r
+           dac_user       = credential.getAuthParameter("username");\r
+           dac_uri        = credential.getAuthParameter("uri");\r
+           dac_response   = credential.getAuthParameter("response");\r
+           dac_realm      = credential.getAuthParameter("realm");\r
+           dac_method     = request.getMethod();\r
+           dac_nonce      = credential.getAuthParameter("nonce");\r
+           dac_opaque     = credential.getAuthParameter("opaque");\r
+           dac_cnonce     = credential.getAuthParameter("cnonce");\r
+           dac_nc         = credential.getAuthParameter("nc");\r
+           dac_qop        = credential.getAuthParameter("qop");\r
+           if (dac_qop == null) {\r
+               dac_qop = "auth";\r
+           } else {\r
+               if (!dac_qop.equals("auth")) {\r
+                   String msg = "qop value not supported";\r
+                   throw new InvalidAuthException(msg);\r
+               }\r
+           }\r
+           this.nonce     = nonce;\r
+           this.old_nonce = old_nonce;\r
+           this.algo      = algo;\r
+           if (dac_user == null || dac_uri == null || dac_response == null ||\r
+               dac_realm == null || dac_cnonce == null) {\r
+               String msg = ("Invalid authentication header");\r
+               throw new InvalidAuthException(msg);\r
+           }\r
+       }\r
+    }\r
+\r
+    public DigestQopAuthPrincipal(Request request)\r
+       throws InvalidAuthException\r
+    {\r
+       super(request);\r
+       throw new InvalidAuthException("Bad call for authentification");\r
+    }\r
+}\r