IDEMPIERE-613 Column Encryption Enhancement.
This commit is contained in:
parent
11603bc4fe
commit
b6af6a3489
|
@ -117,7 +117,7 @@ public class ColumnEncryption extends SvrProcess {
|
||||||
if (column.isKey() || column.isParent() || column.isStandardColumn()
|
if (column.isKey() || column.isParent() || column.isStandardColumn()
|
||||||
|| column.isVirtualColumn() || column.isIdentifier()
|
|| column.isVirtualColumn() || column.isIdentifier()
|
||||||
|| column.isTranslated() || DisplayType.isLookup(dt)
|
|| column.isTranslated() || DisplayType.isLookup(dt)
|
||||||
|| DisplayType.isLOB(dt)
|
|| DisplayType.isLOB(dt) || DisplayType.isDate(dt) || DisplayType.isNumeric(dt)
|
||||||
|| "DocumentNo".equalsIgnoreCase(column.getColumnName())
|
|| "DocumentNo".equalsIgnoreCase(column.getColumnName())
|
||||||
|| "Value".equalsIgnoreCase(column.getColumnName())
|
|| "Value".equalsIgnoreCase(column.getColumnName())
|
||||||
|| "Name".equalsIgnoreCase(column.getColumnName())) {
|
|| "Name".equalsIgnoreCase(column.getColumnName())) {
|
||||||
|
@ -126,7 +126,7 @@ public class ColumnEncryption extends SvrProcess {
|
||||||
column.saveEx();
|
column.saveEx();
|
||||||
}
|
}
|
||||||
StringBuilder msgreturn = new StringBuilder().append(columnName).append(": cannot be encrypted");
|
StringBuilder msgreturn = new StringBuilder().append(columnName).append(": cannot be encrypted");
|
||||||
return msgreturn.toString();
|
throw new Exception(msgreturn.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start
|
// Start
|
||||||
|
@ -137,10 +137,10 @@ public class ColumnEncryption extends SvrProcess {
|
||||||
|
|
||||||
// Test Value
|
// Test Value
|
||||||
if (p_TestValue != null && p_TestValue.length() > 0) {
|
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);
|
msglog = new StringBuilder("Encrypted Test Value=").append(encString);
|
||||||
addLog(0, null, null, msglog.toString());
|
addLog(0, null, null, msglog.toString());
|
||||||
String clearString = SecureEngine.decrypt(encString);
|
String clearString = SecureEngine.decrypt(encString, 0);
|
||||||
if (p_TestValue.equals(clearString)){
|
if (p_TestValue.equals(clearString)){
|
||||||
msglog = new StringBuilder("Decrypted=").append(clearString)
|
msglog = new StringBuilder("Decrypted=").append(clearString)
|
||||||
.append(" (same as test value)");
|
.append(" (same as test value)");
|
||||||
|
@ -181,7 +181,7 @@ public class ColumnEncryption extends SvrProcess {
|
||||||
.append("Test=").append(testClear.toString()).append(" (").append(p_MaxLength).append(")");
|
.append("Test=").append(testClear.toString()).append(" (").append(p_MaxLength).append(")");
|
||||||
log.config(msglog.toString());
|
log.config(msglog.toString());
|
||||||
//
|
//
|
||||||
String encString = SecureEngine.encrypt(testClear.toString());
|
String encString = SecureEngine.encrypt(testClear.toString(), 0);
|
||||||
int encLength = encString.length();
|
int encLength = encString.length();
|
||||||
msglog = new StringBuilder("Test Max Length=").append(testClear.length())
|
msglog = new StringBuilder("Test Max Length=").append(testClear.length())
|
||||||
.append(" -> ").append(encLength);
|
.append(" -> ").append(encLength);
|
||||||
|
@ -224,7 +224,7 @@ public class ColumnEncryption extends SvrProcess {
|
||||||
// Check if the encryption exceeds the current length.
|
// Check if the encryption exceeds the current length.
|
||||||
int oldLength = column.getFieldLength();
|
int oldLength = column.getFieldLength();
|
||||||
int newLength = encryptedColumnLength(oldLength);
|
int newLength = encryptedColumnLength(oldLength);
|
||||||
if (newLength > oldLength)
|
if (newLength > oldLength) {
|
||||||
if (changeFieldLength(columnID, columnName, newLength,
|
if (changeFieldLength(columnID, columnName, newLength,
|
||||||
tableName) == -1) {
|
tableName) == -1) {
|
||||||
log.warning("EncryptError [ChangeFieldLength]: "
|
log.warning("EncryptError [ChangeFieldLength]: "
|
||||||
|
@ -232,6 +232,7 @@ public class ColumnEncryption extends SvrProcess {
|
||||||
+ newLength);
|
+ newLength);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Encrypt column contents.
|
// Encrypt column contents.
|
||||||
if (encryptColumnContents(columnName, column.getAD_Table_ID()) == -1) {
|
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 idColumnName = new StringBuilder(tableName).append("_ID");
|
||||||
|
|
||||||
StringBuilder selectSql = new StringBuilder();
|
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(" FROM ").append(tableName);
|
||||||
selectSql.append(" ORDER BY ").append(idColumnName);
|
selectSql.append(" ORDER BY ").append(idColumnName);
|
||||||
|
|
||||||
|
@ -306,32 +307,36 @@ public class ColumnEncryption extends SvrProcess {
|
||||||
|
|
||||||
PreparedStatement selectStmt = null;
|
PreparedStatement selectStmt = null;
|
||||||
PreparedStatement updateStmt = null;
|
PreparedStatement updateStmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
selectStmt = m_conn.prepareStatement(selectSql.toString(),
|
|
||||||
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
|
try {
|
||||||
updateStmt = m_conn.prepareStatement(updateSql.toString());
|
selectStmt = m_conn.prepareStatement(selectSql.toString(),
|
||||||
|
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
|
||||||
ResultSet rs = selectStmt.executeQuery();
|
updateStmt = m_conn.prepareStatement(updateSql.toString());
|
||||||
|
|
||||||
for (recordsEncrypted = 0; rs.next(); ++recordsEncrypted) {
|
rs = selectStmt.executeQuery();
|
||||||
// Get the row id and column value
|
|
||||||
int id = rs.getInt(1);
|
for (recordsEncrypted = 0; rs.next(); ++recordsEncrypted) {
|
||||||
String value = rs.getString(2);
|
// Get the row id and column value
|
||||||
// Encrypt the value
|
int id = rs.getInt(1);
|
||||||
value = SecureEngine.encrypt(value);
|
String value = rs.getString(2);
|
||||||
// Update the row
|
int AD_Client_ID = rs.getInt(3);
|
||||||
updateStmt.setString(1, value);
|
// Encrypt the value
|
||||||
updateStmt.setInt(2, id);
|
value = SecureEngine.encrypt(value, AD_Client_ID);
|
||||||
if (updateStmt.executeUpdate() != 1) {
|
// Update the row
|
||||||
log.warning("EncryptError: Table=" + tableName + ", ID=" + id);
|
updateStmt.setString(1, value);
|
||||||
throw new Exception();
|
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;
|
return recordsEncrypted;
|
||||||
} // encryptColumnContents
|
} // encryptColumnContents
|
||||||
|
|
||||||
|
@ -348,7 +353,7 @@ public class ColumnEncryption extends SvrProcess {
|
||||||
for (int i = 0; i < colLength; i++) {
|
for (int i = 0; i < colLength; i++) {
|
||||||
str.append("1");
|
str.append("1");
|
||||||
}
|
}
|
||||||
str = new StringBuilder().append(SecureEngine.encrypt(str.toString()));
|
str = new StringBuilder().append(SecureEngine.encrypt(str.toString(), 0));
|
||||||
return str.length();
|
return str.length();
|
||||||
} // encryptedColumnLength
|
} // encryptedColumnLength
|
||||||
|
|
||||||
|
@ -387,34 +392,36 @@ public class ColumnEncryption extends SvrProcess {
|
||||||
updateSql.append(" WHERE AD_Column_ID=").append(columnID);
|
updateSql.append(" WHERE AD_Column_ID=").append(columnID);
|
||||||
|
|
||||||
PreparedStatement selectStmt = null;
|
PreparedStatement selectStmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
selectStmt = m_conn.prepareStatement(selectSql.toString(),
|
|
||||||
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
|
try {
|
||||||
|
selectStmt = m_conn.prepareStatement(selectSql.toString(),
|
||||||
selectStmt.setInt(1, columnID);
|
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
|
||||||
ResultSet rs = selectStmt.executeQuery();
|
|
||||||
|
selectStmt.setInt(1, columnID);
|
||||||
if (rs.next()) {
|
rs = selectStmt.executeQuery();
|
||||||
// Change the column size physically.
|
|
||||||
if (DB.executeUpdate(alterSql.toString(), false, m_trx
|
if (rs.next()) {
|
||||||
.getTrxName()) == -1) {
|
// Change the column size physically.
|
||||||
log.warning("EncryptError [ChangeFieldLength]: ColumnID="
|
if (DB.executeUpdate(alterSql.toString(), false, m_trx
|
||||||
+ columnID + ", NewLength=" + length);
|
.getTrxName()) == -1) {
|
||||||
throw new Exception();
|
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) {
|
// Change the column size in AD.
|
||||||
log.warning("EncryptError [ChangeFieldLength]: ColumnID="
|
if (DB.executeUpdate(updateSql.toString(), false, m_trx
|
||||||
+ columnID + ", NewLength=" + length);
|
.getTrxName()) == -1) {
|
||||||
throw new Exception();
|
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.
|
// Update number of rows effected.
|
||||||
rowsEffected++;
|
rowsEffected++;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.adempiere.base.keystore.default">
|
||||||
|
<implementation class="org.compiere.util.DefaultKeyStore"/>
|
||||||
|
<service>
|
||||||
|
<provide interface="org.adempiere.base.IKeyStore"/>
|
||||||
|
</service>
|
||||||
|
</scr:component>
|
|
@ -104,6 +104,14 @@ public class Core {
|
||||||
return Service.locator().locate(ModelValidator.class, "org.adempiere.base.ModelValidator", serviceId, null).getService();
|
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
|
* Get payment processor instance
|
||||||
* @param mbap payment processor model
|
* @param mbap payment processor model
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1814,7 +1814,7 @@ public class GridTable extends AbstractTableModel
|
||||||
else
|
else
|
||||||
iii = new Integer(dd.toString());
|
iii = new Integer(dd.toString());
|
||||||
if (encrypted)
|
if (encrypted)
|
||||||
iii = (Integer)encrypt(iii);
|
iii = (Integer)encrypt(iii, getAD_Client_ID());
|
||||||
if (manualUpdate)
|
if (manualUpdate)
|
||||||
createUpdateSql (columnName, String.valueOf (iii));
|
createUpdateSql (columnName, String.valueOf (iii));
|
||||||
else
|
else
|
||||||
|
@ -1834,7 +1834,7 @@ public class GridTable extends AbstractTableModel
|
||||||
{
|
{
|
||||||
BigDecimal bd = (BigDecimal)rowData[col];
|
BigDecimal bd = (BigDecimal)rowData[col];
|
||||||
if (encrypted)
|
if (encrypted)
|
||||||
bd = (BigDecimal)encrypt(bd);
|
bd = (BigDecimal)encrypt(bd, getAD_Client_ID());
|
||||||
if (manualUpdate)
|
if (manualUpdate)
|
||||||
createUpdateSql (columnName, bd.toString ());
|
createUpdateSql (columnName, bd.toString ());
|
||||||
else
|
else
|
||||||
|
@ -1846,7 +1846,7 @@ public class GridTable extends AbstractTableModel
|
||||||
{
|
{
|
||||||
Timestamp ts = (Timestamp)rowData[col];
|
Timestamp ts = (Timestamp)rowData[col];
|
||||||
if (encrypted)
|
if (encrypted)
|
||||||
ts = (Timestamp)encrypt(ts);
|
ts = (Timestamp)encrypt(ts, getAD_Client_ID());
|
||||||
if (manualUpdate)
|
if (manualUpdate)
|
||||||
createUpdateSql (columnName, DB.TO_DATE (ts, false));
|
createUpdateSql (columnName, DB.TO_DATE (ts, false));
|
||||||
else
|
else
|
||||||
|
@ -1884,7 +1884,7 @@ public class GridTable extends AbstractTableModel
|
||||||
{
|
{
|
||||||
String str = rowData[col].toString ();
|
String str = rowData[col].toString ();
|
||||||
if (encrypted)
|
if (encrypted)
|
||||||
str = (String)encrypt(str);
|
str = (String)encrypt(str, getAD_Client_ID());
|
||||||
if (manualUpdate)
|
if (manualUpdate)
|
||||||
createUpdateSql (columnName, DB.TO_STRING (str));
|
createUpdateSql (columnName, DB.TO_STRING (str));
|
||||||
else
|
else
|
||||||
|
@ -3121,7 +3121,7 @@ public class GridTable extends AbstractTableModel
|
||||||
{
|
{
|
||||||
String str = rs.getString(j+1);
|
String str = rs.getString(j+1);
|
||||||
if (field.isEncryptedColumn())
|
if (field.isEncryptedColumn())
|
||||||
str = (String)decrypt(str);
|
str = (String)decrypt(str, getAD_Client_ID());
|
||||||
rowData[j] = new Boolean ("Y".equals(str)); // Boolean
|
rowData[j] = new Boolean ("Y".equals(str)); // Boolean
|
||||||
}
|
}
|
||||||
// LOB
|
// LOB
|
||||||
|
@ -3152,7 +3152,7 @@ public class GridTable extends AbstractTableModel
|
||||||
rowData[j] = rs.getString(j+1); // String
|
rowData[j] = rs.getString(j+1); // String
|
||||||
// Encrypted
|
// Encrypted
|
||||||
if (field.isEncryptedColumn() && displayType != DisplayType.YesNo)
|
if (field.isEncryptedColumn() && displayType != DisplayType.YesNo)
|
||||||
rowData[j] = decrypt(rowData[j]);
|
rowData[j] = decrypt(rowData[j], getAD_Client_ID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
|
@ -3167,11 +3167,11 @@ public class GridTable extends AbstractTableModel
|
||||||
* @param xx clear data
|
* @param xx clear data
|
||||||
* @return encrypted value
|
* @return encrypted value
|
||||||
*/
|
*/
|
||||||
private Object encrypt (Object xx)
|
private Object encrypt (Object xx, int AD_Client_ID)
|
||||||
{
|
{
|
||||||
if (xx == null)
|
if (xx == null)
|
||||||
return null;
|
return null;
|
||||||
return SecureEngine.encrypt(xx);
|
return SecureEngine.encrypt(xx, AD_Client_ID);
|
||||||
} // encrypt
|
} // encrypt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3179,13 +3179,23 @@ public class GridTable extends AbstractTableModel
|
||||||
* @param yy encrypted data
|
* @param yy encrypted data
|
||||||
* @return clear data
|
* @return clear data
|
||||||
*/
|
*/
|
||||||
private Object decrypt (Object yy)
|
private Object decrypt (Object yy, int AD_Client_ID)
|
||||||
{
|
{
|
||||||
if (yy == null)
|
if (yy == null)
|
||||||
return null;
|
return null;
|
||||||
return SecureEngine.decrypt(yy);
|
return SecureEngine.decrypt(yy, AD_Client_ID);
|
||||||
} // decrypt
|
} // 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
|
* Remove Data Status Listener
|
||||||
* @param l listener
|
* @param l listener
|
||||||
|
|
|
@ -3020,8 +3020,9 @@ public abstract class PO
|
||||||
{
|
{
|
||||||
if (xx == null)
|
if (xx == null)
|
||||||
return null;
|
return null;
|
||||||
if (index != -1 && p_info.isEncrypted(index))
|
if (index != -1 && p_info.isEncrypted(index)) {
|
||||||
return SecureEngine.encrypt(xx);
|
return SecureEngine.encrypt(xx, getAD_Client_ID());
|
||||||
|
}
|
||||||
return xx;
|
return xx;
|
||||||
} // encrypt
|
} // encrypt
|
||||||
|
|
||||||
|
@ -3035,8 +3036,9 @@ public abstract class PO
|
||||||
{
|
{
|
||||||
if (yy == null)
|
if (yy == null)
|
||||||
return null;
|
return null;
|
||||||
if (index != -1 && p_info.isEncrypted(index))
|
if (index != -1 && p_info.isEncrypted(index)) {
|
||||||
return SecureEngine.decrypt(yy);
|
return SecureEngine.decrypt(yy, getAD_Client_ID());
|
||||||
|
}
|
||||||
return yy;
|
return yy;
|
||||||
} // decrypt
|
} // decrypt
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -515,7 +515,7 @@ public final class Ini implements Serializable
|
||||||
else if (!isClient())
|
else if (!isClient())
|
||||||
result = s_prop.getProperty (key, SecureInterface.CLEARVALUE_START + defaultValue + SecureInterface.CLEARVALUE_END);
|
result = s_prop.getProperty (key, SecureInterface.CLEARVALUE_START + defaultValue + SecureInterface.CLEARVALUE_END);
|
||||||
else
|
else
|
||||||
result = s_prop.getProperty (key, SecureEngine.encrypt(defaultValue));
|
result = s_prop.getProperty (key, SecureEngine.encrypt(defaultValue, 0));
|
||||||
s_prop.setProperty (key, result);
|
s_prop.setProperty (key, result);
|
||||||
return result;
|
return result;
|
||||||
} // checkProperty
|
} // checkProperty
|
||||||
|
@ -577,7 +577,7 @@ public final class Ini implements Serializable
|
||||||
s_prop.setProperty(key, "");
|
s_prop.setProperty(key, "");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String eValue = SecureEngine.encrypt(value);
|
String eValue = SecureEngine.encrypt(value, 0);
|
||||||
if (eValue == null)
|
if (eValue == null)
|
||||||
s_prop.setProperty(key, "");
|
s_prop.setProperty(key, "");
|
||||||
else
|
else
|
||||||
|
@ -619,7 +619,7 @@ public final class Ini implements Serializable
|
||||||
if (retStr == null || retStr.length() == 0)
|
if (retStr == null || retStr.length() == 0)
|
||||||
return "";
|
return "";
|
||||||
//
|
//
|
||||||
String value = SecureEngine.decrypt(retStr);
|
String value = SecureEngine.decrypt(retStr, 0);
|
||||||
// getLogger().finer(key + "=" + value);
|
// getLogger().finer(key + "=" + value);
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -304,35 +304,27 @@ public class Login
|
||||||
if ( user.authenticateHash(app_pwd) )
|
if ( user.authenticateHash(app_pwd) )
|
||||||
{
|
{
|
||||||
authenticated = true;
|
authenticated = true;
|
||||||
app_pwd = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
StringBuffer sql = new StringBuffer("SELECT AD_User.AD_User_ID,")
|
StringBuffer sql = new StringBuffer("SELECT AD_User.AD_User_ID ").append(" FROM AD_User ");
|
||||||
.append(" AD_User.ConnectionProfile ")
|
|
||||||
.append(" FROM AD_User ");
|
|
||||||
sql.append(" WHERE ").append(userNameCol).append("=?");
|
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')");
|
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;
|
PreparedStatement pstmt1=null;
|
||||||
ResultSet rs1=null;
|
ResultSet rs1=null;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
pstmt1 = DB.prepareStatement(sql.toString(), null);
|
pstmt1 = DB.prepareStatement(sql.toString(), null);
|
||||||
pstmt1.setString(1, app_user);
|
pstmt1.setString(1, app_user);
|
||||||
if (app_pwd != null)
|
|
||||||
{
|
|
||||||
pstmt1.setString(2, app_pwd);
|
|
||||||
pstmt1.setString(3, SecureEngine.encrypt(app_pwd));
|
|
||||||
}
|
|
||||||
rs1 = pstmt1.executeQuery();
|
rs1 = pstmt1.executeQuery();
|
||||||
|
|
||||||
while(rs1.next()){
|
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) {
|
}catch (Exception ex) {
|
||||||
|
@ -349,9 +341,8 @@ public class Login
|
||||||
}
|
}
|
||||||
|
|
||||||
if(authenticated){
|
if(authenticated){
|
||||||
StringBuffer sql = new StringBuffer("SELECT AD_User.AD_User_ID, r.AD_Role_ID,r.Name,")
|
StringBuffer sql = new StringBuffer("SELECT AD_User.AD_User_ID, r.AD_Role_ID,r.Name")
|
||||||
.append(" AD_User.ConnectionProfile ")
|
.append(" FROM AD_User ")
|
||||||
.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_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') ");
|
.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')");
|
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");
|
sql.append(" ORDER BY r.Name");
|
||||||
|
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
|
@ -372,11 +359,6 @@ public class Login
|
||||||
pstmt = DB.prepareStatement(sql.toString(), null);
|
pstmt = DB.prepareStatement(sql.toString(), null);
|
||||||
pstmt.setString(1, app_user);
|
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
|
// execute a query
|
||||||
rs = pstmt.executeQuery();
|
rs = pstmt.executeQuery();
|
||||||
|
|
||||||
|
@ -413,13 +395,16 @@ public class Login
|
||||||
}
|
}
|
||||||
|
|
||||||
do // read all roles
|
do // read all roles
|
||||||
{
|
{
|
||||||
int AD_Role_ID = rs.getInt(2);
|
MUser user = new MUser(m_ctx, rs.getInt(1), null);
|
||||||
if (AD_Role_ID == 0)
|
if (user.getPassword() != null && user.getPassword().equals(app_pwd)) {
|
||||||
Env.setContext(m_ctx, "#SysAdmin", "Y");
|
int AD_Role_ID = rs.getInt(2);
|
||||||
String Name = rs.getString(3);
|
if (AD_Role_ID == 0)
|
||||||
KeyNamePair p = new KeyNamePair(AD_Role_ID, Name);
|
Env.setContext(m_ctx, "#SysAdmin", "Y");
|
||||||
list.add(p);
|
String Name = rs.getString(3);
|
||||||
|
KeyNamePair p = new KeyNamePair(AD_Role_ID, Name);
|
||||||
|
list.add(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (rs.next());
|
while (rs.next());
|
||||||
//
|
//
|
||||||
|
@ -440,6 +425,7 @@ public class Login
|
||||||
{
|
{
|
||||||
DB.close(rs, pstmt);
|
DB.close(rs, pstmt);
|
||||||
rs = null; pstmt = null;
|
rs = null; pstmt = null;
|
||||||
|
app_pwd = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//long ms = System.currentTimeMillis () - start;
|
//long ms = System.currentTimeMillis () - start;
|
||||||
|
@ -1333,7 +1319,7 @@ public class Login
|
||||||
valid = user.authenticateHash(app_pwd);
|
valid = user.authenticateHash(app_pwd);
|
||||||
} else {
|
} else {
|
||||||
// password not hashed
|
// password not hashed
|
||||||
valid = user.getPassword().equals(app_pwd);
|
valid = user.getPassword() != null && user.getPassword().equals(app_pwd);
|
||||||
}
|
}
|
||||||
if (valid ) {
|
if (valid ) {
|
||||||
if (user.isLocked())
|
if (user.isLocked())
|
||||||
|
|
|
@ -26,7 +26,9 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.SecretKey;
|
|
||||||
|
import org.adempiere.base.Core;
|
||||||
|
import org.adempiere.base.IKeyStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Security Services.
|
* Security Services.
|
||||||
|
@ -128,14 +130,11 @@ public class Secure implements SecureInterface
|
||||||
{
|
{
|
||||||
initCipher();
|
initCipher();
|
||||||
} // Secure
|
} // Secure
|
||||||
|
|
||||||
/** Adempiere Cipher */
|
|
||||||
private Cipher m_cipher = null;
|
|
||||||
/** Adempiere Key */
|
|
||||||
private SecretKey m_key = null;
|
|
||||||
/** Message Digest */
|
/** Message Digest */
|
||||||
private MessageDigest m_md = null;
|
private MessageDigest m_md = null;
|
||||||
|
|
||||||
|
private IKeyStore m_keyStore = null;
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static Logger log = Logger.getLogger (Secure.class.getName());
|
private static Logger log = Logger.getLogger (Secure.class.getName());
|
||||||
|
|
||||||
|
@ -144,34 +143,10 @@ public class Secure implements SecureInterface
|
||||||
*/
|
*/
|
||||||
private synchronized void initCipher()
|
private synchronized void initCipher()
|
||||||
{
|
{
|
||||||
if (m_cipher != null)
|
if(m_keyStore==null){
|
||||||
return;
|
m_keyStore = getKeyStore();
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
log.log(Level.SEVERE, "", ex);
|
|
||||||
}
|
|
||||||
m_cipher = cc;
|
|
||||||
} // initCipher
|
} // initCipher
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,35 +154,35 @@ public class Secure implements SecureInterface
|
||||||
/**
|
/**
|
||||||
* Encryption.
|
* Encryption.
|
||||||
* @param value clear value
|
* @param value clear value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return encrypted String
|
* @return encrypted String
|
||||||
*/
|
*/
|
||||||
public String encrypt (String value)
|
public String encrypt (String value,int AD_Client_ID)
|
||||||
{
|
{
|
||||||
String clearText = value;
|
String clearText = value;
|
||||||
if (clearText == null)
|
if (clearText == null)
|
||||||
clearText = "";
|
clearText = "";
|
||||||
// Init
|
// Init
|
||||||
if (m_cipher == null)
|
if (m_keyStore == null)
|
||||||
initCipher();
|
initCipher();
|
||||||
// Encrypt
|
|
||||||
if (m_cipher != null)
|
// Encrypt
|
||||||
{
|
try {
|
||||||
try
|
Cipher cipher = Cipher.getInstance(m_keyStore.getAlgorithm());
|
||||||
{
|
|
||||||
m_cipher.init(Cipher.ENCRYPT_MODE, m_key);
|
cipher.init(Cipher.ENCRYPT_MODE, m_keyStore.getKey(AD_Client_ID));
|
||||||
byte[] encBytes = m_cipher.doFinal(clearText.getBytes("UTF8"));
|
byte[] encBytes = cipher.doFinal(clearText.getBytes("UTF8"));
|
||||||
String encString = convertToHexString(encBytes);
|
|
||||||
// globalqss - [ 1577737 ] Security Breach - show database password
|
String encString = convertToHexString(encBytes);
|
||||||
// log.log (Level.ALL, value + " => " + encString);
|
// globalqss - [ 1577737 ] Security Breach - show database password
|
||||||
return encString;
|
// log.log (Level.ALL, value + " => " + encString);
|
||||||
}
|
return encString;
|
||||||
catch (Exception ex)
|
} catch (Exception ex) {
|
||||||
{
|
// log.log(Level.INFO, value, ex);
|
||||||
// log.log(Level.INFO, value, ex);
|
log.log(Level.INFO, "Problem encrypting string", ex);
|
||||||
log.log(Level.INFO, "Problem encrypting string", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Fallback
|
|
||||||
|
// Fallback
|
||||||
return CLEARVALUE_START + value + CLEARVALUE_END;
|
return CLEARVALUE_START + value + CLEARVALUE_END;
|
||||||
} // encrypt
|
} // encrypt
|
||||||
|
|
||||||
|
@ -215,9 +190,10 @@ public class Secure implements SecureInterface
|
||||||
* Decryption.
|
* Decryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value encrypted value
|
* @param value encrypted value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return decrypted String
|
* @return decrypted String
|
||||||
*/
|
*/
|
||||||
public String decrypt (String value)
|
public String decrypt (String value,int AD_Client_ID)
|
||||||
{
|
{
|
||||||
if (value == null || value.length() == 0)
|
if (value == null || value.length() == 0)
|
||||||
return value;
|
return value;
|
||||||
|
@ -238,17 +214,18 @@ public class Secure implements SecureInterface
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
// Init
|
// Init
|
||||||
if (m_cipher == null)
|
if (m_keyStore == null)
|
||||||
initCipher();
|
initCipher();
|
||||||
|
|
||||||
// Encrypt
|
// Encrypt
|
||||||
if (m_cipher != null && value != null && value.length() > 0)
|
if (value != null && value.length() > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AlgorithmParameters ap = m_cipher.getParameters();
|
Cipher cipher = Cipher.getInstance(m_keyStore.getAlgorithm());
|
||||||
m_cipher.init(Cipher.DECRYPT_MODE, m_key, ap);
|
AlgorithmParameters ap = cipher.getParameters();
|
||||||
byte[] out = m_cipher.doFinal(data);
|
cipher.init(Cipher.DECRYPT_MODE, m_keyStore.getKey(AD_Client_ID), ap);
|
||||||
|
byte[] out = cipher.doFinal(data);
|
||||||
String retValue = new String(out, "UTF8");
|
String retValue = new String(out, "UTF8");
|
||||||
// globalqss - [ 1577737 ] Security Breach - show database password
|
// globalqss - [ 1577737 ] Security Breach - show database password
|
||||||
// log.log (Level.ALL, value + " => " + retValue);
|
// log.log (Level.ALL, value + " => " + retValue);
|
||||||
|
@ -267,9 +244,10 @@ public class Secure implements SecureInterface
|
||||||
* Encryption.
|
* Encryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value clear value
|
* @param value clear value
|
||||||
|
* @param ad_client_id
|
||||||
* @return encrypted String
|
* @return encrypted String
|
||||||
*/
|
*/
|
||||||
public Integer encrypt (Integer value)
|
public Integer encrypt (Integer value,int ad_client_id)
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
} // encrypt
|
} // encrypt
|
||||||
|
@ -280,7 +258,7 @@ public class Secure implements SecureInterface
|
||||||
* @param value encrypted value
|
* @param value encrypted value
|
||||||
* @return decrypted String
|
* @return decrypted String
|
||||||
*/
|
*/
|
||||||
public Integer decrypt (Integer value)
|
public Integer decrypt (Integer value,int ad_client_id)
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
} // decrypt
|
} // decrypt
|
||||||
|
@ -289,9 +267,10 @@ public class Secure implements SecureInterface
|
||||||
* Encryption.
|
* Encryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value clear value
|
* @param value clear value
|
||||||
|
* @param ad_client_id
|
||||||
* @return encrypted String
|
* @return encrypted String
|
||||||
*/
|
*/
|
||||||
public BigDecimal encrypt (BigDecimal value)
|
public BigDecimal encrypt (BigDecimal value,int ad_client_id)
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
} // encrypt
|
} // encrypt
|
||||||
|
@ -302,7 +281,7 @@ public class Secure implements SecureInterface
|
||||||
* @param value encrypted value
|
* @param value encrypted value
|
||||||
* @return decrypted String
|
* @return decrypted String
|
||||||
*/
|
*/
|
||||||
public BigDecimal decrypt (BigDecimal value)
|
public BigDecimal decrypt (BigDecimal value,int ad_client_id)
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
} // decrypt
|
} // decrypt
|
||||||
|
@ -311,9 +290,10 @@ public class Secure implements SecureInterface
|
||||||
* Encryption.
|
* Encryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value clear value
|
* @param value clear value
|
||||||
|
* @param ad_client_id
|
||||||
* @return encrypted String
|
* @return encrypted String
|
||||||
*/
|
*/
|
||||||
public Timestamp encrypt (Timestamp value)
|
public Timestamp encrypt (Timestamp value,int ad_client_id)
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
} // encrypt
|
} // encrypt
|
||||||
|
@ -324,7 +304,7 @@ public class Secure implements SecureInterface
|
||||||
* @param value encrypted value
|
* @param value encrypted value
|
||||||
* @return decrypted String
|
* @return decrypted String
|
||||||
*/
|
*/
|
||||||
public Timestamp decrypt (Timestamp value)
|
public Timestamp decrypt (Timestamp value,int ad_client_id)
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
} // decrypt
|
} // decrypt
|
||||||
|
@ -412,9 +392,20 @@ public class Secure implements SecureInterface
|
||||||
public String toString ()
|
public String toString ()
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder ("Secure[");
|
StringBuilder sb = new StringBuilder ("Secure[");
|
||||||
sb.append(m_cipher)
|
sb.append(m_keyStore.getAlgorithm())
|
||||||
.append ("]");
|
.append ("]");
|
||||||
return sb.toString ();
|
return sb.toString ();
|
||||||
} // toString
|
} // toString
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return keystore
|
||||||
|
*/
|
||||||
|
public IKeyStore getKeyStore(){
|
||||||
|
IKeyStore keyStore = Core.getKeyStore();
|
||||||
|
if(keyStore==null)
|
||||||
|
keyStore = new DefaultKeyStore();
|
||||||
|
|
||||||
|
return keyStore;
|
||||||
|
}
|
||||||
} // Secure
|
} // Secure
|
||||||
|
|
|
@ -106,9 +106,10 @@ public class SecureEngine
|
||||||
* Encryption.
|
* Encryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value clear value
|
* @param value clear value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return encrypted String
|
* @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)
|
if (value == null || value.length() == 0)
|
||||||
return value;
|
return value;
|
||||||
|
@ -119,19 +120,21 @@ public class SecureEngine
|
||||||
if (inQuotes)
|
if (inQuotes)
|
||||||
value = value.substring(1, value.length()-1);
|
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)
|
if (inQuotes)
|
||||||
return "'" + retValue + "'";
|
return "'" + retValue + "'";
|
||||||
return retValue;
|
return retValue;
|
||||||
} // encrypt
|
} // encrypt
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decryption.
|
* Decryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value encrypted value
|
* @param value encrypted value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return decrypted String
|
* @return decrypted String
|
||||||
*/
|
*/
|
||||||
public static String decrypt (String value)
|
public static String decrypt (String value, int AD_Client_ID)
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -144,22 +147,23 @@ public class SecureEngine
|
||||||
if (value.startsWith(SecureInterface.CLEARVALUE_START) && value.endsWith(SecureInterface.CLEARVALUE_END))
|
if (value.startsWith(SecureInterface.CLEARVALUE_START) && value.endsWith(SecureInterface.CLEARVALUE_END))
|
||||||
retValue = value.substring(SecureInterface.CLEARVALUE_START.length(), value.length()-SecureInterface.CLEARVALUE_END.length());
|
retValue = value.substring(SecureInterface.CLEARVALUE_START.length(), value.length()-SecureInterface.CLEARVALUE_END.length());
|
||||||
else
|
else
|
||||||
retValue = s_engine.implementation.decrypt(value);
|
retValue = s_engine.implementation.decrypt(value,AD_Client_ID);
|
||||||
if (inQuotes)
|
if (inQuotes)
|
||||||
return "'" + retValue + "'";
|
return "'" + retValue + "'";
|
||||||
return retValue;
|
return retValue;
|
||||||
} // decrypt
|
} // decrypt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encryption.
|
* Encryption.
|
||||||
* The methods must recognize clear values
|
* The methods must recognize clear values
|
||||||
* @param value clear value
|
* @param value clear value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return encrypted String
|
* @return encrypted String
|
||||||
*/
|
*/
|
||||||
public static Object encrypt (Object value)
|
public static Object encrypt (Object value, int AD_Client_ID)
|
||||||
{
|
{
|
||||||
if (value instanceof String)
|
if (value instanceof String)
|
||||||
return encrypt((String) value);
|
return encrypt((String) value, AD_Client_ID);
|
||||||
return value;
|
return value;
|
||||||
} // encrypt
|
} // encrypt
|
||||||
|
|
||||||
|
@ -169,10 +173,10 @@ public class SecureEngine
|
||||||
* @param value encrypted value
|
* @param value encrypted value
|
||||||
* @return decrypted String
|
* @return decrypted String
|
||||||
*/
|
*/
|
||||||
public static Object decrypt (Object value)
|
public static Object decrypt (Object value, int AD_Client_ID)
|
||||||
{
|
{
|
||||||
if (value instanceof String)
|
if (value instanceof String)
|
||||||
return decrypt((String) value);
|
return decrypt((String) value, AD_Client_ID);
|
||||||
return value;
|
return value;
|
||||||
} // decrypt
|
} // decrypt
|
||||||
|
|
||||||
|
@ -204,8 +208,8 @@ public class SecureEngine
|
||||||
System.exit(10);
|
System.exit(10);
|
||||||
}
|
}
|
||||||
// See if it works
|
// See if it works
|
||||||
String testE = implementation.encrypt(TEST);
|
String testE = implementation.encrypt(TEST,0);
|
||||||
String testC = implementation.decrypt(testE);
|
String testC = implementation.decrypt(testE,0);
|
||||||
if (!testC.equals(TEST))
|
if (!testC.equals(TEST))
|
||||||
throw new IllegalStateException(realClass
|
throw new IllegalStateException(realClass
|
||||||
+ ": " + TEST
|
+ ": " + TEST
|
||||||
|
@ -269,10 +273,10 @@ public class SecureEngine
|
||||||
log.info("Decrypt null =" + test(decrypt(null), null));
|
log.info("Decrypt null =" + test(decrypt(null), null));
|
||||||
log.info("Decrypt test =" + test(decrypt("test"), "test"));
|
log.info("Decrypt test =" + test(decrypt("test"), "test"));
|
||||||
**/
|
**/
|
||||||
log.info("Decrypt {test} =" + test(decrypt("af2309f390afed74"), "test"));
|
log.info("Decrypt {test} =" + test(decrypt("af2309f390afed74", 0), "test"));
|
||||||
log.info("Decrypt ~{test}~ =" + test(decrypt(SecureInterface.ENCRYPTEDVALUE_START + "af2309f390afed74" + SecureInterface.ENCRYPTEDVALUE_END), "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"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,64 +52,71 @@ public interface SecureInterface
|
||||||
/**
|
/**
|
||||||
* Encryption.
|
* Encryption.
|
||||||
* @param value clear value
|
* @param value clear value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return encrypted String
|
* @return encrypted String
|
||||||
*/
|
*/
|
||||||
public String encrypt (String value);
|
public String encrypt (String value,int AD_Client_ID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decryption.
|
* Decryption.
|
||||||
* @param value encrypted value
|
* @param value encrypted value
|
||||||
* @return decrypted String
|
* @return decrypted String
|
||||||
*/
|
*/
|
||||||
public String decrypt (String value);
|
public String decrypt (String value,int AD_Client_ID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encryption.
|
* Encryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value clear value
|
* @param value clear value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return encrypted String
|
* @return encrypted String
|
||||||
*/
|
*/
|
||||||
public Integer encrypt (Integer value);
|
public Integer encrypt (Integer value,int AD_Client_ID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decryption.
|
* Decryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value encrypted value
|
* @param value encrypted value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return decrypted String
|
* @return decrypted String
|
||||||
*/
|
*/
|
||||||
public Integer decrypt (Integer value);
|
public Integer decrypt (Integer value,int AD_Client_ID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encryption.
|
* Encryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value clear value
|
* @param value clear value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return encrypted String
|
* @return encrypted String
|
||||||
*/
|
*/
|
||||||
public BigDecimal encrypt (BigDecimal value);
|
public BigDecimal encrypt (BigDecimal value,int AD_Client_ID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decryption.
|
* Decryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value encrypted value
|
* @param value encrypted value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return decrypted String
|
* @return decrypted String
|
||||||
*/
|
*/
|
||||||
public BigDecimal decrypt (BigDecimal value);
|
public BigDecimal decrypt (BigDecimal value,int AD_Client_ID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encryption.
|
* Encryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value clear value
|
* @param value clear value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return encrypted String
|
* @return encrypted String
|
||||||
*/
|
*/
|
||||||
public Timestamp encrypt (Timestamp value);
|
public Timestamp encrypt (Timestamp value,int AD_Client_ID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decryption.
|
* Decryption.
|
||||||
* The methods must recognize clear text values
|
* The methods must recognize clear text values
|
||||||
* @param value encrypted value
|
* @param value encrypted value
|
||||||
|
* @param AD_Client_ID
|
||||||
* @return decrypted String
|
* @return decrypted String
|
||||||
*/
|
*/
|
||||||
public Timestamp decrypt (Timestamp value);
|
public Timestamp decrypt (Timestamp value,int AD_Client_ID);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -682,8 +682,6 @@ public class WebUser
|
||||||
{
|
{
|
||||||
String sql = "SELECT * FROM AD_User "
|
String sql = "SELECT * FROM AD_User "
|
||||||
+ "WHERE COALESCE(LDAPUser, Name)=? " // #1
|
+ "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
|
+ " AND IsActive='Y' " // #4
|
||||||
;
|
;
|
||||||
PreparedStatement pstmt = null;
|
PreparedStatement pstmt = null;
|
||||||
|
@ -692,14 +690,17 @@ public class WebUser
|
||||||
{
|
{
|
||||||
pstmt = DB.prepareStatement (sql, null);
|
pstmt = DB.prepareStatement (sql, null);
|
||||||
pstmt.setString (1, m_bpc.getName());
|
pstmt.setString (1, m_bpc.getName());
|
||||||
pstmt.setString (2, password);
|
|
||||||
pstmt.setString (3, SecureEngine.encrypt(password));
|
|
||||||
rs = pstmt.executeQuery ();
|
rs = pstmt.executeQuery ();
|
||||||
if (rs.next ())
|
if (rs.next ())
|
||||||
{
|
{
|
||||||
retValue = true;
|
do
|
||||||
if (rs.next())
|
{
|
||||||
log.warning ("More then one user with Name/Password = " + m_bpc.getName());
|
MUser user = new MUser(Env.getCtx(), rs, null);
|
||||||
|
if (user.getPassword() != null && user.getPassword().equals(password)) {
|
||||||
|
retValue = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (rs.next());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log.fine("No record");
|
log.fine("No record");
|
||||||
|
|
|
@ -1697,7 +1697,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
|
||||||
GridField field = getTargetMField(ColumnName);
|
GridField field = getTargetMField(ColumnName);
|
||||||
// add encryption here if the field is encrypted.
|
// add encryption here if the field is encrypted.
|
||||||
if (field.isEncryptedColumn()) {
|
if (field.isEncryptedColumn()) {
|
||||||
value = SecureEngine.encrypt(value);
|
value = SecureEngine.encrypt(value, Env.getAD_Client_ID(Env.getCtx()));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID());
|
boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID());
|
||||||
|
|
Loading…
Reference in New Issue