1 18 19 20 package sync4j.framework.security; 21 22 import java.util.HashMap ; 23 import java.util.logging.Logger ; 24 import java.util.logging.Level ; 25 26 import java.security.Principal ; 27 import javax.security.auth.*; 28 import javax.security.auth.login.*; 29 import javax.security.*; 30 31 import sync4j.framework.security.Officer; 32 import sync4j.framework.security.jaas.CredentialHandler; 33 import sync4j.framework.logging.Sync4jLogger; 34 import sync4j.framework.core.Cred; 35 import sync4j.framework.core.Authentication; 36 import sync4j.framework.config.Configuration; 37 import sync4j.framework.config.ConfigurationConstants; 38 import sync4j.framework.core.HMACAuthentication; 39 import sync4j.framework.core.Constants; 40 import sync4j.framework.tools.MD5; 41 import sync4j.framework.tools.Base64; 42 import sync4j.framework.server.store.*; 43 import sync4j.framework.server.Sync4jDevice; 44 import sync4j.framework.server.SyncUser; 45 46 import sync4j.server.admin.UserManager; 47 48 49 54 public class DBOfficer implements Officer, java.io.Serializable { 55 56 58 protected transient Logger log = Sync4jLogger.getLogger(); 59 protected PersistentStore ps = null; 60 61 64 67 private boolean loginFailed = false; 68 69 public boolean isLoginFailed() { 70 return loginFailed; 71 } 72 73 76 private boolean loginExpired = false; 77 78 81 private boolean guestEnabled = true; 82 83 public boolean isGuestEnabled() { 84 return this.guestEnabled; 85 } 86 87 public void setGuestEnabled(boolean guestEnabled) { 88 this.guestEnabled = guestEnabled; 89 } 90 91 94 private String authType = "syncml:auth-md5"; 95 96 public String getAuthType() { 97 return this.authType; 98 } 99 100 public void setAuthType(String authType) { 101 this.authType = authType; 102 103 this.supportedAuthType = this.supportedAuthType + this.authType; 105 } 106 107 108 private String supportedAuthType = null; 109 110 public String getSupportedAuthType() { 111 return this.supportedAuthType; 112 } 113 114 public void setSupportedAuthType(String supportedAuthType) { 115 116 this.supportedAuthType = this.authType + supportedAuthType; 118 } 119 120 121 123 130 public boolean authenticate(Cred credential) { 131 132 String type = credential.getType(); 133 134 if ( (Constants.AUTH_TYPE_BASIC).equals(type) ) { 135 return authenticateBasicCredential(credential); 136 } else if ( (Constants.AUTH_TYPE_MD5).equals(type) ) { 137 return authenticateMD5Credential(credential); 138 } else if ( (Constants.AUTH_TYPE_HMAC).equals(type) ) { 139 return authenticateHMACCredential(credential); 140 } else { 141 return false; 142 } 143 } 144 145 154 public boolean authorize(Principal principal, String resource) { 155 return true; 156 } 157 158 162 public void unAuthenticate(Cred credential) { 163 } 168 169 172 public boolean isAccountExpired() { 173 return loginExpired; 174 } 175 176 177 private void readObject(java.io.ObjectInputStream in) 179 throws java.io.IOException , ClassNotFoundException { 180 in.defaultReadObject(); 181 log = Sync4jLogger.getLogger(); 182 } 183 184 185 private boolean authenticateBasicCredential(Cred credential) { 186 SyncUser user = null ; 187 Authentication auth = credential.getAuthentication(); 188 189 String username = null; 190 String password = null; 191 192 String s = new String (Base64.decode(credential.getData())); 193 194 int p = s.indexOf(':'); 195 196 if (p == -1) { 197 username = s; 198 password = ""; 199 } else { 200 username = (p>0) ? s.substring(0, p) : ""; 201 password = (p == (s.length()-1)) ? "" : s.substring(p+1); 202 } 203 204 if (log.isLoggable(Level.FINE)) { 205 log.fine("Username: " + username + "; password: " + password); 206 } 207 208 try { 209 user = readUser(username); 210 } catch (NotFoundException e) { 211 if (log.isLoggable(Level.FINE)) { 212 log.fine("User " + username + " not found!"); 213 } 214 } catch (PersistentStoreException e) { 215 log.severe( "Error reading the user " 216 + username 217 + ": " 218 + e.getMessage() 219 ); 220 log.throwing(getClass().getName(), "authenticateBasicCredential", e); 221 222 return false; 223 } 224 225 return password.equals(user.getPassword()); 226 } 227 228 private boolean authenticateMD5Credential(Cred credential) { 229 230 Sync4jDevice device = null ; 231 Authentication auth = credential.getAuthentication(); 232 233 try { 234 device = readDevice(auth.getDeviceId()); 235 } catch (PersistentStoreException e) { 236 log.severe("Error configuring the persistent store: " + e); 237 log.throwing(getClass().getName(), "authenticateMD5Credential", e); 238 239 return false; 240 } 241 242 String userDigest = device.getDigest(); 247 byte[] clientNonce = auth.getNextNonce().getValue(); 248 249 if (log.isLoggable(Level.FINE)) { 250 log.fine("userDigest: " + userDigest); 251 } 252 253 byte[] userDigestBytes = userDigest.getBytes(); 254 255 byte[] buf = new byte[userDigestBytes.length + 1 + clientNonce.length]; 261 262 System.arraycopy(userDigestBytes, 0, buf, 0, userDigestBytes.length); 263 buf[userDigestBytes.length] = (byte)':'; 264 System.arraycopy(clientNonce, 0, buf, userDigestBytes.length+1, clientNonce.length); 265 266 byte[] digest = MD5.digest(buf); 267 268 String serverDigestNonceB64 = new String (Base64.encode(digest)); 272 273 String msgDigestNonceB64 = auth.getData(); 277 278 if (log.isLoggable(Level.FINE)) { 279 log.fine("serverDigestNonceB64: " + serverDigestNonceB64); 280 log.fine("msgDigestNonceB64: " + msgDigestNonceB64 ); 281 } 282 283 if (!msgDigestNonceB64.equals(serverDigestNonceB64)) { 284 return false; 285 } 286 287 auth.setUsername(userDigest); 288 289 return true; 290 291 } 292 293 private boolean authenticateHMACCredential(Cred credential) { 294 Sync4jDevice device = null ; 295 Authentication auth = credential.getAuthentication(); 296 297 if ( !(auth instanceof HMACAuthentication) ) { 298 throw new IllegalStateException ("Authentication not valid!"); 299 } 300 301 try { 302 device = readDevice(auth.getDeviceId()); 303 } catch (PersistentStoreException e) { 304 log.severe("Error configuring the persistent store: " + e); 305 log.throwing(getClass().getName(), "authenticateMD5Credential", e); 306 307 return false; 308 } 309 310 String userMac = ((HMACAuthentication)auth).getUserMac() ; 311 String calculatedMac = ((HMACAuthentication)auth).getCalculatedMac(); 312 313 if ((userMac != null) && (userMac.equals(calculatedMac))) { 314 auth.setUsername(device.getDigest()); 315 return true; 316 } 317 318 return false; 319 } 320 321 330 private Sync4jDevice readDevice(String deviceId) 331 throws PersistentStoreException { 332 Configuration config = Configuration.getConfiguration(); 333 334 PersistentStore ps = 335 (PersistentStore)config.getBeanInstance(ConfigurationConstants.CFG_PERSISTENT_STORE); 336 337 Sync4jDevice device = new Sync4jDevice(deviceId, null, null); 338 ps.read(device); 339 340 return device; 341 } 342 343 351 private SyncUser readUser(String username) 352 throws NotFoundException, PersistentStoreException { 353 Configuration config = Configuration.getConfiguration(); 354 355 UserManager um = 356 (UserManager)config.getBeanInstance(ConfigurationConstants.CFG_USER_MANAGER); 357 358 SyncUser[] results = um.getUsers( 359 new WhereClause("username", new String [] { username }, WhereClause.OPT_EQ, false) 360 ); 361 362 if ((results == null) || (results.length == 0)) { 363 throw new NotFoundException(username); 364 } 365 366 return results[0]; 367 } 368 369 370 } | Popular Tags |