diff --git a/org.adempiere.base.process/src/org/compiere/process/ColumnEncryption.java b/org.adempiere.base.process/src/org/compiere/process/ColumnEncryption.java
index 0823509493..b4bd4fa88f 100644
--- a/org.adempiere.base.process/src/org/compiere/process/ColumnEncryption.java
+++ b/org.adempiere.base.process/src/org/compiere/process/ColumnEncryption.java
@@ -117,7 +117,7 @@ public class ColumnEncryption extends SvrProcess {
if (column.isKey() || column.isParent() || column.isStandardColumn()
|| column.isVirtualColumn() || column.isIdentifier()
|| column.isTranslated() || DisplayType.isLookup(dt)
- || DisplayType.isLOB(dt)
+ || DisplayType.isLOB(dt) || DisplayType.isDate(dt) || DisplayType.isNumeric(dt)
|| "DocumentNo".equalsIgnoreCase(column.getColumnName())
|| "Value".equalsIgnoreCase(column.getColumnName())
|| "Name".equalsIgnoreCase(column.getColumnName())) {
@@ -126,7 +126,7 @@ public class ColumnEncryption extends SvrProcess {
column.saveEx();
}
StringBuilder msgreturn = new StringBuilder().append(columnName).append(": cannot be encrypted");
- return msgreturn.toString();
+ throw new Exception(msgreturn.toString());
}
// Start
@@ -137,10 +137,10 @@ public class ColumnEncryption extends SvrProcess {
// Test Value
if (p_TestValue != null && p_TestValue.length() > 0) {
- String encString = SecureEngine.encrypt(p_TestValue);
+ String encString = SecureEngine.encrypt(p_TestValue, 0);
msglog = new StringBuilder("Encrypted Test Value=").append(encString);
addLog(0, null, null, msglog.toString());
- String clearString = SecureEngine.decrypt(encString);
+ String clearString = SecureEngine.decrypt(encString, 0);
if (p_TestValue.equals(clearString)){
msglog = new StringBuilder("Decrypted=").append(clearString)
.append(" (same as test value)");
@@ -181,7 +181,7 @@ public class ColumnEncryption extends SvrProcess {
.append("Test=").append(testClear.toString()).append(" (").append(p_MaxLength).append(")");
log.config(msglog.toString());
//
- String encString = SecureEngine.encrypt(testClear.toString());
+ String encString = SecureEngine.encrypt(testClear.toString(), 0);
int encLength = encString.length();
msglog = new StringBuilder("Test Max Length=").append(testClear.length())
.append(" -> ").append(encLength);
@@ -224,7 +224,7 @@ public class ColumnEncryption extends SvrProcess {
// Check if the encryption exceeds the current length.
int oldLength = column.getFieldLength();
int newLength = encryptedColumnLength(oldLength);
- if (newLength > oldLength)
+ if (newLength > oldLength) {
if (changeFieldLength(columnID, columnName, newLength,
tableName) == -1) {
log.warning("EncryptError [ChangeFieldLength]: "
@@ -232,6 +232,7 @@ public class ColumnEncryption extends SvrProcess {
+ newLength);
throw new Exception();
}
+ }
// Encrypt column contents.
if (encryptColumnContents(columnName, column.getAD_Table_ID()) == -1) {
@@ -295,7 +296,7 @@ public class ColumnEncryption extends SvrProcess {
StringBuilder idColumnName = new StringBuilder(tableName).append("_ID");
StringBuilder selectSql = new StringBuilder();
- selectSql.append("SELECT ").append(idColumnName).append(",").append(columnName);
+ selectSql.append("SELECT ").append(idColumnName).append(",").append(columnName).append(",AD_Client_ID");
selectSql.append(" FROM ").append(tableName);
selectSql.append(" ORDER BY ").append(idColumnName);
@@ -306,32 +307,36 @@ public class ColumnEncryption extends SvrProcess {
PreparedStatement selectStmt = null;
PreparedStatement updateStmt = null;
-
- selectStmt = m_conn.prepareStatement(selectSql.toString(),
- ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
- updateStmt = m_conn.prepareStatement(updateSql.toString());
-
- ResultSet rs = selectStmt.executeQuery();
-
- for (recordsEncrypted = 0; rs.next(); ++recordsEncrypted) {
- // Get the row id and column value
- int id = rs.getInt(1);
- String value = rs.getString(2);
- // Encrypt the value
- value = SecureEngine.encrypt(value);
- // Update the row
- updateStmt.setString(1, value);
- updateStmt.setInt(2, id);
- if (updateStmt.executeUpdate() != 1) {
- log.warning("EncryptError: Table=" + tableName + ", ID=" + id);
- throw new Exception();
+ ResultSet rs = null;
+
+ try {
+ selectStmt = m_conn.prepareStatement(selectSql.toString(),
+ ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
+ updateStmt = m_conn.prepareStatement(updateSql.toString());
+
+ rs = selectStmt.executeQuery();
+
+ for (recordsEncrypted = 0; rs.next(); ++recordsEncrypted) {
+ // Get the row id and column value
+ int id = rs.getInt(1);
+ String value = rs.getString(2);
+ int AD_Client_ID = rs.getInt(3);
+ // Encrypt the value
+ value = SecureEngine.encrypt(value, AD_Client_ID);
+ // Update the row
+ updateStmt.setString(1, value);
+ updateStmt.setInt(2, id);
+ if (updateStmt.executeUpdate() != 1) {
+ log.severe("EncryptError: Table=" + tableName + ", ID=" + id);
+ throw new Exception();
+ }
}
+ } finally {
+ DB.close(rs);
+ DB.close(selectStmt);
+ DB.close(updateStmt);
}
- rs.close();
- selectStmt.close();
- updateStmt.close();
-
return recordsEncrypted;
} // encryptColumnContents
@@ -348,7 +353,7 @@ public class ColumnEncryption extends SvrProcess {
for (int i = 0; i < colLength; i++) {
str.append("1");
}
- str = new StringBuilder().append(SecureEngine.encrypt(str.toString()));
+ str = new StringBuilder().append(SecureEngine.encrypt(str.toString(), 0));
return str.length();
} // encryptedColumnLength
@@ -387,34 +392,36 @@ public class ColumnEncryption extends SvrProcess {
updateSql.append(" WHERE AD_Column_ID=").append(columnID);
PreparedStatement selectStmt = null;
-
- selectStmt = m_conn.prepareStatement(selectSql.toString(),
- ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
-
- selectStmt.setInt(1, columnID);
- ResultSet rs = selectStmt.executeQuery();
-
- if (rs.next()) {
- // Change the column size physically.
- if (DB.executeUpdate(alterSql.toString(), false, m_trx
- .getTrxName()) == -1) {
- log.warning("EncryptError [ChangeFieldLength]: ColumnID="
- + columnID + ", NewLength=" + length);
- throw new Exception();
- }
-
- // Change the column size in AD.
- if (DB.executeUpdate(updateSql.toString(), false, m_trx
- .getTrxName()) == -1) {
- log.warning("EncryptError [ChangeFieldLength]: ColumnID="
- + columnID + ", NewLength=" + length);
- throw new Exception();
+ ResultSet rs = null;
+
+ try {
+ selectStmt = m_conn.prepareStatement(selectSql.toString(),
+ ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
+
+ selectStmt.setInt(1, columnID);
+ rs = selectStmt.executeQuery();
+
+ if (rs.next()) {
+ // Change the column size physically.
+ if (DB.executeUpdate(alterSql.toString(), false, m_trx
+ .getTrxName()) == -1) {
+ log.severe("EncryptError [ChangeFieldLength]: ColumnID="
+ + columnID + ", NewLength=" + length);
+ throw new Exception();
+ }
+
+ // Change the column size in AD.
+ if (DB.executeUpdate(updateSql.toString(), false, m_trx
+ .getTrxName()) == -1) {
+ log.severe("EncryptError [ChangeFieldLength]: ColumnID="
+ + columnID + ", NewLength=" + length);
+ throw new Exception();
+ }
}
+ } finally {
+ DB.close(rs, selectStmt);
}
- rs.close();
- selectStmt.close();
-
// Update number of rows effected.
rowsEffected++;
diff --git a/org.adempiere.base/OSGI-INF/keystore.xml b/org.adempiere.base/OSGI-INF/keystore.xml
new file mode 100644
index 0000000000..eb288e633e
--- /dev/null
+++ b/org.adempiere.base/OSGI-INF/keystore.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/org.adempiere.base/src/org/adempiere/base/Core.java b/org.adempiere.base/src/org/adempiere/base/Core.java
index b13bf38eb5..14302b9757 100644
--- a/org.adempiere.base/src/org/adempiere/base/Core.java
+++ b/org.adempiere.base/src/org/adempiere/base/Core.java
@@ -104,6 +104,14 @@ public class Core {
return Service.locator().locate(ModelValidator.class, "org.adempiere.base.ModelValidator", serviceId, null).getService();
}
+ /**
+ *
+ * @return keystore
+ */
+ public static IKeyStore getKeyStore(){
+ return Service.locator().locate(IKeyStore.class).getService();
+ }
+
/**
* Get payment processor instance
* @param mbap payment processor model
diff --git a/org.adempiere.base/src/org/adempiere/base/IKeyStore.java b/org.adempiere.base/src/org/adempiere/base/IKeyStore.java
new file mode 100644
index 0000000000..5c14f484d2
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/IKeyStore.java
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * Copyright (C) 2013 Deepak *
+ * Copyright (C) 2013 Trek Global *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program is distributed in the hope *
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
+ * See the GNU General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.base;
+
+import javax.crypto.SecretKey;
+
+/**
+ *
+ * @author deepak
+ *
+ */
+public interface IKeyStore {
+
+ /**
+ *
+ * @param AD_Client_ID
+ * @return secret key
+ */
+ public SecretKey getKey(int AD_Client_ID);
+
+ /**
+ * @return encryption algorithm id, for e.g AES
+ */
+ public String getAlgorithm();
+}
+
+
+
diff --git a/org.adempiere.base/src/org/compiere/model/GridTable.java b/org.adempiere.base/src/org/compiere/model/GridTable.java
index b1b557425c..aa95094c85 100644
--- a/org.adempiere.base/src/org/compiere/model/GridTable.java
+++ b/org.adempiere.base/src/org/compiere/model/GridTable.java
@@ -1814,7 +1814,7 @@ public class GridTable extends AbstractTableModel
else
iii = new Integer(dd.toString());
if (encrypted)
- iii = (Integer)encrypt(iii);
+ iii = (Integer)encrypt(iii, getAD_Client_ID());
if (manualUpdate)
createUpdateSql (columnName, String.valueOf (iii));
else
@@ -1834,7 +1834,7 @@ public class GridTable extends AbstractTableModel
{
BigDecimal bd = (BigDecimal)rowData[col];
if (encrypted)
- bd = (BigDecimal)encrypt(bd);
+ bd = (BigDecimal)encrypt(bd, getAD_Client_ID());
if (manualUpdate)
createUpdateSql (columnName, bd.toString ());
else
@@ -1846,7 +1846,7 @@ public class GridTable extends AbstractTableModel
{
Timestamp ts = (Timestamp)rowData[col];
if (encrypted)
- ts = (Timestamp)encrypt(ts);
+ ts = (Timestamp)encrypt(ts, getAD_Client_ID());
if (manualUpdate)
createUpdateSql (columnName, DB.TO_DATE (ts, false));
else
@@ -1884,7 +1884,7 @@ public class GridTable extends AbstractTableModel
{
String str = rowData[col].toString ();
if (encrypted)
- str = (String)encrypt(str);
+ str = (String)encrypt(str, getAD_Client_ID());
if (manualUpdate)
createUpdateSql (columnName, DB.TO_STRING (str));
else
@@ -3121,7 +3121,7 @@ public class GridTable extends AbstractTableModel
{
String str = rs.getString(j+1);
if (field.isEncryptedColumn())
- str = (String)decrypt(str);
+ str = (String)decrypt(str, getAD_Client_ID());
rowData[j] = new Boolean ("Y".equals(str)); // Boolean
}
// LOB
@@ -3152,7 +3152,7 @@ public class GridTable extends AbstractTableModel
rowData[j] = rs.getString(j+1); // String
// Encrypted
if (field.isEncryptedColumn() && displayType != DisplayType.YesNo)
- rowData[j] = decrypt(rowData[j]);
+ rowData[j] = decrypt(rowData[j], getAD_Client_ID());
}
}
catch (SQLException e)
@@ -3167,11 +3167,11 @@ public class GridTable extends AbstractTableModel
* @param xx clear data
* @return encrypted value
*/
- private Object encrypt (Object xx)
+ private Object encrypt (Object xx, int AD_Client_ID)
{
if (xx == null)
return null;
- return SecureEngine.encrypt(xx);
+ return SecureEngine.encrypt(xx, AD_Client_ID);
} // encrypt
/**
@@ -3179,13 +3179,23 @@ public class GridTable extends AbstractTableModel
* @param yy encrypted data
* @return clear data
*/
- private Object decrypt (Object yy)
+ private Object decrypt (Object yy, int AD_Client_ID)
{
if (yy == null)
return null;
- return SecureEngine.decrypt(yy);
+ return SecureEngine.decrypt(yy, AD_Client_ID);
} // decrypt
+ private int getAD_Client_ID()
+ {
+ int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
+ GridField field = getField("AD_Client_ID");
+ if (field != null && field.getValue() != null) {
+ AD_Client_ID = ((Number)field.getValue()).intValue();
+ }
+ return AD_Client_ID;
+ }
+
/**************************************************************************
* Remove Data Status Listener
* @param l listener
diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java
index 12d56add58..5feaf4f60e 100644
--- a/org.adempiere.base/src/org/compiere/model/PO.java
+++ b/org.adempiere.base/src/org/compiere/model/PO.java
@@ -3020,8 +3020,9 @@ public abstract class PO
{
if (xx == null)
return null;
- if (index != -1 && p_info.isEncrypted(index))
- return SecureEngine.encrypt(xx);
+ if (index != -1 && p_info.isEncrypted(index)) {
+ return SecureEngine.encrypt(xx, getAD_Client_ID());
+ }
return xx;
} // encrypt
@@ -3035,8 +3036,9 @@ public abstract class PO
{
if (yy == null)
return null;
- if (index != -1 && p_info.isEncrypted(index))
- return SecureEngine.decrypt(yy);
+ if (index != -1 && p_info.isEncrypted(index)) {
+ return SecureEngine.decrypt(yy, getAD_Client_ID());
+ }
return yy;
} // decrypt
diff --git a/org.adempiere.base/src/org/compiere/util/DefaultKeyStore.java b/org.adempiere.base/src/org/compiere/util/DefaultKeyStore.java
new file mode 100644
index 0000000000..b2b6536549
--- /dev/null
+++ b/org.adempiere.base/src/org/compiere/util/DefaultKeyStore.java
@@ -0,0 +1,137 @@
+/******************************************************************************
+ * Copyright (C) 2013 Deepak *
+ * Copyright (C) 2013 Heng Sin Low *
+ * Copyright (C) 2013 Trek Global *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program is distributed in the hope *
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
+ * See the GNU General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.compiere.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.security.KeyStore;
+import java.security.KeyStore.PasswordProtection;
+import java.security.KeyStore.SecretKeyEntry;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+import org.adempiere.base.IKeyStore;
+
+/**
+ * @author deepak
+ * @author hengsin
+ *
+ */
+public class DefaultKeyStore implements IKeyStore {
+
+ private static final String LEGACY_ALGORITHM = "DES";
+
+ private static final String IDEMPIERE_KEYSTORE_PROPERTIES = "idempiere-ks.properties";
+
+ private static final String IDEMPIERE_KEYSTORE = "idempiere.ks";
+
+ /** Logger */
+ private static Logger log = Logger.getLogger (DefaultKeyStore.class.getName());
+
+ /** Adempiere Key */
+ private SecretKey m_key = null;
+
+ private KeyStore keyStore;
+
+ private char[] password = null;
+
+ private String algorithm;
+
+ public DefaultKeyStore(){
+ File file = new File(Ini.getAdempiereHome(), IDEMPIERE_KEYSTORE_PROPERTIES);
+ if (file.exists()) {
+ try{
+ Properties p = new Properties();
+ p.load(new FileInputStream(file));
+ String s = p.getProperty("password");
+ String a = p.getProperty("algorithm");
+ if (!Util.isEmpty(s) && !Util.isEmpty(a)) {
+ password = s.toCharArray();
+ algorithm = a;
+ keyStore = KeyStore.getInstance("JCEKS");
+ file = new File(Ini.getAdempiereHome(), IDEMPIERE_KEYSTORE);
+ if (file.exists()) {
+ FileInputStream stream = new FileInputStream(file);
+ keyStore.load(stream, password );
+ } else {
+ keyStore.load(null, password );
+ }
+ } else {
+ createLegacyKey();
+ }
+ } catch (Exception ex) {
+ log.log(Level.SEVERE, "", ex);
+ password = null;
+ createLegacyKey();
+ }
+ } else {
+ createLegacyKey();
+ }
+ }
+
+ private void createLegacyKey() {
+ m_key = new javax.crypto.spec.SecretKeySpec
+ (new byte[] {100,25,28,-122,-26,94,-3,-26}, LEGACY_ALGORITHM);
+ }
+
+ @Override
+ public SecretKey getKey(int AD_Client_ID) {
+ if (password != null) {
+ try {
+ PasswordProtection protParam = new PasswordProtection(password);
+ String alias = "ad_client_"+AD_Client_ID;
+ SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(alias, protParam);
+ if (entry == null) {
+ KeyGenerator generator = KeyGenerator.getInstance(algorithm);
+ SecretKey key = generator.generateKey();
+ entry = new SecretKeyEntry((SecretKey) key);
+
+ keyStore.setEntry(alias, entry, protParam);
+ File file = new File(IDEMPIERE_KEYSTORE);
+ FileOutputStream stream = null;
+ try {
+ stream = new FileOutputStream(file);
+ keyStore.store(stream, password);
+ stream.flush();
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (Exception e) {}
+ }
+ }
+ }
+ return entry.getSecretKey();
+ } catch (Exception ex) {
+ log.log(Level.SEVERE, "", ex);
+ }
+ }
+ return m_key;
+ }
+
+ @Override
+ public String getAlgorithm() {
+ if (algorithm == null)
+ return LEGACY_ALGORITHM;
+ else
+ return algorithm;
+ }
+
+}
diff --git a/org.adempiere.base/src/org/compiere/util/Ini.java b/org.adempiere.base/src/org/compiere/util/Ini.java
index 9f121f7e69..ecbf13c743 100644
--- a/org.adempiere.base/src/org/compiere/util/Ini.java
+++ b/org.adempiere.base/src/org/compiere/util/Ini.java
@@ -515,7 +515,7 @@ public final class Ini implements Serializable
else if (!isClient())
result = s_prop.getProperty (key, SecureInterface.CLEARVALUE_START + defaultValue + SecureInterface.CLEARVALUE_END);
else
- result = s_prop.getProperty (key, SecureEngine.encrypt(defaultValue));
+ result = s_prop.getProperty (key, SecureEngine.encrypt(defaultValue, 0));
s_prop.setProperty (key, result);
return result;
} // checkProperty
@@ -577,7 +577,7 @@ public final class Ini implements Serializable
s_prop.setProperty(key, "");
else
{
- String eValue = SecureEngine.encrypt(value);
+ String eValue = SecureEngine.encrypt(value, 0);
if (eValue == null)
s_prop.setProperty(key, "");
else
@@ -619,7 +619,7 @@ public final class Ini implements Serializable
if (retStr == null || retStr.length() == 0)
return "";
//
- String value = SecureEngine.decrypt(retStr);
+ String value = SecureEngine.decrypt(retStr, 0);
// getLogger().finer(key + "=" + value);
if (value == null)
return "";
diff --git a/org.adempiere.base/src/org/compiere/util/Login.java b/org.adempiere.base/src/org/compiere/util/Login.java
index 2a44f785c0..1bcfe90733 100644
--- a/org.adempiere.base/src/org/compiere/util/Login.java
+++ b/org.adempiere.base/src/org/compiere/util/Login.java
@@ -304,35 +304,27 @@ public class Login
if ( user.authenticateHash(app_pwd) )
{
authenticated = true;
- app_pwd = null;
}
}
else{
- StringBuffer sql = new StringBuffer("SELECT AD_User.AD_User_ID,")
- .append(" AD_User.ConnectionProfile ")
- .append(" FROM AD_User ");
+ StringBuffer sql = new StringBuffer("SELECT AD_User.AD_User_ID ").append(" FROM AD_User ");
sql.append(" WHERE ").append(userNameCol).append("=?");
sql.append(" AND AD_User.IsActive='Y'").append(" AND EXISTS (SELECT * FROM AD_Client c WHERE AD_User.AD_Client_ID=c.AD_Client_ID AND c.IsActive='Y')");
- if (app_pwd != null)
- sql.append(" AND ((AD_User.Password=? AND (SELECT IsEncrypted FROM AD_Column WHERE AD_Column_ID=417)='N') "
- + "OR (AD_User.Password=? AND (SELECT IsEncrypted FROM AD_Column WHERE AD_Column_ID=417)='Y'))"); // #2/3
-
PreparedStatement pstmt1=null;
ResultSet rs1=null;
try{
pstmt1 = DB.prepareStatement(sql.toString(), null);
pstmt1.setString(1, app_user);
- if (app_pwd != null)
- {
- pstmt1.setString(2, app_pwd);
- pstmt1.setString(3, SecureEngine.encrypt(app_pwd));
- }
rs1 = pstmt1.executeQuery();
while(rs1.next()){
- authenticated=true;
+ MUser user = new MUser(m_ctx, rs1.getInt(1), null);
+ if (user.getPassword() != null && user.getPassword().equals(app_pwd)) {
+ authenticated=true;
+ }
+
}
}catch (Exception ex) {
@@ -349,9 +341,8 @@ public class Login
}
if(authenticated){
- StringBuffer sql = new StringBuffer("SELECT AD_User.AD_User_ID, r.AD_Role_ID,r.Name,")
- .append(" AD_User.ConnectionProfile ")
- .append("FROM AD_User ")
+ StringBuffer sql = new StringBuffer("SELECT AD_User.AD_User_ID, r.AD_Role_ID,r.Name")
+ .append(" FROM AD_User ")
.append(" INNER JOIN AD_User_Roles ur ON (AD_User.AD_User_ID=ur.AD_User_ID AND ur.IsActive='Y')")
.append(" INNER JOIN AD_Role r ON (ur.AD_Role_ID=r.AD_Role_ID AND r.IsActive='Y') ");
@@ -359,10 +350,6 @@ public class Login
sql.append(" AND AD_User.IsActive='Y'").append(" AND EXISTS (SELECT * FROM AD_Client c WHERE AD_User.AD_Client_ID=c.AD_Client_ID AND c.IsActive='Y')");
- /* if (app_pwd != null && !hash_password)
- sql.append(" AND ((AD_User.Password=? AND (SELECT IsEncrypted FROM AD_Column WHERE AD_Column_ID=417)='N') "
- + "OR (AD_User.Password=? AND (SELECT IsEncrypted FROM AD_Column WHERE AD_Column_ID=417)='Y'))"); // #2/3*/
-
sql.append(" ORDER BY r.Name");
PreparedStatement pstmt = null;
@@ -372,11 +359,6 @@ public class Login
pstmt = DB.prepareStatement(sql.toString(), null);
pstmt.setString(1, app_user);
- /*if (app_pwd != null && !hash_password)
- {
- pstmt.setString(2, app_pwd);
- pstmt.setString(3, SecureEngine.encrypt(app_pwd));
- }*/
// execute a query
rs = pstmt.executeQuery();
@@ -413,13 +395,16 @@ public class Login
}
do // read all roles
- {
- int AD_Role_ID = rs.getInt(2);
- if (AD_Role_ID == 0)
- Env.setContext(m_ctx, "#SysAdmin", "Y");
- String Name = rs.getString(3);
- KeyNamePair p = new KeyNamePair(AD_Role_ID, Name);
- list.add(p);
+ {
+ MUser user = new MUser(m_ctx, rs.getInt(1), null);
+ if (user.getPassword() != null && user.getPassword().equals(app_pwd)) {
+ int AD_Role_ID = rs.getInt(2);
+ if (AD_Role_ID == 0)
+ Env.setContext(m_ctx, "#SysAdmin", "Y");
+ String Name = rs.getString(3);
+ KeyNamePair p = new KeyNamePair(AD_Role_ID, Name);
+ list.add(p);
+ }
}
while (rs.next());
//
@@ -440,6 +425,7 @@ public class Login
{
DB.close(rs, pstmt);
rs = null; pstmt = null;
+ app_pwd = null;
}
}
//long ms = System.currentTimeMillis () - start;
@@ -1333,7 +1319,7 @@ public class Login
valid = user.authenticateHash(app_pwd);
} else {
// password not hashed
- valid = user.getPassword().equals(app_pwd);
+ valid = user.getPassword() != null && user.getPassword().equals(app_pwd);
}
if (valid ) {
if (user.isLocked())
diff --git a/org.adempiere.base/src/org/compiere/util/Secure.java b/org.adempiere.base/src/org/compiere/util/Secure.java
index 0752ab5238..7094458925 100644
--- a/org.adempiere.base/src/org/compiere/util/Secure.java
+++ b/org.adempiere.base/src/org/compiere/util/Secure.java
@@ -26,7 +26,9 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
+
+import org.adempiere.base.Core;
+import org.adempiere.base.IKeyStore;
/**
* Security Services.
@@ -128,14 +130,11 @@ public class Secure implements SecureInterface
{
initCipher();
} // Secure
-
- /** Adempiere Cipher */
- private Cipher m_cipher = null;
- /** Adempiere Key */
- private SecretKey m_key = null;
+
/** Message Digest */
private MessageDigest m_md = null;
+ private IKeyStore m_keyStore = null;
/** Logger */
private static Logger log = Logger.getLogger (Secure.class.getName());
@@ -144,34 +143,10 @@ public class Secure implements SecureInterface
*/
private synchronized void initCipher()
{
- if (m_cipher != null)
- return;
- Cipher cc = null;
- try
- {
- cc = Cipher.getInstance("DES/ECB/PKCS5Padding");
- // Key
- /*if (false)
- {
- KeyGenerator keygen = KeyGenerator.getInstance("DES");
- m_key = keygen.generateKey();
- byte[] key = m_key.getEncoded();
- StringBuffer sb = new StringBuffer ("Key ")
- .append(m_key.getAlgorithm())
- .append("(").append(key.length).append(")= ");
- for (int i = 0; i < key.length; i++)
- sb.append(key[i]).append(",");
- log.info(sb.toString());
- }
- else*/
- m_key = new javax.crypto.spec.SecretKeySpec
- (new byte[] {100,25,28,-122,-26,94,-3,-26}, "DES");
+ if(m_keyStore==null){
+ m_keyStore = getKeyStore();
}
- catch (Exception ex)
- {
- log.log(Level.SEVERE, "", ex);
- }
- m_cipher = cc;
+
} // initCipher
@@ -179,35 +154,35 @@ public class Secure implements SecureInterface
/**
* Encryption.
* @param value clear value
+ * @param AD_Client_ID
* @return encrypted String
*/
- public String encrypt (String value)
- {
+ public String encrypt (String value,int AD_Client_ID)
+ {
String clearText = value;
if (clearText == null)
clearText = "";
- // Init
- if (m_cipher == null)
+ // Init
+ if (m_keyStore == null)
initCipher();
- // Encrypt
- if (m_cipher != null)
- {
- try
- {
- m_cipher.init(Cipher.ENCRYPT_MODE, m_key);
- byte[] encBytes = m_cipher.doFinal(clearText.getBytes("UTF8"));
- String encString = convertToHexString(encBytes);
- // globalqss - [ 1577737 ] Security Breach - show database password
- // log.log (Level.ALL, value + " => " + encString);
- return encString;
- }
- catch (Exception ex)
- {
- // log.log(Level.INFO, value, ex);
- log.log(Level.INFO, "Problem encrypting string", ex);
- }
+
+ // Encrypt
+ try {
+ Cipher cipher = Cipher.getInstance(m_keyStore.getAlgorithm());
+
+ cipher.init(Cipher.ENCRYPT_MODE, m_keyStore.getKey(AD_Client_ID));
+ byte[] encBytes = cipher.doFinal(clearText.getBytes("UTF8"));
+
+ String encString = convertToHexString(encBytes);
+ // globalqss - [ 1577737 ] Security Breach - show database password
+ // log.log (Level.ALL, value + " => " + encString);
+ return encString;
+ } catch (Exception ex) {
+ // log.log(Level.INFO, value, ex);
+ log.log(Level.INFO, "Problem encrypting string", ex);
}
- // Fallback
+
+ // Fallback
return CLEARVALUE_START + value + CLEARVALUE_END;
} // encrypt
@@ -215,9 +190,10 @@ public class Secure implements SecureInterface
* Decryption.
* The methods must recognize clear text values
* @param value encrypted value
+ * @param AD_Client_ID
* @return decrypted String
*/
- public String decrypt (String value)
+ public String decrypt (String value,int AD_Client_ID)
{
if (value == null || value.length() == 0)
return value;
@@ -238,17 +214,18 @@ public class Secure implements SecureInterface
return value;
}
// Init
- if (m_cipher == null)
+ if (m_keyStore == null)
initCipher();
// Encrypt
- if (m_cipher != null && value != null && value.length() > 0)
+ if (value != null && value.length() > 0)
{
try
{
- AlgorithmParameters ap = m_cipher.getParameters();
- m_cipher.init(Cipher.DECRYPT_MODE, m_key, ap);
- byte[] out = m_cipher.doFinal(data);
+ Cipher cipher = Cipher.getInstance(m_keyStore.getAlgorithm());
+ AlgorithmParameters ap = cipher.getParameters();
+ cipher.init(Cipher.DECRYPT_MODE, m_keyStore.getKey(AD_Client_ID), ap);
+ byte[] out = cipher.doFinal(data);
String retValue = new String(out, "UTF8");
// globalqss - [ 1577737 ] Security Breach - show database password
// log.log (Level.ALL, value + " => " + retValue);
@@ -267,9 +244,10 @@ public class Secure implements SecureInterface
* Encryption.
* The methods must recognize clear text values
* @param value clear value
+ * @param ad_client_id
* @return encrypted String
*/
- public Integer encrypt (Integer value)
+ public Integer encrypt (Integer value,int ad_client_id)
{
return value;
} // encrypt
@@ -280,7 +258,7 @@ public class Secure implements SecureInterface
* @param value encrypted value
* @return decrypted String
*/
- public Integer decrypt (Integer value)
+ public Integer decrypt (Integer value,int ad_client_id)
{
return value;
} // decrypt
@@ -289,9 +267,10 @@ public class Secure implements SecureInterface
* Encryption.
* The methods must recognize clear text values
* @param value clear value
+ * @param ad_client_id
* @return encrypted String
*/
- public BigDecimal encrypt (BigDecimal value)
+ public BigDecimal encrypt (BigDecimal value,int ad_client_id)
{
return value;
} // encrypt
@@ -302,7 +281,7 @@ public class Secure implements SecureInterface
* @param value encrypted value
* @return decrypted String
*/
- public BigDecimal decrypt (BigDecimal value)
+ public BigDecimal decrypt (BigDecimal value,int ad_client_id)
{
return value;
} // decrypt
@@ -311,9 +290,10 @@ public class Secure implements SecureInterface
* Encryption.
* The methods must recognize clear text values
* @param value clear value
+ * @param ad_client_id
* @return encrypted String
*/
- public Timestamp encrypt (Timestamp value)
+ public Timestamp encrypt (Timestamp value,int ad_client_id)
{
return value;
} // encrypt
@@ -324,7 +304,7 @@ public class Secure implements SecureInterface
* @param value encrypted value
* @return decrypted String
*/
- public Timestamp decrypt (Timestamp value)
+ public Timestamp decrypt (Timestamp value,int ad_client_id)
{
return value;
} // decrypt
@@ -412,9 +392,20 @@ public class Secure implements SecureInterface
public String toString ()
{
StringBuilder sb = new StringBuilder ("Secure[");
- sb.append(m_cipher)
+ sb.append(m_keyStore.getAlgorithm())
.append ("]");
return sb.toString ();
} // toString
+ /**
+ *
+ * @return keystore
+ */
+ public IKeyStore getKeyStore(){
+ IKeyStore keyStore = Core.getKeyStore();
+ if(keyStore==null)
+ keyStore = new DefaultKeyStore();
+
+ return keyStore;
+ }
} // Secure
diff --git a/org.adempiere.base/src/org/compiere/util/SecureEngine.java b/org.adempiere.base/src/org/compiere/util/SecureEngine.java
index ef9be7313c..d9fd5cf5da 100644
--- a/org.adempiere.base/src/org/compiere/util/SecureEngine.java
+++ b/org.adempiere.base/src/org/compiere/util/SecureEngine.java
@@ -106,9 +106,10 @@ public class SecureEngine
* Encryption.
* The methods must recognize clear text values
* @param value clear value
+ * @param AD_Client_ID
* @return encrypted String
*/
- public static String encrypt (String value)
+ public static String encrypt (String value,int AD_Client_ID)
{
if (value == null || value.length() == 0)
return value;
@@ -119,19 +120,21 @@ public class SecureEngine
if (inQuotes)
value = value.substring(1, value.length()-1);
//
- String retValue = s_engine.implementation.encrypt(value);
+ String retValue = s_engine.implementation.encrypt(value,AD_Client_ID);
if (inQuotes)
return "'" + retValue + "'";
return retValue;
} // encrypt
+
/**
* Decryption.
* The methods must recognize clear text values
* @param value encrypted value
+ * @param AD_Client_ID
* @return decrypted String
*/
- public static String decrypt (String value)
+ public static String decrypt (String value, int AD_Client_ID)
{
if (value == null)
return null;
@@ -144,22 +147,23 @@ public class SecureEngine
if (value.startsWith(SecureInterface.CLEARVALUE_START) && value.endsWith(SecureInterface.CLEARVALUE_END))
retValue = value.substring(SecureInterface.CLEARVALUE_START.length(), value.length()-SecureInterface.CLEARVALUE_END.length());
else
- retValue = s_engine.implementation.decrypt(value);
+ retValue = s_engine.implementation.decrypt(value,AD_Client_ID);
if (inQuotes)
return "'" + retValue + "'";
return retValue;
} // decrypt
-
+
/**
* Encryption.
* The methods must recognize clear values
* @param value clear value
+ * @param AD_Client_ID
* @return encrypted String
*/
- public static Object encrypt (Object value)
+ public static Object encrypt (Object value, int AD_Client_ID)
{
if (value instanceof String)
- return encrypt((String) value);
+ return encrypt((String) value, AD_Client_ID);
return value;
} // encrypt
@@ -169,10 +173,10 @@ public class SecureEngine
* @param value encrypted value
* @return decrypted String
*/
- public static Object decrypt (Object value)
+ public static Object decrypt (Object value, int AD_Client_ID)
{
if (value instanceof String)
- return decrypt((String) value);
+ return decrypt((String) value, AD_Client_ID);
return value;
} // decrypt
@@ -204,8 +208,8 @@ public class SecureEngine
System.exit(10);
}
// See if it works
- String testE = implementation.encrypt(TEST);
- String testC = implementation.decrypt(testE);
+ String testE = implementation.encrypt(TEST,0);
+ String testC = implementation.decrypt(testE,0);
if (!testC.equals(TEST))
throw new IllegalStateException(realClass
+ ": " + TEST
@@ -269,10 +273,10 @@ public class SecureEngine
log.info("Decrypt null =" + test(decrypt(null), null));
log.info("Decrypt test =" + test(decrypt("test"), "test"));
**/
- log.info("Decrypt {test} =" + test(decrypt("af2309f390afed74"), "test"));
- log.info("Decrypt ~{test}~ =" + test(decrypt(SecureInterface.ENCRYPTEDVALUE_START + "af2309f390afed74" + SecureInterface.ENCRYPTEDVALUE_END), "test"));
+ log.info("Decrypt {test} =" + test(decrypt("af2309f390afed74", 0), "test"));
+ log.info("Decrypt ~{test}~ =" + test(decrypt(SecureInterface.ENCRYPTEDVALUE_START + "af2309f390afed74" + SecureInterface.ENCRYPTEDVALUE_END, 0), "test"));
- log.info("Encrypt test =" + test(encrypt("test"), "af2309f390afed74"));
+ log.info("Encrypt test =" + test(encrypt("test", 0), "af2309f390afed74"));
diff --git a/org.adempiere.base/src/org/compiere/util/SecureInterface.java b/org.adempiere.base/src/org/compiere/util/SecureInterface.java
index c4917f2614..9e5141668f 100644
--- a/org.adempiere.base/src/org/compiere/util/SecureInterface.java
+++ b/org.adempiere.base/src/org/compiere/util/SecureInterface.java
@@ -52,64 +52,71 @@ public interface SecureInterface
/**
* Encryption.
* @param value clear value
+ * @param AD_Client_ID
* @return encrypted String
*/
- public String encrypt (String value);
+ public String encrypt (String value,int AD_Client_ID);
/**
* Decryption.
* @param value encrypted value
* @return decrypted String
*/
- public String decrypt (String value);
+ public String decrypt (String value,int AD_Client_ID);
/**
* Encryption.
* The methods must recognize clear text values
* @param value clear value
+ * @param AD_Client_ID
* @return encrypted String
*/
- public Integer encrypt (Integer value);
+ public Integer encrypt (Integer value,int AD_Client_ID);
/**
* Decryption.
* The methods must recognize clear text values
* @param value encrypted value
+ * @param AD_Client_ID
* @return decrypted String
*/
- public Integer decrypt (Integer value);
+ public Integer decrypt (Integer value,int AD_Client_ID);
/**
* Encryption.
* The methods must recognize clear text values
* @param value clear value
+ * @param AD_Client_ID
* @return encrypted String
*/
- public BigDecimal encrypt (BigDecimal value);
+ public BigDecimal encrypt (BigDecimal value,int AD_Client_ID);
/**
* Decryption.
* The methods must recognize clear text values
* @param value encrypted value
+ * @param AD_Client_ID
* @return decrypted String
*/
- public BigDecimal decrypt (BigDecimal value);
+ public BigDecimal decrypt (BigDecimal value,int AD_Client_ID);
/**
* Encryption.
* The methods must recognize clear text values
* @param value clear value
+ * @param AD_Client_ID
* @return encrypted String
*/
- public Timestamp encrypt (Timestamp value);
+ public Timestamp encrypt (Timestamp value,int AD_Client_ID);
/**
* Decryption.
* The methods must recognize clear text values
* @param value encrypted value
+ * @param AD_Client_ID
* @return decrypted String
*/
- public Timestamp decrypt (Timestamp value);
+ public Timestamp decrypt (Timestamp value,int AD_Client_ID);
/**
diff --git a/org.adempiere.base/src/org/compiere/util/WebUser.java b/org.adempiere.base/src/org/compiere/util/WebUser.java
index 5f8fea21ca..e4859d6a28 100644
--- a/org.adempiere.base/src/org/compiere/util/WebUser.java
+++ b/org.adempiere.base/src/org/compiere/util/WebUser.java
@@ -682,8 +682,6 @@ public class WebUser
{
String sql = "SELECT * FROM AD_User "
+ "WHERE COALESCE(LDAPUser, Name)=? " // #1
- + " AND ((Password=? AND (SELECT IsEncrypted FROM AD_Column WHERE AD_Column_ID=417)='N') " // #2
- + "OR (Password=? AND (SELECT IsEncrypted FROM AD_Column WHERE AD_Column_ID=417)='Y'))" // #3
+ " AND IsActive='Y' " // #4
;
PreparedStatement pstmt = null;
@@ -692,14 +690,17 @@ public class WebUser
{
pstmt = DB.prepareStatement (sql, null);
pstmt.setString (1, m_bpc.getName());
- pstmt.setString (2, password);
- pstmt.setString (3, SecureEngine.encrypt(password));
rs = pstmt.executeQuery ();
if (rs.next ())
{
- retValue = true;
- if (rs.next())
- log.warning ("More then one user with Name/Password = " + m_bpc.getName());
+ do
+ {
+ MUser user = new MUser(Env.getCtx(), rs, null);
+ if (user.getPassword() != null && user.getPassword().equals(password)) {
+ retValue = true;
+ break;
+ }
+ } while (rs.next());
}
else
log.fine("No record");
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java
index 809036a8db..06c040b196 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java
@@ -1697,7 +1697,7 @@ public class FindWindow extends Window implements EventListener, ValueCha
GridField field = getTargetMField(ColumnName);
// add encryption here if the field is encrypted.
if (field.isEncryptedColumn()) {
- value = SecureEngine.encrypt(value);
+ value = SecureEngine.encrypt(value, Env.getAD_Client_ID(Env.getCtx()));
}
boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID());