version 1.7, 2004/12/17 15:12:05
|
version 1.8, 2005/02/18 17:32:40
|
Line 5
|
Line 5
|
|
|
package org.w3c.jigsaw.acl; |
package org.w3c.jigsaw.acl; |
|
|
|
import java.io.UnsupportedEncodingException; |
import java.security.Principal; |
import java.security.Principal; |
import java.security.MessageDigest; |
import java.security.MessageDigest; |
import java.security.NoSuchAlgorithmException; |
import java.security.NoSuchAlgorithmException; |
Line 20 import org.w3c.util.StringUtils;
|
Line 21 import org.w3c.util.StringUtils;
|
*/ |
*/ |
public class DigestAuthPrincipal extends HTTPPrincipal { |
public class DigestAuthPrincipal extends HTTPPrincipal { |
|
|
|
protected |
String dac_user = null; |
String dac_user = null; |
String dac_realm = null; |
String dac_realm = null; |
String dac_nonce = null; |
String dac_nonce = null; |
Line 36 public class DigestAuthPrincipal extends
|
Line 38 public class DigestAuthPrincipal extends
|
public boolean isStale() { |
public boolean isStale() { |
return stale; |
return stale; |
} |
} |
|
|
|
/** |
|
* Check that the challenge matches with the provided nonce |
|
* @return true if it matches |
|
*/ |
|
private boolean checkDigest2069(String username, String realm , |
|
String password, String nonce) { |
|
// check if the user knows the right passwd |
|
String a1, a2, ha1, ha2; |
|
StringBuffer sb = new StringBuffer(256); |
|
// a1 = unq(username-value) ":" unq(realm-value) ":" passwd |
|
sb.append(username).append(':').append(realm); |
|
sb.append(':').append(password); |
|
a1 = sb.toString(); |
|
// A2 = Method ":" digest-uri-value |
|
sb = new StringBuffer(256); |
|
sb.append(dac_method).append(':').append(dac_uri); |
|
a2 = sb.toString(); |
|
MessageDigest md = null; |
|
try { |
|
md = MessageDigest.getInstance(this.algo); |
|
} catch (NoSuchAlgorithmException algex) { |
|
// fatal error, can't authenticate |
|
return false; |
|
} |
|
try { |
|
md.update(a1.getBytes("ISO-8859-1")); |
|
ha1 = StringUtils.toHexString(md.digest()); |
|
md.reset(); |
|
md.update(a2.getBytes("ISO-8859-1")); |
|
ha2 = StringUtils.toHexString(md.digest()); |
|
md.reset(); |
|
String kd, hkd; |
|
// KD( H(A1), unq(nonce-value) ":" H(A2) |
|
sb = new StringBuffer(256); |
|
sb.append(ha1).append(':').append(nonce).append(':').append(ha2); |
|
kd = sb.toString(); |
|
md.update(kd.getBytes("ISO-8859-1")); |
|
hkd = StringUtils.toHexString(md.digest()); |
|
return hkd.equals(dac_response); |
|
} catch (UnsupportedEncodingException ex) { |
|
// in case iso-8859-1 is not known... |
|
} |
|
return false; |
|
} |
|
|
public boolean equals(Object another) { |
public boolean equals(Object another) { |
if (no_user) |
if (no_user) |
return false; |
return false; |
Line 45 public class DigestAuthPrincipal extends
|
Line 92 public class DigestAuthPrincipal extends
|
String username = aclp.getName(); |
String username = aclp.getName(); |
String realm = aclp.getRealm(); |
String realm = aclp.getRealm(); |
String passwd = aclp.getPassword(); |
String passwd = aclp.getPassword(); |
|
|
if (!dac_user.equals(username)) |
if (!dac_user.equals(username)) |
return false; |
return false; |
if (!dac_realm.equals(realm)) |
if (!dac_realm.equals(realm)) |
return false; |
return false; |
if (dac_algorithm != null && !dac_algorithm.equals(this.algo)) |
if (dac_algorithm != null && !dac_algorithm.equals(this.algo)) |
return false; |
return false; |
|
// are we using the current nonce? |
if (!dac_nonce.equals(this.nonce)) { |
if (!dac_nonce.equals(this.nonce)) { |
if (!dac_nonce.equals(this.old_nonce)) { |
// no, is it the old one? |
// check if the user knows the right passwd |
if (dac_nonce.equals(this.old_nonce)) { |
String a1, a2, ha1, ha2; |
// yes, does it matches? |
a1 = username + ":" + realm + ":" + passwd; |
if (checkDigest2069(username, realm, passwd, old_nonce)) { |
a2 = dac_method + ":" + dac_uri; |
// it doesn't mean that we are validating an old nonce |
MessageDigest md = null; |
// but it is a trick, allowing two nonces at the same |
try { |
// time to populate "AuthenticationInfo" with the |
md = MessageDigest.getInstance(this.algo); |
// next nonce. |
} catch (NoSuchAlgorithmException algex) { |
stale = true; |
// fatal error, can't authenticate |
return true; |
return false; |
|
} |
} |
md.update(a1.getBytes()); |
|
ha1 = StringUtils.toHexString(md.digest()); |
|
md.reset(); |
|
md.update(a2.getBytes()); |
|
ha2 = StringUtils.toHexString(md.digest()); |
|
md.reset(); |
|
String kd, hkd; |
|
// KD( H(A1), unq(nonce-value) ":" H(A2) |
|
kd = ha1 + ":" + dac_nonce + ":" + ha2; |
|
md.update(kd.getBytes()); |
|
hkd = StringUtils.toHexString(md.digest()); |
|
stale = hkd.equals(dac_response); |
|
return false; |
|
} else { |
} else { |
stale = true; |
// reject but mark as atale if auth is ok with nonce. |
|
if (checkDigest2069(username, realm, passwd, dac_nonce)) { |
|
stale = true; |
|
} |
} |
} |
} |
|
// basic things have been checked... now try the real thing |
|
String a1, a2, ha1, ha2; |
|
a1 = username + ":" + realm + ":" + passwd; |
|
a2 = dac_method + ":" + dac_uri; |
|
MessageDigest md = null; |
|
try { |
|
md = MessageDigest.getInstance(this.algo); |
|
} catch (NoSuchAlgorithmException algex) { |
|
// fatal error, can't authenticate |
|
return false; |
return false; |
} |
} |
md.update(a1.getBytes()); |
return checkDigest2069(username, realm, passwd, nonce); |
ha1 = StringUtils.toHexString(md.digest()); |
|
md.reset(); |
|
md.update(a2.getBytes()); |
|
ha2 = StringUtils.toHexString(md.digest()); |
|
md.reset(); |
|
String kd, hkd; |
|
if (stale) // KD( H(A1), unq(nonce-value) ":" H(A2) |
|
kd = ha1 + ":" + old_nonce + ":" + ha2; |
|
else |
|
kd = ha1 + ":" + nonce + ":" + ha2; |
|
md.update(kd.getBytes()); |
|
hkd = StringUtils.toHexString(md.digest()); |
|
if (!hkd.equals(dac_response)) |
|
return false; |
|
// yeah!!! |
|
return true; |
|
} else if (another instanceof DigestAuthPrincipal) { |
} else if (another instanceof DigestAuthPrincipal) { |
return false; |
return false; |
} |
} |
Line 170 public class DigestAuthPrincipal extends
|
Line 181 public class DigestAuthPrincipal extends
|
super(request); |
super(request); |
throw new InvalidAuthException("Bad call for authentification"); |
throw new InvalidAuthException("Bad call for authentification"); |
} |
} |
|
|
|
protected DigestAuthPrincipal(Request request, String internal) |
|
throws InvalidAuthException |
|
{ |
|
super(request); |
|
} |
} |
} |