KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > util > Credential


1 // ========================================================================
2
// $Id: Credential.java,v 1.7 2005/08/13 00:01:28 gregwilkins Exp $
3
// Copyright 1998-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.util;
17
18 import java.security.MessageDigest JavaDoc;
19
20 import org.apache.commons.logging.Log;
21 import org.mortbay.log.LogFactory;
22
23
24 /* ------------------------------------------------------------ */
25 /** Credentials.
26  * The Credential class represents an abstract mechanism for checking
27  * authentication credentials. A credential instance either represents a
28  * secret, or some data that could only be derived from knowing the secret.
29  * <p>
30  * Often a Credential is related to a Password via a one way algorithm, so
31  * while a Password itself is a Credential, a UnixCrypt or MD5 digest of a
32  * a password is only a credential that can be checked against the password.
33  * <p>
34  * This class includes an implementation for unix Crypt an MD5 digest.
35  * @see Password
36  * @version $Id: Credential.java,v 1.7 2005/08/13 00:01:28 gregwilkins Exp $
37  * @author Greg Wilkins (gregw)
38  */

39 public abstract class Credential
40 {
41     static Log log = LogFactory.getLog(Credential.class);
42
43     /* ------------------------------------------------------------ */
44     /** Check a credential
45      * @param credentials The credential to check against. This may either be
46      * another Credential object, a Password object or a String which is
47      * interpreted by this credential.
48      * @return True if the credentials indicated that the shared secret is
49      * known to both this Credential and the passed credential.
50      */

51     public abstract boolean check(Object JavaDoc credentials);
52
53     /* ------------------------------------------------------------ */
54     /** Get a credential from a String.
55      * If the credential String starts with a known Credential type (eg
56      * "CRYPT:" or "MD5:" ) then a Credential of that type is returned. Else the
57      * credential is assumed to be a Password.
58      * @param credential String representation of the credential
59      * @return A Credential or Password instance.
60      */

61     public static Credential getCredential(String JavaDoc credential)
62     {
63         if (credential.startsWith(Crypt.__TYPE))
64             return new Crypt(credential);
65         if (credential.startsWith(MD5.__TYPE))
66             return new MD5(credential);
67         
68         return new Password(credential);
69     }
70
71
72     /* ------------------------------------------------------------ */
73     /** Unix Crypt Credentials
74      */

75     public static class Crypt extends Credential
76     {
77         public static final String JavaDoc __TYPE="CRYPT:";
78         
79         private String JavaDoc _cooked;
80         Crypt(String JavaDoc cooked)
81         {
82             _cooked=cooked.startsWith(Crypt.__TYPE)
83                 ?cooked.substring(__TYPE.length())
84                 :cooked;
85         }
86         
87         public boolean check(Object JavaDoc credentials)
88         {
89             if (!(credentials instanceof String JavaDoc) &&
90                 !(credentials instanceof Password))
91                 log.warn("Can't check "+credentials.getClass()+" against CRYPT");
92             
93             String JavaDoc passwd = credentials.toString();
94             return _cooked.equals(UnixCrypt.crypt(passwd,_cooked));
95         }
96
97         public static String JavaDoc crypt(String JavaDoc user,String JavaDoc pw)
98         {
99             return "CRYPT:"+UnixCrypt.crypt(pw,user);
100         }
101     }
102     
103     /* ------------------------------------------------------------ */
104     /** MD5 Credentials
105      */

106     public static class MD5 extends Credential
107     {
108         public static final String JavaDoc __TYPE="MD5:";
109         private static MessageDigest JavaDoc __md;
110         
111         private byte[] _digest;
112         
113         /* ------------------------------------------------------------ */
114         MD5(String JavaDoc digest)
115         {
116             digest=digest.startsWith(__TYPE)
117                 ?digest.substring(__TYPE.length())
118                 :digest;
119             _digest=TypeUtil.parseBytes(digest,16);
120         }
121         
122         /* ------------------------------------------------------------ */
123         public byte[] getDigest()
124         {
125             return _digest;
126         }
127         
128         /* ------------------------------------------------------------ */
129         public boolean check(Object JavaDoc credentials)
130         {
131             try
132             {
133                 byte[] digest=null;
134                 
135                 if (credentials instanceof Password ||
136                     credentials instanceof String JavaDoc)
137                 {
138                     synchronized(__TYPE)
139                     {
140                         if (__md==null)
141                             __md = MessageDigest.getInstance("MD5");
142                         __md.reset();
143                         __md.update(credentials.toString().getBytes(StringUtil.__ISO_8859_1));
144                         digest=__md.digest();
145                     }
146                     if (digest==null || digest.length!=_digest.length)
147                         return false;
148                     for (int i=0;i<digest.length;i++)
149                         if (digest[i]!=_digest[i])
150                             return false;
151                     return true;
152                 }
153                 else if (credentials instanceof MD5)
154                 {
155                     MD5 md5 = (MD5)credentials;
156                     if (_digest.length!=md5._digest.length)
157                         return false;
158                     for (int i=0;i<_digest.length;i++)
159                         if (_digest[i]!=md5._digest[i])
160                             return false;
161                     return true;
162                 }
163                 else if(credentials instanceof Credential)
164                 {
165                     // Allow credential to attempt check - i.e. this'll work
166
// for DigestAuthenticator$Digest credentials
167
return ((Credential)credentials).check(this);
168                 }
169                 else
170                 {
171                     log.warn("Can't check "+credentials.getClass()+" against MD5");
172                     return false;
173                 }
174             }
175             catch (Exception JavaDoc e)
176             {
177                 log.warn(LogSupport.EXCEPTION,e);
178                 return false;
179             }
180         }
181
182         /* ------------------------------------------------------------ */
183         public static String JavaDoc digest(String JavaDoc password)
184         {
185             try
186             {
187                 byte[] digest;
188                 synchronized(__TYPE)
189                 {
190                     if (__md==null)
191                     {
192                         try{__md = MessageDigest.getInstance("MD5");}
193                         catch (Exception JavaDoc e ) {log.warn(LogSupport.EXCEPTION,e);return null;}
194                     }
195                     
196                     __md.reset();
197                     __md.update(password.getBytes(StringUtil.__ISO_8859_1));
198                     digest=__md.digest();
199                 }
200                 
201                 return __TYPE+TypeUtil.toString(digest,16);
202             }
203             catch (Exception JavaDoc e)
204             {
205                 log.warn(LogSupport.EXCEPTION,e);
206                 return null;
207             }
208         }
209     }
210 }
211
Popular Tags