KickJava   Java API By Example, From Geeks To Geeks.

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


1 // ========================================================================
2
// $Id: Password.java,v 1.13 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 import java.io.IOException JavaDoc;
18
19 import org.apache.commons.logging.Log;
20 import org.mortbay.log.LogFactory;
21
22 /* ------------------------------------------------------------ */
23 /** Password utility class.
24  *
25  * This utility class gets a password or pass phrase either by:<PRE>
26  * + Password is set as a system property.
27  * + The password is prompted for and read from standard input
28  * + A program is run to get the password.
29  * </pre>
30  * Passwords that begin with OBF: are de obfuscated.
31  * Passwords can be obfuscated by run org.mortbay.util.Password as a
32  * main class. Obfuscated password are required if a system needs
33  * to recover the full password (eg. so that it may be passed to another
34  * system). They are not secure, but prevent casual observation.
35  * <p>
36  * Passwords that begin with CRYPT: are oneway encrypted with
37  * UnixCrypt. The real password cannot be retrieved, but comparisons
38  * can be made to other passwords. A Crypt can be generated by running
39  * org.mortbay.util.UnixCrypt as a main class, passing password and
40  * then the username. Checksum passwords are a secure(ish) way to
41  * store passwords that only need to be checked rather
42  * than recovered. Note that it is not strong security - specially if
43  * simple passwords are used.
44  *
45  * @version $Id: Password.java,v 1.13 2005/08/13 00:01:28 gregwilkins Exp $
46  * @author Greg Wilkins (gregw)
47  */

48 public class Password extends Credential
49 {
50     private static Log log = LogFactory.getLog(Password.class);
51
52     private String JavaDoc _pw;
53     
54     /* ------------------------------------------------------------ */
55     /** Constructor.
56      * @param password The String password.
57      */

58     public Password(String JavaDoc password)
59     {
60         _pw=password;
61         
62         // expand password
63
while (_pw!=null && _pw.startsWith("OBF:"))
64             _pw=deobfuscate(_pw);
65     }
66
67     /* ------------------------------------------------------------ */
68     public String JavaDoc toString()
69     {
70         return _pw;
71     }
72     
73     /* ------------------------------------------------------------ */
74     public String JavaDoc toStarString()
75     {
76         return "*****************************************************"
77             .substring(0,_pw.length());
78     }
79
80     /* ------------------------------------------------------------ */
81     public boolean check(Object JavaDoc credentials)
82     {
83     if (this == credentials)
84         return true;
85     
86         if (credentials instanceof Password)
87             return credentials.equals(_pw);
88         
89         if (credentials instanceof String JavaDoc)
90             return credentials.equals(_pw);
91         
92         if (credentials instanceof Credential)
93             return ((Credential)credentials).check(_pw);
94             
95         return false;
96     }
97
98     /* ------------------------------------------------------------ */
99     public boolean equals(Object JavaDoc o)
100     {
101     if (this == o)
102         return true;
103
104         if (null == o)
105             return false;
106
107         if (o instanceof Password)
108         {
109             Password p=(Password)o;
110             return p._pw == _pw || (null != _pw && _pw.equals(p._pw));
111         }
112         
113         if (o instanceof String JavaDoc)
114             return o.equals(_pw);
115             
116         return false;
117     }
118
119     /* ------------------------------------------------------------ */
120     public int hashCode() {
121         return null == _pw ? super.hashCode() : _pw.hashCode();
122     }
123
124     /* ------------------------------------------------------------ */
125     public static String JavaDoc obfuscate(String JavaDoc s)
126     {
127         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
128         byte[] b = s.getBytes();
129         
130         synchronized(buf)
131         {
132             buf.append("OBF:");
133             for (int i=0;i<b.length;i++)
134             {
135                 byte b1 = b[i];
136                 byte b2 = b[s.length()-(i+1)];
137                 int i1= (int)b1+(int)b2+127;
138                 int i2= (int)b1-(int)b2+127;
139                 int i0=i1*256+i2;
140                 String JavaDoc x=Integer.toString(i0,36);
141
142                 switch(x.length())
143                 {
144                   case 1:buf.append('0');
145                   case 2:buf.append('0');
146                   case 3:buf.append('0');
147                   default:buf.append(x);
148                 }
149             }
150             return buf.toString();
151         }
152     }
153     
154     /* ------------------------------------------------------------ */
155     public static String JavaDoc deobfuscate(String JavaDoc s)
156     {
157         if (s.startsWith("OBF:"))
158             s=s.substring(4);
159         
160         byte[] b=new byte[s.length()/2];
161         int l=0;
162         for (int i=0;i<s.length();i+=4)
163         {
164             String JavaDoc x=s.substring(i,i+4);
165             int i0 = Integer.parseInt(x,36);
166             int i1=(i0/256);
167             int i2=(i0%256);
168             b[l++]=(byte)((i1+i2-254)/2);
169         }
170
171         return new String JavaDoc(b,0,l);
172     }
173
174     /* ------------------------------------------------------------ */
175     /** Get a password.
176      * A password is obtained by trying <UL>
177      * <LI>Calling <Code>System.getProperty(realm,dft)</Code>
178      * <LI>Prompting for a password
179      * <LI>Using promptDft if nothing was entered.
180      * </UL>
181      * @param realm The realm name for the password, used as a SystemProperty name.
182      * @param dft The default password.
183      * @param promptDft The default to use if prompting for the password.
184      * @return Password
185      */

186     public static Password getPassword(String JavaDoc realm,String JavaDoc dft, String JavaDoc promptDft)
187     {
188         String JavaDoc passwd=System.getProperty(realm,dft);
189         if (passwd==null || passwd.length()==0)
190         {
191             try
192             {
193                 System.out.print(realm+
194                                  ((promptDft!=null && promptDft.length()>0)
195                                   ?" [dft]":"")+" : ");
196                 System.out.flush();
197                 byte[] buf = new byte[512];
198                 int len=System.in.read(buf);
199                 if (len>0)
200                     passwd=new String JavaDoc(buf,0,len).trim();
201             }
202             catch(IOException JavaDoc e)
203             {
204                 log.warn(LogSupport.EXCEPTION,e);
205             }
206             if (passwd==null || passwd.length()==0)
207                 passwd=promptDft;
208         }
209         return new Password(passwd);
210     }
211     
212     
213     /* ------------------------------------------------------------ */
214     /**
215      * @param arg
216      */

217     public static void main(String JavaDoc[] arg)
218     {
219         if (arg.length!=1 && arg.length!=2 )
220         {
221             System.err.println("Usage - java org.mortbay.util.Password [<user>] <password>");
222             System.err.println("If the password is ?, the user will be prompted for the password");
223             System.exit(1);
224         }
225         String JavaDoc p=arg[arg.length==1?0:1];
226         Password pw = "?".equals(p)?new Password(p):new Password(p);
227         System.err.println(pw.toString());
228         System.err.println(obfuscate(pw.toString()));
229         System.err.println(Credential.MD5.digest(p));
230         if (arg.length==2)
231             System.err.println(Credential.Crypt.crypt(arg[0],pw.toString()));
232     }
233 }
234
235
236
Popular Tags