1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.efaps.admin.datamodel.attributevalue;
22
23 import java.io.IOException;
24 import java.io.StringReader;
25 import java.io.StringWriter;
26 import java.util.Properties;
27
28 import org.efaps.admin.EFapsSystemConfiguration;
29 import org.efaps.admin.KernelSettings;
30 import org.efaps.admin.common.SystemConfiguration;
31 import org.efaps.db.Context;
32 import org.efaps.util.EFapsException;
33 import org.jasypt.digest.config.SimpleDigesterConfig;
34 import org.jasypt.util.password.ConfigurablePasswordEncryptor;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38
39
40
41
42
43
44 public class PasswordStore
45 {
46
47
48
49
50 private static final Logger LOG = LoggerFactory.getLogger(PasswordStore.class);
51
52
53
54
55 private static final String DIGEST = "Digest";
56
57
58
59
60 private static final String ALGORITHM = "Algorithm";
61
62
63
64
65 private static final String ITERATIONS = "Iterations";
66
67
68
69
70 private static final String SALTSIZE = "Saltsize";
71
72
73
74
75 private final Properties props = new Properties();
76
77
78
79
80 private final SimpleDigesterConfig digesterConfig = new SimpleDigesterConfig();
81
82
83
84
85 private int threshold = 5;
86
87
88
89
90
91 public PasswordStore()
92 {
93 this.digesterConfig.setAlgorithm("SHA-256");
94 this.digesterConfig.setIterations(100000);
95 this.digesterConfig.setSaltSizeBytes(16);
96 }
97
98
99
100
101
102 private void initConfig()
103 {
104 SystemConfiguration config = null;
105 try {
106 config = EFapsSystemConfiguration.get();
107 if (config != null) {
108 final Properties confProps = config.getAttributeValueAsProperties(KernelSettings.PWDSTORE);
109 this.digesterConfig.setAlgorithm(confProps.getProperty(PasswordStore.ALGORITHM,
110 this.digesterConfig.getAlgorithm()));
111 this.digesterConfig.setIterations(confProps.getProperty(PasswordStore.ITERATIONS,
112 this.digesterConfig.getIterations().toString()));
113 this.digesterConfig.setSaltSizeBytes(confProps.getProperty(PasswordStore.SALTSIZE,
114 this.digesterConfig.getSaltSizeBytes().toString()));
115 this.threshold = config.getAttributeValueAsInteger(KernelSettings.PWDTH);
116 }
117 } catch (final EFapsException e) {
118 PasswordStore.LOG.error("Error on reading SystemConfiguration for PasswordStore", e);
119 }
120
121 }
122
123
124
125
126
127
128
129 public void read(final String _readValue)
130 throws EFapsException
131 {
132 if (_readValue != null) {
133 try {
134 this.props.load(new StringReader(_readValue));
135 } catch (final IOException e) {
136 throw new EFapsException(PasswordStore.class.getName(), e);
137 }
138 }
139 }
140
141
142
143
144
145
146
147
148 public boolean checkCurrent(final String _plainPassword)
149 {
150 return check(_plainPassword, 0);
151 }
152
153
154
155
156
157
158
159
160
161 private boolean check(final String _plainPassword,
162 final int _pos)
163 {
164 boolean ret = false;
165 if (this.props.containsKey(PasswordStore.DIGEST + _pos)) {
166 final ConfigurablePasswordEncryptor passwordEncryptor = new ConfigurablePasswordEncryptor();
167 this.digesterConfig.setAlgorithm(this.props.getProperty(PasswordStore.ALGORITHM + _pos));
168 this.digesterConfig.setIterations(this.props.getProperty(PasswordStore.ITERATIONS + _pos));
169 this.digesterConfig.setSaltSizeBytes(this.props.getProperty(PasswordStore.SALTSIZE + _pos));
170 passwordEncryptor.setConfig(this.digesterConfig);
171 ret = passwordEncryptor.checkPassword(_plainPassword, this.props.getProperty(PasswordStore.DIGEST + _pos));
172 }
173 return ret;
174 }
175
176
177
178
179
180
181
182
183 public boolean isRepeated(final String _plainPassword)
184 {
185 boolean ret = false;
186 for (int i = 1; i < this.threshold + 1; i++) {
187 ret = check(_plainPassword, i);
188 if (ret) {
189 break;
190 }
191 }
192 return ret;
193 }
194
195
196
197
198
199
200
201
202
203
204 public void setNew(final String _plainPassword,
205 final String _currentValue)
206 throws EFapsException
207 {
208 initConfig();
209 read(_currentValue);
210 final ConfigurablePasswordEncryptor passwordEncryptor = new ConfigurablePasswordEncryptor();
211 passwordEncryptor.setConfig(this.digesterConfig);
212 final String encrypted = passwordEncryptor.encryptPassword(_plainPassword);
213 shiftAll();
214 this.props.setProperty(PasswordStore.DIGEST + 0, encrypted);
215 this.props.setProperty(PasswordStore.ALGORITHM + 0, this.digesterConfig.getAlgorithm());
216 this.props.setProperty(PasswordStore.ITERATIONS + 0, this.digesterConfig.getIterations().toString());
217 this.props.setProperty(PasswordStore.SALTSIZE + 0, this.digesterConfig.getSaltSizeBytes().toString());
218 }
219
220
221
222
223 private void shiftAll()
224 {
225 shift(PasswordStore.DIGEST);
226 shift(PasswordStore.ALGORITHM);
227 shift(PasswordStore.ITERATIONS);
228 shift(PasswordStore.SALTSIZE);
229 }
230
231
232
233
234
235
236 private void shift(final String _key)
237 {
238 for (int i = this.threshold; i > 0; i--) {
239 this.props.setProperty(_key + i, this.props.getProperty(_key + (i - 1), "").trim());
240 }
241 int i = this.threshold + 1;
242 while (this.props.contains(_key + i)) {
243 this.props.remove(_key + i);
244 i++;
245 }
246 }
247
248 @Override
249 public String toString()
250 {
251 final StringWriter writer = new StringWriter();
252 try {
253 this.props.store(writer, "Stored by User: " + Context.getThreadContext().getPersonId());
254 } catch (final IOException e) {
255 PasswordStore.LOG.error("Could not write to Writer", e);
256 } catch (final EFapsException e) {
257 PasswordStore.LOG.error("Could not read Context", e);
258 }
259 return writer.toString();
260 }
261 }