comparison src/org/eclipse/jetty/util/security/Password.java @ 802:3428c60d7cfc

replace jetty jars with source
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 07 Sep 2016 21:15:48 -0600
parents
children 8e9db0bbf4f9
comparison
equal deleted inserted replaced
801:6a21393191c1 802:3428c60d7cfc
1 //
2 // ========================================================================
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
8 //
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
11 //
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
14 //
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
17 //
18
19 package org.eclipse.jetty.util.security;
20
21 import java.io.IOException;
22 import java.util.Arrays;
23
24 import org.eclipse.jetty.util.log.Log;
25 import org.eclipse.jetty.util.log.Logger;
26
27 /* ------------------------------------------------------------ */
28 /**
29 * Password utility class.
30 *
31 * This utility class gets a password or pass phrase either by:
32 *
33 * <PRE>
34 * + Password is set as a system property.
35 * + The password is prompted for and read from standard input
36 * + A program is run to get the password.
37 * </pre>
38 *
39 * Passwords that begin with OBF: are de obfuscated. Passwords can be obfuscated
40 * by run org.eclipse.util.Password as a main class. Obfuscated password are
41 * required if a system needs to recover the full password (eg. so that it may
42 * be passed to another system). They are not secure, but prevent casual
43 * observation.
44 * <p>
45 * Passwords that begin with CRYPT: are oneway encrypted with UnixCrypt. The
46 * real password cannot be retrieved, but comparisons can be made to other
47 * passwords. A Crypt can be generated by running org.eclipse.util.UnixCrypt as
48 * a main class, passing password and then the username. Checksum passwords are
49 * a secure(ish) way to store passwords that only need to be checked rather than
50 * recovered. Note that it is not strong security - specially if simple
51 * passwords are used.
52 *
53 *
54 */
55 public class Password extends Credential
56 {
57 private static final Logger LOG = Log.getLogger(Password.class);
58
59 private static final long serialVersionUID = 5062906681431569445L;
60
61 public static final String __OBFUSCATE = "OBF:";
62
63 private String _pw;
64
65 /* ------------------------------------------------------------ */
66 /**
67 * Constructor.
68 *
69 * @param password The String password.
70 */
71 public Password(String password)
72 {
73 _pw = password;
74
75 // expand password
76 while (_pw != null && _pw.startsWith(__OBFUSCATE))
77 _pw = deobfuscate(_pw);
78 }
79
80 /* ------------------------------------------------------------ */
81 @Override
82 public String toString()
83 {
84 return _pw;
85 }
86
87 /* ------------------------------------------------------------ */
88 public String toStarString()
89 {
90 return "*****************************************************".substring(0, _pw.length());
91 }
92
93 /* ------------------------------------------------------------ */
94 @Override
95 public boolean check(Object credentials)
96 {
97 if (this == credentials) return true;
98
99 if (credentials instanceof Password) return credentials.equals(_pw);
100
101 if (credentials instanceof String) return credentials.equals(_pw);
102
103 if (credentials instanceof char[]) return Arrays.equals(_pw.toCharArray(), (char[]) credentials);
104
105 if (credentials instanceof Credential) return ((Credential) credentials).check(_pw);
106
107 return false;
108 }
109
110 /* ------------------------------------------------------------ */
111 @Override
112 public boolean equals(Object o)
113 {
114 if (this == o)
115 return true;
116
117 if (null == o)
118 return false;
119
120 if (o instanceof Password)
121 {
122 Password p = (Password) o;
123 //noinspection StringEquality
124 return p._pw == _pw || (null != _pw && _pw.equals(p._pw));
125 }
126
127 if (o instanceof String)
128 return o.equals(_pw);
129
130 return false;
131 }
132
133 /* ------------------------------------------------------------ */
134 @Override
135 public int hashCode()
136 {
137 return null == _pw ? super.hashCode() : _pw.hashCode();
138 }
139
140 /* ------------------------------------------------------------ */
141 public static String obfuscate(String s)
142 {
143 StringBuilder buf = new StringBuilder();
144 byte[] b = s.getBytes();
145
146 buf.append(__OBFUSCATE);
147 for (int i = 0; i < b.length; i++)
148 {
149 byte b1 = b[i];
150 byte b2 = b[s.length() - (i + 1)];
151 int i1 = 127 + b1 + b2;
152 int i2 = 127 + b1 - b2;
153 int i0 = i1 * 256 + i2;
154 String x = Integer.toString(i0, 36);
155
156 switch (x.length())
157 {
158 case 1:
159 buf.append('0');
160 buf.append('0');
161 buf.append('0');
162 buf.append(x);
163 break;
164 case 2:
165 buf.append('0');
166 buf.append('0');
167 buf.append(x);
168 break;
169 case 3:
170 buf.append('0');
171 buf.append(x);
172 break;
173 default:
174 buf.append(x);
175 break;
176 }
177 }
178 return buf.toString();
179
180 }
181
182 /* ------------------------------------------------------------ */
183 public static String deobfuscate(String s)
184 {
185 if (s.startsWith(__OBFUSCATE)) s = s.substring(4);
186
187 byte[] b = new byte[s.length() / 2];
188 int l = 0;
189 for (int i = 0; i < s.length(); i += 4)
190 {
191 String x = s.substring(i, i + 4);
192 int i0 = Integer.parseInt(x, 36);
193 int i1 = (i0 / 256);
194 int i2 = (i0 % 256);
195 b[l++] = (byte) ((i1 + i2 - 254) / 2);
196 }
197
198 return new String(b, 0, l);
199 }
200
201 /* ------------------------------------------------------------ */
202 /**
203 * Get a password. A password is obtained by trying
204 * <UL>
205 * <LI>Calling <Code>System.getProperty(realm,dft)</Code>
206 * <LI>Prompting for a password
207 * <LI>Using promptDft if nothing was entered.
208 * </UL>
209 *
210 * @param realm The realm name for the password, used as a SystemProperty
211 * name.
212 * @param dft The default password.
213 * @param promptDft The default to use if prompting for the password.
214 * @return Password
215 */
216 public static Password getPassword(String realm, String dft, String promptDft)
217 {
218 String passwd = System.getProperty(realm, dft);
219 if (passwd == null || passwd.length() == 0)
220 {
221 try
222 {
223 System.out.print(realm + ((promptDft != null && promptDft.length() > 0) ? " [dft]" : "") + " : ");
224 System.out.flush();
225 byte[] buf = new byte[512];
226 int len = System.in.read(buf);
227 if (len > 0) passwd = new String(buf, 0, len).trim();
228 }
229 catch (IOException e)
230 {
231 LOG.warn(Log.EXCEPTION, e);
232 }
233 if (passwd == null || passwd.length() == 0) passwd = promptDft;
234 }
235 return new Password(passwd);
236 }
237
238 /* ------------------------------------------------------------ */
239 /**
240 * @param arg
241 */
242 public static void main(String[] arg)
243 {
244 if (arg.length != 1 && arg.length != 2)
245 {
246 System.err.println("Usage - java org.eclipse.jetty.security.Password [<user>] <password>");
247 System.err.println("If the password is ?, the user will be prompted for the password");
248 System.exit(1);
249 }
250 String p = arg[arg.length == 1 ? 0 : 1];
251 Password pw = new Password(p);
252 System.err.println(pw.toString());
253 System.err.println(obfuscate(pw.toString()));
254 System.err.println(Credential.MD5.digest(p));
255 if (arg.length == 2) System.err.println(Credential.Crypt.crypt(arg[0], pw.toString()));
256 }
257 }